Initial stable/unstable split done.

-Yosh
This commit is contained in:
Manish Singh 1998-02-20 10:41:20 +00:00
parent 6d3d71865f
commit beddbcd626
82 changed files with 1579 additions and 19842 deletions

View file

@ -1,3 +1,7 @@
Fri Feb 20 02:38:24 PST 1998 Manish Singh <yosh@gimp.org>
* initial plug-in stable/unstable split
Wed Feb 18 16:46:37 1998 Owen Taylor <owt1@cornell.edu> Wed Feb 18 16:46:37 1998 Owen Taylor <owt1@cornell.edu>
* plug-ins/ifscompose/ifscompose.c: refcounting fixups * plug-ins/ifscompose/ifscompose.c: refcounting fixups

View file

@ -148,17 +148,17 @@ dnl Test for libmpeg
AC_MSG_WARN(*** MPEG plug-in will not be built ***)) AC_MSG_WARN(*** MPEG plug-in will not be built ***))
fi fi
dnl Test for libtcl #dnl Test for libtcl
if test -z "$LIBTCL_LIB"; then # if test -z "$LIBTCL_LIB"; then
AC_CHECK_LIB(dl, dlopen, DL_LIBRARY=-ldl) # AC_CHECK_LIB(dl, dlopen, DL_LIBRARY=-ldl)
AC_ARG_WITH(tcl, --with-{tcl/tk} use this tcl/tk library, # AC_ARG_WITH(tcl, --with-{tcl/tk} use this tcl/tk library,
AC_CHECK_LIB($with_tcl, Tcl_StaticPackage, # AC_CHECK_LIB($with_tcl, Tcl_StaticPackage,
GIMPTCL='gimptcl'; LIBTCL_LIB="-l$with_tcl -l$with_tk $DL_LIBRARY", # GIMPTCL='gimptcl'; LIBTCL_LIB="-l$with_tcl -l$with_tk $DL_LIBRARY",
AC_MSG_WARN(*** gimptcl plug-in will not be built ***), -lm $DL_LIBRARY), # AC_MSG_WARN(*** gimptcl plug-in will not be built ***), -lm $DL_LIBRARY),
AC_CHECK_LIB(tcl, Tcl_StaticPackage, # AC_CHECK_LIB(tcl, Tcl_StaticPackage,
GIMPTCL='gimptcl'; LIBTCL_LIB="-ltcl -ltk $DL_LIBRARY", # GIMPTCL='gimptcl'; LIBTCL_LIB="-ltcl -ltk $DL_LIBRARY",
AC_MSG_WARN(*** gimptcl plug-in will not be built ***), -lm $DL_LIBRARY)) # AC_MSG_WARN(*** gimptcl plug-in will not be built ***), -lm $DL_LIBRARY))
fi # fi
dnl Test for libxdelta dnl Test for libxdelta
if test -z "$LIBXDELTA_LIB"; then if test -z "$LIBXDELTA_LIB"; then
@ -256,8 +256,8 @@ AC_SUBST(PNG)
AC_SUBST(LIBPNG_LIB) AC_SUBST(LIBPNG_LIB)
AC_SUBST(MPEG) AC_SUBST(MPEG)
AC_SUBST(LIBMPEG_LIB) AC_SUBST(LIBMPEG_LIB)
AC_SUBST(GIMPTCL) #AC_SUBST(GIMPTCL)
AC_SUBST(LIBTCL_LIB) #AC_SUBST(LIBTCL_LIB)
AC_SUBST(XD) AC_SUBST(XD)
AC_SUBST(LIBXDELTA_LIB) AC_SUBST(LIBXDELTA_LIB)
AC_SUBST(XPM) AC_SUBST(XPM)
@ -288,7 +288,6 @@ plug-ins/mblur/Makefile
plug-ins/maze/Makefile plug-ins/maze/Makefile
plug-ins/max_rgb/Makefile plug-ins/max_rgb/Makefile
plug-ins/mail/Makefile plug-ins/mail/Makefile
plug-ins/magiceye/Makefile
plug-ins/laplace/Makefile plug-ins/laplace/Makefile
plug-ins/ifscompose/Makefile plug-ins/ifscompose/Makefile
plug-ins/iwarp/Makefile plug-ins/iwarp/Makefile
@ -319,7 +318,6 @@ plug-ins/depthmerge/Makefile
plug-ins/deinterlace/Makefile plug-ins/deinterlace/Makefile
plug-ins/decompose/Makefile plug-ins/decompose/Makefile
plug-ins/cubism/Makefile plug-ins/cubism/Makefile
plug-ins/coordmap/Makefile
plug-ins/compose/Makefile plug-ins/compose/Makefile
plug-ins/checkerboard/Makefile plug-ins/checkerboard/Makefile
plug-ins/bz2/Makefile plug-ins/bz2/Makefile
@ -338,10 +336,7 @@ plug-ins/bmp/Makefile
plug-ins/megawidget/Makefile plug-ins/megawidget/Makefile
plug-ins/blur/Makefile plug-ins/blur/Makefile
plug-ins/flame/Makefile plug-ins/flame/Makefile
plug-ins/gimptcl/Makefile
plug-ins/gimptcl/scripts/Makefile
plug-ins/struc/Makefile plug-ins/struc/Makefile
plug-ins/user_filter/Makefile
plug-ins/zealouscrop/Makefile plug-ins/zealouscrop/Makefile
plug-ins/xwd/Makefile plug-ins/xwd/Makefile
plug-ins/whirlpinch/Makefile plug-ins/whirlpinch/Makefile
@ -350,14 +345,12 @@ plug-ins/vpropagate/Makefile
plug-ins/vinvert/Makefile plug-ins/vinvert/Makefile
plug-ins/video/Makefile plug-ins/video/Makefile
plug-ins/url/Makefile plug-ins/url/Makefile
plug-ins/universal/Makefile
plug-ins/tiler/Makefile plug-ins/tiler/Makefile
plug-ins/tile/Makefile plug-ins/tile/Makefile
plug-ins/tileit/Makefile plug-ins/tileit/Makefile
plug-ins/threshold_alpha/Makefile plug-ins/threshold_alpha/Makefile
plug-ins/tga/Makefile plug-ins/tga/Makefile
plug-ins/sunras/Makefile plug-ins/sunras/Makefile
plug-ins/stereogram/Makefile
plug-ins/spread/Makefile plug-ins/spread/Makefile
plug-ins/sparkle/Makefile plug-ins/sparkle/Makefile
plug-ins/sobel/Makefile plug-ins/sobel/Makefile
@ -366,14 +359,12 @@ plug-ins/snoise/Makefile
plug-ins/smooth_palette/Makefile plug-ins/smooth_palette/Makefile
plug-ins/sinus/Makefile plug-ins/sinus/Makefile
plug-ins/shift/Makefile plug-ins/shift/Makefile
plug-ins/sharpen/Makefile
plug-ins/sgi/Makefile plug-ins/sgi/Makefile
plug-ins/scatter_hsv/Makefile plug-ins/scatter_hsv/Makefile
plug-ins/rotators/Makefile plug-ins/rotators/Makefile
plug-ins/rotate/Makefile plug-ins/rotate/Makefile
plug-ins/ripple/Makefile plug-ins/ripple/Makefile
plug-ins/randomize/Makefile plug-ins/randomize/Makefile
plug-ins/psd/Makefile
plug-ins/ps/Makefile plug-ins/ps/Makefile
plug-ins/print/Makefile plug-ins/print/Makefile
plug-ins/polar/Makefile plug-ins/polar/Makefile
@ -382,7 +373,6 @@ plug-ins/plasma/Makefile
plug-ins/pixelize/Makefile plug-ins/pixelize/Makefile
plug-ins/pcx/Makefile plug-ins/pcx/Makefile
plug-ins/pat/Makefile plug-ins/pat/Makefile
plug-ins/blur2/Makefile
plug-ins/blinds/Makefile plug-ins/blinds/Makefile
plug-ins/autostretch_hsv/Makefile plug-ins/autostretch_hsv/Makefile
plug-ins/autocrop/Makefile plug-ins/autocrop/Makefile

View file

@ -2,10 +2,8 @@
SUBDIRS = \ SUBDIRS = \
megawidget \ megawidget \
libgck \
AlienMap \ AlienMap \
dbbrowser \ dbbrowser \
@GIMPTCL@ \
script-fu \ script-fu \
struc \ struc \
@TIFF@ \ @TIFF@ \
@ -22,7 +20,6 @@ SUBDIRS = \
autostretch_hsv \ autostretch_hsv \
blinds \ blinds \
blur \ blur \
blur2 \
bmp \ bmp \
bumpmap \ bumpmap \
bz2 \ bz2 \
@ -32,7 +29,6 @@ SUBDIRS = \
colorify \ colorify \
compose \ compose \
convmatrix \ convmatrix \
coordmap \
cubism \ cubism \
decompose \ decompose \
deinterlace \ deinterlace \
@ -69,7 +65,6 @@ SUBDIRS = \
illusion \ illusion \
iwarp \ iwarp \
laplace \ laplace \
magiceye \
mail \ mail \
max_rgb \ max_rgb \
maze \ maze \
@ -97,7 +92,6 @@ SUBDIRS = \
rotators \ rotators \
scatter_hsv \ scatter_hsv \
sgi \ sgi \
sharpen \
shift \ shift \
sinus \ sinus \
smooth_palette \ smooth_palette \
@ -106,14 +100,12 @@ SUBDIRS = \
sobel \ sobel \
sparkle \ sparkle \
spread \ spread \
stereogram \
sunras \ sunras \
tga \ tga \
threshold_alpha \ threshold_alpha \
tile \ tile \
tileit \ tileit \
tiler \ tiler \
universal \
url \ url \
video \ video \
vinvert \ vinvert \

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
blur2

View file

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = blur2
blur2_SOURCES = \
blur2.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
blur2_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View file

@ -1,544 +0,0 @@
/*
* This is a plug-in for the GIMP.
*
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
* Copyright (C) 1996 Torsten Martinsen
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
/*
* This filter is like the standard 'blur', except that it uses
* a convolution kernel of variable size.
*
* I am greatly indebted to Johan Klockars <d8klojo@dtek.chalmers.se>
* for supplying the algorithm used here, which is of complexity O(1).
* Compared with the original naive algorithm, which is O(k^2) (where
* k is the kernel size), it gives _massive_ speed improvements.
* The code is quite simple, too.
*/
#include <stdlib.h>
#include <stdio.h> /**/
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#define ENTRY_WIDTH 30
#define SCALE_WIDTH 125
typedef struct {
gdouble mask_size;
} BlurVals;
typedef struct {
gint run;
} BlurInterface;
/* Declare local functions.
*/
static void query(void);
static void run(char *name,
int nparams,
GParam * param,
int *nreturn_vals,
GParam ** return_vals);
static void blur(GDrawable * drawable);
static gint blur2_dialog ();
static void blur2_close_callback (GtkWidget *widget,
gpointer data);
static void blur2_ok_callback (GtkWidget *widget,
gpointer data);
static void blur2_scale_update (GtkAdjustment *adjustment,
double *scale_val);
static void blur2_entry_update (GtkWidget *widget,
gdouble *value);
static void dialog_create_value (char *title,
GtkTable *table,
int row,
gdouble *value,
double left,
double right);
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
static BlurVals bvals =
{
6+5.0 /* mask size */
};
static BlurInterface bint =
{
FALSE /* run */
};
MAIN()
static void
query()
{
static GParamDef args[] =
{
{PARAM_INT32, "run_mode", "Interactive, non-interactive"},
{PARAM_IMAGE, "image", "Input image (unused)"},
{PARAM_DRAWABLE, "drawable", "Input drawable"},
{PARAM_INT32, "mask_size", "Blur mask size"},
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof(args[0]);
static int nreturn_vals = 0;
gimp_install_procedure("plug_in_blur2",
"Blur the contents of the specified drawable",
"This function applies a NxN blurring convolution kernel to the specified drawable.",
"Torsten Martinsen",
"Torsten Martinsen",
"1996-1997",
"<Image>/Filters/Blur/Variable Blur",
"RGB, GRAY",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
static void
run(char *name,
int nparams,
GParam * param,
int *nreturn_vals,
GParam ** return_vals)
{
static GParam values[1];
GDrawable *drawable;
GRunModeType run_mode;
GStatusType status = STATUS_SUCCESS;
run_mode = param[0].data.d_int32;
switch (run_mode) {
case RUN_INTERACTIVE:
/* Possibly retrieve data */
gimp_get_data("plug_in_blur2", &bvals);
/* First acquire information with a dialog */
if (!blur2_dialog())
return;
break;
case RUN_NONINTERACTIVE:
/* Make sure all the arguments are there! */
if (nparams != 4)
status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS) {
bvals.mask_size = (gdouble) param[3].data.d_int32;
}
if (status == STATUS_SUCCESS &&
(bvals.mask_size < 1.0))
status = STATUS_CALLING_ERROR;
break;
case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */
gimp_get_data("plug_in_blur2", &bvals);
break;
default:
break;
}
/* Get the specified drawable */
drawable = gimp_drawable_get(param[2].data.d_drawable);
/* Make sure that the drawable is gray or RGB color */
if (gimp_drawable_color(drawable->id) || gimp_drawable_gray(drawable->id)) {
gimp_progress_init("Variable Blur");
gimp_tile_cache_ntiles(2 * (drawable->width / gimp_tile_width() + 1));
blur(drawable);
if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush();
/* Store data */
if (run_mode == RUN_INTERACTIVE)
gimp_set_data ("plug_in_blur2", &bvals, sizeof (BlurVals));
} else {
/* gimp_message ("blur2: cannot operate on indexed color images"); */
status = STATUS_EXECUTION_ERROR;
}
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
gimp_drawable_detach(drawable);
}
static void
blur(GDrawable * drawable)
{
GPixelRgn srcPR, destPR;
gint width, height;
gint bytes;
guchar *dest, *d;
guchar *cr, *cc;
gint sum[4];
gint row, col, i, n, div;
gint x1, y1, x2, y2;
/* Get the input area. This is the bounding box of the selection in
* the image (or the entire image if there is no selection). Only
* operating on the input area is simply an optimization. It doesn't
* need to be done for correct operation. (It simply makes it go
* faster, since fewer pixels need to be operated on).
*/
gimp_drawable_mask_bounds(drawable->id, &x1, &y1, &x2, &y2);
/* Get the size of the input image. (This will/must be the same
* as the size of the output image).
*/
width = drawable->width;
height = drawable->height;
bytes = drawable->bpp;
n = bvals.mask_size;
/* Include edges if possible */
x1 = MAX(x1 - n / 2, 0);
x2 = MIN(x2 + n / 2 + 1, width);
y1 = MAX(y1 - n / 2, 0);
y2 = MIN(y2 + n / 2 + 1, height);
/* initialize the pixel regions */
gimp_pixel_rgn_init(&srcPR, drawable, 0, 0, width, height, FALSE, FALSE);
gimp_pixel_rgn_init(&destPR, drawable, 0, 0, width, height, TRUE, TRUE);
/* allocate row buffers */
cr = (guchar *) malloc((x2 - x1 + 2) * bytes);
dest = (guchar *) malloc((x2 - x1) * bytes);
/* loop through the rows, applying horizontal blur */
for (row = y1; row < y2; row++) {
gimp_pixel_rgn_get_row(&srcPR, cr, x1, row, (x2 - x1));
d = dest + bytes * (n / 2);
for (i = 0; i < bytes; ++i)
sum[i] = 0;
for (i = 0; i < n * bytes; ++i)
sum[i % bytes] += cr[i];
for (col = 0; col < (x2 - x1 - n) * bytes; col++) {
sum[col % bytes] += cr[col + n * bytes] - cr[col];
*d++ = sum[col % bytes]/n;
}
/* store the dest */
gimp_pixel_rgn_set_row(&destPR, dest, x1, row, (x2 - x1));
if ((row % 5) == 0)
gimp_progress_update((double) (row/2) / (double) (x2 - x1));
}
free(cr);
free(dest);
cc = (guchar *) malloc((y2 - y1 + 2) * bytes);
dest = (guchar *) malloc((y2 - y1) * bytes);
/* loop through the columns, applying vertical blur */
for (col = x1; col < x2; col++) {
gimp_pixel_rgn_get_col(&destPR, cc, col, y1, (y2 - y1));
d = dest + bytes * (n / 2);
for (i = 0; i < bytes; ++i)
sum[i] = 0;
for (i = 0; i < n * bytes; ++i)
sum[i % bytes] += cc[i];
for (row = 0; row < (y2 - y1 - n) * bytes; row++) {
sum[row % bytes] += cc[row + n * bytes] - cc[row];
*d++ = sum[row % bytes]/n;
}
/* store the dest */
gimp_pixel_rgn_set_col(&destPR, dest, col, y1, (y2 - y1));
if ((col % 5) == 0)
gimp_progress_update(((double) (x2-x1)/2+(col/2)) / (double) (x2-x1));
}
div = n/2+1;
if (y1-n/2 < 0)
for (col = x1; col < x2; ++col) {
gimp_pixel_rgn_get_col(&srcPR, cc, col, 0, div);
gimp_pixel_rgn_set_col(&destPR, cc, col, 0, div);
}
if (y2+n/2 > height)
for (col = x1; col < x2; ++col) {
gimp_pixel_rgn_get_col(&srcPR, cc, col, height-div, div);
gimp_pixel_rgn_set_col(&destPR, cc, col, height-div, div);
}
if (x1-n/2 < 0)
for (row = y1; row < y2; ++row) {
gimp_pixel_rgn_get_row(&srcPR, cr, 0, row, div);
gimp_pixel_rgn_set_row(&destPR, cr, 0, row, div);
}
if (x2+n/2 > width)
for (row = y1; row < y2; ++row) {
gimp_pixel_rgn_get_row(&srcPR, cr, width-div, row, div);
gimp_pixel_rgn_set_row(&destPR, cr, width-div, row, div);
}
#if 0
/* Do remaining top pixels, if any */
if (y1-n/2 < 0) {
for (col = x1; col < x2; ++col) {
div = n/2+1;
gimp_pixel_rgn_get_col(&srcPR, cc, col, 0, div);
d = dest;
s = cc;
for (i = 0; i < bytes; ++i)
sum[i] = 0;
for (i = 0; i < div * bytes; ++i)
sum[i % bytes] += *s++;
memset(dest, 0, (y2 - y1) * bytes);
for (i = 0; i < bytes; ++i)
*d++ = sum[i]/div;
for (row = 0; row < n/2; ++row) {
++div;
for (i = 0; i < bytes; ++i) {
sum[i] += *s++;
*d++ = sum[i]/div;
}
}
gimp_pixel_rgn_set_col(&destPR, dest, col, 0, n/2+1);
}
}
/* Do remaining bottom pixels, if any */
if (y2+n/2 > height) {
for (col = x1; col < x2; ++col) {
div = n/2+1;
gimp_pixel_rgn_get_col(&srcPR, cc, col, height-1-div, div);
s = cc+div*bytes-1;
d = dest+div*bytes-1; /* points to last byte */
for (i = 0; i < bytes; ++i)
sum[i] = 0;
for (i = 0; i < div * bytes; ++i)
sum[i % bytes] += *s--;
for (i = 0; i < bytes; ++i)
*d-- = sum[i]/div;
for (row = 0; row < n/2; ++row) {
for (i = 0; i < bytes; ++i) {
sum[i] += *s--;
*d-- = sum[i]/div;
}
++div;
}
gimp_pixel_rgn_set_col(&destPR, dest, col, height-1-div, n/2+1);
}
}
#endif
free(cc);
free(dest);
/* update the blurred region */
gimp_drawable_flush(drawable);
gimp_drawable_merge_shadow(drawable->id, TRUE);
gimp_drawable_update(drawable->id, x1, y1, (x2 - x1), (y2 - y1));
}
static gint
blur2_dialog ()
{
GtkWidget *dlg;
GtkWidget *button;
GtkWidget *frame;
GtkWidget *table;
gchar **argv;
gint argc;
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("blur2");
gtk_init (&argc, &argv);
dlg = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dlg), "Variable Blur");
gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
(GtkSignalFunc) blur2_close_callback,
NULL);
/* Action area */
button = gtk_button_new_with_label ("OK");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) blur2_ok_callback,
dlg);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_grab_default (button);
gtk_widget_show (button);
button = gtk_button_new_with_label ("Cancel");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (dlg));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
/* parameter settings */
frame = gtk_frame_new ("Parameter Settings");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 10);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0);
table = gtk_table_new (3, 3, FALSE);
gtk_container_border_width (GTK_CONTAINER (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
dialog_create_value("Mask Size", GTK_TABLE(table), 1, &bvals.mask_size, 3.0, 50.0);
gtk_widget_show (frame);
gtk_widget_show (table);
gtk_widget_show (dlg);
gtk_main ();
gdk_flush ();
return bint.run;
}
static void
blur2_close_callback (GtkWidget *widget,
gpointer data)
{
gtk_main_quit ();
}
static void
blur2_ok_callback (GtkWidget *widget,
gpointer data)
{
bint.run = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}
/*
* Thanks to Quartic for these.
*/
static void
dialog_create_value(char *title, GtkTable *table, int row, gdouble *value, double left, double right)
{
GtkWidget *label;
GtkWidget *scale;
GtkWidget *entry;
GtkObject *scale_data;
char buf[256];
label = gtk_label_new(title);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(table, label, 0, 1, row, row + 1, GTK_FILL, GTK_FILL, 4, 0);
gtk_widget_show(label);
scale_data = gtk_adjustment_new(*value, left, right,
1.0, 5.0, 5.0);
gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed",
(GtkSignalFunc) blur2_scale_update,
value);
scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data));
gtk_widget_set_usize(scale, SCALE_WIDTH, 0);
gtk_table_attach(table, scale, 1, 2, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_scale_set_draw_value(GTK_SCALE(scale), FALSE);
gtk_scale_set_digits(GTK_SCALE(scale), 3);
gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_CONTINUOUS);
gtk_widget_show(scale);
entry = gtk_entry_new();
gtk_object_set_user_data(GTK_OBJECT(entry), scale_data);
gtk_object_set_user_data(scale_data, entry);
gtk_widget_set_usize(entry, ENTRY_WIDTH, 0);
sprintf(buf, "%.0f", *value);
gtk_entry_set_text(GTK_ENTRY(entry), buf);
gtk_signal_connect(GTK_OBJECT(entry), "changed",
(GtkSignalFunc) blur2_entry_update,
value);
gtk_table_attach(GTK_TABLE(table), entry, 2, 3, row, row + 1, GTK_FILL, GTK_FILL, 4, 0);
gtk_widget_show(entry);
}
static void
blur2_entry_update(GtkWidget *widget, gdouble *value)
{
GtkAdjustment *adjustment;
gdouble new_value;
new_value = atof(gtk_entry_get_text(GTK_ENTRY(widget)));
if (*value != new_value) {
adjustment = gtk_object_get_user_data(GTK_OBJECT(widget));
if ((new_value >= adjustment->lower) &&
(new_value <= adjustment->upper)) {
*value = new_value;
adjustment->value = new_value;
gtk_signal_emit_by_name(GTK_OBJECT(adjustment), "value_changed");
} /* if */
} /* if */
}
static void
blur2_scale_update (GtkAdjustment *adjustment, gdouble *value)
{
GtkWidget *entry;
char buf[256];
if (*value != adjustment->value) {
*value = adjustment->value;
entry = gtk_object_get_user_data(GTK_OBJECT(adjustment));
sprintf(buf, "%.0f", *value);
gtk_signal_handler_block_by_data(GTK_OBJECT(entry), value);
gtk_entry_set_text(GTK_ENTRY(entry), buf);
gtk_signal_handler_unblock_by_data(GTK_OBJECT(entry), value);
} /* if */
}

View file

@ -27,6 +27,19 @@
*/ */
/* Version 1.0:
* This is the follow-up release. It contains a few minor changes, the
* most major being that the first time I released the wrong version of
* the code, and this time the changes have been fixed. I also added
* tooltips to the dialog.
*
* Feel free to email me if you have any comments or suggestions on this
* plugin.
* --Daniel Dunbar
* ddunbar@diads.com
*/
/* Version .5: /* Version .5:
* This is the first version publicly released, it will probably be the * This is the first version publicly released, it will probably be the
* last also unless i can think of some features i want to add. * last also unless i can think of some features i want to add.
@ -73,9 +86,9 @@
typedef struct { typedef struct {
gdouble circle; gdouble circle;
gdouble angle; gdouble angle;
gint8 backwards; gint backwards;
gint8 inverse; gint inverse;
gint8 polrec; gint polrec;
} polarize_vals_t; } polarize_vals_t;
typedef struct { typedef struct {
@ -129,9 +142,8 @@ static void dialog_close_callback(GtkWidget *widget, gpointer data);
static void dialog_ok_callback(GtkWidget *widget, gpointer data); static void dialog_ok_callback(GtkWidget *widget, gpointer data);
static void dialog_cancel_callback(GtkWidget *widget, gpointer data); static void dialog_cancel_callback(GtkWidget *widget, gpointer data);
static void backwards_toggled(GtkWidget *widget, gpointer data); static void polar_toggle_callback(GtkWidget *widget, gpointer data);
static void top_toggled(GtkWidget *widget, gpointer data); static void set_tooltip (GtkTooltips *tooltips, GtkWidget *widget, const char *desc);
static void pr_toggled(GtkWidget *widget, gpointer data);
/***** Variables *****/ /***** Variables *****/
@ -142,22 +154,22 @@ GPlugInInfo PLUG_IN_INFO = {
run /* run_proc */ run /* run_proc */
}; /* PLUG_IN_INFO */ }; /* PLUG_IN_INFO */
static polarize_vals_t wpvals = { static polarize_vals_t pcvals = {
100.0, /* circle */ 100.0, /* circle */
0.0, /* angle */ 0.0, /* angle */
0, /* backwards */ 0, /* backwards */
1, /* inverse */ 1, /* inverse */
1 /* polar to rectangular? */ 1 /* polar to rectangular? */
}; /* wpvals */ }; /* pcvals */
static polarize_interface_t wpint = { static polarize_interface_t pcint = {
NULL, /* preview */ NULL, /* preview */
NULL, /* check_row_0 */ NULL, /* check_row_0 */
NULL, /* check_row_1 */ NULL, /* check_row_1 */
NULL, /* image */ NULL, /* image */
NULL, /* dimage */ NULL, /* dimage */
FALSE /* run */ FALSE /* run */
}; /* wpint */ }; /* pcint */
static GDrawable *drawable; static GDrawable *drawable;
@ -289,7 +301,7 @@ run(char *name,
case RUN_INTERACTIVE: case RUN_INTERACTIVE:
/* Possibly retrieve data */ /* Possibly retrieve data */
gimp_get_data(PLUG_IN_NAME, &wpvals); gimp_get_data(PLUG_IN_NAME, &pcvals);
/* Get information from the dialog */ /* Get information from the dialog */
@ -305,11 +317,11 @@ run(char *name,
status = STATUS_CALLING_ERROR; status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS) { if (status == STATUS_SUCCESS) {
wpvals.circle = param[3].data.d_float; pcvals.circle = param[3].data.d_float;
wpvals.angle = param[4].data.d_float; pcvals.angle = param[4].data.d_float;
wpvals.backwards = param[5].data.d_int8; pcvals.backwards = param[5].data.d_int8;
wpvals.inverse = param[6].data.d_int8; pcvals.inverse = param[6].data.d_int8;
wpvals.polrec = param[7].data.d_int8; pcvals.polrec = param[7].data.d_int8;
} /* if */ } /* if */
break; break;
@ -317,7 +329,7 @@ run(char *name,
case RUN_WITH_LAST_VALS: case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */ /* Possibly retrieve data */
gimp_get_data(PLUG_IN_NAME, &wpvals); gimp_get_data(PLUG_IN_NAME, &pcvals);
break; break;
default: default:
@ -345,7 +357,7 @@ run(char *name,
/* Store data */ /* Store data */
if (run_mode == RUN_INTERACTIVE) if (run_mode == RUN_INTERACTIVE)
gimp_set_data(PLUG_IN_NAME, &wpvals, sizeof(polarize_vals_t)); gimp_set_data(PLUG_IN_NAME, &pcvals, sizeof(polarize_vals_t));
} else if (status == STATUS_SUCCESS) } else if (status == STATUS_SUCCESS)
status = STATUS_EXECUTION_ERROR; status = STATUS_EXECUTION_ERROR;
@ -472,11 +484,11 @@ calc_undistorted_coords(double wx, double wy,
ydiff = y2 - y1; ydiff = y2 - y1;
xm = xdiff / 2.0; xm = xdiff / 2.0;
ym = ydiff / 2.0; ym = ydiff / 2.0;
circle = wpvals.circle; circle = pcvals.circle;
angle = wpvals.angle; angle = pcvals.angle;
angl = (double)angle / 180.0 * M_PI; angl = (double)angle / 180.0 * M_PI;
if (wpvals.polrec) { if (pcvals.polrec) {
if (wx >= cen_x) { if (wx >= cen_x) {
if (wy > cen_y) { if (wy > cen_y) {
phi = M_PI - atan (((double)(wx - cen_x))/((double)(wy - cen_y))); phi = M_PI - atan (((double)(wx - cen_x))/((double)(wy - cen_y)));
@ -526,12 +538,12 @@ calc_undistorted_coords(double wx, double wy,
phi = fmod (phi + angl, 2*M_PI); phi = fmod (phi + angl, 2*M_PI);
if (wpvals.backwards) if (pcvals.backwards)
x_calc = x2 - 1 - (x2 - x1 - 1)/(2*M_PI) * phi; x_calc = x2 - 1 - (x2 - x1 - 1)/(2*M_PI) * phi;
else else
x_calc = (x2 - x1 - 1)/(2*M_PI) * phi + x1; x_calc = (x2 - x1 - 1)/(2*M_PI) * phi + x1;
if (wpvals.inverse) if (pcvals.inverse)
y_calc = (y2 - y1)/rmax * r + y1; y_calc = (y2 - y1)/rmax * r + y1;
else else
y_calc = y2 - (y2 - y1)/rmax * r; y_calc = y2 - (y2 - y1)/rmax * r;
@ -549,7 +561,7 @@ calc_undistorted_coords(double wx, double wy,
} }
} else { } else {
if (wpvals.backwards) if (pcvals.backwards)
phi = (2 * M_PI) * (x2 - wx) / xdiff; phi = (2 * M_PI) * (x2 - wx) / xdiff;
else else
phi = (2 * M_PI) * (wx - x1) / xdiff; phi = (2 * M_PI) * (wx - x1) / xdiff;
@ -598,7 +610,7 @@ calc_undistorted_coords(double wx, double wy,
rmax = (rmax - t) / 100.0 * (100 - circle) + t; rmax = (rmax - t) / 100.0 * (100 - circle) + t;
if (wpvals.inverse) if (pcvals.inverse)
r = rmax * (double)((wy - y1) / (double)(ydiff)); r = rmax * (double)((wy - y1) / (double)(ydiff));
else else
r = rmax * (double)((y2 - wy) / (double)(ydiff)); r = rmax * (double)((y2 - wy) / (double)(ydiff));
@ -778,10 +790,10 @@ build_preview_source_image(void)
guchar pixel[4]; guchar pixel[4];
pixel_fetcher_t *pf; pixel_fetcher_t *pf;
wpint.check_row_0 = g_malloc(preview_width * sizeof(guchar)); pcint.check_row_0 = g_malloc(preview_width * sizeof(guchar));
wpint.check_row_1 = g_malloc(preview_width * sizeof(guchar)); pcint.check_row_1 = g_malloc(preview_width * sizeof(guchar));
wpint.image = g_malloc(preview_width * preview_height * 4 * sizeof(guchar)); pcint.image = g_malloc(preview_width * preview_height * 4 * sizeof(guchar));
wpint.dimage = g_malloc(preview_width * preview_height * 3 * sizeof(guchar)); pcint.dimage = g_malloc(preview_width * preview_height * 3 * sizeof(guchar));
left = sel_x1; left = sel_x1;
right = sel_x2 - 1; right = sel_x2 - 1;
@ -795,7 +807,7 @@ build_preview_source_image(void)
pf = pixel_fetcher_new(drawable); pf = pixel_fetcher_new(drawable);
p = wpint.image; p = pcint.image;
for (y = 0; y < preview_height; y++) { for (y = 0; y < preview_height; y++) {
px = left; px = left;
@ -804,11 +816,11 @@ build_preview_source_image(void)
/* Checks */ /* Checks */
if ((x / CHECK_SIZE) & 1) { if ((x / CHECK_SIZE) & 1) {
wpint.check_row_0[x] = CHECK_DARK; pcint.check_row_0[x] = CHECK_DARK;
wpint.check_row_1[x] = CHECK_LIGHT; pcint.check_row_1[x] = CHECK_LIGHT;
} else { } else {
wpint.check_row_0[x] = CHECK_LIGHT; pcint.check_row_0[x] = CHECK_LIGHT;
wpint.check_row_1[x] = CHECK_DARK; pcint.check_row_1[x] = CHECK_DARK;
} /* else */ } /* else */
/* Thumbnail image */ /* Thumbnail image */
@ -854,6 +866,8 @@ polarize_dialog(void)
GtkWidget *button; GtkWidget *button;
GtkWidget *toggle; GtkWidget *toggle;
GtkWidget *hbox; GtkWidget *hbox;
GtkTooltips *tips;
GdkColor tips_fg, tips_bg;
gint argc; gint argc;
gchar **argv; gchar **argv;
guchar *color_cube; guchar *color_cube;
@ -894,6 +908,21 @@ polarize_dialog(void)
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), top_table, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), top_table, FALSE, FALSE, 0);
gtk_widget_show(top_table); gtk_widget_show(top_table);
/* Initialize Tooltips */
/* use black as foreground: */
tips = gtk_tooltips_new ();
tips_fg.red = 0;
tips_fg.green = 0;
tips_fg.blue = 0;
/* postit yellow (khaki) as background: */
gdk_color_alloc (gtk_widget_get_colormap (dialog), &tips_fg);
tips_bg.red = 61669;
tips_bg.green = 59113;
tips_bg.blue = 35979;
gdk_color_alloc (gtk_widget_get_colormap (dialog), &tips_bg);
gtk_tooltips_set_colors (tips,&tips_bg,&tips_fg);
/* Preview */ /* Preview */
frame = gtk_frame_new(NULL); frame = gtk_frame_new(NULL);
@ -901,10 +930,10 @@ polarize_dialog(void)
gtk_table_attach(GTK_TABLE(top_table), frame, 1, 2, 0, 1, 0, 0, 0, 0); gtk_table_attach(GTK_TABLE(top_table), frame, 1, 2, 0, 1, 0, 0, 0, 0);
gtk_widget_show(frame); gtk_widget_show(frame);
wpint.preview = gtk_preview_new(GTK_PREVIEW_COLOR); pcint.preview = gtk_preview_new(GTK_PREVIEW_COLOR);
gtk_preview_size(GTK_PREVIEW(wpint.preview), preview_width, preview_height); gtk_preview_size(GTK_PREVIEW(pcint.preview), preview_width, preview_height);
gtk_container_add(GTK_CONTAINER(frame), wpint.preview); gtk_container_add(GTK_CONTAINER(frame), pcint.preview);
gtk_widget_show(wpint.preview); gtk_widget_show(pcint.preview);
/* Controls */ /* Controls */
@ -913,8 +942,8 @@ polarize_dialog(void)
gtk_table_attach(GTK_TABLE(top_table), table, 0, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(top_table), table, 0, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0);
gtk_widget_show(table); gtk_widget_show(table);
dialog_create_value("Circle depth in percent", GTK_TABLE(table), 0, &wpvals.circle, 0, 100.0, 1.0); dialog_create_value("Circle depth in percent", GTK_TABLE(table), 0, &pcvals.circle, 0, 100.0, 1.0);
dialog_create_value("Offset angle", GTK_TABLE(table), 1, &wpvals.angle, 0, 359, 1.0); dialog_create_value("Offset angle", GTK_TABLE(table), 1, &pcvals.angle, 0, 359, 1.0);
/* togglebuttons for backwards, top, polar->rectangular */ /* togglebuttons for backwards, top, polar->rectangular */
@ -923,23 +952,32 @@ polarize_dialog(void)
gtk_table_attach( GTK_TABLE(top_table), hbox, 0, 3, 2, 3, gtk_table_attach( GTK_TABLE(top_table), hbox, 0, 3, 2, 3,
GTK_FILL, 0 , 0, 0); GTK_FILL, 0 , 0, 0);
toggle = gtk_toggle_button_new_with_label("Map Backwards"); toggle = gtk_check_button_new_with_label("Map Backwards");
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), wpvals.backwards); gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), pcvals.backwards);
gtk_signal_connect( GTK_OBJECT(toggle), "clicked", (GtkSignalFunc)backwards_toggled,NULL); gtk_signal_connect(GTK_OBJECT(toggle), "clicked",
(GtkSignalFunc) polar_toggle_callback,
&pcvals.backwards);
gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0); gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0);
gtk_widget_show(toggle); gtk_widget_show(toggle);
set_tooltip(tips,toggle,"If checked the mapping will begin at the right side, as opposed to beginning at the left.");
toggle = gtk_toggle_button_new_with_label("Map from Top"); toggle = gtk_check_button_new_with_label("Map from Top");
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), wpvals.inverse); gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), pcvals.inverse);
gtk_signal_connect( GTK_OBJECT(toggle), "clicked", (GtkSignalFunc)top_toggled, NULL); gtk_signal_connect( GTK_OBJECT(toggle), "clicked",
(GtkSignalFunc) polar_toggle_callback,
&pcvals.inverse);
gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0); gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0);
gtk_widget_show(toggle); gtk_widget_show(toggle);
set_tooltip(tips,toggle,"If unchecked the mapping will put the bottom row in the middle and the top row on the outside. If checked it will be the opposite.");
toggle = gtk_toggle_button_new_with_label("Polar to Rectangular"); toggle = gtk_check_button_new_with_label("Polar to Rectangular");
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), wpvals.polrec); gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), pcvals.polrec);
gtk_signal_connect( GTK_OBJECT(toggle), "clicked", (GtkSignalFunc)pr_toggled, NULL); gtk_signal_connect( GTK_OBJECT(toggle), "clicked",
(GtkSignalFunc) polar_toggle_callback,
&pcvals.polrec);
gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0); gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0);
gtk_widget_show(toggle); gtk_widget_show(toggle);
set_tooltip(tips,toggle,"If unchecked the image will be circularly mapped onto a rectangle. If checked the image will be mapped onto a circle.");
gtk_widget_show(hbox); gtk_widget_show(hbox);
@ -970,14 +1008,15 @@ polarize_dialog(void)
dialog_update_preview(); dialog_update_preview();
gtk_main(); gtk_main();
gtk_object_unref(GTK_OBJECT(tips));
gdk_flush(); gdk_flush();
g_free(wpint.check_row_0); g_free(pcint.check_row_0);
g_free(wpint.check_row_1); g_free(pcint.check_row_1);
g_free(wpint.image); g_free(pcint.image);
g_free(wpint.dimage); g_free(pcint.dimage);
return wpint.run; return pcint.run;
} /* polarize_dialog */ } /* polarize_dialog */
@ -1019,16 +1058,16 @@ dialog_update_preview(void)
py = top; py = top;
p_ul = wpint.dimage; p_ul = pcint.dimage;
/* p_lr = wpint.dimage + 3 * (preview_width * preview_height - 1);*/ /* p_lr = pcint.dimage + 3 * (preview_width * preview_height - 1);*/
for (y = 0; y < preview_height; y++) { for (y = 0; y < preview_height; y++) {
px = left; px = left;
if ((y / CHECK_SIZE) & 1) if ((y / CHECK_SIZE) & 1)
check_ul = wpint.check_row_0; check_ul = pcint.check_row_0;
else else
check_ul = wpint.check_row_1; check_ul = pcint.check_row_1;
for (x = 0; x < preview_width; x++) { for (x = 0; x < preview_width; x++) {
calc_undistorted_coords(px, py, &cx, &cy); calc_undistorted_coords(px, py, &cx, &cy);
@ -1043,7 +1082,7 @@ dialog_update_preview(void)
if ((ix >= 0) && (ix < preview_width) && if ((ix >= 0) && (ix < preview_width) &&
(iy >= 0) && (iy < preview_height)) (iy >= 0) && (iy < preview_height))
i = wpint.image + 4 * (preview_width * iy + ix); i = pcint.image + 4 * (preview_width * iy + ix);
else else
i = outside; i = outside;
@ -1059,15 +1098,15 @@ dialog_update_preview(void)
py += dy; py += dy;
} /* for */ } /* for */
p = wpint.dimage; p = pcint.dimage;
for (y = 0; y < img_height; y++) { for (y = 0; y < img_height; y++) {
gtk_preview_draw_row(GTK_PREVIEW(wpint.preview), p, 0, y, preview_width); gtk_preview_draw_row(GTK_PREVIEW(pcint.preview), p, 0, y, preview_width);
p += preview_width * 3; p += preview_width * 3;
} /* for */ } /* for */
gtk_widget_draw(wpint.preview, NULL); gtk_widget_draw(pcint.preview, NULL);
gdk_flush(); gdk_flush();
} /* dialog_update_preview */ } /* dialog_update_preview */
@ -1183,7 +1222,7 @@ dialog_close_callback(GtkWidget *widget, gpointer data)
static void static void
dialog_ok_callback(GtkWidget *widget, gpointer data) dialog_ok_callback(GtkWidget *widget, gpointer data)
{ {
wpint.run = TRUE; pcint.run = TRUE;
gtk_widget_destroy(GTK_WIDGET(data)); gtk_widget_destroy(GTK_WIDGET(data));
} /* dialog_ok_callback */ } /* dialog_ok_callback */
@ -1196,25 +1235,23 @@ dialog_cancel_callback(GtkWidget *widget, gpointer data)
gtk_widget_destroy(GTK_WIDGET(data)); gtk_widget_destroy(GTK_WIDGET(data));
} /* dialog_cancel_callback */ } /* dialog_cancel_callback */
static void static void polar_toggle_callback (GtkWidget *widget, gpointer data)
backwards_toggled(GtkWidget *widget, gpointer data)
{ {
wpvals.backwards ^= 1; int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON (widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
dialog_update_preview(); dialog_update_preview();
} }
static void static void
top_toggled(GtkWidget *widget, gpointer data) set_tooltip (GtkTooltips *tooltips, GtkWidget *widget, const char *desc)
{ {
wpvals.inverse ^= 1; if (desc && desc[0])
dialog_update_preview(); gtk_tooltips_set_tips (tooltips, widget, (char *) desc);
} }
static void
pr_toggled(GtkWidget *widget, gpointer data)
{
wpvals.polrec ^= 1;
dialog_update_preview();
}

File diff suppressed because it is too large Load diff

View file

@ -30,8 +30,19 @@
/**************************************************************************** /****************************************************************************
* Randomize: * Randomize:
* *
* randomize version 1.0 (19 Oct 1997, MEO) * randomize version 1.4 (3 Feb 1998, MEO)
* history * history
* 1.4 - 3 Feb 1998 MEO
* added details to PDB parameter help strings
* 1.3 - 3 Feb 1998 MEO
* removed tooltips from action buttons
* fixed param[5] type (was int32, should have been float)
* 1.2 - 2 Feb 1998 MEO
* converted macro'd functions from 0.5 to inline functions
* 2 casts added for portability by 0.99.18 release coordinator
* moved from Distorts to Noise menu
* went to GUI convenience routines as much as reasonable
* broke out GUI convenience routines into gpc.h and gpc.c
* 1.1 - 30 Nov 1997 MEO * 1.1 - 30 Nov 1997 MEO
* added tooltips * added tooltips
* 1.0 - 19 Nov 1997 MEO * 1.0 - 19 Nov 1997 MEO
@ -120,6 +131,7 @@
#include <time.h> #include <time.h>
#include "libgimp/gimp.h" #include "libgimp/gimp.h"
#include "gtk/gtk.h" #include "gtk/gtk.h"
#include "gpc.h"
/********************************* /*********************************
* *
@ -127,11 +139,6 @@
* *
********************************/ ********************************/
/*
* Set this to 1 for faster processing, to 0 if for some
* reason you want all functions to be subroutines
*/
#define OPTIMIZE_SUBS 0
/* /*
* progress meter update frequency * progress meter update frequency
@ -139,11 +146,11 @@
#define PROG_UPDATE_TIME ((row % 10) == 0) #define PROG_UPDATE_TIME ((row % 10) == 0)
#define PLUG_IN_NAME "plug_in_randomize" #define PLUG_IN_NAME "plug_in_randomize"
#define RNDM_VERSION "Randomize 1.1" #define RNDM_VERSION "Randomize 1.4"
#define RNDM_BLUR 1 #define RNDM_BLUR 1
#define RNDM_PICK 2 #define RNDM_HURL 2
#define RNDM_HURL 3 #define RNDM_PICK 3
#define RNDM_SLUR 4 #define RNDM_SLUR 4
#define SEED_TIME 10 #define SEED_TIME 10
@ -208,52 +215,21 @@ GPlugInInfo PLUG_IN_INFO = {
static void randomize(GDrawable *drawable); static void randomize(GDrawable *drawable);
#if (OPTIMIZE_SUBS == 0) static inline void randomize_prepare_row(
static void randomize_prepare_row( GPixelRgn *pixel_rgn,
GPixelRgn *pixel_rgn, guchar *data,
guchar *data, int x,
int x, int y,
int y, int w
int w );
);
#endif
static gint randomize_dialog(); static gint randomize_dialog();
static void randomize_close_callback(
GtkWidget *widget,
gpointer data
);
static void randomize_ok_callback( static void randomize_ok_callback(
GtkWidget *widget, GtkWidget *widget,
gpointer data gpointer data
); );
static void randomize_cancel_callback(
GtkWidget *widget,
gpointer data
);
static void randomize_scale_update(
GtkAdjustment *adjustment,
double *scale_val
);
static void randomize_toggle_update(
GtkWidget *widget,
gpointer data
);
static void randomize_text_update(
GtkWidget *widget,
gpointer data
);
static void set_tooltip(
GtkWidget *widget,
const char *tip
);
static void setup_tooltips();
static GtkTooltips *tips;
/************************************ Guts ***********************************/ /************************************ Guts ***********************************/
@ -274,9 +250,10 @@ query()
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" }, { PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image (unused)" }, { PARAM_IMAGE, "image", "Input image (unused)" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" }, { PARAM_DRAWABLE, "drawable", "Input drawable" },
{ PARAM_INT32, "rndm_type", "Randomization type" }, { PARAM_INT32, "rndm_type",
{ PARAM_FLOAT, "rndm_pct", "Randomization percentage" }, "Randomization type (1=blur 2=hurl 3=pick 4=slur)" },
{ PARAM_FLOAT, "rndm_rcount", "Repeat count" }, { PARAM_FLOAT, "rndm_pct", "Randomization percentage (1 - 100)" },
{ PARAM_FLOAT, "rndm_rcount", "Repeat count(1 - 100)" },
}; };
static GParamDef *return_vals = NULL; static GParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof (args[0]); static int nargs = sizeof(args) / sizeof (args[0]);
@ -307,12 +284,14 @@ query()
* candidate, although in the spirit of randomity * candidate, although in the spirit of randomity
* we could pick one at random! * we could pick one at random!
*/ */
#define FIX_INDEX_BLUR() \ void
if (gimp_drawable_indexed(drawable->id)) { \ fix_index_blur(GDrawable *drawable) {
is_indexed_drawable = TRUE; \ if (gimp_drawable_indexed(drawable->id)) {
if (pivals.rndm_type == RNDM_BLUR) { \ is_indexed_drawable = TRUE;
pivals.rndm_type = RNDM_PICK; \ if (pivals.rndm_type == RNDM_BLUR) {
} \ pivals.rndm_type = RNDM_PICK;
}
}
} }
@ -358,7 +337,7 @@ run(char *name, int nparams, GParam *param, int *nreturn_vals,
* If we're running interactively, pop up the dialog box. * If we're running interactively, pop up the dialog box.
*/ */
case RUN_INTERACTIVE: case RUN_INTERACTIVE:
FIX_INDEX_BLUR(); fix_index_blur(drawable);
gimp_get_data(PLUG_IN_NAME, &pivals); gimp_get_data(PLUG_IN_NAME, &pivals);
if (!randomize_dialog()) /* return on Cancel */ if (!randomize_dialog()) /* return on Cancel */
return; return;
@ -370,14 +349,14 @@ run(char *name, int nparams, GParam *param, int *nreturn_vals,
* parameters have legitimate values. * parameters have legitimate values.
*/ */
case RUN_NONINTERACTIVE: case RUN_NONINTERACTIVE:
FIX_INDEX_BLUR(); fix_index_blur(drawable);
if (nparams != 6) { if (nparams != 6) {
status = STATUS_CALLING_ERROR; status = STATUS_CALLING_ERROR;
} }
if (status == STATUS_SUCCESS) { if (status == STATUS_SUCCESS) {
pivals.rndm_type = (gint) param[3].data.d_int32; pivals.rndm_type = (gint) param[3].data.d_int32;
pivals.rndm_pct = (gdouble) param[4].data.d_float; pivals.rndm_pct = (gdouble) param[4].data.d_float;
pivals.rndm_rcount = (gdouble) param[5].data.d_int32; pivals.rndm_rcount = (gdouble) param[5].data.d_float;
} }
if (status == STATUS_SUCCESS && if (status == STATUS_SUCCESS &&
((pivals.rndm_type != RNDM_PICK && ((pivals.rndm_type != RNDM_PICK &&
@ -401,39 +380,41 @@ run(char *name, int nparams, GParam *param, int *nreturn_vals,
default: default:
break; break;
} }
if (status == STATUS_SUCCESS) {
/* /*
* JUST DO IT! * JUST DO IT!
*/ */
switch (pivals.rndm_type) { switch (pivals.rndm_type) {
case RNDM_BLUR: rndm_type_str = "blur"; break; case RNDM_BLUR: rndm_type_str = "blur"; break;
case RNDM_HURL: rndm_type_str = "hurl"; break; case RNDM_HURL: rndm_type_str = "hurl"; break;
case RNDM_PICK: rndm_type_str = "pick"; break; case RNDM_PICK: rndm_type_str = "pick"; break;
case RNDM_SLUR: rndm_type_str = "slur"; break; case RNDM_SLUR: rndm_type_str = "slur"; break;
} }
sprintf(prog_label, "%s (%s)", RNDM_VERSION, rndm_type_str); sprintf(prog_label, "%s (%s)", RNDM_VERSION, rndm_type_str);
gimp_progress_init(prog_label); gimp_progress_init(prog_label);
gimp_tile_cache_ntiles(2 * (drawable->width / gimp_tile_width() + 1)); gimp_tile_cache_ntiles(2 * (drawable->width / gimp_tile_width() + 1));
/* /*
* Initialize the rand() function seed * Initialize the rand() function seed
*/ */
if (pivals.seed_type == SEED_TIME) if (pivals.seed_type == SEED_TIME)
srand(time(NULL)); srand(time(NULL));
else else
srand(pivals.rndm_seed); srand(pivals.rndm_seed);
randomize(drawable); randomize(drawable);
/* /*
* If we ran interactively (even repeating) update the display. * If we ran interactively (even repeating) update the display.
*/ */
if (run_mode != RUN_NONINTERACTIVE) { if (run_mode != RUN_NONINTERACTIVE) {
gimp_displays_flush(); gimp_displays_flush();
} }
/* /*
* If we use the dialog popup, set the data for future use. * If we use the dialog popup, set the data for future use.
*/ */
if (run_mode == RUN_INTERACTIVE) { if (run_mode == RUN_INTERACTIVE) {
gimp_set_data(PLUG_IN_NAME, &pivals, sizeof(RandomizeVals)); gimp_set_data(PLUG_IN_NAME, &pivals, sizeof(RandomizeVals));
} }
}
} else { } else {
/* /*
* If we got the wrong drawable type, we need to complain. * If we got the wrong drawable type, we need to complain.
@ -458,8 +439,7 @@ run(char *name, int nparams, GParam *param, int *nreturn_vals,
* *
********************************/ ********************************/
#if (OPTIMIZE_SUBS == 0) static inline void
static void
randomize_prepare_row(GPixelRgn *pixel_rgn, guchar *data, int x, int y, int w) randomize_prepare_row(GPixelRgn *pixel_rgn, guchar *data, int x, int y, int w)
{ {
int b; int b;
@ -479,27 +459,6 @@ randomize_prepare_row(GPixelRgn *pixel_rgn, guchar *data, int x, int y, int w)
data[w * pixel_rgn->bpp + b] = data[(w - 1) * pixel_rgn->bpp + b]; data[w * pixel_rgn->bpp + b] = data[(w - 1) * pixel_rgn->bpp + b];
} }
} }
#else
#define randomize_prepare_row(pixel_rgn, data, x, y, w) \
{ \
int b; \
\
if (y == 0) { \
gimp_pixel_rgn_get_row(pixel_rgn, data, x, (y + 1), w); \
} else if (y == (pixel_rgn)->h) { \
gimp_pixel_rgn_get_row(pixel_rgn, data, x, (y - 1), w); \
} else { \
gimp_pixel_rgn_get_row(pixel_rgn, data, x, y, w); \
} \
/* \
* Fill in edge pixels \
*/ \
for (b = 0; b < (pixel_rgn)->bpp; b++) { \
data[-(gint)(pixel_rgn)->bpp + b] = data[b]; \
data[w * (pixel_rgn)->bpp + b] = data[(w - 1) * (pixel_rgn)->bpp + b]; \
} \
}
#endif
/********************************* /*********************************
* *
@ -711,34 +670,6 @@ randomize(GDrawable *drawable)
* *
********************************/ ********************************/
#define randomize_add_action_button(label, callback, dialog, tip) \
{ \
GtkWidget *button; \
\
button = gtk_button_new_with_label(label); \
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); \
gtk_signal_connect(GTK_OBJECT(button), "clicked", callback, dialog); \
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), \
button, TRUE, TRUE, 0); \
gtk_widget_grab_default(button); \
gtk_widget_show(button); \
set_tooltip(button, tip); \
}
#define randomize_add_radio_button(group, label, box, callback, value, tip) \
{ \
GtkWidget *toggle; \
\
toggle = gtk_radio_button_new_with_label(group, label); \
group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle)); \
gtk_box_pack_start(GTK_BOX(box), toggle, FALSE, FALSE, 0); \
gtk_signal_connect(GTK_OBJECT(toggle), "toggled", \
(GtkSignalFunc) callback, value); \
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), *value); \
gtk_widget_show(toggle); \
gtk_widget_show(box); \
set_tooltip(toggle, tip); \
}
/********************************* /*********************************
* *
@ -749,9 +680,8 @@ randomize(GDrawable *drawable)
static gint static gint
randomize_dialog() randomize_dialog()
{ {
GtkWidget *dlg, *entry, *frame, *label, *scale, GtkWidget *dlg, *entry, *frame,
*seed_hbox, *seed_vbox, *table, *toggle_hbox; *seed_hbox, *seed_vbox, *table, *toggle_hbox;
GtkObject *scale_data;
GSList *type_group = NULL; GSList *type_group = NULL;
GSList *seed_group = NULL; GSList *seed_group = NULL;
gchar **argv; gchar **argv;
@ -781,7 +711,7 @@ randomize_dialog()
gtk_window_set_title(GTK_WINDOW(dlg), RNDM_VERSION); gtk_window_set_title(GTK_WINDOW(dlg), RNDM_VERSION);
gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE); gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dlg), "destroy", gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
(GtkSignalFunc) randomize_close_callback, NULL); (GtkSignalFunc) gpc_close_callback, NULL);
/* /*
* Parameter settings * Parameter settings
* *
@ -795,24 +725,18 @@ randomize_dialog()
gtk_container_border_width(GTK_CONTAINER(table), 10); gtk_container_border_width(GTK_CONTAINER(table), 10);
gtk_container_add(GTK_CONTAINER(frame), table); gtk_container_add(GTK_CONTAINER(frame), table);
gtk_widget_show(table); gtk_widget_show(table);
setup_tooltips(table); gpc_setup_tooltips(table);
/* /*
* Action area OK & Cancel buttons * Action area OK & Cancel buttons
*/ */
randomize_add_action_button("OK", gpc_add_action_button("OK", (GtkSignalFunc) randomize_ok_callback, dlg
(GtkSignalFunc) randomize_ok_callback, dlg, /* , "Accept settings and apply filter to image" */);
"Accept settings and apply filter to image"); gpc_add_action_button("Cancel", (GtkSignalFunc) gpc_cancel_callback, dlg
randomize_add_action_button("Cancel", /* , "Close plug-in without making any changes" */);
(GtkSignalFunc) randomize_cancel_callback, dlg,
"Close plug-in without making any changes");
/* /*
* Randomization Type - label & radio buttons * Randomization Type - label & radio buttons
*/ */
label = gtk_label_new("Randomization Type:"); gpc_add_label("Randomization Type:", table, 0, 1, 0, 1);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show(label);
toggle_hbox = gtk_hbox_new(FALSE, 5); toggle_hbox = gtk_hbox_new(FALSE, 5);
gtk_container_border_width(GTK_CONTAINER(toggle_hbox), 5); gtk_container_border_width(GTK_CONTAINER(toggle_hbox), 5);
@ -823,29 +747,22 @@ randomize_dialog()
* don't allow blur as an option) * don't allow blur as an option)
*/ */
if (! is_indexed_drawable) { if (! is_indexed_drawable) {
randomize_add_radio_button(type_group, "Blur", toggle_hbox, gpc_add_radio_button(&type_group, "Blur", toggle_hbox, &do_blur,
(GtkSignalFunc) randomize_toggle_update, &do_blur,
"Blur each pixel by averaging its value with those of its neighbors"); "Blur each pixel by averaging its value with those of its neighbors");
} }
/* /*
* Hurl, Pick and Slur buttons * Hurl, Pick and Slur buttons
*/ */
randomize_add_radio_button(type_group, "Hurl", toggle_hbox, gpc_add_radio_button(&type_group, "Hurl", toggle_hbox, &do_hurl,
(GtkSignalFunc) randomize_toggle_update, &do_hurl,
"Hurl random colors onto pixels"); "Hurl random colors onto pixels");
randomize_add_radio_button(type_group, "Pick", toggle_hbox, gpc_add_radio_button(&type_group, "Pick", toggle_hbox, &do_pick,
(GtkSignalFunc) randomize_toggle_update, &do_pick,
"Pick at random from neighboring pixels"); "Pick at random from neighboring pixels");
randomize_add_radio_button(type_group, "Slur", toggle_hbox, gpc_add_radio_button(&type_group, "Slur", toggle_hbox, &do_slur,
(GtkSignalFunc) randomize_toggle_update, &do_slur,
"Simplistic melt"); "Simplistic melt");
/* /*
* Randomization seed initialization controls * Randomization seed initialization controls
*/ */
label = gtk_label_new("Randomization Seed"); gpc_add_label("Randomization Seed:", table, 0, 1, 1, 2);
gtk_misc_set_alignment(GTK_MISC (label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, 0, 5, 0);
gtk_widget_show(label);
/* /*
* Box to hold seed initialization radio buttons * Box to hold seed initialization radio buttons
*/ */
@ -856,8 +773,7 @@ randomize_dialog()
/* /*
* Time button * Time button
*/ */
randomize_add_radio_button(seed_group, "Current Time", seed_vbox, gpc_add_radio_button(&seed_group, "Current Time", seed_vbox, &do_time,
(GtkSignalFunc) randomize_toggle_update, &do_time,
"Seed random number generator from the current time - this guarantees a reasonable randomization"); "Seed random number generator from the current time - this guarantees a reasonable randomization");
/* /*
* Box to hold seed user initialization controls * Box to hold seed user initialization controls
@ -868,8 +784,7 @@ randomize_dialog()
/* /*
* User button * User button
*/ */
randomize_add_radio_button(seed_group, "Other Value", seed_hbox, gpc_add_radio_button(&seed_group, "Other Value", seed_hbox, &do_user,
(GtkSignalFunc) randomize_toggle_update, &do_user,
"Enable user-entered value for random number generator seed - this allows you to repeat a given \"random\" operation"); "Enable user-entered value for random number generator seed - this allows you to repeat a given \"random\" operation");
/* /*
* Randomization seed number (text) * Randomization seed number (text)
@ -880,54 +795,26 @@ randomize_dialog()
sprintf(buffer, "%d", pivals.rndm_seed); sprintf(buffer, "%d", pivals.rndm_seed);
gtk_entry_set_text(GTK_ENTRY(entry), buffer); gtk_entry_set_text(GTK_ENTRY(entry), buffer);
gtk_signal_connect(GTK_OBJECT(entry), "changed", gtk_signal_connect(GTK_OBJECT(entry), "changed",
(GtkSignalFunc) randomize_text_update, &pivals.rndm_seed); (GtkSignalFunc) gpc_text_update, &pivals.rndm_seed);
gtk_widget_show(entry); gtk_widget_show(entry);
set_tooltip(entry, "Value for seeding the random number generator"); gpc_set_tooltip(entry, "Value for seeding the random number generator");
gtk_widget_show(seed_hbox); gtk_widget_show(seed_hbox);
/* /*
* Randomization percentage label & scale (1 to 100) * Randomization percentage label & scale (1 to 100)
*/ */
label = gtk_label_new("Randomization %:"); gpc_add_label("Randomization %:", table, 0, 1, 2, 3);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gpc_add_hscale(table, SCALE_WIDTH,
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, 1.0, 100.0, &pivals.rndm_pct, 1, 2, 2, 3,
GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 0); "Percentage of pixels to be filtered");
scale_data = gtk_adjustment_new(pivals.rndm_pct,
1.0, 100.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data));
gtk_widget_set_usize(scale, SCALE_WIDTH, 0);
gtk_table_attach(GTK_TABLE(table), scale, 1, 2, 2, 3,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
gtk_scale_set_digits(GTK_SCALE(scale), 0);
gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_DELAYED);
gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed",
(GtkSignalFunc) randomize_scale_update, &pivals.rndm_pct);
gtk_widget_show(label);
gtk_widget_show(scale);
set_tooltip(scale, "Percentage of pixels to be filtered");
/* /*
* Repeat count label & scale (1 to 100) * Repeat count label & scale (1 to 100)
*/ */
label = gtk_label_new("Repeat"); gpc_add_label("Repeat:", table, 0, 1, 3, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gpc_add_hscale(table, SCALE_WIDTH,
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, 1.0, 100.0, &pivals.rndm_rcount, 1, 2, 3, 4,
GTK_FILL, 0, 5, 0); "Number of times to apply filter");
scale_data = gtk_adjustment_new(pivals.rndm_rcount,
1.0, 100.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data));
gtk_widget_set_usize(scale, SCALE_WIDTH, 0);
gtk_table_attach(GTK_TABLE(table), scale, 1, 2, 3, 4,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
gtk_scale_set_digits(GTK_SCALE(scale), 0);
gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_DELAYED);
gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed",
(GtkSignalFunc) randomize_scale_update, &pivals.rndm_rcount);
gtk_widget_show(label);
gtk_widget_show(scale);
set_tooltip(scale, "Number of times to apply filter");
/* /*
* Display everything. * Display everything.
*/ */
@ -935,7 +822,6 @@ randomize_dialog()
gtk_widget_show(dlg); gtk_widget_show(dlg);
gtk_main(); gtk_main();
gtk_object_unref (GTK_OBJECT (tips));
gdk_flush(); gdk_flush();
/* /*
* Figure out which type of randomization to apply. * Figure out which type of randomization to apply.
@ -962,103 +848,8 @@ randomize_dialog()
} }
/*********************************
*
* GUI accessories (callbacks, etc)
*
********************************/
/*
* DESTROY callback
*/
static void
randomize_close_callback(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
/*
* OK BUTTON callback
*/
static void static void
randomize_ok_callback(GtkWidget *widget, gpointer data) { randomize_ok_callback(GtkWidget *widget, gpointer data) {
rndm_int.run = TRUE; rndm_int.run = TRUE;
gtk_widget_destroy(GTK_WIDGET(data)); gtk_widget_destroy(GTK_WIDGET(data));
} }
/*
* CANCEL BUTTON callback
*/
static void
randomize_cancel_callback(GtkWidget *widget, gpointer data) {
gtk_widget_destroy(GTK_WIDGET(data));
}
/*
* SCALE UPDATE callback
*/
static void
randomize_scale_update(GtkAdjustment *adjustment, double *scale_val) {
*scale_val = adjustment->value;
}
/*
* TOGGLE UPDATE callback
*/
static void
randomize_toggle_update(GtkWidget *widget, gpointer data) {
int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON(widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
}
/*
* TEXT UPDATE callback
*/
static void
randomize_text_update(GtkWidget *widget, gpointer data) {
gint *text_val;
text_val = (gint *) data;
*text_val = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
}
/*
* TOOLTIPS ROUTINES
*/
void setup_tooltips(GtkWidget *parent)
{
static GdkColor tips_fg, tips_bg;
tips = gtk_tooltips_new();
/* black as foreground: */
tips_fg.red = 0;
tips_fg.green = 0;
tips_fg.blue = 0;
gdk_color_alloc(gtk_widget_get_colormap(parent), &tips_fg);
/* postit yellow (khaki) as background: */
tips_bg.red = 61669;
tips_bg.green = 59113;
tips_bg.blue = 35979;
gdk_color_alloc(gtk_widget_get_colormap(parent), &tips_bg);
gtk_tooltips_set_colors(tips, &tips_bg, &tips_fg);
}
void set_tooltip(GtkWidget *widget, const char *tip)
{
if (tip && tip[0])
gtk_tooltips_set_tips(tips, widget, (char *) tip);
}

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
coordmap

View file

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = coordmap
coordmap_SOURCES = \
coordmap.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
coordmap_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View file

@ -1,759 +0,0 @@
/* Coordinate Map plug-in for The Gimp
* Copyright (C) 1997 Michael Schubart (schubart@best.com)
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* This plug-in for The Gimp uses the algorithm described below to map
* a source image to a destination image. Two grayscale images X and Y
* are used to describe the mapping.
*
* For each position in the destination image, get the luminosity of the
* pixels at the same position in the X and Y images. Interpret this pair
* of values as a coordinate pair. Copy the pixel at these coordinates in
* the source image to the destination image.
*
* The latest version and some examples can be found at
* http://www.best.com/~schubart/cm/
*
* This is my first plug-in for The Gimp. You are very welcome to send
* me any comments you have.
*/
/*
* Version 0.2 -- Sep 1 1997
*
* Cosmetic changes to the source code.
*/
/*
* Version 0.1 -- Aug 28 1997
*
* The first version.
*/
#include <stdlib.h>
#include <stdio.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#include "libgimp/gimpui.h"
/*
* definitions
*/
#undef GARRULOUS /* lots of messages to stdout? */
#define MODE_COPY 0
#define MODE_GRAY_TO_COLOR 1
#define MODE_COLOR_TO_GRAY 2
#define ALPHA_NONE 0
#define ALPHA_COPY 1
#define ALPHA_CLEAR 2
#define LUMINOSITY(X) ((X[0]*30 + X[1]*59 + X[2]*11)/100)
#define SRC_WIDTH 256
#define SRC_HEIGHT 256
/*
* declare types
*/
typedef struct
{
gint32 src_drawable_id; /* the source drawable */
gint32 x_drawable_id; /* the x drawable */
gint32 y_drawable_id; /* the y drawable */
} coordmap_values_t;
typedef struct
{
gint run; /* did the user press "ok"? */
} coordmap_interface_t;
/*
* declare local functions
*/
static void query(void);
static void run(char *name,
int nparams, GParam *param,
int *nreturn_vals, GParam **return_vals);
static gint coordmap(gint32 dst_drawable_id);
static gint coordmap_dialog(gint32 dst_drawable_id);
static gint coordmap_src_drawable_constraint(gint32 image_id,
gint32 drawable_id,
gpointer data);
static gint coordmap_xy_drawable_constraint(gint32 image_id,
gint32 drawable_id,
gpointer data);
static void message_box(char *message);
static void coordmap_close_callback(GtkWidget *widget, gpointer data);
static void coordmap_ok_callback(GtkWidget *widget, gpointer dialog);
static void coordmap_src_drawable_callback(gint32 id, gpointer data);
static void coordmap_x_drawable_callback(gint32 id, gpointer data);
static void coordmap_y_drawable_callback(gint32 id, gpointer data);
/*
* local variables
*/
static coordmap_values_t cvals=
{
-1, /* src_drawable_id */
-1, /* x_drawable_id */
-1, /* y_drawable_id */
};
static coordmap_interface_t cint=
{
FALSE /* run */
};
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
/*
* functions
*/
MAIN ()
static void query()
{
static GParamDef args[] =
{
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image" },
{ PARAM_DRAWABLE, "dst_drawable", "Destination drawable" },
{ PARAM_DRAWABLE, "src_drawable",
"Source drawable, size must be 256x256" },
{ PARAM_DRAWABLE, "x_drawable",
"X drawable, size must be equal to dst_drawable." },
{ PARAM_DRAWABLE, "y_drawable",
"Y drawable, size must be equal to dst_drawable." },
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof (args) / sizeof (args[0]);
static int nreturn_vals = 0;
gimp_install_procedure ("plug_in_coordmap",
"Maps a source image to a destination image.",
"Maps a source image to a destination image. For each position in "
"the destination image, the luminosity of of the X map and the Y "
"map at the same position are interpreted as coordinates. The pixel "
"that is found at these coordinates in the source image is copied "
"to the destination image.",
"Michael Schubart",
"Michael Schubart",
"Sep 1 1997",
"<Image>/Filters/Map/Coordinate Map",
"RGB*, GRAY*",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
static void run(char *name,
int nparams, GParam *param,
int *nreturn_vals, GParam **return_vals)
{
static GParam values[1];
GRunModeType run_mode=param[0].data.d_int32;
values[0].type=PARAM_STATUS;
values[0].data.d_status=STATUS_SUCCESS;
*nreturn_vals = 1;
*return_vals = values;
switch (run_mode)
{
case RUN_INTERACTIVE:
/* get the parameter values of the last incocation */
gimp_get_data("plug_in_coordmap",&cvals);
if (!coordmap_dialog(param[2].data.d_drawable))
return;
break;
case RUN_NONINTERACTIVE:
/* check number of parameters */
if (nparams!=6)
values[0].data.d_status=STATUS_CALLING_ERROR;
else
{
cvals.src_drawable_id=param[3].data.d_drawable;
cvals.x_drawable_id=param[4].data.d_drawable;
cvals.y_drawable_id=param[5].data.d_drawable;
}
break;
case RUN_WITH_LAST_VALS:
/* get the parameter values of the last incocation */
gimp_get_data("plug_in_coordmap",&cvals);
break;
default:
break;
}
if (values[0].data.d_status==STATUS_SUCCESS)
{
/*
* @@ Who can explain to me what this gimp_tile_cache_ntiles() is about,
* and what's a good value? Thanks!
*/
gimp_tile_cache_ntiles(48);
if (!coordmap(param[2].data.d_drawable))
/* bad parameter values */
values[0].data.d_status=STATUS_EXECUTION_ERROR;
else
{
if (run_mode!=RUN_NONINTERACTIVE)
gimp_displays_flush();
if (run_mode==RUN_INTERACTIVE)
/* store parameter values for next invocation */
gimp_set_data("plug_in_coordmap",&cvals,sizeof(coordmap_values_t));
}
}
}
static gint coordmap(gint32 dst_drawable_id)
{
GDrawable *dst_drawable;
GDrawable *src_drawable;
GDrawable *x_drawable;
GDrawable *y_drawable;
gint src_mode=MODE_COPY;
gint x_mode=MODE_COPY;
gint y_mode=MODE_COPY;
gint src_bpp;
gint dst_bpp;
gint copy_bpp;
gint src_alpha_index;
gint dst_alpha_index;
gint alpha_mode=ALPHA_NONE;
gint x1,y1,x2,y2;
gint progress,max_progress;
GPixelRgn dst_rgn;
GPixelRgn src_rgn;
GPixelRgn x_rgn;
GPixelRgn y_rgn;
guchar *src;
gpointer pr;
/* initialize */
src_alpha_index = 0;
dst_alpha_index = 0;
/*
* some tests to see whether we want to run at all
*/
/* crude way to test if the drawables still exist */
if (gimp_drawable_bpp(dst_drawable_id)==-1 ||
gimp_drawable_bpp(cvals.src_drawable_id)==-1 ||
gimp_drawable_bpp(cvals.x_drawable_id)==-1 ||
gimp_drawable_bpp(cvals.y_drawable_id)==-1)
{
#ifdef GARRULOUS
g_print("coordmap: drawable missing\n");
#endif
return FALSE;
}
/* reject indexed drawables */
if (gimp_drawable_indexed(dst_drawable_id) ||
gimp_drawable_indexed(cvals.src_drawable_id) ||
gimp_drawable_indexed(cvals.x_drawable_id) ||
gimp_drawable_indexed(cvals.y_drawable_id))
{
#ifdef GARRULOUS
g_print("coordmap: won't work on indexed images\n");
#endif
return FALSE;
}
/* check source image size */
if (gimp_drawable_width(cvals.src_drawable_id)!=SRC_WIDTH ||
gimp_drawable_height(cvals.src_drawable_id)!=SRC_HEIGHT)
{
#ifdef GARRULOUS
g_print("coordmap: source image size must be 256x256\n");
#endif
return FALSE;
}
/* check x and y map size */
if (gimp_drawable_width(cvals.x_drawable_id)!=
gimp_drawable_width(dst_drawable_id) ||
gimp_drawable_height(cvals.x_drawable_id)!=
gimp_drawable_height(dst_drawable_id) ||
gimp_drawable_width(cvals.y_drawable_id)!=
gimp_drawable_width(dst_drawable_id) ||
gimp_drawable_height(cvals.y_drawable_id)!=
gimp_drawable_height(dst_drawable_id))
{
#ifdef GARRULOUS
g_print("coordmap: x and y map must be of the same size as "
"the destination image\n");
#endif
return FALSE;
}
/*
* examine the drawables to see what kind of transformations we need
*/
/* convert gray source pixel to color destination pixel? */
if (gimp_drawable_gray(cvals.src_drawable_id) &&
gimp_drawable_color(dst_drawable_id))
src_mode=MODE_GRAY_TO_COLOR;
/* convert color source pixel to gray destination pixel? */
if (gimp_drawable_color(cvals.src_drawable_id) &&
gimp_drawable_gray(dst_drawable_id))
src_mode=MODE_COLOR_TO_GRAY;
/* is the x map gray, or do we have to computer its luminosity? */
if (gimp_drawable_color(cvals.x_drawable_id))
x_mode=MODE_COLOR_TO_GRAY;
/* is the y map gray, or do we have to computer its luminosity? */
if (gimp_drawable_color(cvals.y_drawable_id))
y_mode=MODE_COLOR_TO_GRAY;
/* how may bytes of color information in the destination image? */
dst_bpp=gimp_drawable_bpp(dst_drawable_id);
if (gimp_drawable_has_alpha(dst_drawable_id))
{
dst_alpha_index=--dst_bpp;
alpha_mode=ALPHA_CLEAR;
}
/* how may bytes of color information in the source image? */
src_bpp=gimp_drawable_bpp(cvals.src_drawable_id);
if (gimp_drawable_has_alpha(cvals.src_drawable_id))
src_alpha_index=--src_bpp;
/* how many bytes of of color information are we going to copy? */
copy_bpp=MIN(src_bpp,dst_bpp);
/* copy alpha together with color if both drawables have alpha */
if (gimp_drawable_has_alpha(dst_drawable_id) &&
gimp_drawable_has_alpha(cvals.src_drawable_id))
{
if (src_mode==MODE_COPY)
copy_bpp++;
else
alpha_mode=ALPHA_COPY;
}
#ifdef GARRULOUS
/* some debug messages */
if (src_mode==MODE_COPY)
{
g_print("src_mode: MODE_COPY\n");
g_print("copy_bpp: %d\n",copy_bpp);
}
else if (src_mode==MODE_GRAY_TO_COLOR)
g_print("src_mode: MODE_GRAY_TO_COLOR\n");
else
g_print("src_mode: MODE_COLOR_TO_GRAY\n");
if (alpha_mode==ALPHA_NONE)
g_print("alpha_mode: ALPHA_NONE\n");
else if (alpha_mode==ALPHA_COPY)
{
g_print("alpha_mode: ALPHA_COPY\n");
g_print("src_alpha_index: %d\n",src_alpha_index);
g_print("dst_alpha_index: %d\n",dst_alpha_index);
}
else if (alpha_mode==ALPHA_CLEAR)
{
g_print("alpha_mode: ALPHA_CLEAR\n");
g_print("dst_alpha_index: %d\n",dst_alpha_index);
}
g_print("\n");
#endif
/* get the drawables form the drawable ids */
dst_drawable=gimp_drawable_get(dst_drawable_id);
src_drawable=gimp_drawable_get(cvals.src_drawable_id);
x_drawable=gimp_drawable_get(cvals.x_drawable_id);
y_drawable=gimp_drawable_get(cvals.y_drawable_id);
/* copy the source drawable to one big array */
gimp_pixel_rgn_init(&src_rgn,src_drawable,0,0,
SRC_WIDTH,SRC_HEIGHT,FALSE,FALSE);
src=g_new(guchar,SRC_WIDTH*SRC_HEIGHT*src_drawable->bpp);
gimp_pixel_rgn_get_rect(&src_rgn,src,0,0,SRC_WIDTH,SRC_HEIGHT);
/* get the area that is going to be processed */
gimp_drawable_mask_bounds(dst_drawable->id,&x1,&y1,&x2,&y2);
progress=0;
max_progress=(x2-x1)*(y2-y1);
gimp_progress_init("Coordinate Map...");
/* initialize the pixel regions */
gimp_pixel_rgn_init(&dst_rgn,dst_drawable,x1,y1,x2-x1,y2-y1,TRUE,TRUE);
gimp_pixel_rgn_init(&x_rgn,x_drawable,x1,y1,x2-x1,y2-y1,FALSE,FALSE);
gimp_pixel_rgn_init(&y_rgn,y_drawable,x1,y1,x2-x1,y2-y1,FALSE,FALSE);
/* iterate over the areas the Gimp chooses for us */
for (pr=gimp_pixel_rgns_register(3,&dst_rgn,&x_rgn,&y_rgn);
pr!=NULL;pr=gimp_pixel_rgns_process(pr))
{
gint x,y;
guchar *dst_ptr=dst_rgn.data;
guchar *x_ptr=x_rgn.data;
guchar *y_ptr=y_rgn.data;
guchar *src_ptr;
guchar x_value;
guchar y_value;
gint byte;
/* iterate over all pixels in the current area */
for (y=0;y<dst_rgn.h;y++)
for (x=0;x<dst_rgn.w;x++)
{
/* get the source address */
x_value=(x_mode==MODE_COPY)?x_ptr[0]:LUMINOSITY(x_ptr);
y_value=(y_mode==MODE_COPY)?y_ptr[0]:LUMINOSITY(y_ptr);
src_ptr=src+(y_value*SRC_WIDTH+x_value)*src_rgn.bpp;
/* simply copy the color information? */
if (src_mode==MODE_COPY)
for (byte=0;byte<copy_bpp;byte++)
dst_ptr[byte]=src_ptr[byte];
/* or copy a gray value to red, green and blue? */
else if (src_mode==MODE_GRAY_TO_COLOR)
for (byte=0;byte<dst_bpp;byte++)
dst_ptr[byte]=src_ptr[0];
/* or convert from color to gray? (MODE_COLOR_TO_GRAY) */
else
dst_ptr[0]=LUMINOSITY(src_ptr);
/* copy alpha information? */
if (alpha_mode==ALPHA_COPY)
dst_ptr[dst_alpha_index]=src_ptr[src_alpha_index];
/* or clear the alpha chennel? */
else if (alpha_mode==ALPHA_CLEAR)
dst_ptr[dst_alpha_index]=0xff;
/* next pixel */
dst_ptr+=dst_rgn.bpp;
x_ptr+=x_rgn.bpp;
y_ptr+=y_rgn.bpp;
}
/* update progress indicator */
progress+=dst_rgn.w*dst_rgn.h;
gimp_progress_update((double)progress/(double)max_progress);
}
/* update the destination drawable */
gimp_drawable_flush(dst_drawable);
gimp_drawable_merge_shadow(dst_drawable->id,TRUE);
gimp_drawable_update(dst_drawable->id,x1,y1,(x2-x1),(y2-y1));
/* free the memory used for the contents of the source drawable */
g_free(src);
/* free the drawable structs */
gimp_drawable_detach(dst_drawable);
gimp_drawable_detach(src_drawable);
gimp_drawable_detach(x_drawable);
gimp_drawable_detach(y_drawable);
/* success! */
return TRUE;
}
static gint coordmap_dialog(gint32 dst_drawable_id)
{
GtkWidget *dlg;
GtkWidget *button;
GtkWidget *frame;
GtkWidget *table;
GtkWidget *label;
GtkWidget *option_menu;
GtkWidget *menu;
gint argc=1;
gchar **argv=g_new(gchar *,1);
gint src_drawable_count=0;
/* initialize gtk */
argv[0]=g_strdup("Coordinate Map");
gtk_init(&argc,&argv);
gtk_rc_parse(gimp_gtkrc());
g_free(argv[0]);
g_free(argv);
/* the dialog box */
dlg=gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dlg),"Coordinate Map");
gtk_window_position(GTK_WINDOW(dlg),GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dlg),"destroy",
(GtkSignalFunc)coordmap_close_callback,
NULL);
/* the "OK" button */
button=gtk_button_new_with_label("OK");
GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
gtk_signal_connect(GTK_OBJECT(button),"clicked",
(GtkSignalFunc)coordmap_ok_callback,
dlg);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area),
button,TRUE,TRUE,0);
gtk_widget_grab_default(button);
gtk_widget_show(button);
/* the "Cancel" button */
button=gtk_button_new_with_label("Cancel");
GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
gtk_signal_connect_object(GTK_OBJECT(button),"clicked",
(GtkSignalFunc)gtk_widget_destroy,
GTK_OBJECT(dlg));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area),
button,TRUE,TRUE,0);
gtk_widget_show (button);
/* a frame for that extra sexy look */
frame=gtk_frame_new("Coordinate Map Options");
gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_ETCHED_IN);
gtk_container_border_width(GTK_CONTAINER(frame),10);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox),frame,TRUE,TRUE,0);
/* table to arrange the following labels and option menus*/
table=gtk_table_new(3,2,FALSE);
gtk_container_border_width(GTK_CONTAINER(table),10);
gtk_container_add(GTK_CONTAINER(frame),table);
/* the "Source Image" label */
label=gtk_label_new("Source Image");
gtk_misc_set_alignment(GTK_MISC(label),0.0,0.5);
gtk_table_attach(GTK_TABLE(table),label, 0,1,0,1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2,2);
gtk_widget_show(label);
/* option menu with a list of the possible source drawables */
option_menu=gtk_option_menu_new();
gtk_table_attach(GTK_TABLE(table),option_menu, 1,2,0,1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2,2);
menu=gimp_drawable_menu_new(coordmap_src_drawable_constraint,
coordmap_src_drawable_callback,
&src_drawable_count,cvals.src_drawable_id);
gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu),menu);
gtk_widget_show(option_menu);
/* the "X Map" label */
label=gtk_label_new("X Map");
gtk_misc_set_alignment(GTK_MISC(label),0.0,0.5);
gtk_table_attach(GTK_TABLE(table),label, 0,1,1,2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2,2);
gtk_widget_show(label);
/* option menu with a list of the possible x drawables */
option_menu=gtk_option_menu_new();
gtk_table_attach(GTK_TABLE(table),option_menu, 1,2,1,2,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2,2);
menu=gimp_drawable_menu_new(coordmap_xy_drawable_constraint,
coordmap_x_drawable_callback,
&dst_drawable_id,cvals.x_drawable_id);
gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu),menu);
gtk_widget_show(option_menu);
/* the "Y Map" label */
label=gtk_label_new("Y Map");
gtk_misc_set_alignment(GTK_MISC(label),0.0,0.5);
gtk_table_attach(GTK_TABLE(table),label, 0,1,2,3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 2,2);
gtk_widget_show(label);
/* option menu with a list of the possible y drawables */
option_menu=gtk_option_menu_new();
gtk_table_attach(GTK_TABLE(table),option_menu,1,2,2,3,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2,2);
menu=gimp_drawable_menu_new(coordmap_xy_drawable_constraint,
coordmap_y_drawable_callback,
&dst_drawable_id,cvals.y_drawable_id);
gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu),menu);
gtk_widget_show(option_menu);
gtk_widget_show(table);
gtk_widget_show(frame);
/* display error message if no appropriate source drawables were found */
if (src_drawable_count)
gtk_widget_show(dlg);
else
{
gtk_widget_destroy(dlg);
message_box("No source image was found."
"(The source image size must be 256x256)");
}
gtk_main();
gdk_flush();
return cint.run;
}
static gint coordmap_src_drawable_constraint(gint32 image_id,
gint32 drawable_id,
gpointer data)
/*
* only appropriate drawables appear in the the "Source image" option menu:
* size must be SRC_WIDTH x SRC_HEIGHT.
* drawable must not be indexed.
*/
{
gint *src_drawable_count=(gint *)data;
if (drawable_id==-1)
return TRUE;
if (gimp_drawable_width(drawable_id)==SRC_WIDTH &&
gimp_drawable_height(drawable_id)==SRC_HEIGHT &&
!gimp_drawable_indexed(drawable_id))
{
/* count how many valid drawables there are */
(*src_drawable_count)++;
return TRUE;
}
return FALSE;
}
static gint coordmap_xy_drawable_constraint(gint32 image_id,
gint32 drawable_id,
gpointer data)
/*
* only appropriate drawables appear in the the "X/Y MAP" option menus:
* size must be equal to destination drawable.
* drawable must not be indexed.
*/
{
gint32 dst_drawable_id=*(gint32 *)data;
return (drawable_id==-1 ||
(gimp_drawable_width(drawable_id)==
gimp_drawable_width(dst_drawable_id) &&
gimp_drawable_height(drawable_id)==
gimp_drawable_height(dst_drawable_id) &&
!gimp_drawable_indexed(drawable_id)));
}
static void message_box(char *message)
/*
* display a small dialog box for error messages
*/
{
GtkWidget *dlg;
GtkWidget *button;
GtkWidget *label;
/* the dialog box */
dlg=gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dlg),"Coordinate Map Error");
gtk_window_position(GTK_WINDOW(dlg),GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dlg),"destroy",
(GtkSignalFunc)coordmap_close_callback,
NULL);
/* the "OK" button */
button=gtk_button_new_with_label("OK");
GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT);
gtk_signal_connect_object(GTK_OBJECT(button),"clicked",
(GtkSignalFunc)coordmap_close_callback,
GTK_OBJECT(dlg));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area),
button,TRUE,TRUE,0);
gtk_widget_grab_default(button);
gtk_widget_show(button);
/* the label showing the message */
label=gtk_label_new(message);
gtk_misc_set_padding(GTK_MISC(label),10,10);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox),label,TRUE,TRUE,0);
gtk_widget_show(label);
gtk_widget_show(dlg);
}
static void coordmap_close_callback(GtkWidget *widget, gpointer data)
/*
* gets called when the dialog window is closed via window manager
*/
{
gtk_main_quit();
}
static void coordmap_ok_callback(GtkWidget *widget, gpointer dialog)
/*
* gets called when "OK" is pressed
*/
{
/* yes, we're going to run the plug-in */
cint.run=TRUE;
/* close dialog window */
gtk_widget_destroy(GTK_WIDGET(dialog));
}
static void coordmap_src_drawable_callback(gint32 id, gpointer data)
/*
* gets called when the user selects a different source drawable
*/
{
cvals.src_drawable_id=id;
}
static void coordmap_x_drawable_callback(gint32 id, gpointer data)
/*
* gets called when the user selects a different x drawable
*/
{
cvals.x_drawable_id=id;
}
static void coordmap_y_drawable_callback(gint32 id, gpointer data)
/*
* gets called when the user selects a different y drawable
*/
{
cvals.y_drawable_id=id;
}

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
gimptcl

View file

@ -1,34 +0,0 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = scripts
BUILT_SOURCES= gtclenums.h
AUTOMAKE_OPTIONS= no-dependencies
SUFFIXES = .h
scriptdata =
libexec_PROGRAMS = gimptcl
gimptcl_SOURCES= \
gtcl.h \
gtclenums.h \
gtclMain.c \
gtcl_misc.c \
gtclConst.c \
gtclPDB.c \
gtclEnums.h
INCLUDES= \
${X_CFLAGS} \
-I/usr/local/include \
-I$(top_srcdir)
LDADD = \
$(top_builddir)/libgimp/libgimp.la \
@LIBTCL_LIB@ \
$(X_LIBS) \
-lc \
-lm
gtclenums.h: ${top_srcdir}/libgimp/gimpenums.h gtclEnums.h
misc/enum.pl ${top_srcdir}/libgimp/gimpenums.h gtclEnums.h >$@

View file

@ -1,23 +0,0 @@
This is the first real release of gimptcl-1.0, distributed in
the FreeBSD gimp-0.99.14 port.
It comes with three sample plug-ins.
* Consolio, an interactive gimptcl shell
* pdb-help, an interactive thing for browsing
the pdb and running procedures
* stained-glass, a simple (and ugly) plugin for creating
stained glassy backgrounds.
The ``scripts'' directory contains plug-ins that are real Tcl scripts.
The ``frags'' directory contains tcl procs and fragments that I've used
for testing the interpreter. I usually just source them from inside
consolio, then call the procs interactively.
Unfortunately I'm not very artistic, so there's no pretty pictures
to look at.
Eric L. Hernes
erich@rrnet.com

View file

@ -1,23 +0,0 @@
This is the first real release of gimptcl-1.0, distributed in
the FreeBSD gimp-0.99.14 port.
It comes with three sample plug-ins.
* Consolio, an interactive gimptcl shell
* pdb-help, an interactive thing for browsing
the pdb and running procedures
* stained-glass, a simple (and ugly) plugin for creating
stained glassy backgrounds.
The ``scripts'' directory contains plug-ins that are real Tcl scripts.
The ``frags'' directory contains tcl procs and fragments that I've used
for testing the interpreter. I usually just source them from inside
consolio, then call the procs interactively.
Unfortunately I'm not very artistic, so there's no pretty pictures
to look at.
Eric L. Hernes
erich@rrnet.com

View file

@ -1,10 +0,0 @@
#!/usr/bin/tclsh
proc scroll-string {str} {
set l [string length $str]
set t "$str$str"
for {set i 0} {$i < $l} {incr i} {
set sstr [string range $t $i [expr $i + 3]]
puts $sstr
}
}

View file

@ -1,192 +0,0 @@
set DebugLevel 0
set size 120
set font "ParkAvenue"
set text_pattern "Fibers"
set bg_color {255 255 255}
proc gen-bg {img} {
set width [gimp-image-width $img]
set height [gimp-image-height $img]
set b1 [gimp-layer-new $img $width $height RGBA_IMAGE "Blend 1" \
50 NORMAL]
set old_fg [gimp-palette-get-foreground]
set old_bg [gimp-palette-get-background]
gimp-palette-set-foreground {47 17 216}
gimp-palette-set-background {55 214 23}
gimp-blend $img $b1 FG_BG_RGB NORMAL CONICAL_SYMMETRIC 100 \
0 95 95 40 45
gimp-blend $img $b1 FG_BG_RGB NORMAL CONICAL_SYMMETRIC 50 \
0 280 180 310 205
gimp-image-add-layer $img $b1 1
set b2 [gimp-layer-new $img $width $height RGBA_IMAGE "Blend 2" \
100 NORMAL]
gimp-palette-set-foreground {247 229 37}
gimp-palette-set-background {244 24 31}
gimp-blend $img $b2 FG_BG_RGB NORMAL CONICAL_SYMMETRIC 100 \
0 270 95 300 220
gimp-blend $img $b2 FG_BG_RGB NORMAL CONICAL_SYMMETRIC 50 \
0 105 180 58 205
gimp-image-add-layer $img $b2 1
foreach layer [lindex [gimp-image-get-layers $img] 1] {
if {$layer != $b1 && $layer != $b2} {
gimp-layer-set-visible $layer 0
}
}
set d [gimp-image-merge-visible-layers $img 0]
gimp-image-set-active-layer $img $d
plug-in-c-astretch $img $d
plug-in-mosaic $img $d 15 15 1.1 0.0 60 0.5 1 1 1 1 0
gimp-palette-set-foreground $old_fg
gimp-palette-set-background $old_bg
return $d
}
proc add-text {img text} {
global size bg_color text_pattern font
set f_size [expr $size * 0.075]
set b_size [expr $size * 0.1]
set b_size_2 [expr $size * 0.05]
set ts_size [expr $b_size_2 - 3]
set ds_size [expr $size * 0.05]
set old_w [gimp-image-width $img]
set old_h [gimp-image-height $img]
set text_layer [gimp-text $img -1 0 0 $text $b_size TRUE $size PIXELS "*" $font "*" "*" "*" "*"]
set old_fg [gimp-palette-get-foreground]
set old_bg [gimp-palette-get-background]
set width [gimp-drawable-width $text_layer]
set height [gimp-drawable-height $text_layer]
gimp-image-resize $img $width $height 0 0
set text_shadow_layer [gimp-layer-new $img $width $height RGBA_IMAGE "Text Shadow" 100 MULTIPLY]
set tsl_layer_mask [gimp-layer-create-mask $text_shadow_layer BLACK_MASK]
set drop_shadow_layer [gimp-layer-new $img $width $height RGBA_IMAGE "Drop Shadow" 100 MULTIPLY]
set dsl_layer_mask [gimp-layer-create-mask $drop_shadow_layer BLACK_MASK]
gimp-image-add-layer $img $drop_shadow_layer 1
gimp-image-add-layer $img $text_shadow_layer 0
gimp-selection-all $img
gimp-patterns-set-pattern $text_pattern
gimp-layer-set-preserve-trans $text_layer TRUE
gimp-bucket-fill $img $text_layer PATTERN_BUCKET_FILL NORMAL 100 0 FALSE 0 0
gimp-selection-none $img
gimp-edit-clear $img $text_shadow_layer
gimp-edit-clear $img $drop_shadow_layer
gimp-palette-set-background $bg_color
gimp-selection-layer-alpha $img $text_layer
gimp-image-add-layer-mask $img $text_shadow_layer $tsl_layer_mask
gimp-palette-set-background {255 255 255}
gimp-edit-fill $img $tsl_layer_mask
gimp-selection-feather $img $f_size
gimp-palette-set-background {23 23 23}
gimp-edit-fill $img $drop_shadow_layer
gimp-palette-set-background {0 0 0}
gimp-edit-fill $img $text_shadow_layer
gimp-palette-set-foreground {255 255 255}
gimp-blend $img $text_shadow_layer FG_BG_RGB NORMAL SHAPEBURST_ANGULAR 100 0 0 0 1 1
gimp-selection-none $img
gimp-layer-translate $text_layer -$b_size_2 -$b_size_2
gimp-layer-translate $text_shadow_layer -$ts_size -$ts_size
gimp-layer-translate $drop_shadow_layer $ds_size $ds_size
gimp-image-add-layer-mask $img $drop_shadow_layer $dsl_layer_mask
gimp-palette-set-background {255 255 255}
gimp-edit-fill $img $dsl_layer_mask
gimp-image-remove-layer-mask $img $drop_shadow_layer APPLY
gimp-palette-set-foreground $old_fg
gimp-palette-set-background $old_bg
foreach layer [lindex [gimp-image-get-layers $img] 1] {
if {$layer != $text_layer
&& $layer != $text_shadow_layer
&& $layer != $drop_shadow_layer} {
gimp-layer-set-visible $layer 0
}
}
set d [gimp-image-merge-visible-layers $img 0]
gimp-image-resize $img $old_w $old_h 0 0
return $d
}
proc run {} {
set bg_w 352
set bg_h 240
set img [gimp-image-new 352 240 RGB]
set bg_d [gen-bg $img]
set t_d [add-text $img "Eric L. Hernes, esq."]
gimp-layer-set-visible $bg_d 0
gimp-layer-set-visible $t_d 0
set frame 0
set tx_w [gimp-drawable-width $t_d]
set tx_h [gimp-drawable-height $t_d]
set y [expr $bg_h - $tx_h]
# for {set x $bg_w;set frame 0} {$x + $tx_w > 0} {incr x -1;incr frame}
# for {set x [expr $bg_w - 584];set frame 583} {$x + $tx_w > 0} {incr x -3;incr frame}
set ppf 2
set frame 0
# {$x + $tx_w > 0}
set frame 412
set total [expr ($bg_w + $tx_w) / $ppf]
set eframe $total
set eframe 413
for {set x [expr $bg_w - [expr $frame * $ppf]]} {$frame < $eframe} {
incr x -$ppf;incr frame} {
set bg [gimp-layer-copy $bg_d 0]
plug-in-whirl $img $bg [expr -10 * $frame]
set bg_c [gimp-layer-copy $bg 0]
gimp-layer-delete $bg
gimp-image-add-layer $img $bg_c 0
set t_c [gimp-layer-copy $t_d 0]
gimp-image-add-layer $img $t_c 0
gimp-layer-set-visible $bg_c 1
gimp-layer-set-visible $t_c 1
gimp-layer-set-offsets $t_c $x $y
set d [gimp-image-merge-visible-layers $img 2]
set fn [format "/src/t/%04d.jpg" $frame]
puts "$fn : $x $y \[$frame / $total\]"
file-jpeg-save $img $d $fn 100 0
gimp-layer-set-visible $d 0
gimp-layer-delete $d
}
}
proc w {i d} {
set r [plug-in-whirl $i $d -25]
gimp-displays-flush
return $r
}
proc m {i d} {
set r [plug-in-mosaic $i $d 15 15 1.1 0.0 60 0.5 1 1 1 1 0]
gimp-displays-flush
return $r
}
proc r {} {
set i [gimp-image-new 256 256 RGB]
set d [gen-bg $i]
set tx [add-text $i "Eric L. Hernes"]
gimp-display-new $i
return [list $i $d $tx]
}

View file

@ -1,95 +0,0 @@
proc scale {size percent} {
return [expr $size * $percent]
}
proc bds-logo {bg text_pattern blend_fg blend_bg tile_type text size font} {
global RGB TRUE FALSE RGBA_IMAGE NORMAL MULTIPLY
global BLACK_MASK PAT_BUCKET_FILL BG_IMAGE_FILL REPLACE
global FG_BG_RGB SHAPEBURST_ANGULAR LINEAR APPLY
set PIXELS 0
set img [gimp_image_new 256 256 $RGB]
set b_size [scale $size 0.1]
set b_size_2 [scale $size 0.05]
set f_size [scale $size 0.075]
set ds_size [scale $size 0.05]
set ts_size [expr $b_size - 3]
set text_layer [gimp_text $img -1 0 0 $text $b_size $TRUE $size \
$PIXELS "*" $font "*" "*" "*" "*"]
set width [gimp_drawable_width $text_layer]
set height [gimp_drawable_height $text_layer]
set blend_layer [gimp_layer_new $img $width $height $RGBA_IMAGE "Blend" \
100 $NORMAL]
set shadow_layer [gimp_layer_new $img $width $height $RGBA_IMAGE "Shadow" \
100 $NORMAL]
set text_shadow_layer [gimp_layer_new $img $width $height $RGBA_IMAGE \
"Text Shadow" 100 $MULTIPLY]
set tsl_layer_mask [gimp_layer_create_mask $text_shadow_layer $BLACK_MASK]
set drop_shadow_layer [gimp_layer_new $img $width $height $RGBA_IMAGE \
"Drop Shadow" 100 $MULTIPLY]
set dsl_layer_mask [gimp_layer_create_mask $drop_shadow_layer $BLACK_MASK]
set old_fg [gimp_palette_get_foreground]
set old_bg [gimp_palette_get_background]
gimp_image_disable_undo $img
gimp_image_resize $img $width $height 0 0
gimp_image_add_layer $img $shadow_layer 1
gimp_image_add_layer $img $blend_layer 1
gimp_image_add_layer $img $drop_shadow_layer 1
gimp_image_add_layer $img $text_shadow_layer 0
gimp_selection_all $img
gimp_layer_set_preserve_trans $text_layer $TRUE
gimp_bucket_fill $img $text_layer $PAT_BUCKET_FILL $NORMAL \
100 0 $FALSE 0 0
gimp_selection_none $img
gimp_edit_clear $img $text_shadow_layer
gimp_edit_clear $img $drop_shadow_layer
gimp_palette_set_background $bg
gimp_drawable_fill $shadow_layer $BG_IMAGE_FILL
gimp_rect_select $img $b_size_2 $b_size_2 [expr $width - $b_size] \
[expr $height - $b_size] $REPLACE $TRUE $b_size_2
gimp_palette_set_background {0 0 0}
gimp_edit_fill $img $shadow_layer
gimp_selection_layer_alpha $img $text_layer
gimp_image_add_layer_mask $img $text_shadow_layer $tsl_layer_mask
gimp_palette_set_background {255 255 255}
gimp_edit_fill $img $tsl_layer_mask
gimp_selection_feather $img $f_size
gimp_palette_set_background {63 63 63}
gimp_edit_fill $img $drop_shadow_layer
gimp_palette_set_background {0 0 0}
gimp_edit_fill $img $text_shadow_layer
gimp_palette_set_foreground {255 255 255}
gimp_blend $img $text_shadow_layer $FG_BG_RGB NORMAL $SHAPEBURST_ANGULAR \
100 0 0 0 1 1
gimp_selection_none $img
gimp_palette_set_foreground $blend_fg
gimp_palette_set_background $blend_bg
gimp_blend $img $blend_layer $FG_BG_RGB $NORMAL $LINEAR 100 0 0 0 $width 0
plug_in_mosaic $img $blend_layer 12 1 1 0.7 135 0.2 $TRUE $FALSE \
$tile_type 1 0
gimp_layer_translate $text_layer -$b_size_2 -$b_size_2
gimp_layer_translate $blend_layer -$b_size -$b_size
gimp_layer_translate $text_shadow_layer -$ts_size -$ts_size
gimp_layer_translate $drop_shadow_layer $ds_size $ds_size
gimp_selection_layer_alpha $img $blend_layer
gimp_image_add_layer_mask $img $drop_shadow_layer $dsl_layer_mask
gimp_palette_set_background {255 255 255}
gimp_edit_fill $img $dsl_layer_mask
gimp_image_remove_layer_mask $img $drop_shadow_layer $APPLY
gimp_selection_none $img
gimp_layer_set_name $text_layer $text
gimp_palette_set_foreground [lindex $old_fg 0]
gimp_palette_set_background [lindex $old_bg 0]
gimp_image_enable_undo $img
# gimp_display_new $img
return $img
}
proc bds-1 {text} {
return [bds-logo {255 255 255} Fibers {32 106 0} {0 0 106} 0 $text \
200 courier]
}

View file

@ -1,76 +0,0 @@
proc air-box {img drw x1 y1 x2 y2} {
set p [list \
$x1 $y1 $x2 $y1\
$x2 $y1 $x2 $y2\
$x2 $y2 $x1 $y2\
$x1 $y2 $x1 $y1]
set lp [llength $p]
gimp-airbrush $img $drw 70 $lp $p
gimp-displays-flush
}
proc paint-box {img drw x1 y1 x2 y2} {
set p [list \
$x1 $y1 $x2 $y1\
$x2 $y1 $x2 $y2\
$x2 $y2 $x1 $y2\
$x1 $y2 $x1 $y1]
set lp [llength $p]
set fade [expr (abs($x2 - $x1) + abs($y2 - $y1))]
gimp-paintbrush $img $drw $fade $lp $p
gimp-displays-flush
}
proc air-circle {img drw n x y r} {
set twopi [expr 2 * 3.1415926]
set rinc [expr $twopi / $n]
for {set theta 0} {$theta < $twopi} {set theta [expr $theta + $rinc]} {
set X [expr $x + $r * sin($theta)]
set Y [expr $y + $r * cos($theta)]
lappend p $X $Y
}
lappend p [lindex $p 0] [lindex $p 1]
set lp [llength $p]
gimp-airbrush $img $drw 70 $lp $p
gimp-displays-flush
}
proc paint-circle {img drw n x y r} {
set twopi [expr 2 * 3.1415926]
set rinc [expr $twopi / $n]
for {set theta 0} {$theta < $twopi} {set theta [expr $theta + $rinc]} {
set X [expr $x + $r * sin($theta)]
set Y [expr $y + $r * cos($theta)]
lappend p $X $Y
}
lappend p [lindex $p 0] [lindex $p 1]
set lp [llength $p]
# [expr 3.1415926 * $r]
set fade 0
gimp-paintbrush $img $drw $fade $lp $p
gimp-displays-flush
}
proc n {} {
set i [gimp-image-new 352 240 RGB]
set d [gimp-layer-new $i 352 240 RGBA_IMAGE "New Layer" 100 NORMAL]
gimp-image-add-layer $i $d 0
gimp-drawable-fill $d BG_IMAGE_FILL
gimp-display-new $i
return [list $i $d]
}
proc t {} {
set id [n]
set i [lindex $id 0]
set d [lindex $id 1]
# there's a bug in gimp-airbrush, this one'll core
# unless you've patched app/airbrush.c
#
air-box $i $d 10 10 100 100
paint-box $i $d 110 110 200 200
}

View file

@ -1,64 +0,0 @@
proc Shadow_Sphere {radius sphere_color bg_color light shadow} {
global RGB_IMAGE RGB NORMAL TRUE FALSE FG_BG_RGB
global MULTIPLY REPLACE BG_BUCKET_FILL RADIAL
# puts "radius: $radius"
# puts "sphere_color: $sphere_color"
# puts "bg_color: $bg_color"
# puts "light: $light"
# puts "shadow: $shadow"
set w [expr $radius * 3.52]
set h [expr $radius * 2.40]
set img [gimp-image-new $w $h RGB]
set drawable [gimp-layer-new $img $w $h \
RGB_IMAGE "Sphere" 100 NORMAL]
set radians [expr ($light * 3.1415926) / 180]
set cx [expr $w / 2]
set cy [expr $h / 2]
set light_x [expr $cx + ((cos($radians) * 0.6) * $radius)]
set light_y [expr $cy - ((sin($radians) * 0.6) * $radius)]
set light_end_x [expr $cx + ($radius * (cos(3.1415926 + $radians)))]
set light_end_y [expr $cy - ($radius * (sin(3.1415926 + $radians)))]
set offset [expr $radius * 0.1]
gimp-image-disable-undo $img
gimp-image-add-layer $img $drawable 0
gimp-palette-set-foreground $sphere_color
gimp-palette-set-background $bg_color
gimp-edit-fill $img $drawable
gimp-palette-set-background {20 20 20}
if {((($light >= 45) && ($light <= 75))
|| (($light <= 135) && ($light >= 105)))
&& ($shadow == 1)} {
set shadow_w [expr ($radius * 2.5) * (cos(3.1415926 * $radians))]
set shadow_h [expr $radius * 0.5]
set shadow_x $cx
set shadow_y [expr $cy + ($radius * 0.65)]
if {$shadow_w < 0} {
set shadow_x [expr $cx + $shadow_w]
set shadow_w [expr -$shadow_w]
}
gimp-ellipse-select $img $shadow_x $shadow_y \
$shadow_w $shadow_h REPLACE TRUE $TRUE 7.5
gimp-bucket-fill $img $drawable BG_BUCKET_FILL \
MULTIPLY 100 0 FALSE 0 0
}
gimp-ellipse-select $img [expr $cx - $radius] \
[expr $cy - $radius] [expr 2 * $radius] [expr 2 * $radius] \
REPLACE TRUE FALSE 0
gimp-blend $img $drawable FG_BG_RGB NORMAL RADIAL 100 \
$offset FALSE FALSE 0 0 $light_x $light_y $light_end_x $light_end_y
gimp-selection-none $img
gimp-image-enable-undo $img
gimp-display-new $img
return $img
}
Shadow_Sphere 100 {255 0 0} {255 255 255} 45 FALSE

View file

@ -1,14 +0,0 @@
source sphere.tcl
for {set l 15; set i 0} {$l <= 150} {incr l; incr i} {
set fn [format "/src/t/%04d.jpg" $i]
puts $fn
set img [Shadow_Sphere 100 {0 255 128} {255 255 255} $l $TRUE]
set drw [gimp-image-active-drawable $img]
# gimp-display-new $img
# gimp-image-scale $img 352 240
file-jpeg-save $img $drw $fn 100 $TRUE
gimp-image-free-shadow $img
gimp-image-delete $img
}

View file

@ -1,65 +0,0 @@
/***************************************************
* file: gtcl.h
*
* Copyright (c) 1996 Eric L. Hernes (erich@rrnet.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
int Gtcl_PDBInit(Tcl_Interp *interp);
int Gtcl_ConstInit(Tcl_Interp *interp);
int Gtcl_GimpRunProc(ClientData data, Tcl_Interp *interp, int ac, char *av[]);
int Gtcl_QueryDBProc(ClientData data, Tcl_Interp *interp, int ac, char *av[]);
int Gtcl_QueryDB(ClientData data, Tcl_Interp *interp, int ac, char *av[]);
int Gtcl_InstallProc(ClientData data, Tcl_Interp *interp, int ac, char *av[]);
int Gtcl_GimpMain(ClientData data, Tcl_Interp *interp, int ac, char *av[]);
int Gtcl_SetData(ClientData data, Tcl_Interp *interp, int ac, char *av[]);
int Gtcl_GetData(ClientData data, Tcl_Interp *interp, int ac, char *av[]);
int Argv_to_GParam(Tcl_Interp *interp, char *name, int ac, char **av,
GParam *parr);
int GParam_to_Argv(Tcl_Interp *interp, char *name, int ac, GParam *vals,
char **av);
void gtcl_addconst(Tcl_Interp *interp);
void cvtfrom (char *str);
void cvtto (char *str);
extern char *GtclConst;
extern char *GtclProcs;
#define debugging 1
#ifdef debugging
extern int debuglevel;
#define DPRINTF(l,m) if(debuglevel>=l) fprintf m
#else
#define DPRINTF(l,m)
#endif
#ifdef __linux__
#define Tcl_Free free
#endif

View file

@ -1,91 +0,0 @@
/***************************************************
* file: gtclConst.c
*
* Copyright (c) 1996 Eric L. Hernes (erich@rrnet.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include <stdlib.h>
#include <tcl.h>
#include <glib.h>
#include <libgimp/gimp.h>
#include "gtcl.h"
#include "gtclEnums.h"
#include <stdio.h>
char* GtclConst="GtclConst";
#define Gtcl_CAdd(c) sprintf(t, "%d", c); \
sprintf(t1, "%s", # c); \
Tcl_SetVar2(interp, GtclConst, t1, t, \
TCL_GLOBAL_ONLY); \
cvtfrom(t1); \
Tcl_SetVar2(interp, GtclConst, t1, t, \
TCL_GLOBAL_ONLY);
#define Gtcl_CAddf(c) sprintf(t, "%g", c); \
sprintf(t1, "%s", # c); \
Tcl_SetVar2(interp, GtclConst, t1, t, \
TCL_GLOBAL_ONLY); \
cvtfrom(t1); \
Tcl_SetVar2(interp, GtclConst, t1, t, \
TCL_GLOBAL_ONLY);
int
Gtcl_ConstInit(Tcl_Interp *interp){
char t[30], t1[30];
Tcl_PkgProvide(interp, "GtclConstant", "1.0");
/* the auto-generated ones from <gimpenums.h> */
#include "gtclenums.h"
/* and a few manifest constants from <glib.h> */
Gtcl_CAddf(G_MINFLOAT);
Gtcl_CAddf(G_MAXFLOAT);
Gtcl_CAddf(G_MINDOUBLE);
Gtcl_CAddf(G_MAXDOUBLE);
Gtcl_CAdd(G_MINSHORT);
Gtcl_CAdd(G_MAXSHORT);
Gtcl_CAdd(G_MININT);
Gtcl_CAdd(G_MAXINT);
Gtcl_CAdd(G_MINLONG);
Gtcl_CAdd(G_MAXLONG);
/* and a few others */
Gtcl_CAdd(TRUE);
Gtcl_CAdd(FALSE);
/* for gimp-text */
#define NEW_LAYER -1
#define PIXELS 0
#define POINTS 1
Gtcl_CAdd(NEW_LAYER);
Gtcl_CAdd(PIXELS);
Gtcl_CAdd(POINTS);
return TCL_OK;
}

View file

@ -1,125 +0,0 @@
/***************************************************
* file: gtclenums.h
*
* Copyright (c) 1996 Eric L. Hernes (erich@rrnet.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
/*
* enums that are needed both by the
* interface file and at compile time
*/
/* bucket fill stuff */
enum {
FG_BUCKET_FILL,
BG_BUCKET_FILL,
PATTERN_BUCKET_FILL
};
/* blend stuff */
enum {
LINEAR,
BILINEAR,
RADIAL,
SQUARE,
CONICAL_SYMMETRIC,
CONICAL_ASYMMETRIC,
SHAPEBURST_ANGULAR,
SHAPEBURST_SPHERICAL,
SHAPEBURST_DIMPLED
};
enum {
FG_BG_RGB,
FG_BG_HSV,
FG_TRANS,
CUSTOM
};
/* layer modes */
enum {
NORMAL = 0,
DISSOLVE = 1,
BEHIND = 2,
MULTIPLY = 3,
SCREEN = 4,
OVERLAY = 5,
DIFFERENCE = 6,
ADDITION = 7,
SUBTRACT = 8,
DARKEN_ONLY = 9,
LIGHTEN_ONLY = 10,
HUE = 11,
SATURATION = 12,
COLOR = 13,
VALUE = 14
};
/* gimp image get components */
enum {
RED_CHANNEL,
GREEN_CHANNEL,
BLUE_CHANNEL,
GRAY_CHANNEL,
INDEXED_CHANNEL
};
/* layer masks */
enum {
WHITE_MASK,
BLACK_MASK,
ALPHA_MASK
};
/* remove layer mask */
enum {
APPLY,
DISCARD
};
/* types of layer merges */
enum {
EXPAND_AS_NECESSARY,
CLIP_TO_IMAGE,
CLIP_TO_BOTTOM_LAYER
};
/* rect_select args */
enum {
ADD,
SUB,
REPLACE
};
/* cloning */
enum {
IMAGE_CLONE,
PATTERN_CLONE
};
/* convolving type */
enum {
BLUR,
SHARPEN
};

View file

@ -1,276 +0,0 @@
/***************************************************
* file: gtclMain.c
*
* Copyright (c) 1996 Eric L. Hernes (erich@rrnet.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include <string.h>
#include <stdlib.h>
#include <libgimp/gimp.h>
#include <tcl.h>
#include <tk.h>
#include "gtcl.h"
int debuglevel=0;
int Gtcl_Init(Tcl_Interp *interp);
static void gtcl_init(void);
static void gtcl_quit(void);
static void gtcl_query(void);
static void gtcl_run(char *name, int nparm, GParam *p, int *nrv, GParam **rv);
int Gimptcl_Init(Tcl_Interp *interp);
Tcl_Interp *theInterp=NULL;
GPlugInInfo PLUG_IN_INFO = {
gtcl_init,
gtcl_quit,
gtcl_query,
gtcl_run
};
int
main(int ac, char *av[]){
char *tcllib_p, *tcllib;
/* fprintf(stderr, "gimptcl: %d %s\n", ac, av[1]);*/
if (ac < 2) {
fprintf(stderr, "usage: %s <script>\n", av[0]);
exit(1);
}
theInterp = Tcl_CreateInterp();
Tcl_SetVar(theInterp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
tcllib_p = Tcl_GetVar(theInterp, "tcl_library", TCL_GLOBAL_ONLY);
tcllib = malloc(strlen(tcllib_p)+10);
sprintf(tcllib, "%s/init.tcl", tcllib_p);
Tcl_EvalFile(theInterp, tcllib);
free(tcllib);
free(tcllib_p);
Gimptcl_Init(theInterp);
Tcl_StaticPackage(theInterp, "Gimptcl", Gimptcl_Init, Gimptcl_Init);
Tcl_EvalFile(theInterp, av[1]);
return gimp_main(ac-1, av+1);
}
/*
* add Gimp package to a Tcl Interp
*/
int
Gimptcl_Init(Tcl_Interp *interp){
char debuglevelvar[] = "DebugLevel";
char GimpTclProcsVar[] = "GimpTclProcs";
Tcl_PkgProvide(interp, "Gimptcl", "1.0");
Tcl_CreateCommand(interp, "gimp-run-procedure", Gtcl_GimpRunProc,
(ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "gimp-query-dbproc", Gtcl_QueryDBProc,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateCommand(interp, "gimp-query-db", Gtcl_QueryDB,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateCommand(interp, "gimp-install-procedure", Gtcl_InstallProc,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateCommand(interp, "gimp-set-data", Gtcl_SetData,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateCommand(interp, "gimp-get-data", Gtcl_GetData,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
#ifdef SHLIB_METHOD
Tcl_CreateCommand(interp, "gimp-main", Gtcl_GimpMain,
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
#endif
Tcl_LinkVar(interp, debuglevelvar, (char *)&debuglevel,
TCL_LINK_INT);
Tcl_LinkVar(interp, GimpTclProcsVar, (char *)&GtclProcs,
TCL_LINK_STRING |TCL_LINK_READ_ONLY);
/*
* we have to delay adding PDB and Const to the interp
* until gtcl_run is called, because we need
* gimp_main to setup the IPC to the PDB.
*/
if (!theInterp)
theInterp=interp;
return TCL_OK;
}
static void
gtcl_init(void){
if (theInterp == NULL){
fprintf(stderr, "gtcl_init, theInterp not initialized\n");
return;
}
Tcl_Eval(theInterp, "info procs gimptcl_init");
if (strcmp(theInterp->result, "gimptcl_init")==0){
if(Tcl_Eval(theInterp, "gimptcl_init")==TCL_ERROR){
fprintf(stderr, "Error in gtcl_init:\n\t%s\n", theInterp->result);
} else {
/* printf("%s\n", theInterp->result);*/
}
}
}
static void
gtcl_quit(void){
if (theInterp == NULL){
fprintf(stderr, "gtcl_quit, theInterp not initialized\n");
return;
}
Tcl_Eval(theInterp, "info procs gimptcl_quit");
if (strcmp(theInterp->result, "gimptcl_quit")==0){
if(Tcl_Eval(theInterp, "gimptcl_quit")==TCL_ERROR){
fprintf(stderr, "Error in gtcl_quit:\n\t%s\n", theInterp->result);
} else {
/* printf("%s\n", theInterp->result);*/
}
}
}
static void
gtcl_query(void){
if (theInterp == NULL){
fprintf(stderr, "gtcl_quit, theInterp not initialized\n");
return;
}
Tcl_Eval(theInterp, "info procs gimptcl_query");
if (strcmp(theInterp->result, "gimptcl_query")!=0){
fprintf(stderr, "Whoa there, no query\n");
} else {
if(Tcl_Eval(theInterp, "gimptcl_query")==TCL_ERROR){
fprintf(stderr, "Error in gtcl_query:%s\n", theInterp->result);
} else {
/* printf("%s\n", theInterp->result);*/
}
}
}
static void
gtcl_run(char *name, int nparm, GParam *p, int *nrv, GParam **rv){
char **pars, **rvs, *t, cmd[80];
int rstat;
if (theInterp == NULL){
fprintf(stderr, "gtcl_run, theInterp not initialized\n");
rstat=STATUS_EXECUTION_ERROR;
goto error_done;
}
/* ok, add in our constants and the full PDB */
Gtcl_PDBInit(theInterp);
Gtcl_ConstInit(theInterp);
Tcl_StaticPackage(theInterp, "GtclConstant", Gtcl_ConstInit, Gtcl_ConstInit);
Tcl_StaticPackage(theInterp, "GtclPDB", Gtcl_PDBInit, Gtcl_PDBInit);
Tcl_Eval(theInterp, "info procs gimptcl_run");
if (strcmp(theInterp->result, "gimptcl_run")!=0){
fprintf(stderr, "gimptcl_run: nothing to do");
rstat = STATUS_EXECUTION_ERROR;
goto error_done;
}
pars=(char **)malloc(sizeof(char *)*nparm);
/* fprintf(stderr, "gimptcl_run, need %d args\n", nparm);*/
if(GParam_to_Argv(theInterp, "gimptcl_run", nparm, p, pars)==TCL_ERROR){
rstat=STATUS_CALLING_ERROR;
goto error_done;
}
t=Tcl_Merge(nparm, pars);
free(pars);
sprintf(cmd, "gimptcl_run %s", t);
Tcl_Free(t);
if (p[0].data.d_int32 == RUN_INTERACTIVE) {
if (Tk_Init(theInterp) == TCL_OK) {
} else {
fprintf (stderr, "error in Tk_Init(): %s\n", theInterp->result);
}
#if TK_MAJOR_VERSION == 8
Tcl_StaticPackage(theInterp, "Tk", Tk_Init, Tk_SafeInit);
#else
Tcl_StaticPackage(theInterp, "Tk", Tk_Init, NULL);
#endif
}
if(Tcl_Eval(theInterp, cmd)==TCL_ERROR){
fprintf(stderr, "Error in gtcl_run:%s\n", theInterp->result);
rstat=STATUS_CALLING_ERROR;
goto error_done;
}
if (p[0].data.d_int32 == RUN_INTERACTIVE) {
Tk_MainLoop();
rstat=STATUS_SUCCESS;
goto error_done; /* XXX a bit kludgey */
}
/* fprintf(stderr, "gimptcl_run returned `%s'\n", theInterp->result);*/
Tcl_SplitList(theInterp, theInterp->result, nrv, &rvs);
/* fprintf(stderr, "split into %d rets\n", *nrv);*/
*rv=(GParam*)malloc(sizeof(GParam) * ((*nrv)+1));
rv[0]->type=PARAM_STATUS;
{
char *b, *h, *a, *c, *d;
int type, nparams, nrvs, i;
GParamDef *p_params, *p_rvals;
if(gimp_query_procedure(name, &b, &h, &a, &c, &d, &type, &nparams, &nrvs,
&p_params, &p_rvals) != TRUE) {
rstat=STATUS_EXECUTION_ERROR;
goto error_done;
}
/* fprintf(stderr, "%s returns %d rets\n", name, nrvs);*/
for(i=0;i<*nrv;i++){
fprintf(stderr, "setting rv[%d] to %d", i+1, p_rvals[i].type);
(*rv)[i+1].type= p_rvals[i].type;
fprintf(stderr, "\n");
}
g_free(b);
g_free(h);
g_free(a);
g_free(d);
}
if(Argv_to_GParam(theInterp, "gtcl_run", *nrv, rvs, &((*rv)[1]))==TCL_ERROR){
rv[0]->data.d_status=STATUS_EXECUTION_ERROR;
} else {
rv[0]->data.d_status=STATUS_SUCCESS;
}
return;
error_done:
*nrv=0;
*rv=(GParam*)malloc(sizeof(GParam));
rv[0]->type = PARAM_STATUS;
rv[0]->data.d_status=rstat;
}

View file

@ -1,540 +0,0 @@
/***************************************************
* file: gtclPDB.c
*
* Copyright (c) 1996 Eric L. Hernes (erich@rrnet.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include <ctype.h>
#include <tcl.h>
#include <stdlib.h>
#include <string.h>
#include <libgimp/gimp.h>
#include "gtcl.h"
char *GtclProcs = NULL;
static char *proc_types[] = {
"undefined",
"plug-in",
"Extension",
};
static char *param_types[] = {
"int32",
"int16",
"int8",
"float",
"string",
"int32array",
"int16array",
"int8array",
"floatarray",
"stringarray",
"color",
"region",
"display",
"image",
"layer",
"channel",
"drawable",
"selection",
"boundary",
"path",
"status",
"end"
};
static int str_to_typeenum(char *type);
static int list_to_pdef(Tcl_Interp *interp, char *list, GParamDef *p);
/*
* add the procedural-database to a Tcl Interpreter
*/
int
Gtcl_PDBInit(Tcl_Interp *interp){
char **proc_list;
char *proc_name;
char *proc_blurb;
char *proc_help;
char *proc_author;
char *proc_copyright;
char *proc_date;
int proc_type;
int nparams;
int nreturn_vals;
GParamDef *params, *return_vals;
int num_procs, i, j;
char whole_proc[4096];
char arglist[1024];
char carglist[1024];
char **theproc_list;
Tcl_PkgProvide(interp, "GtclPDB", "1.0");
gimp_query_database (".*", ".*", ".*", ".*", ".*", ".*", ".*",
&num_procs, &proc_list);
theproc_list = (char **)malloc(num_procs * sizeof(char *));
for (i = 0; i < num_procs; i++) {
memset(whole_proc, 0, sizeof(whole_proc));
memset(arglist, 0, sizeof(arglist));
memset(carglist, 0, (sizeof(carglist)));
proc_name = strdup (proc_list[i]);
/* fprintf(stderr, "(proc %d/%d %s)\n", i, num_procs, proc_name);*/
/* lookup the procedure */
if(gimp_query_procedure(proc_name, &proc_blurb, &proc_help, &proc_author,
&proc_copyright, &proc_date, &proc_type,
&nparams, &nreturn_vals,
&params, &return_vals) == TRUE) {
cvtfrom(proc_name);
theproc_list[i] = (char *)malloc(strlen(proc_name)+1);
strcpy(theproc_list[i], proc_name);
/* fprintf(stderr, "adding %d `%s' -> `%s' %d\n", i, proc_name,
theproc_list[i], strlen(proc_name)); */
sprintf(carglist, "gimp-run-procedure %s ", proc_name);
for(j=0;j<nparams;j++){
if (strcmp(params[j].name, "run_mode")==0){
strcat(carglist, "1 ");
} else {
char vname[30];
sprintf(vname, "%s%d", params[j].name, j);
strcat(arglist, vname);
strcat(arglist, " ");
strcat(carglist, "$");
strcat(carglist, vname);
strcat(carglist, " ");
}
}
sprintf(whole_proc, "proc {%s} {%s} {\n global env\n set env(GimpPDBCmd) %s\n update\n return [%s]\n}\n\n",
proc_name, arglist, proc_name, carglist);
#if 0
fprintf(stderr, "%s", whole_proc);
#endif
Tcl_GlobalEval(interp, whole_proc);
free(proc_name);
g_free(proc_blurb);
g_free(proc_help);
g_free(proc_author);
g_free(proc_copyright);
g_free(proc_date);
g_free(params);
g_free(return_vals);
}
}
GtclProcs = Tcl_Merge(num_procs, theproc_list);
/* fprintf(stderr, "%s", GtclProcs);*/
for(i=0;i<num_procs;i++) free(theproc_list[i]);
free(theproc_list);
return TCL_OK;
}
/*
* run a procedure from the PDB, really the heart of
* this thing... Virtually everything goes through here.
*/
int
Gtcl_GimpRunProc(ClientData data, Tcl_Interp *interp, int ac, char *av[]){
GParam *par, *vals;
char *p_blurb, *p_help, *p_author, *p_copy, *p_date, **rv_a;
int p_type, p_npar, p_nrv;
GParamDef *p_par, *p_rv;
char *p_name;
int i;
if (ac < 2) {
Tcl_SetResult(interp, "gimp-run-procedure: too few arguments",
TCL_STATIC);
return TCL_ERROR;
}
rv_a=(char **)NULL;
p_name = strdup(av[1]);
/* first try the name as given */
if (gimp_query_procedure(p_name, &p_blurb, &p_help, &p_author, &p_copy,
&p_date, &p_type, &p_npar, &p_nrv, &p_par,
&p_rv) == FALSE) {
/* nope?, try `tr - _` */
cvtto(p_name);
if (gimp_query_procedure(p_name, &p_blurb, &p_help, &p_author, &p_copy,
&p_date, &p_type, &p_npar, &p_nrv, &p_par,
&p_rv) == FALSE) {
Tcl_SetResult(interp, "gimp-run-procedure invalid command: ",
TCL_STATIC);
Tcl_AppendResult(interp, p_name, (char *)NULL);
return TCL_ERROR;
}
}
ac-=2; /* subtract off own name and the proc name */
if (ac != p_npar){
Tcl_SetResult(interp, "gimp-run-procedure: ", TCL_STATIC);
Tcl_AppendResult(interp, p_name, " : Wrong # args\n",
"usage: ", p_name, (char *)NULL);
for (i=0;i<p_npar;i++){
Tcl_AppendResult(interp, " ", p_par[i].name, (char *)NULL);
}
return TCL_ERROR;
}
par = (GParam *)malloc(sizeof(GParam)*ac);
for(i=0;i<p_npar;i++){
par[i].type = p_par[i].type;
}
if(Argv_to_GParam(interp, p_name, p_npar, av+2, par)==TCL_ERROR){
free(par);
return TCL_ERROR;
}
DPRINTF(1,(stderr, "\nGimp PDB Running: (%s:", p_name));
vals = gimp_run_procedure2 (p_name, &p_nrv, p_npar, par);
if (! vals) {
Tcl_SetResult(interp, "pdb: no status returned from", TCL_STATIC);
Tcl_AppendResult(interp, p_name, (char *)NULL);
free(par);
return TCL_ERROR;
}
DPRINTF(1,(stderr, " returned %d)\n", vals[0].data.d_status));
switch (vals[0].data.d_status) {
case STATUS_EXECUTION_ERROR:
gimp_destroy_params (vals, p_nrv);
free(par);
Tcl_SetResult(interp, "pdb: exec failed for ", TCL_STATIC);
cvtfrom(p_name);
Tcl_AppendResult(interp, p_name, (char *)NULL);
return TCL_ERROR;
break;
case STATUS_CALLING_ERROR:
gimp_destroy_params (vals, p_nrv);
Tcl_SetResult(interp, "pdb: invalid arguments for ", TCL_STATIC);
Tcl_AppendResult(interp, p_name, (char *)NULL);
return TCL_ERROR;
break;
case STATUS_SUCCESS:
rv_a=(char **)malloc(sizeof(char *)*p_nrv-1);
if(GParam_to_Argv(interp, p_name, p_nrv-1, &vals[1], rv_a)==TCL_ERROR){
gimp_destroy_params (vals, p_nrv);
return TCL_ERROR;
}
}
if(p_nrv==2){
Tcl_SetResult(interp, rv_a[0], TCL_VOLATILE);
} else {
char *t;
t=Tcl_Merge(p_nrv-1, rv_a);
Tcl_SetResult(interp, t, TCL_DYNAMIC);
}
for(i=0;i<p_nrv-1;i++){
free(rv_a[i]);
}
free((char *)rv_a);
free(par);
g_free(p_blurb);
g_free(p_help);
g_free(p_author);
g_free(p_copy);
g_free(p_date);
g_free(p_par);
g_free(p_rv);
gimp_destroy_params (vals, p_nrv);
return TCL_OK;
}
/*
* query the database for info on a procedure
*/
int
Gtcl_QueryDBProc(ClientData data, Tcl_Interp *interp, int ac, char *av[]){
char *blurb, *help, *author, *copyright, *date, **tl0, *tl1[3];
char *t, *p_name;
int type, npar, nrv, i;
GParamDef *par_d, *rv_d;
if (ac!=2) {
Tcl_SetResult(interp, "gimp-query-dbproc: wrong # arguments", TCL_STATIC);
return TCL_ERROR;
}
p_name = strdup(av[1]);
cvtto(p_name);
if(gimp_query_procedure(av[1], &blurb, &help, &author, &copyright,
&date, &type, &npar, &nrv, &par_d, &rv_d) == FALSE) {
if(gimp_query_procedure(p_name, &blurb, &help, &author, &copyright,
&date, &type, &npar, &nrv, &par_d, &rv_d)
== FALSE) {
Tcl_SetResult(interp, "gimp-query-dbproc: invalid command: ",
TCL_STATIC);
Tcl_AppendResult(interp, av[1], (char *)NULL);
return TCL_ERROR;
}
}
free(p_name);
Tcl_AppendElement(interp, av[1]);
Tcl_AppendElement(interp, blurb);
Tcl_AppendElement(interp, help);
Tcl_AppendElement(interp, author);
Tcl_AppendElement(interp, copyright);
Tcl_AppendElement(interp, date);
Tcl_AppendElement(interp, proc_types[type]);
tl0=(char**)malloc(sizeof(char*) * npar);
for(i=0;i<npar;i++){
tl1[0]=param_types[par_d[i].type];
tl1[1]=par_d[i].name;
tl1[2]=par_d[i].description;
t=Tcl_Merge(3, tl1);
tl0[i]=t;
}
t = Tcl_Merge(npar, tl0);
Tcl_AppendElement(interp, t);
Tcl_Free(t);
for(i=0;i<npar;i++)
Tcl_Free(tl0[i]);
free(tl0);
tl0=(char**)malloc(sizeof(char*) * nrv);
for(i=0;i<nrv;i++){
tl1[0]=param_types[rv_d[i].type];
tl1[1]=rv_d[i].name;
tl1[2]=rv_d[i].description;
t=Tcl_Merge(3, tl1);
tl0[i]=t;
}
t = Tcl_Merge(nrv, tl0);
Tcl_AppendElement(interp, t);
Tcl_Free(t);
for(i=0;i<nrv;i++)
Tcl_Free(tl0[i]);
free(tl0);
g_free(blurb);
g_free(help);
g_free(author);
g_free(copyright);
g_free(date);
g_free(par_d);
g_free(rv_d);
return TCL_OK;
}
/*
* query the database for any or all procedures
*/
int
Gtcl_QueryDB(ClientData data, Tcl_Interp *interp, int ac, char *av[]){
char **procs, *r, *p_name;
int nproc, i;
if(ac != 8) {
Tcl_SetResult(interp, "gimp-query-db: wrong # args", TCL_STATIC);
return TCL_ERROR;
}
p_name = strdup(av[1]);
cvtto(p_name);
gimp_query_database (p_name, av[2], av[3], av[4], av[5], av[6], av[7],
&nproc, &procs);
free(p_name);
for(i=0;i<nproc;i++){
cvtfrom(procs[i]);
}
r=Tcl_Merge(nproc, procs);
for(i=1;i<nproc;i++){
free(procs[i]);
}
free(procs);
Tcl_SetResult(interp, r, TCL_DYNAMIC);
return TCL_OK;
}
/*
* install a procedure in the database
*/
int
Gtcl_InstallProc(ClientData data, Tcl_Interp *interp, int ac, char *av[]){
GParamDef *args_p, *rets_p;
char **args, **rets;
int narg, nret, i, type;
if(ac!=12){
Tcl_SetResult(interp, "gimp-install-procedure: wrong # args:\n",
TCL_STATIC);
Tcl_AppendResult(interp, "usage: ", av[0],
" <name> <blurb> <help> <author> <copyright> <date> "
"<menu-path> <image-types> <type> <args> <retvals>",
(char *)NULL);
return(TCL_ERROR);
}
if (strncasecmp("plug", av[9], 4)==0){
type=PROC_PLUG_IN;
} else if (strcasecmp("extension", av[9])==0){
type=PROC_EXTENSION;
} else {
Tcl_SetResult(interp, "unknown procedure type: `", TCL_STATIC);
Tcl_AppendResult(interp, av[9], "'", (char *)NULL);
return TCL_ERROR;
}
if (Tcl_SplitList(interp, av[10], &narg, &args)==TCL_ERROR) {
return(TCL_ERROR);
}
if (Tcl_SplitList(interp, av[11], &nret, &rets)==TCL_ERROR) {
return(TCL_ERROR);
}
args_p=(GParamDef*)malloc(sizeof(GParamDef)*narg);
rets_p=(GParamDef*)malloc(sizeof(GParamDef)*nret);
for(i=0;i<narg;i++){
if (list_to_pdef(interp, args[i], &args_p[i])== TCL_ERROR){
return TCL_ERROR;
}
}
for(i=0;i<nret;i++){
if (list_to_pdef(interp, rets[i], &rets_p[i])== TCL_ERROR){
return TCL_ERROR;
}
}
#if 0
fprintf(stderr, "proc_inst: %s [arg: %d] [ret: %d]\n", av[1], narg, nret);
fprintf(stderr, "g_i_p(n=%s,\n b=%s,\n h=%s,\n a=%s,\n",
av[1], av[2], av[3], av[4]);
fprintf(stderr, " c=%s,\n d=%s,\n m=%s,\n i=%s,\n",
av[5], av[6], av[7], av[8]);
fprintf(stderr, " t=%d,\n np=%d,\n nr=%d)\n",
type, narg, nret);
#endif
gimp_install_procedure(av[1], av[2], av[3], av[4], av[5], av[6], av[7],
av[8], type, narg, nret, args_p, rets_p);
free(args_p);
free(rets_p);
return TCL_OK;
}
/*
* the libgimp dispatcher -- needed for plugins
*/
int
Gtcl_GimpMain(ClientData data, Tcl_Interp *interp, int argc, char *argv[]){
char **av, **av0, *av1;
int ac0, i;
av1=Tcl_GetVar(interp, "argv", TCL_GLOBAL_ONLY);
Tcl_SplitList(interp, av1, &ac0, &av0);
av=(char **)malloc(sizeof(char*)*ac0+1);
av[0] = Tcl_GetVar(interp, "argv0", TCL_GLOBAL_ONLY);
for(i=0;i<ac0;i++){
av[i+1]=av0[i];
}
gimp_main(ac0+1, av);
free((char*)av);
free((char*)av0);
return TCL_OK;
}
/*
* get/set runtime data from the gimp program
* for running with last args
*/
int
Gtcl_SetData(ClientData data, Tcl_Interp *interp, int ac, char *av[]){
if(ac!=3){
Tcl_SetResult(interp, "gimp-set-data: wrong # args:\n",
TCL_STATIC);
Tcl_AppendResult(interp, "usage: ", av[0],
" <key> <value>", (char *)NULL);
return(TCL_ERROR);
}
gimp_set_data(av[1], av[2], strlen(av[2]));
return TCL_OK;
}
int
Gtcl_GetData(ClientData data, Tcl_Interp *interp, int ac, char *av[]){
char tmp[1024];
memset(tmp, 0, 1024);
if(ac!=2){
Tcl_SetResult(interp, "gimp-get-data: wrong # args:\n",
TCL_STATIC);
Tcl_AppendResult(interp, "usage: ", av[0],
" <key>", (char *)NULL);
return(TCL_ERROR);
}
gimp_get_data(av[1], tmp);
Tcl_SetResult(interp, tmp, TCL_VOLATILE);
return TCL_OK;
}
/*
* static conveninence functions...
*/
/*
* translate a 3 element list into a ParamDef structure
*/
static int
list_to_pdef(Tcl_Interp *interp, char *list, GParamDef *p){
char **l;
int n, t;
if(Tcl_SplitList(interp, list, &n, &l)==TCL_ERROR){
return TCL_ERROR;
}
if(n!=3) {
Tcl_SetResult(interp, "ParamDef wasn't 3 elements", TCL_STATIC);
return TCL_ERROR;
}
if((t=str_to_typeenum(l[0]))==-1) {
Tcl_SetResult(interp, "ParamDef: unknown type `", TCL_STATIC);
Tcl_AppendResult(interp, l[0], "'", (char *)NULL);
return(TCL_ERROR);
}
p->type=t;
p->name=strdup(l[1]);
p->description=strdup(l[2]);
Tcl_Free((char *)l);
return TCL_OK;
}
static int
str_to_typeenum(char *type){
int i;
for(i=0;i<sizeof(param_types);i++)
if(strcasecmp(type, param_types[i])==0) return i;
return -1;
}

View file

@ -1,494 +0,0 @@
/***************************************************
* file: gtcl_misc.c
*
* Copyright (c) 1996 Eric L. Hernes (erich@rrnet.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. The name of the author may not be used to endorse or promote products
* derived from this software withough specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Id$
*/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <tcl.h>
#include <libgimp/gimp.h>
#include "gtcl.h"
int
Argv_to_GParam(Tcl_Interp *interp, char *name, int ac, char **av,
GParam *par){
GParam *pc;
int i;
for(i=0;i<ac;i++){
pc=&par[i];
switch(pc->type) {
case PARAM_INT32:
if (isalpha(*av[i])) {
char *t;
DPRINTF(3,(stderr, "i32 ht lu: %s\n", av[i]));
if ((t=Tcl_GetVar2(interp, GtclConst, av[i], TCL_GLOBAL_ONLY))
== NULL){
Tcl_SetResult(interp, name, TCL_VOLATILE);
Tcl_AppendResult(interp, ": argument error: ", av[i],
" unknown constant", (char *)NULL);
return TCL_ERROR;
}
pc->data.d_int32 = strtol(t, (char **)NULL, 0);
} else {
pc->data.d_int32 = strtol(av[i], (char **)NULL, 0);
}
DPRINTF(2,(stderr, " (i32)%d ", pc->data.d_int32));
break;
case PARAM_INT16:
if (isalpha(*av[i])) {
char *t;
DPRINTF(3,(stderr, "i16 ht lu: %s\n", av[i]));
if ((t=Tcl_GetVar2(interp, GtclConst, av[i], TCL_GLOBAL_ONLY))
== NULL){
Tcl_SetResult(interp, name, TCL_VOLATILE);
Tcl_AppendResult(interp, ": argument error: ", av[i],
" unknown constant", (char *)NULL);
return TCL_ERROR;
}
pc->data.d_int16 = strtol(t, (char **)NULL, 0);
} else {
pc->data.d_int16 = strtol(av[i], (char **)NULL, 0);
}
DPRINTF(2,(stderr, " (i16)%d ", pc->data.d_int16));
break;
case PARAM_INT8:
if (isalpha(*av[i])) {
char *t;
DPRINTF(3,(stderr, "ht lu: %s\n", av[i]));
if ((t=Tcl_GetVar2(interp, GtclConst, av[i], TCL_GLOBAL_ONLY))
== NULL){
Tcl_SetResult(interp, name, TCL_VOLATILE);
Tcl_AppendResult(interp, ": argument error: ", av[i],
" unknown constant", (char *)NULL);
return TCL_ERROR;
}
pc->data.d_int8 = strtol(t, (char **)NULL, 0);
} else {
pc->data.d_int8 = strtol(av[i], (char **)NULL, 0);
}
DPRINTF(2,(stderr, " (i8)%d ", pc->data.d_int8));
break;
case PARAM_FLOAT:
if (isalpha(*av[i])) {
char *t;
DPRINTF(3,(stderr, "fl ht lu: %s\n", av[i]));
if ((t=Tcl_GetVar2(interp, GtclConst, av[i], TCL_GLOBAL_ONLY))
== NULL){
Tcl_SetResult(interp, name, TCL_VOLATILE);
Tcl_AppendResult(interp, ": argument error: ", av[i],
" unknown constant", (char *)NULL);
return TCL_ERROR;
}
pc->data.d_float = strtod(t, (char **)NULL);
} else {
pc->data.d_float = strtod(av[i], (char **)NULL);
}
DPRINTF(2,(stderr, " (f.%s.)%g ", av[i], pc->data.d_float));
break;
case PARAM_STRING:
pc->data.d_string = av[i];
DPRINTF(2,(stderr, " `%s' ", pc->data.d_string));
break;
case PARAM_INT32ARRAY: {
int tc, j;
char **ar;
if (Tcl_SplitList(interp, av[i], &tc, &ar)==TCL_ERROR){
return TCL_ERROR;
}
pc->data.d_int32array = (gint32*)malloc(sizeof(gint32)*tc);
for(j=0;j<tc;j++){
if (isalpha(*ar[j])) {
char *t;
DPRINTF(3,(stderr, "i32a ht lu: %s\n", ar[j]));
if ((t=Tcl_GetVar2(interp, GtclConst, ar[j], TCL_GLOBAL_ONLY))
== NULL){
Tcl_SetResult(interp, name, TCL_VOLATILE);
Tcl_AppendResult(interp, ": argument error: ", ar[j],
" unknown constant", (char *)NULL);
return TCL_ERROR;
}
pc->data.d_int32array[j] = strtol(t, (char **)NULL, 0);
} else {
pc->data.d_int32array[j] = strtol(ar[j], (char **)NULL, 0);
}
}
Tcl_Free((char *)ar);
}
break;
case PARAM_INT16ARRAY: {
int tc, j;
char **ar;
if (Tcl_SplitList(interp, av[i], &tc, &ar)==TCL_ERROR){
return TCL_ERROR;
}
pc->data.d_int16array = (gint16*)malloc(sizeof(gint16)*tc);
for(j=0;j<tc;j++){
if (isalpha(*ar[j])) {
char *t;
DPRINTF(3,(stderr, "i16a ht lu: %s\n", av[i]));
if ((t=Tcl_GetVar2(interp, GtclConst, ar[j], TCL_GLOBAL_ONLY))
== NULL){
Tcl_SetResult(interp, name, TCL_VOLATILE);
Tcl_AppendResult(interp, ": argument error: ", ar[j],
" unknown constant", (char *)NULL);
return TCL_ERROR;
}
pc->data.d_int16array[j] = strtol(t, (char **)NULL, 0);
} else {
pc->data.d_int16array[j] = strtol(ar[j], (char **)NULL, 0);
}
}
Tcl_Free((char *)ar);
}
break;
case PARAM_INT8ARRAY: {
int tc, j;
char **ar;
if (Tcl_SplitList(interp, av[i], &tc, &ar)==TCL_ERROR){
return TCL_ERROR;
}
pc->data.d_int8array = (gint8*)malloc(sizeof(gint8)*tc);
for(j=0;j<tc;j++){
if (isalpha(*ar[j])) {
char *t;
DPRINTF(3,(stderr, "i8a ht lu: %s\n", av[i]));
if ((t=Tcl_GetVar2(interp, GtclConst, ar[j], TCL_GLOBAL_ONLY))
== NULL){
Tcl_SetResult(interp, name, TCL_VOLATILE);
Tcl_AppendResult(interp, ": argument error: ", ar[j],
" unknown constant", (char *)NULL);
return TCL_ERROR;
}
pc->data.d_int8array[j] = strtol(t, (char **)NULL, 0);
} else {
pc->data.d_int8array[j] = strtol(ar[j], (char **)NULL, 0);
}
}
Tcl_Free((char *)ar);
}
break;
case PARAM_FLOATARRAY: {
int tc, j;
char **ar;
if (Tcl_SplitList(interp, av[i], &tc, &ar)==TCL_ERROR){
return TCL_ERROR;
}
DPRINTF(2, (stderr, "fla("));
pc->data.d_floatarray = (gdouble*)malloc(sizeof(gdouble)*tc);
for(j=0;j<tc;j++){
DPRINTF(2, (stderr, "%s ", ar[j]));
if (isalpha(*ar[j])) {
char *t;
DPRINTF(3,(stderr, "fla ht lu: %s\n", ar[j]));
if ((t=Tcl_GetVar2(interp, GtclConst, ar[j], TCL_GLOBAL_ONLY))
== NULL){
Tcl_SetResult(interp, name, TCL_VOLATILE);
Tcl_AppendResult(interp, ": argument error: ", ar[j],
" unknown constant", (char *)NULL);
return TCL_ERROR;
}
pc->data.d_floatarray[j] = strtod(t, (char **)NULL);
} else {
pc->data.d_floatarray[j] = strtod(ar[j], (char **)NULL);
}
}
DPRINTF(2,(stderr, ") "));
Tcl_Free((char *)ar);
}
break;
case PARAM_STRINGARRAY: {
int tc;
if (Tcl_SplitList(interp, av[i], &tc, &pc->data.d_stringarray)
==TCL_ERROR){
Tcl_SetResult(interp, "argument error in stringarray", TCL_STATIC);
return TCL_ERROR;
}
if (tc != (pc-1)->data.d_int32) {
char tt[150];
Tcl_SetResult(interp, "argument error in stringarray:", TCL_STATIC);
sprintf(tt, "expected %d, got %d\n", (pc-1)->data.d_int32, tc);
Tcl_AppendResult(interp, tt, (char *)NULL);
}
}
break;
case PARAM_COLOR: {
int tc;
char **ar;
if (Tcl_SplitList(interp, av[i], &tc, &ar)==TCL_ERROR){
return TCL_ERROR;
}
if(tc!=3) {
Tcl_SetResult(interp, "argument type error, expected RGB", TCL_STATIC);
Tcl_Free((char *)ar);
return TCL_ERROR;
}
pc->data.d_color.red = strtol(ar[0], (char **)NULL, 0);
pc->data.d_color.green = strtol(ar[1], (char **)NULL, 0);
pc->data.d_color.blue = strtol(ar[2], (char **)NULL, 0);
Tcl_Free((char *)ar);
}
DPRINTF(2,(stderr, " {%d %d %d} ", pc->data.d_color.red, pc->data.d_color.green, pc->data.d_color.blue));
break;
case PARAM_REGION:
Tcl_SetResult(interp, "Unsupported argument type: region", TCL_STATIC);
return TCL_ERROR;
break;
case PARAM_DISPLAY:
sscanf(av[i], "display-%d", &pc->data.d_int32);
DPRINTF(2,(stderr, " (display)%d ", pc->data.d_int32));
break;
case PARAM_IMAGE:
sscanf(av[i], "image-%d", &pc->data.d_int32);
DPRINTF(2,(stderr, " (image)%d ", pc->data.d_int32));
break;
case PARAM_LAYER:
sscanf(av[i], "layer-%d", &pc->data.d_int32);
DPRINTF(2,(stderr, " (layer)%d ", pc->data.d_int32));
break;
case PARAM_CHANNEL:
sscanf(av[i], "channel-%d", &pc->data.d_int32);
DPRINTF(2,(stderr, " (channel)%d ", pc->data.d_int32));
break;
case PARAM_DRAWABLE:
sscanf(av[i], "layer-%d", &pc->data.d_int32);
DPRINTF(2,(stderr, " (drawable)%d ", pc->data.d_int32));
break;
case PARAM_SELECTION:
sscanf(av[i], "selection-%d", &pc->data.d_int32);
DPRINTF(2,(stderr, " (selection)%d ", pc->data.d_int32));
break;
case PARAM_BOUNDARY:
Tcl_SetResult(interp, "Unsupported argument type: Boundary", TCL_STATIC);
return TCL_ERROR;
break;
case PARAM_PATH:
Tcl_SetResult(interp, "Unsupported argument type: Path", TCL_STATIC);
return TCL_ERROR;
break;
case PARAM_STATUS:
Tcl_SetResult(interp, "Unsupported argument type: Status", TCL_STATIC);
return TCL_ERROR;
break;
default:
Tcl_SetResult(interp, "Unknown argument type", TCL_STATIC);
return TCL_ERROR;
}
}
return TCL_OK;
}
int
GParam_to_Argv(Tcl_Interp *interp, char *p_name, int p_nrv,
GParam *vals, char **av){
int i;
char t[100];
for(i=0;i<p_nrv;i++) {
memset(t, 0, 100);
switch(vals[i].type) {
case PARAM_INT32:
sprintf(t, "%d", vals[i].data.d_int32);
break;
case PARAM_INT16:
sprintf(t, "%d", vals[i].data.d_int16);
break;
case PARAM_INT8:
sprintf(t, "%d", vals[i].data.d_int8);
break;
case PARAM_FLOAT:
sprintf(t, "%g", vals[i].data.d_float);
break;
case PARAM_STRING:
if(vals[i].data.d_string)
strcpy(t,vals[i].data.d_string);
else
sprintf(t,"(null)");
break;
case PARAM_INT32ARRAY: {
char **ar, *t1;
int c, j;
c=vals[i-1].data.d_int32;
ar = (char **)malloc(sizeof(char *)*c);
for(j=0;j<c;j++){
sprintf(t, "%d", vals[i].data.d_int32array[j]);
ar[j] = strdup(t);
}
t1 = Tcl_Merge(c, ar);
for(j=0;j<c;j++){
free(ar[j]);
}
free(ar);
strcpy(t, t1);
free(t1);
}
break;
case PARAM_INT16ARRAY: {
char **ar, *t1;
int c, j;
c=vals[i-1].data.d_int32;
ar = (char **)malloc(sizeof(char *)*c);
for(j=0;j<c;j++){
sprintf(t, "%d", vals[i].data.d_int16array[j]);
ar[j] = strdup(t);
}
t1=Tcl_Merge(c, ar);
for(j=0;j<c;j++){
free(ar[j]);
}
free(ar);
strcpy(t, t1);
free(t1);
}
break;
case PARAM_INT8ARRAY:{
char **ar, *t1;
int c, j;
c=vals[i-1].data.d_int32;
ar = (char **)malloc(sizeof(char *)*c);
for(j=0;j<c;j++){
sprintf(t, "%d", vals[i].data.d_int8array[j]);
ar[j] = strdup(t);
}
t1=Tcl_Merge(c, ar);
for(j=0;j<c;j++){
free(ar[j]);
}
free(ar);
strcpy(t, t1);
free(t1);
}
break;
case PARAM_STRINGARRAY: {
char *t1;
t1=Tcl_Merge(vals[i-1].data.d_int32, vals[i].data.d_stringarray);
strcpy(t, t1);
free(t1);
}
break;
case PARAM_COLOR: {
char *rgb[3], *t1;
sprintf(t, "%d", vals[i].data.d_color.red);
rgb[0] = strdup(t);
sprintf(t, "%d", vals[i].data.d_color.green);
rgb[1] = strdup(t);
sprintf(t, "%d", vals[i].data.d_color.blue);
rgb[2] = strdup(t);
t1=Tcl_Merge(3, rgb);
free(rgb[0]); free(rgb[1]); free(rgb[2]);
strcpy(t, t1);
free(t1);
}
break;
case PARAM_REGION:
Tcl_SetResult(interp, "Unsupported return type: Region",
TCL_STATIC);
return TCL_ERROR;
break;
case PARAM_DISPLAY:
sprintf(t, "display-%d", vals[i].data.d_int32);
break;
case PARAM_IMAGE:
sprintf(t, "image-%d", vals[i].data.d_int32);
break;
case PARAM_LAYER:
sprintf(t, "layer-%d", vals[i].data.d_int32);
break;
case PARAM_CHANNEL:
sprintf(t, "channel-%d", vals[i].data.d_int32);
break;
case PARAM_DRAWABLE:
sprintf(t, "layer-%d", vals[i].data.d_int32);
break;
case PARAM_SELECTION:
sprintf(t, "selection-%d", vals[i].data.d_int32);
break;
case PARAM_BOUNDARY:
Tcl_SetResult(interp, "Unsupported return type: Boundary",
TCL_STATIC);
return TCL_ERROR;
break;
case PARAM_PATH:
Tcl_SetResult(interp, "Unsupported return type: Path", TCL_STATIC);
return TCL_ERROR;
break;
case PARAM_STATUS:
Tcl_SetResult(interp, "pdb: multiple return status", TCL_STATIC);
return TCL_ERROR;
break;
default:
Tcl_SetResult(interp, "Unknown return type", TCL_STATIC);
return TCL_ERROR;
break;
}
av[i] = strdup(t);
}
return TCL_OK;
}
void
cvtfrom (char *str) {
for(;*str;str++) {
if (*str == '_') {
*str = '-';
}
}
}
void
cvtto (char *str) {
for(;*str;str++) {
if (*str == '-') {
*str = '_';
}
}
}

View file

@ -1,109 +0,0 @@
Gtcl_CAdd(RGB);
Gtcl_CAdd(GRAY);
Gtcl_CAdd(INDEXED);
Gtcl_CAdd(RGB_IMAGE);
Gtcl_CAdd(RGBA_IMAGE);
Gtcl_CAdd(GRAY_IMAGE);
Gtcl_CAdd(GRAYA_IMAGE);
Gtcl_CAdd(INDEXED_IMAGE);
Gtcl_CAdd(INDEXEDA_IMAGE);
Gtcl_CAdd(NORMAL_MODE);
Gtcl_CAdd(DISSOLVE_MODE);
Gtcl_CAdd(MULTIPLY_MODE);
Gtcl_CAdd(SCREEN_MODE);
Gtcl_CAdd(OVERLAY_MODE);
Gtcl_CAdd(DIFFERENCE_MODE);
Gtcl_CAdd(ADDITION_MODE);
Gtcl_CAdd(SUBTRACT_MODE);
Gtcl_CAdd(DARKEN_ONLY_MODE);
Gtcl_CAdd(LIGHTEN_ONLY_MODE);
Gtcl_CAdd(HUE_MODE);
Gtcl_CAdd(SATURATION_MODE);
Gtcl_CAdd(COLOR_MODE);
Gtcl_CAdd(VALUE_MODE);
Gtcl_CAdd(BG_IMAGE_FILL);
Gtcl_CAdd(WHITE_IMAGE_FILL);
Gtcl_CAdd(TRANS_IMAGE_FILL);
Gtcl_CAdd(PARAM_INT32);
Gtcl_CAdd(PARAM_INT16);
Gtcl_CAdd(PARAM_INT8);
Gtcl_CAdd(PARAM_FLOAT);
Gtcl_CAdd(PARAM_STRING);
Gtcl_CAdd(PARAM_INT32ARRAY);
Gtcl_CAdd(PARAM_INT16ARRAY);
Gtcl_CAdd(PARAM_INT8ARRAY);
Gtcl_CAdd(PARAM_FLOATARRAY);
Gtcl_CAdd(PARAM_STRINGARRAY);
Gtcl_CAdd(PARAM_COLOR);
Gtcl_CAdd(PARAM_REGION);
Gtcl_CAdd(PARAM_DISPLAY);
Gtcl_CAdd(PARAM_IMAGE);
Gtcl_CAdd(PARAM_LAYER);
Gtcl_CAdd(PARAM_CHANNEL);
Gtcl_CAdd(PARAM_DRAWABLE);
Gtcl_CAdd(PARAM_SELECTION);
Gtcl_CAdd(PARAM_BOUNDARY);
Gtcl_CAdd(PARAM_PATH);
Gtcl_CAdd(PARAM_STATUS);
Gtcl_CAdd(PARAM_END);
Gtcl_CAdd(PROC_PLUG_IN);
Gtcl_CAdd(PROC_EXTENSION);
Gtcl_CAdd(PROC_TEMPORARY);
Gtcl_CAdd(RUN_INTERACTIVE);
Gtcl_CAdd(RUN_NONINTERACTIVE);
Gtcl_CAdd(RUN_WITH_LAST_VALS);
Gtcl_CAdd(STATUS_EXECUTION_ERROR);
Gtcl_CAdd(STATUS_CALLING_ERROR);
Gtcl_CAdd(STATUS_PASS_THROUGH);
Gtcl_CAdd(STATUS_SUCCESS);
Gtcl_CAdd(FG_BUCKET_FILL);
Gtcl_CAdd(BG_BUCKET_FILL);
Gtcl_CAdd(PATTERN_BUCKET_FILL);
Gtcl_CAdd(LINEAR);
Gtcl_CAdd(BILINEAR);
Gtcl_CAdd(RADIAL);
Gtcl_CAdd(SQUARE);
Gtcl_CAdd(CONICAL_SYMMETRIC);
Gtcl_CAdd(CONICAL_ASYMMETRIC);
Gtcl_CAdd(SHAPEBURST_ANGULAR);
Gtcl_CAdd(SHAPEBURST_SPHERICAL);
Gtcl_CAdd(SHAPEBURST_DIMPLED);
Gtcl_CAdd(FG_BG_RGB);
Gtcl_CAdd(FG_BG_HSV);
Gtcl_CAdd(FG_TRANS);
Gtcl_CAdd(CUSTOM);
Gtcl_CAdd(NORMAL);
Gtcl_CAdd(DISSOLVE);
Gtcl_CAdd(BEHIND);
Gtcl_CAdd(MULTIPLY);
Gtcl_CAdd(SCREEN);
Gtcl_CAdd(OVERLAY);
Gtcl_CAdd(DIFFERENCE);
Gtcl_CAdd(ADDITION);
Gtcl_CAdd(SUBTRACT);
Gtcl_CAdd(DARKEN_ONLY);
Gtcl_CAdd(LIGHTEN_ONLY);
Gtcl_CAdd(HUE);
Gtcl_CAdd(SATURATION);
Gtcl_CAdd(COLOR);
Gtcl_CAdd(VALUE);
Gtcl_CAdd(RED_CHANNEL);
Gtcl_CAdd(GREEN_CHANNEL);
Gtcl_CAdd(BLUE_CHANNEL);
Gtcl_CAdd(GRAY_CHANNEL);
Gtcl_CAdd(INDEXED_CHANNEL);
Gtcl_CAdd(WHITE_MASK);
Gtcl_CAdd(BLACK_MASK);
Gtcl_CAdd(ALPHA_MASK);
Gtcl_CAdd(APPLY);
Gtcl_CAdd(DISCARD);
Gtcl_CAdd(EXPAND_AS_NECESSARY);
Gtcl_CAdd(CLIP_TO_IMAGE);
Gtcl_CAdd(CLIP_TO_BOTTOM_LAYER);
Gtcl_CAdd(ADD);
Gtcl_CAdd(SUB);
Gtcl_CAdd(REPLACE);
Gtcl_CAdd(IMAGE_CLONE);
Gtcl_CAdd(PATTERN_CLONE);
Gtcl_CAdd(BLUR);
Gtcl_CAdd(SHARPEN);

View file

@ -1,230 +0,0 @@
#!/usr/bin/sed -f
s,gimp_color_balance,gimp-color-balance,
s,gimp_brushes_get_brush,gimp-brushes-get-brush,
s,gimp_register_load_handler,gimp-register-load-handler,
s,gimp_bucket_fill,gimp-bucket-fill,
s,gimp_image_clean_all,gimp-image-clean-all,
s,gimp_edit_stroke,gimp-edit-stroke,
s,gimp_channel_ops_offset,gimp-channel-ops-offset,
s,gimp_channel_delete,gimp-channel-delete,
s,gimp_color_picker,gimp-color-picker,
s,gimp_brightness_contrast,gimp-brightness-contrast,
s,gimp_image_get_component_active,gimp-image-get-component-active,
s,gimp_list_images,gimp-list-images,
s,gimp_image_height,gimp-image-height,
s,gimp_image_raise_channel,gimp-image-raise-channel,
s,plug_in_map_sphere,plug-in-map-sphere,
s,gimp_progress_update,gimp-progress-update,
s,gimp_selection_clear,gimp-selection-clear,
s,gimp_image_get_selection,gimp-image-get-selection,
s,gimp_procedural_db_set_data,gimp-procedural-db-set-data,
s,gimp_drawable_height,gimp-drawable-height,
s,gimp_drawable_bytes,gimp-drawable-bytes,
s,gimp_image_base_type,gimp-image-base-type,
s,gimp_image_get_filename,gimp-image-get-filename,
s,gimp_image_set_active_layer,gimp-image-set-active-layer,
s,gimp_drawable_channel,gimp-drawable-channel,
s,gimp_drawable_image,gimp-drawable-image,
s,gimp_selection_float,gimp-selection-float,
s,gimp_image_resize,gimp-image-resize,
s,gimp_patterns_list,gimp-patterns-list,
s,gimp_procedural_db_dump,gimp-procedural-db-dump,
s,gimp_layer_get_show_mask,gimp-layer-get-show-mask,
s,gimp_image_unset_active_channel,gimp-image-unset-active-channel,
s,gimp_image_add_layer_mask,gimp-image-add-layer-mask,
s,gimp_procedural_db_proc_arg,gimp-procedural-db-proc-arg,
s,gimp_channel_get_opacity,gimp-channel-get-opacity,
s,gimp_channel_copy,gimp-channel-copy,
s,file_header_save,file-header-save,
s,gimp_quit,gimp-quit,
s,gimp_patterns_get_pattern,gimp-patterns-get-pattern,
s,gimp_layer_get_apply_mask,gimp-layer-get-apply-mask,
s,gimp_layer_resize,gimp-layer-resize,
s,gimp_levels,gimp-levels,
s,gimp_tcl,gimp-tcl,
s,gimp_image_set_component_active,gimp-image-set-component-active,
s,plug_in_cubism,plug-in-cubism,
s,gimp_scale,gimp-scale,
s,gimp_channel_set_visible,gimp-channel-set-visible,
s,plug_in_mosaic,plug-in-mosaic,
s,gimp_image_get_cmap,gimp-image-get-cmap,
s,gimp_drawable_layer,gimp-drawable-layer,
s,gimp_layer_set_mode,gimp-layer-set-mode,
s,gimp_paintbrush,gimp-paintbrush,
s,gimp_invert,gimp-invert,
s,gimp_selection_border,gimp-selection-border,
s,gimp_palette_set_foreground,gimp-palette-set-foreground,
s,gimp_free_select,gimp-free-select,
s,plug_in_script_fu,plug-in-script-fu,
s,gimp_layer_set_name,gimp-layer-set-name,
s,gimp_blend,gimp-blend,
s,gimp_selection_translate,gimp-selection-translate,
s,plug_in_noisify,plug-in-noisify,
s,gimp_display_delete,gimp-display-delete,
s,gimp_brushes_get_spacing,gimp-brushes-get-spacing,
s,gimp_drawable_color,gimp-drawable-color,
s,gimp_layer_get_opacity,gimp-layer-get-opacity,
s,gimp_edit_paste,gimp-edit-paste,
s,gimp_gimprc_query,gimp-gimprc-query,
s,gimp_image_lower_channel,gimp-image-lower-channel,
s,gimp_selection_feather,gimp-selection-feather,
s,gimp_drawable_get_pixel,gimp-drawable-get-pixel,
s,gimp_convolve,gimp-convolve,
s,gimp_drawable_has_alpha,gimp-drawable-has-alpha,
s,gimp_channel_set_color,gimp-channel-set-color,
s,gimp_hue_saturation,gimp-hue-saturation,
s,gimp_selection_all,gimp-selection-all,
s,gimp_drawable_width,gimp-drawable-width,
s,gimp_channel_set_show_masked,gimp-channel-set-show-masked,
s,gimp_channel_set_name,gimp-channel-set-name,
s,plug_in_blur,plug-in-blur,
s,gimp_layer_copy,gimp-layer-copy,
s,gimp_progress_init,gimp-progress-init,
s,gimp_image_remove_channel,gimp-image-remove-channel,
s,gimp_image_new,gimp-image-new,
s,gimp_procedural_db_proc_val,gimp-procedural-db-proc-val,
s,gimp_image_get_active_layer,gimp-image-get-active-layer,
s,gimp_selection_load,gimp-selection-load,
s,gimp_curves_spline,gimp-curves-spline,
s,gimp_image_get_layers,gimp-image-get-layers,
s,gimp_airbrush,gimp-airbrush,
s,plug_in_video,plug-in-video,
s,gimp_layer_get_preserve_trans,gimp-layer-get-preserve-trans,
s,gimp_floating_sel_anchor,gimp-floating-sel-anchor,
s,gimp_brushes_get_paint_mode,gimp-brushes-get-paint-mode,
s,gimp_image_lower_layer,gimp-image-lower-layer,
s,gimp_convert_indexed,gimp-convert-indexed,
s,gimp_selection_layer_alpha,gimp-selection-layer-alpha,
s,plug_in_pinch,plug-in-pinch,
s,gimp_palette_get_background,gimp-palette-get-background,
s,gimp_image_floating_selection,gimp-image-floating-selection,
s,gimp_image_pick_correlate_layer,gimp-image-pick-correlate-layer,
s,gimp_image_add_channel,gimp-image-add-channel,
s,gimp_display_new,gimp-display-new,
s,gimp_edit_clear,gimp-edit-clear,
s,file_gif_load,file-gif-load,
s,gimp_image_remove_layer_mask,gimp-image-remove-layer-mask,
s,gimp_threshold,gimp-threshold,
s,gimp_brushes_get_opacity,gimp-brushes-get-opacity,
s,gimp_layer_set_apply_mask,gimp-layer-set-apply-mask,
s,gimp_drawable_gray,gimp-drawable-gray,
s,gimp_layer_set_edit_mask,gimp-layer-set-edit-mask,
s,gimp_selection_grow,gimp-selection-grow,
s,plug_in_gauss_rle,plug-in-gauss-rle,
s,gimp_brushes_set_brush,gimp-brushes-set-brush,
s,gimp_image_delete,gimp-image-delete,
s,gimp_channel_set_opacity,gimp-channel-set-opacity,
s,gimp_image_add_layer,gimp-image-add-layer,
s,gimp_image_enable_undo,gimp-image-enable-undo,
s,gimp_image_width,gimp-image-width,
s,gimp_selection_save,gimp-selection-save,
s,gimp_equalize,gimp-equalize,
s,plug_in_sparkle,plug-in-sparkle,
s,gimp_text,gimp-text,
s,gimp_layer_set_offsets,gimp-layer-set-offsets,
s,plug_in_oilify,plug-in-oilify,
s,gimp_image_set_cmap,gimp-image-set-cmap,
s,gimp_desaturate,gimp-desaturate,
s,file_jpeg_load,file-jpeg-load,
s,gimp_ellipse_select,gimp-ellipse-select,
s,gimp_layer_delete,gimp-layer-delete,
s,gimp_image_merge_visible_layers,gimp-image-merge-visible-layers,
s,gimp_channel_ops_duplicate,gimp-channel-ops-duplicate,
s,gimp_channel_get_show_masked,gimp-channel-get-show-masked,
s,gimp_layer_set_visible,gimp-layer-set-visible,
s,gimp_layer_scale,gimp-layer-scale,
s,gimp_perspective,gimp-perspective,
s,gimp_xcf_load,gimp-xcf-load,
s,gimp_layer_translate,gimp-layer-translate,
s,gimp_selection_bounds,gimp-selection-bounds,
s,gimp_image_active_drawable,gimp-image-active-drawable,
s,gimp_drawable_mask_bounds,gimp-drawable-mask-bounds,
s,gimp_layer_create_mask,gimp-layer-create-mask,
s,gimp_image_remove_layer,gimp-image-remove-layer,
s,file_gif_save,file-gif-save,
s,gimp_brushes_list,gimp-brushes-list,
s,gimp_brushes_set_spacing,gimp-brushes-set-spacing,
s,plug_in_tile,plug-in-tile,
s,gimp_procedural_db_get_data,gimp-procedural-db-get-data,
s,gimp_floating_sel_to_layer,gimp-floating-sel-to-layer,
s,gimp_image_flatten,gimp-image-flatten,
s,gimp_drawable_update,gimp-drawable-update,
s,gimp_image_raise_layer,gimp-image-raise-layer,
s,gimp_image_free_shadow,gimp-image-free-shadow,
s,plug_in_whirl,plug-in-whirl,
s,gimp_rotate,gimp-rotate,
s,gimp_layer_new,gimp-layer-new,
s,plug_in_gauss_iir,plug-in-gauss-iir,
s,file_pnm_load,file-pnm-load,
s,gimp_drawable_type,gimp-drawable-type,
s,gimp_text_get_extents,gimp-text-get-extents,
s,gimp_by_color_select,gimp-by-color-select,
s,gimp_displays_flush,gimp-displays-flush,
s,gimp_floating_sel_remove,gimp-floating-sel-remove,
s,gimp_selection_shrink,gimp-selection-shrink,
s,gimp_image_scale,gimp-image-scale,
s,gimp_drawable_type_with_alpha,gimp-drawable-type-with-alpha,
s,gimp_selection_invert,gimp-selection-invert,
s,gimp_image_get_active_channel,gimp-image-get-active-channel,
s,gimp_image_get_component_visible,gimp-image-get-component-visible,
s,file_jpeg_save,file-jpeg-save,
s,gimp_crop,gimp-crop,
s,gimp_xcf_save,gimp-xcf-save,
s,file_tiff_load,file-tiff-load,
s,gimp_channel_get_color,gimp-channel-get-color,
s,gimp_layer_set_show_mask,gimp-layer-set-show-mask,
s,gimp_brushes_set_paint_mode,gimp-brushes-set-paint-mode,
s,gimp_channel_get_visible,gimp-channel-get-visible,
s,gimp_layer_get_mode,gimp-layer-get-mode,
s,gimp_shear,gimp-shear,
s,gimp_fuzzy_select,gimp-fuzzy-select,
s,gimp_pencil,gimp-pencil,
s,gimp_edit_copy,gimp-edit-copy,
s,gimp_image_get_channels,gimp-image-get-channels,
s,gimp_palette_set_background,gimp-palette-set-background,
s,gimp_image_set_filename,gimp-image-set-filename,
s,gimp_layer_get_name,gimp-layer-get-name,
s,gimp_layer_get_edit_mask,gimp-layer-get-edit-mask,
s,gimp_image_set_component_visible,gimp-image-set-component-visible,
s,gimp_layer_set_preserve_trans,gimp-layer-set-preserve-trans,
s,plug_in_demo,plug-in-demo,
s,gimp_image_set_active_channel,gimp-image-set-active-channel,
s,gimp_patterns_set_pattern,gimp-patterns-set-pattern,
s,gimp_selection_none,gimp-selection-none,
s,file_pnm_save,file-pnm-save,
s,plug_in_c_astretch,plug-in-c-astretch,
s,gimp_clone,gimp-clone,
s,gimp_flip,gimp-flip,
s,gimp_procedural_db_proc_info,gimp-procedural-db-proc-info,
s,gimp_drawable_set_pixel,gimp-drawable-set-pixel,
s,gimp_drawable_indexed,gimp-drawable-indexed,
s,gimp_register_save_handler,gimp-register-save-handler,
s,gimp_edit_cut,gimp-edit-cut,
s,gimp_palette_get_foreground,gimp-palette-get-foreground,
s,gimp_drawable_merge_shadow,gimp-drawable-merge-shadow,
s,plug_in_displace,plug-in-displace,
s,gimp_curves_explicit,gimp-curves-explicit,
s,gimp_selection_value,gimp-selection-value,
s,gimp_brushes_set_opacity,gimp-brushes-set-opacity,
s,gimp_rect_select,gimp-rect-select,
s,gimp_drawable_offsets,gimp-drawable-offsets,
s,gimp_eraser,gimp-eraser,
s,gimp_drawable_layer_mask,gimp-drawable-layer-mask,
s,gimp_layer_get_visible,gimp-layer-get-visible,
s,gimp_selection_sharpen,gimp-selection-sharpen,
s,gimp_procedural_db_query,gimp-procedural-db-query,
s,gimp_convert_grayscale,gimp-convert-grayscale,
s,gimp_drawable_fill,gimp-drawable-fill,
s,gimp_layer_add_alpha,gimp-layer-add-alpha,
s,gimp_image_disable_undo,gimp-image-disable-undo,
s,gimp_convert_rgb,gimp-convert-rgb,
s,gimp_selection_is_empty,gimp-selection-is-empty,
s,file_tiff_save,file-tiff-save,
s,gimp_channel_new,gimp-channel-new,
s,gimp_layer_is_floating_sel,gimp-layer-is-floating-sel,
s,gimp_edit_fill,gimp-edit-fill,
s,gimp_posterize,gimp-posterize,
s,gimp_channel_get_name,gimp-channel-get-name,
s,gimp_layer_mask,gimp-layer-mask,
s,gimp_layer_set_opacity,gimp-layer-set-opacity,

View file

@ -1,13 +0,0 @@
#!/usr/local/bin/perl
Top: while (<>) {
/^(\s|typedef)*enum/ and do {
while (<>){
/^\s*(\w+)/ and do {
print " Gtcl_CAdd($1);\n";
};
/\}.*\;/ and next Top;
};
};
};

View file

@ -1,2 +0,0 @@
Makefile
Makefile.in

View file

@ -1,13 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_SCRIPTS = consolio pdb_help stained_glass sbutton
SUFFIXES = .tcl
CLEANFILES = ${pluginlib_SCRIPTS}
.tcl:
sed s,@THEGIMPTCL@,${libexecdir}/gimptcl, $< > $@
chmod +x $@

File diff suppressed because it is too large Load diff

View file

@ -1,279 +0,0 @@
#!@THEGIMPTCL@
# -*-Mode: Tcl;-*-
##################################################
# file: pdb-help.tcl
#
# Copyright (c) 1997 Eric L. Hernes (erich@rrnet.com)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. The name of the author may not be used to endorse or promote products
# derived from this software withough specific prior written permission
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# $Id$
#
proc gimptcl_query {} {
gimp-install-procedure "pdb_help" \
"Interactive Help with the Procedural Database" \
"Pick a PDB proc; then press `Query' for information" \
"Eric L. Hernes" \
"Eric L. Hernes" \
"1997" \
"<Toolbox>/Xtns/PDB Help" \
"" \
extension \
{
{int32 "run_mode" "Interactive, non-interactive"}
} \
{}
}
proc gimptcl_run {mode} {
pdb-help-init
}
proc show_proc {p} {
global name author copyright
set descr [gimp-query-dbproc $p]
set name [lindex $descr 0]
set blurb [lindex $descr 1]
.about.descr.blurb delete 0.0 end
.about.descr.blurb insert 0.0 $blurb
set help [lindex $descr 2]
set author [lindex $descr 3]
set c [lindex $descr 4]
set date [lindex $descr 5]
set type [lindex $descr 6]
set args [lindex $descr 7]
set retvals [lindex $descr 8]
set copyright "Copyright $c, $date"
.about.descr.ar.a.t.t delete 0.0 end
if {[llength $args] == 0} {
.about.descr.ar.a.t.t insert 0.0 "None"
} else {
set arg_string ""
foreach a $args {
set t [lindex $a 0]
set n [lindex $a 1]
set v [lindex $a 2]
set arg_string "$arg_string$n ($t)\n"
set arg_string "$arg_string $v\n\n"
}
.about.descr.ar.a.t.t insert 0.0 $arg_string
}
.about.descr.ar.r.t.t delete 0.0 end
if {[llength $retvals] == 0} {
.about.descr.ar.r.t.t insert 0.0 "nothing"
} else {
set ret_string ""
foreach r $retvals {
set t [lindex $r 0]
set n [lindex $r 1]
set v [lindex $r 2]
set ret_string "$ret_string$n ($t)\n"
set ret_string "$ret_string $v\n\n"
}
.about.descr.ar.r.t.t insert 0.0 $ret_string
}
.about.descr.help delete 0.0 end
.about.descr.help insert 0.0 $help
}
proc run_proc {p} {
show_proc $p
if {[winfo exists .args]} {
destroy .args
}
toplevel .args
frame .args.entry -relief ridge -border 3
frame .args.ctl -relief ridge -border 3
set descr [gimp-query-dbproc $p]
set name [lindex $descr 0]
label .args.title -relief ridge -border 3 -text $name
wm title .args "PDB run: $name"
set args [lindex $descr 7]
set retvals [lindex $descr 8]
set na [llength $args]
for {set a 0} {$a < $na} {incr a} {
set thisArg [lindex $args $a]
set n [lindex $thisArg 1]
label .args.entry.l$a -text $n
entry .args.entry.e$a -width 10
grid .args.entry.l$a -row $a -column 0
grid .args.entry.e$a -row $a -column 1
}
# pack .args.entry.l .args.entry.e -side left
button .args.ctl.ok -text "Ok" -command {
set p [.args.title cget -text]
set pdb "gimp-run-procedure $p"
puts "running $p"
set descr [gimp-query-dbproc $p]
set args [lindex $descr 7]
set retvals [lindex $descr 8]
set na [llength $args]
set nr [llength $retvals]
for {set a 0} {$a < $na} {incr a} {
append pdb " [.args.entry.e$a get]"
}
set rets [eval $pdb]
if {[winfo exists .rets]} {
destroy .rets
}
toplevel .rets
frame .rets.rets -relief ridge -border 3
frame .rets.ctl -relief ridge -border 3
label .rets.title -relief ridge -border 3 -text "$name results"
wm title .rets "PDB results: $name"
for {set r 0} {$r < $nr} {incr r} {
set thisRet [lindex $retvals $r]
set n [lindex $thisRet 1]
label .rets.rets.l$r -text $n
label .rets.rets.v$r -text [lindex $rets $r]
grid .rets.rets.l$r -row $r -column 0
grid .rets.rets.v$r -row $r -column 1
}
button .rets.ctl.ok -text "Ok" -command {destroy .rets}
pack .rets.ctl.ok -side left
pack .rets.title -fill both
pack .rets.rets .rets.ctl
}
button .args.ctl.cancel -text "Cancel" -command {destroy .args}
pack .args.ctl.cancel .args.ctl.ok -side left
pack .args.title -fill both
pack .args.entry .args.ctl
}
proc pdb-help-init {} {
wm title . "PDB Help"
set db_procs [gimp-query-db .* .* .* .* .* .* .*]
frame .about
frame .about.procs
scrollbar .about.procs.sb -width 12 -command ".about.procs.list yview"
listbox .about.procs.list -height 20 -width 30 -yscroll ".about.procs.sb set"
bind .about.procs.list <Double-Button-1> "run_proc \[selection get\]"
bind .about.procs.list <ButtonRelease-1> {
tkCancelRepeat
%W activate @%x,%y
show_proc [selection get]
}
foreach p [lsort $db_procs] {
.about.procs.list insert end $p
}
pack .about.procs.list .about.procs.sb -side left -expand 1 -fill both
frame .about.descr
label .about.descr.name -textvariable name \
-font -*-Helvetica-Bold-R-Normal--*-180-*-*-*-*-*-*
label .about.descr.author -justify left -width 40 -textvariable author \
-font -*-Helvetica-medium-r-*-*-*-120-*-*-*-*-*-* \
-wraplength 320 -height 2
label .about.descr.copyright -textvariable copyright \
-font -*-Helvetica-medium-r-*-*-*-80-*-*-*-*-*-*
frame .about.descr.b
text .about.descr.blurb -relief ridge -borderwidth 3 -wrap word \
-width 40 -height 2 \
-font -*-Helvetica-medium-r-*-*-*-120-*-*-*-*-*-* \
-yscrollcommand ".about.descr.b.sb set"
scrollbar .about.descr.b.sb -width 6 \
-command ".about.descr.blurb yview"
pack .about.descr.blurb -in .about.descr.b -side left -fill both
pack .about.descr.b.sb -side left -fill both
frame .about.descr.h
text .about.descr.help -relief ridge -borderwidth 3 -wrap word \
-width 40 -height 7 \
-font -*-Helvetica-medium-r-*-*-*-120-*-*-*-*-*-* \
-yscrollcommand ".about.descr.h.sb set"
scrollbar .about.descr.h.sb -width 6 \
-command ".about.descr.help yview"
pack .about.descr.help -in .about.descr.h -side left -fill both
pack .about.descr.h.sb -side left -fill both
frame .about.descr.ar
frame .about.descr.ar.a -relief ridge -borderwidth 3
label .about.descr.ar.a.l -text "Arguments:"
frame .about.descr.ar.a.t
text .about.descr.ar.a.t.t -relief sunken -borderwidth 3 -wrap word \
-width 40 -height 7 \
-font -*-Helvetica-medium-r-*-*-*-120-*-*-*-*-*-* \
-yscrollcommand ".about.descr.ar.a.t.sb set"
scrollbar .about.descr.ar.a.t.sb -width 6 \
-command ".about.descr.ar.a.t.t yview"
pack .about.descr.ar.a.t.t .about.descr.ar.a.t.sb -side left -fill both
pack .about.descr.ar.a.l .about.descr.ar.a.t -side top -anchor w
frame .about.descr.ar.r -relief ridge -borderwidth 3
label .about.descr.ar.r.l -text "Returns:"
frame .about.descr.ar.r.t
text .about.descr.ar.r.t.t -relief sunken -borderwidth 3 -wrap word \
-width 40 -height 7 \
-font -*-Helvetica-medium-r-*-*-*-120-*-*-*-*-*-* \
-yscrollcommand ".about.descr.ar.r.t.sb set"
scrollbar .about.descr.ar.r.t.sb -width 6 \
-command ".about.descr.ar.r.t.t yview"
pack .about.descr.ar.r.t.t .about.descr.ar.r.t.sb -side left -fill both
pack .about.descr.ar.r.l .about.descr.ar.r.t -side top -anchor w
pack .about.descr.ar.a .about.descr.ar.r -side top
pack .about.descr.name .about.descr.author .about.descr.copyright \
.about.descr.b .about.descr.h .about.descr.ar -side top -anchor w
pack .about.procs .about.descr -side left -anchor nw -expand 1 -fill both
frame .ctl
button .ctl.b -text "Bye" -command {destroy .}
button .ctl.query -text "Query" -command {show_proc [selection get]}
button .ctl.run -text "Run" -command {run_proc [selection get]}
pack .ctl.b .ctl.query .ctl.run -side left -fill both -expand 1
pack .about .ctl
show_proc "pdb_help"
}
if {![string compare [interp slave] ""]} {
uplevel \#0 gimptcl_run 1
}

View file

@ -1,277 +0,0 @@
#!@THEGIMPTCL@
proc gimptcl_query {} {
gimp-install-procedure "plug_in_sbutton" \
"Turn the selection into a button" \
"None Yet" \
"Eric L. Hernes" \
"ELH" \
"1997" \
"<Image>/Select/Make Button" \
"RGB*, GRAY*" \
plugin \
{
{int32 "run_mode" "Interactive, non-interactive"}
{image "image" "The image"}
{drawable "drawable" "The drawable"}
{int32 "width" "The Button Width"}
{int32 "hightlight" "The amount of highlight"}
{int32 "shadow" "The amount of shadow"}
{string "angle" "one of `TopLeft' `TopRight' 'BottomLeft' `BottomRight' or a number in the rage [0-360]'"}
} \
{
}
}
proc gimptcl_run {mode image drawable width highlight shadow angle} {
global theImage theDrawable
global theBorderWidth theHighlightLevel theShadowLevel
global theLightAngle theLightAngleMode theLightAngleValue
set theImage $image
set theDrawable $drawable
set stuff [gimp-get-data plug_in_sbutton]
if {$stuff == ""} {
set theBorderWidth 10
set theHighlightLevel 100
set theShadowLevel 100
set theLightAngle TopLeft
set theLightAngleMode TopLeft
set theLightAngleValue 135
} else {
set theBorderWidth [lindex $stuff 0]
set theHighlightLevel [lindex $stuff 1]
set theShadowLevel [lindex $stuff 2]
set theLightAngleMode [lindex $stuff 3]
set theLightAngleValue [lindex $stuff 4]
}
switch $mode {
0 {
buttonUi
}
1 {
set theBorderWidth $width
set theHighlightLevel $highlight
set theShadowLevel $shadow
set theLightAngle $angle
buttonCore
}
2 {
set theBorderWidth [lindex $stuff 0]
set theHighlightLevel [lindex $stuff 1]
set theShadowLevel [lindex $stuff 2]
set theLightAngle [lindex $stuff 3]
buttonCore
}
default {
puts stderr "don't know how to handle run mode $mode"
}
}
}
proc buttonCore {} {
global theImage theDrawable
global theBorderWidth theHighlightLevel theShadowLevel
global theLightAngleMode theLightAngleValue
set s_bounds [gimp-selection-bounds $theImage]
set sx1 [lindex $s_bounds 1]
set sy1 [lindex $s_bounds 2]
set sx2 [lindex $s_bounds 3]
set sy2 [lindex $s_bounds 4]
set sw [expr $sx2 - $sx1].0
set sh [expr $sy2 - $sy1].0
set theta [expr atan($sh/$sw) * 180 / 3.1415926]
switch $theLightAngleMode {
TopLeft {
set theAngle [expr 180 - $theta]
}
TopRight {
set theAngle [expr 180 + $theta]
}
BottomLeft {
set theAngle $theta
}
BottomRight {
set theAngle [expr 360 - $theta]
}
default {
set theAngle $theLightAngle
}
}
doButton $theImage $theDrawable $theBorderWidth $theHighlightLevel \
$theShadowLevel $theAngle
set saveData [list $theBorderWidth $theHighlightLevel \
$theShadowLevel $theLightAngleMode $theAngle]
gimp-set-data plug_in_sbutton $saveData
# puts stderr "setting (plug_in_sbutton :$saveData:)"
destroy .
}
proc doButton {img drw width highlight shadow angle} {
set theta [expr ($angle * 3.1415926 / 180) + (3.1415926 / 2)]
set bg [gimp-palette-get-background]
set fg [gimp-palette-get-foreground]
set selection [gimp-selection-save $img]
set w [gimp-image-width $img]
set h [gimp-image-height $img]
set layers [lindex [gimp-image-get-layers $img] 1]
set vlayers [list]
foreach l $layers {
if [gimp-layer-get-visible layer-$l] {
lappend vlayers $l
}
gimp-layer-set-visible layer-$l 0
}
gimp-layer-set-visible $drw 1
gimp-undo-push-group-start $img
set button_layer [gimp-layer-new $img $w $h RGBA_IMAGE \
"button (angle $angle)" 100 OVERLAY]
gimp-image-add-layer $img $button_layer -1
gimp-drawable-fill $button_layer TRANS_IMAGE_FILL
# gimp-selection-border $img $width
gimp-palette-set-background {0 0 0}
gimp-edit-fill $img $button_layer
gimp-selection-shrink $img $width
gimp-edit-clear $img $button_layer
gimp-selection-layer-alpha $img $button_layer
set hl [expr 128 + $highlight]
set sl [expr 128 - $shadow]
gimp-palette-set-background "$hl $hl $hl"
gimp-palette-set-foreground "$sl $sl $sl"
set s_bounds [gimp-selection-bounds $img]
set sx1 [lindex $s_bounds 1]
set sy1 [lindex $s_bounds 2]
set sx2 [lindex $s_bounds 3]
set sy2 [lindex $s_bounds 4]
set sw [expr $sx2 - $sx1]
set sh [expr $sy2 - $sy1]
set sw2 [expr $sw / 2]
set sh2 [expr $sh / 2]
set xdelta [expr cos($theta) * ($sw / 2)]
set ydelta [expr sin($theta) * ($sh / 2)]
set x1 [expr $sw2 - $xdelta + $sx1]
set y1 [expr $sh2 - $ydelta + $sy1]
set x2 [expr $sw2 + $xdelta + $sx1]
set y2 [expr $sh2 + $ydelta + $sy1]
gimp-blend $img $button_layer FG-BG-RGB NORMAL LINEAR 100 0 0 0 0 0 $x1 $y1 $x2 $y2
gimp-image-merge-visible-layers $img EXPAND-AS-NECESSARY
foreach l $vlayers {
gimp-layer-set-visible layer-$l 1
}
gimp-palette-set-background $bg
gimp-palette-set-foreground $fg
gimp-selection-load $img $selection
gimp-image-remove-channel $img $selection
gimp-undo-push-group-end $img
gimp-drawable-update $button_layer 0 0 $w $h
gimp-displays-flush
}
proc buttonUi {} {
#
# defaults...
wm title . "Selection to Button"
frame .control
button .control.ok -text "Ok" -command {
buttonCore
}
button .control.cancel -text "Cancel" -command {destroy .}
pack .control.ok .control.cancel -side left
frame .parameters
set lev [frame .parameters.levels -relief groove -borderwidth 3]
scale $lev.width -label "Border Width" \
-from 0 -to 50 -variable theBorderWidth -orient horizontal
scale $lev.highlight -label "Highlight Level" \
-from 0 -to 127 -variable theHighlightLevel -orient horizontal
scale $lev.shadow -label "Shadow Level" \
-from 0 -to 127 -variable theShadowLevel -orient horizontal
pack $lev.width $lev.highlight $lev.shadow
set la [frame .parameters.lightAngle -relief groove -borderwidth 3]
label $la.label -text "Light Angle"
radiobutton $la.topLeft -text "Top Left" \
-variable theLightAngleMode -value TopLeft \
-command "$la.ui.scale configure -state disabled"
radiobutton $la.topRight -text "Top Right" \
-variable theLightAngleMode -value TopRight \
-command "$la.ui.scale configure -state disabled"
radiobutton $la.bottomLeft -text "Bottom Left" \
-variable theLightAngleMode -value BottomLeft \
-command "$la.ui.scale configure -state disabled"
radiobutton $la.bottomRight -text "Bottom Right" \
-variable theLightAngleMode -value BottomRight \
-command "$la.ui.scale configure -state disabled"
frame $la.ui
radiobutton $la.ui.button -text "Set Angle" \
-variable theLightAngleMode -value UserSet \
-command "$la.ui.scale configure -state normal"
scale $la.ui.scale -state disabled \
-from 0 -to 360 -variable theLightAngleValue -orient horizontal
pack $la.ui.button $la.ui.scale -side left
pack $la.label
pack $la.topLeft $la.topRight $la.bottomLeft $la.bottomRight $la.ui \
-anchor w
pack $lev $la -side left -anchor n -fill both
pack .parameters .control
}

View file

@ -1,178 +0,0 @@
#!@THEGIMPTCL@
# -*-Mode: Tcl;-*-
#
set red 0
set green 0
set blue 0
set fg1 [list 47 17 216]
set bg1 [list 55 214 23]
set fg2 [list 247 229 37]
set bg2 [list 244 24 31]
proc gimptcl_query {} {
gimp-install-procedure "plug_in_stained_glass" \
"Crank out stained-glassy backgrounds" \
"None Yet" \
"Eric L. Hernes" \
"Eric L. Hernes" \
"1997" \
"<Image>/Filters/Distorts/Stained Glass" \
"RGB" \
plugin \
{
{int32 "run_mode" "Interactive, Non-interactive"}
{image "image" "The image to build the background for"}
{drawable "drawable" "The drawable to use"}
} \
{}
# puts stderr "Testicle installed"
}
# {color "foreground1" "First Foreground Color"}
# {color "background1" "First Background Color"}
# {color "foreground2" "Second Foreground Color"}
# {color "background2" "Second Background Color"}
proc gimptcl_run {mode img drw} {
# puts stderr "mode $mode; image: $img; drawable: $drw"
switch $mode {
0 {
# puts "stained-glass: interactive!"
global image
set image $img
build-ui
}
1 {
# puts "stained-glass: non-interactive!"
}
2 {
# puts "stained-glass: last args!"
}
}
}
proc gen-bg {img fg1 bg1 fg2 bg2} {
# puts "gen-bg:"
# puts " img $img"
# puts " fg1 $fg1"
# puts " bg1 $bg1"
# puts " fg2 $fg2"
# puts " bg2 $bg2"
set width [gimp-image-width $img]
set height [gimp-image-height $img]
set b1 [gimp-layer-new $img $width $height RGBA_IMAGE "Blend 1" \
100 NORMAL]
set old_fg [gimp-palette-get-foreground]
set old_bg [gimp-palette-get-background]
gimp-palette-set-foreground $fg1
gimp-palette-set-background $bg1
gimp-blend $img $b1 FG_BG_RGB NORMAL CONICAL_SYMMETRIC 100 0 \
[expr $width * 0.25] [expr $height * 0.40] \
[expr $width * 0.12] [expr $height * 0.20]
gimp-blend $img $b1 FG_BG_RGB NORMAL CONICAL_SYMMETRIC 50 0 \
[expr $width * 0.85] [expr $height * 0.75] \
[expr $width * 0.92] [expr $height * 0.85]
gimp-image-add-layer $img $b1 1
set b2 [gimp-layer-new $img $width $height RGBA_IMAGE "Blend 2" \
50 SUBTRACT]
gimp-palette-set-foreground $fg2
gimp-palette-set-background $bg2
gimp-blend $img $b2 FG_BG_RGB NORMAL CONICAL_SYMMETRIC 100 0 \
[expr $width * 0.76] [expr $height * 0.39] \
[expr $width * 0.88] [expr $height * 0.91]
gimp-blend $img $b2 FG_BG_RGB NORMAL CONICAL_SYMMETRIC 50 0 \
[expr $width * 0.30] [expr $height * 0.75] \
[expr $width * 0.15] [expr $height * 0.85]
gimp-image-add-layer $img $b2 1
foreach layer [lindex [gimp-image-get-layers $img] 1] {
if {$layer != $b1 && $layer != $b2} {
gimp-layer-set-visible $layer 0
}
}
set d [gimp-image-merge-visible-layers $img 0]
gimp-image-set-active-layer $img $d
plug-in-c-astretch $img $d
plug-in-mosaic $img $d 15 15 1.1 0.15 60 0.5 1 1 1 1 0
gimp-palette-set-foreground $old_fg
gimp-palette-set-background $old_bg
gimp-displays-flush
gimp-layer-set-name $d "Stained Glass BG"
# return $d
}
proc build-ui {} {
global fg1 bg1 fg2 bg2
set _fg1 [format "\#%02x%02x%02x" [lindex $fg1 0] [lindex $fg1 1] [lindex $fg1 2]]
set _bg1 [format "\#%02x%02x%02x" [lindex $bg1 0] [lindex $bg1 1] [lindex $bg1 2]]
set _fg2 [format "\#%02x%02x%02x" [lindex $fg2 0] [lindex $fg2 1] [lindex $fg2 2]]
set _bg2 [format "\#%02x%02x%02x" [lindex $bg2 0] [lindex $bg2 1] [lindex $bg2 2]]
frame .ctl
frame .ctl.1 -relief ridge -borderwidth 3
button .ctl.1.f -background $_fg1 -text "Foreground 1" \
-command {colorset .ctl.1.f fg1 [list $red $green $blue]}
button .ctl.1.b -background $_bg1 -text "Background 1" \
-command {colorset .ctl.1.b bg1 [list $red $green $blue]}
pack .ctl.1.f .ctl.1.b -side left -fill both
frame .ctl.2 -relief ridge -borderwidth 3
button .ctl.2.f -background $_fg2 -text "Foreground 2" \
-command {colorset .ctl.2.f fg2 [list $red $green $blue]}
button .ctl.2.b -background $_bg2 -text "Background 2" \
-command {colorset .ctl.2.b bg2 [list $red $green $blue]}
pack .ctl.2.f .ctl.2.b -side left -fill both
pack .ctl.1 .ctl.2 -side top -fill both
label .ctl.l -textvariable GimpPDBCmd
pack .ctl.l
frame .ctl.aq
button .ctl.aq.apply -text Apply -command {gen-bg $image $fg1 $bg1 $fg2 $bg2}
button .ctl.aq.quit -text Quit -command "destroy ."
pack .ctl.aq.apply .ctl.aq.quit -side left
pack .ctl.aq -side bottom
rgb-widget .rgb
pack .rgb .ctl -side left -fill both
}
proc colorset {widget var val} {
global red green blue $var
set $var $val
$widget configure -background [format "\#%02x%02x%02x" $red $green $blue]
catch "$widget configure -activebackground [format "\#%02x%02x%02x" $red $green $blue]" e
}
proc rgb-widget {t} {
frame $t -relief ridge -borderwidth 3
label $t.b -text "Color"
frame $t.s
foreach c {red green blue} {
frame $t.s.$c
label $t.s.$c.n -text $c -justify r
scale $t.s.$c.s -orient horizontal -from 0 -to 255 \
-command "colorset $t.b $c"
pack $t.s.$c.n $t.s.$c.s -side left -fill both
pack $t.s.$c -side top -anchor e
}
pack $t.s $t.b -fill both
}
proc sg-apply {} {
global image fg1 bg1 fg2 bg2
}

View file

@ -1,32 +0,0 @@
#!@GIMPTCL@
proc gimptcl_query {} {
puts "howdy from gimptcl_query"
gimp-install-procedure "test_plug_in" \
"A Test Of Tclified Plugins" \
"None Yet" \
"Eric L. Hernes" \
"ELH" \
"1997" \
"<Image>/Test plug-in" \
"RGB, GRAY, INDEXED" \
plugin \
{
{int32 "run_mode" "Interactive, non-interactive"}
{image "the image" "some description of it"}
{drawable "the drawable" "some description of it"}
} \
{
{int32 "first return" "some desciption of it too"}
}
}
proc gimptcl_run {mode image drawable} {
puts stderr "mode $mode; image: $image; drawable: $drawable"
if {$mode == 0} {
destroy .
}
gen-bg $image
gimp-displays-flush
return 123
}

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
magiceye

View file

@ -1,41 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = magiceye
magiceye_SOURCES = \
dialog.c magiceye.c magiceye.h
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
\
$(top_builddir)/libgimp/libgimp.la
magiceye_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View file

@ -1,218 +0,0 @@
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpmenu.h>
#include "magiceye.h"
int returnvalue = 0;
gint magiceye_ID;
gint magic_dialog(void)
{
GtkWidget *dialog, *button, *label, *menue, *omenue, *frame, *table, *scale, *toggle;
gchar **argv;
gint argc;
GtkObject *scale_data;
argc = 1;
argv = g_new(gchar *,1);
argv[0] = g_strdup("magiceye");
gtk_init(&argc,&argv);
/* Dialog */
dialog = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dialog), "Magic Eye");
gtk_window_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dialog), "destroy", (GtkSignalFunc) close_callback, NULL);
/* OK-Button */
button = gtk_button_new_with_label ("OK");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) ok_callback,
dialog);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
/* Create-Button */
button = gtk_button_new_with_label("Create");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
(GtkSignalFunc) magiceye_update,
NULL);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, TRUE, TRUE, 0);
gtk_widget_grab_default (button);
gtk_widget_show(button);
/* Cancel-Button */
button = gtk_button_new_with_label ("Cancel");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (dialog));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
/* Rahmen */
frame = gtk_frame_new("Magic Eye Options");
gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_ETCHED_IN);
gtk_container_border_width(GTK_CONTAINER(frame),10);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, TRUE, TRUE, 0);
/* Tabelle */
table = gtk_table_new(6, 4, FALSE);
gtk_container_border_width(GTK_CONTAINER(table), 5);
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_table_set_row_spacings (GTK_TABLE (table),5);
gtk_table_set_col_spacings (GTK_TABLE (table),5);
/* Label */
label = gtk_label_new("Background: ");
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* Menue */
omenue = gtk_option_menu_new();
menue = GTK_WIDGET(gimp_drawable_menu_new(magiceye_constrain,drawable_callback,&magiceye_ID,magiceye_ID));
gtk_option_menu_set_menu(GTK_OPTION_MENU(omenue), menue);
gtk_table_attach(GTK_TABLE(table), omenue, 1, 4, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
/* Label */
label = gtk_label_new("Strip-Width: ");
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* Breiten-Regler */
strip_width = STDWIDTH;
scale_data = gtk_adjustment_new (strip_width, 0.0, 300.0, 1.0, 10.0, 0.0);
scale = gtk_hscale_new (GTK_ADJUSTMENT (scale_data));
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (scale_data), "value_changed",
(GtkSignalFunc) scale_update,
&strip_width);
gtk_table_attach(GTK_TABLE(table), scale, 0, 4, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(scale);
/* Label */
label = gtk_label_new("Depth: ");
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* Tiefen-Regler */
depth = STDDEPTH;
scale_data = gtk_adjustment_new (depth, 0.0, 100.0, 1.0, 10.0, 0.0);
scale = gtk_hscale_new (GTK_ADJUSTMENT (scale_data));
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
gtk_scale_set_digits (GTK_SCALE (scale), 0);
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (scale_data), "value_changed",
(GtkSignalFunc) scale_update,
&depth);
gtk_table_attach(GTK_TABLE(table), scale, 1, 4, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(scale);
/* Links oder Mitte? */
from_left = STDFROMLEFT;
toggle = gtk_check_button_new_with_label ("From left");
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) toggle_update,
&from_left);
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), from_left);
gtk_table_attach(GTK_TABLE(table), toggle, 0, 2, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (toggle);
/* Hoch oder runter? */
up_down = STDUPDOWN;
toggle = gtk_check_button_new_with_label ("Down");
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
(GtkSignalFunc) toggle_update,
&up_down);
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), up_down);
gtk_table_attach(GTK_TABLE(table), toggle, 2, 4, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (toggle);
/* Darstellung */
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_widget_show(omenue);
gtk_widget_show(table);
gtk_widget_show(frame);
gtk_widget_show(dialog);
gtk_main();
return returnvalue;
}
void
scale_update (GtkAdjustment *adjustment,
double *scale_val)
{
*scale_val = adjustment->value;
}
void
toggle_update(GtkWidget *widget,
gpointer data)
{
int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON (widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
}
void close_callback(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
void ok_callback(GtkWidget *widget, gpointer data)
{
returnvalue = 1;
gtk_widget_destroy(GTK_WIDGET(data));
}
gint magiceye_constrain(gint32 image, gint32 drawable_ID, gpointer data)
{
gint moeglich;
moeglich = (gimp_drawable_color(drawable_ID) || gimp_drawable_indexed(drawable_ID) ||gimp_drawable_gray(drawable_ID));
#ifdef DEBUG
printf("%i %i\n",moeglich,drawable_ID);
#endif
if (drawable_ID == -1) return TRUE;
return moeglich;
}
void drawable_callback(gint32 id, gpointer data)
{
/* (gint32 *) data = id; */
magiceye_ID = id;
}
void magiceye_update(GtkWidget *widget, gpointer data)
{
gint32 image_ID, new_layer;
image_ID = magiceye (map_drawable, &new_layer);
if (image_ID>0) gimp_display_new (image_ID);
}

View file

@ -1,333 +0,0 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* ---------------------------------------------------------------------------------------
*
* Magic Eye version 0.2
*
* This is a plugin for the gimp.
* Copyright (C) 1997 Alexander Schulz
* New versions: http://www.uni-karlsruhe.de/~Alexander.Schulz/english/gimp/gimp.html
* Mail: Alexander.Schulz@stud.uni-karlsruhe.de
*
* Some parts that deal with the interaction with the Gimp
* are modified from other plugins.
* Thanks to the other programmers.
*/
#include <libgimp/gimp.h>
#include <libgimp/gimpmenu.h>
#include "magiceye.h"
/* Declare local functions.
*/
/* static void text_callback (int, void *, void *); */
gdouble strip_width;
gdouble depth;
gint from_left, up_down;
GDrawable *map_drawable;
GStatusType status = STATUS_SUCCESS;
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
MAIN ()
void
query ()
{
static GParamDef args[] =
{
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image (unused)" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
{ PARAM_INT32, "mapimage", "Map Image" },
};
static GParamDef return_vals[] =
{
{ PARAM_IMAGE, "new_image", "Output image" },
{ PARAM_IMAGE, "new_layer", "Output layer" },
};
static int nargs = sizeof (args) / sizeof (args[0]);
static int nreturn_vals = sizeof (return_vals) / sizeof (return_vals[0]);
gimp_install_procedure ("plug_in_magic_eye",
"Create a stereogram",
"Create a stereogram",
"Alexander Schulz",
"Alexander Schulz",
"1997",
"<Image>/Filters/Misc/Magic Eye",
"GRAY",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
}
void
run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
static GParam values[3];
GRunModeType run_mode;
gint32 new_layer;
run_mode = param[0].data.d_int32;
*nreturn_vals = 3;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
values[1].type = PARAM_IMAGE;
values[1].type = PARAM_LAYER;
/* Get the specified drawable */
map_drawable = gimp_drawable_get (param[2].data.d_drawable);
switch (run_mode)
{
case RUN_INTERACTIVE:
/* Possibly retrieve data */
/* gimp_get_data ("plug_in_tile", &tvals); */
/* First acquire information with a dialog */
if (! magic_dialog())
return;
break;
case RUN_NONINTERACTIVE:
/* Make sure all the arguments are there! */
/*if (nparams != 5)
status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS)
{
tvals.new_width = param[3].data.d_int32;
tvals.new_height = param[4].data.d_int32;
}
if (tvals.new_width < 0 || tvals.new_height < 0)
status = STATUS_CALLING_ERROR;*/
break;
case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */
/* gimp_get_data ("plug_in_tile", &tvals); */
break;
default:
break;
}
/* Make sure that the drawable is gray or RGB color */
if (status == STATUS_SUCCESS)
{
values[1].data.d_image = magiceye (map_drawable, &new_layer);
values[2].data.d_layer = new_layer;
gimp_display_new (values[1].data.d_image);
return;
}
}
gint
magiceye (GDrawable *mapimage,gint32 *layer)
{
GDrawableType dest_type;
unsigned char *src1p;
unsigned char *src2p;
unsigned char *destp;
unsigned char *cmap;
unsigned char *savep;
unsigned char *temp_buf;
long src1_width, src1_height;
long src2_width, src2_height;
long src2_channels;
long dest_channels;
GPixelRgn streifen_rgn;
GDrawable *streifen;
GPixelRgn dest_rgn;
GDrawable *destination;
GPixelRgn map_rgn;
gint32 dest, image_ID;
int i, j, hoehe, x, _up_down;
gint number;
streifen = gimp_drawable_get(magiceye_ID);
image_ID=gimp_drawable_image_id(magiceye_ID);
gimp_pixel_rgn_init(&streifen_rgn, streifen, 0, 0, streifen->width, streifen->height, FALSE, FALSE);
gimp_pixel_rgn_init(&map_rgn, mapimage, 0, 0, mapimage->width, mapimage->height, FALSE, FALSE);
dest_type = gimp_drawable_type(magiceye_ID);
src2_channels = streifen->bpp;
src1p = g_malloc(mapimage->width*mapimage->height);
src2p = g_malloc(streifen->width*streifen->height*src2_channels);
gimp_pixel_rgn_get_rect(&map_rgn, src1p, 0, 0, mapimage->width, mapimage->height);
gimp_pixel_rgn_get_rect(&streifen_rgn, src2p, 0, 0, streifen->width, streifen->height);
src2_width = streifen->width;
src2_height = streifen->height;
src1_width = mapimage->width;
src1_height = mapimage->height;
dest_channels = src2_channels;
switch (dest_type){
case RGB_IMAGE:
dest= gimp_image_new (src1_width, src1_height, RGB);
break;
case GRAY_IMAGE:
dest= gimp_image_new (src1_width, src1_height, GRAY);
break;
case INDEXED_IMAGE:
dest= gimp_image_new (src1_width, src1_height, INDEXED);
break;
default:
printf("Magic Eye: cannot operate on unknown image types or alpha images");
/* gimp_quit (); */
return -1;
break;
}
*layer = gimp_layer_new (dest, "Background", src1_width, src1_height, dest_type, 100, NORMAL_MODE);
gimp_image_add_layer(dest,*layer,0);
destination = gimp_drawable_get(*layer);
destp = g_malloc(mapimage->width*mapimage->height*dest_channels);
savep = destp;
if (dest_type == INDEXED_IMAGE)
{
cmap = gimp_image_get_cmap (image_ID, &number);
#ifdef DEBUG
printf("ColorMap: %i %i \n",magiceye_ID, image_ID);
for (i=0;i<number;i++) { printf("%4i: %x %x %x\n",i,cmap[i],cmap[i+1],cmap[i+2]); }
#endif
gimp_image_set_cmap(dest, cmap, number);
g_free(cmap);
}
#ifdef DEBUG
printf("%i %i %i %i %i %i %i %i %i %i\n",magiceye_ID,src2_width,src2_height,src1_width,src1_height,dest_channels,(int)strip_width,dest,number,cmap);
#endif
temp_buf = g_malloc (20);
sprintf (temp_buf, "Creating image");
gimp_progress_init (temp_buf);
g_free (temp_buf);
/* Here ist the point where the work is done, not too much actually */
/* First copy the Background to the new image */
for (i = 0; i < src1_height; i++)
{
for (j = 0; j < src1_width*dest_channels; j++)
{
*destp++ = *(src2p+((j%((int)strip_width*dest_channels))+src2_width*(i%src2_height)*dest_channels));
}
if ((i % 5) == 0)
gimp_progress_update ((double) i / (double) src1_height);
}
destp = savep;
gimp_progress_update(0);
if (up_down) _up_down=-1; else _up_down=1;
if (from_left) {
/* Then add the map-image */
/* Beginning from the left */
for (j = strip_width; j < src1_width; j++)
{
for (i = 0; i < src1_height; i++)
{
hoehe=src1p[i*src1_width*1+j*1] * depth / 255;
for (x=0; x<dest_channels; x++)
{
destp[(i*src1_width+j-hoehe*_up_down)*dest_channels+x] =
destp[(i*src1_width+j-(int)strip_width)*dest_channels+x];
}
}
if ((j % 5) == 0)
gimp_progress_update ((double) j / (double) src1_width);
}
} else {
/* Or add the map-image */
/* Beginning from the middle */
for (j = (src1_width / 2 / strip_width) * strip_width; j < src1_width; j++)
{
for (i = 0; i < src1_height; i++)
{
hoehe=src1p[i*src1_width*1+j*1] * depth / 255;
for (x=0; x<dest_channels; x++)
{
destp[(i*src1_width+j-hoehe*_up_down)*dest_channels+x] =
destp[(i*src1_width+j-(int)strip_width)*dest_channels+x];
}
}
if ((j % 5) == 0)
gimp_progress_update ((double) (j - (src1_width / 2 / strip_width) * strip_width ) / (double) src1_width);
}
for (j = (src1_width / 2 / strip_width) * strip_width; j > strip_width; j--)
{
for (i = 0; i < src1_height; i++)
{
hoehe=src1p[i*src1_width*1+j*1] * depth / 255;
for (x=0; x<dest_channels; x++)
{
destp[(i*src1_width+j+hoehe*_up_down-(int)strip_width)*dest_channels+x] =
destp[(i*src1_width+j)*dest_channels+x];
}
}
if ((j % 5) == 0)
gimp_progress_update ((double) (src1_width - j) / (double) src1_width);
}
gimp_progress_update(1);
}
gimp_progress_update(0);
/* end of work */
gimp_pixel_rgn_init(&dest_rgn, destination, 0, 0, destination->width, destination->height, TRUE, FALSE);
gimp_pixel_rgn_set_rect(&dest_rgn, savep, 0, 0, destination->width, destination->height);
gimp_drawable_detach(destination);
g_free(src2p);
g_free(src1p);
g_free(savep);
return dest;
}

View file

@ -1,32 +0,0 @@
#include <libgimp/gimp.h>
#include <gtk/gtk.h>
#define STDWIDTH 80.0
#define STDDEPTH 15.0
#define STDUPDOWN 0
#define STDFROMLEFT 0
extern gint magic_dialog(void);
extern gint magiceye_constrain(gint32 image, gint32 drawable_ID, gpointer data);
extern void toggle_update(GtkWidget *widget, gpointer data);
extern void drawable_callback(gint32 id, gpointer data);
extern void ok_callback(GtkWidget *widget, gpointer data);
extern void close_callback(GtkWidget *widget, gpointer data);
extern void magiceye_update(GtkWidget *widget, gpointer data);
extern void scale_update (GtkAdjustment *adjustment, double *scale_val);
extern gdouble strip_width;
extern gdouble depth;
extern gint from_left;
extern gint up_down;
extern gint magiceye_ID;
extern GDrawable *map_drawable;
extern gint magiceye (GDrawable *mapimage, gint32 *layer);
extern void query(void);
extern void run(char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals);

View file

@ -5,7 +5,7 @@ pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = maze pluginlib_PROGRAMS = maze
maze_SOURCES = \ maze_SOURCES = \
maze.c maze.c maze.h maze_face.c
INCLUDES = \ INCLUDES = \
$(X_CFLAGS) \ $(X_CFLAGS) \

View file

@ -19,6 +19,14 @@
* and used as a template to get me started on this one. :) * and used as a template to get me started on this one. :)
* *
* Revision history: * Revision history:
* 0.6.1 - Made use-time-for-random-seed a toggle button that remembers
* its state, and moved seed to the second notebook page.
* 0.6.0 - Width and height are now seperate options.
* ^^ Note this changed the PDB interface. ^^
*
* - Added interface for selecting sizes by "divisions".
* - Added "Time" button for random seed.
* - Turned out that GParam shouldn't have been "fixed".
* 0.5.0 - Added the long-awaited "tileable" option. * 0.5.0 - Added the long-awaited "tileable" option.
* Required a change to PDB parameters. * Required a change to PDB parameters.
* - fixed some stuff with GParam values in run(); * - fixed some stuff with GParam values in run();
@ -46,12 +54,8 @@
* *
* Fix that stray line down there between maze wall and dead space border... * Fix that stray line down there between maze wall and dead space border...
* *
* Resolve the border & tileable maze difficulty.
*
* Make get_colors() work with indexed. * HELP! * * Make get_colors() work with indexed. * HELP! *
* *
* If we add many more paramaters, we'll need a preview box.
*
* Also someday: * Also someday:
* Maybe make it work with irregularly shaped selections? * Maybe make it work with irregularly shaped selections?
* Add different generation algorythms. * Add different generation algorythms.
@ -75,44 +79,16 @@
* *
*/ */
#include <time.h> /* For random seeding */ #ifdef MAZE_DEBUG
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "gtk/gtk.h" #endif
#include <time.h> /* For random seeding */
#include "libgimp/gimp.h" #include "libgimp/gimp.h"
#include "libgimp/gimpui.h" #include "maze.h"
#define ENTRY_WIDTH 75
#define MAZE_TITLE "Maze 0.5.0"
/* entscale stuff begin */
#define ENTSCALE_INT_SCALE_WIDTH 125
#define ENTSCALE_INT_ENTRY_WIDTH 40
/* entscale stuff end */
typedef struct {
gint width;
gint seed;
gint tile;
gint multiple;
gint offset;
} MazeValues;
typedef struct {
gint run;
} MazeInterface;
/* entscale stuff begin */
typedef void (*EntscaleIntCallbackFunc) (gint value, gpointer data);
typedef struct {
GtkObject *adjustment;
GtkWidget *entry;
gint constraint;
EntscaleIntCallbackFunc callback;
gpointer call_data;
} EntscaleIntData;
/* entscale stuff end */
extern gint maze_dialog (void);
static void query (void); static void query (void);
static void run (gchar *name, static void run (gchar *name,
gint nparams, gint nparams,
@ -141,31 +117,6 @@ static void drawbox (GPixelRgn *dest_rgn,
guint h, guint h,
guint8 clr[4]); guint8 clr[4]);
static gint maze_dialog (void);
static void maze_close_callback (GtkWidget *widget, gpointer data);
static void maze_ok_callback (GtkWidget *widget, gpointer data);
static void maze_entry_callback (GtkWidget *widget, gpointer data);
static void tile_toggle_callback (GtkWidget *widget, gpointer data);
/* entscale stuff begin */
void entscale_int_new ( GtkWidget *table, gint x, gint y,
gchar *caption, gint *intvar,
gint min, gint max, gint constraint,
EntscaleIntCallbackFunc callback,
gpointer data );
static void entscale_int_destroy_callback (GtkWidget *widget,
gpointer data);
static void entscale_int_scale_update (GtkAdjustment *adjustment,
gpointer data);
static void entscale_int_entry_update (GtkWidget *widget,
gpointer data);
/* entscale stuff end */
/* message box stuff begin */
GtkWidget * message_box (char *, GtkCallback, gpointer);
/* message box stuff end */
GPlugInInfo PLUG_IN_INFO = GPlugInInfo PLUG_IN_INFO =
{ {
NULL, /* init_proc */ NULL, /* init_proc */
@ -174,19 +125,20 @@ GPlugInInfo PLUG_IN_INFO =
run, /* run_proc */ run, /* run_proc */
}; };
static MazeValues mvals = MazeValues mvals =
{ {
1, /* Passage width */ /* Calling parameters */
5, /* Passage width */
5, /* Passage height */
0, /* seed */ 0, /* seed */
FALSE, /* Tileable? */ FALSE, /* Tileable? */
57, /* multiple * These two had "Experiment with this?" comments */ 57, /* multiple * These two had "Experiment with this?" comments */
1 /* offset * in the maz.c source, so, lets expiriment. :) */ 1, /* offset * in the maz.c source, so, lets expiriment. :) */
/* Interface options */
TRUE /* Time seed? */
}; };
static MazeInterface mint = guint sel_w, sel_h;
{
FALSE /* run */
};
MAIN () /*;*/ MAIN () /*;*/
@ -199,8 +151,9 @@ query ()
{ PARAM_IMAGE, "image", "Input image (unused)" }, { PARAM_IMAGE, "image", "Input image (unused)" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" }, { PARAM_DRAWABLE, "drawable", "Input drawable" },
/* If we did have parameters, these be them: */ /* If we did have parameters, these be them: */
{ PARAM_INT32, "mazep_size", "Size of the passages" }, { PARAM_INT32, "mazep_width", "Width of the passages" },
{ PARAM_INT32, "maze_tile", "Tileable maze?"}, { PARAM_INT32, "mazep_height", "Height of the passages"},
{ PARAM_INT8, "maze_tile", "Tileable maze?"},
{ PARAM_INT32, "maze_rseed", "Random Seed"}, { PARAM_INT32, "maze_rseed", "Random Seed"},
{ PARAM_INT32, "maze_multiple", "Multiple (use 57)" }, { PARAM_INT32, "maze_multiple", "Multiple (use 57)" },
{ PARAM_INT32, "maze_offset", "Offset (use 1)" } { PARAM_INT32, "maze_offset", "Offset (use 1)" }
@ -229,13 +182,15 @@ run (gchar *name,
gint *nreturn_vals, gint *nreturn_vals,
GParam **return_vals) GParam **return_vals)
{ {
GParam *values; static GParam values[1];
GDrawable *drawable; GDrawable *drawable;
GRunModeType run_mode; GRunModeType run_mode;
GStatusType status = STATUS_SUCCESS; GStatusType status = STATUS_SUCCESS;
gint x1, y1, x2, y2;
values=g_new(GParam,1); #ifdef MAZE_DEBUG
g_print("maze PID: %d\n",getpid());
#endif
run_mode = param[0].data.d_int32; run_mode = param[0].data.d_int32;
*nreturn_vals = 1; *nreturn_vals = 1;
@ -246,16 +201,16 @@ run (gchar *name,
drawable = gimp_drawable_get (param[2].data.d_drawable); drawable = gimp_drawable_get (param[2].data.d_drawable);
#ifdef MAZE_DEBUG
fprintf(stderr, "%d", param[2].data.d_drawable);
#endif
switch (run_mode) switch (run_mode)
{ {
case RUN_INTERACTIVE: case RUN_INTERACTIVE:
/* Possibly retrieve data */ /* Possibly retrieve data */
gimp_get_data ("plug_in_maze", &mvals); gimp_get_data ("plug_in_maze", &mvals);
/* The interface needs to know the dimensions of the image... */
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
sel_w=x2-x1; sel_h=y2-y1;
/* Acquire info with a dialog */ /* Acquire info with a dialog */
if (! maze_dialog ()) { if (! maze_dialog ()) {
gimp_drawable_detach (drawable); gimp_drawable_detach (drawable);
@ -264,30 +219,23 @@ run (gchar *name,
break; break;
case RUN_NONINTERACTIVE: case RUN_NONINTERACTIVE:
/* WARNING: Stupidity Follows */ if (nparams != 9)
if (nparams != 8)
{ {
status = STATUS_CALLING_ERROR; status = STATUS_CALLING_ERROR;
} }
if (status == STATUS_SUCCESS) if (status == STATUS_SUCCESS)
{ {
mvals.width = (gint) param[3].data.d_int32; mvals.width = (gint) param[3].data.d_int32;
mvals.seed = (gint) param[4].data.d_int32; mvals.height = (gint) param[4].data.d_int32;
mvals.tile = (gint) param[5].data.d_int32; mvals.seed = (gint) param[5].data.d_int32;
mvals.multiple = (gint) param[6].data.d_int32; mvals.tile = (gboolean) param[6].data.d_int32;
mvals.offset = (gint) param[7].data.d_int32; mvals.multiple = (gint) param[7].data.d_int32;
mvals.offset = (gint) param[8].data.d_int32;
} }
break; break;
/* #define MAZE_DEBUG */
#ifdef MAZE_DEBUG
fprintf(stderr,"nparams: %d width: %d seed: %d multiple: %d offset: %d\n",
nparams, mvals.width, mvals.seed, mvals.multiple, mvals.offset);
#endif
case RUN_WITH_LAST_VALS: case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */ /* Possibly retrieve data */
gimp_get_data ("plug_in_maze", &mvals); gimp_get_data ("plug_in_maze", &mvals);
mvals.seed=time(NULL); /* ** USES NEW SEED when reruning with "last" */
/* values. Maybe not the Right Thing, but I find it handy. */
break; break;
default: default:
@ -303,7 +251,8 @@ run (gchar *name,
if (run_mode != RUN_NONINTERACTIVE) if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush (); gimp_displays_flush ();
if (run_mode == RUN_INTERACTIVE /*|| run_mode == RUN_WITH_LAST_VALS*/) if (run_mode == RUN_INTERACTIVE ||
(mvals.timeseed && run_mode == RUN_WITH_LAST_VALS))
gimp_set_data ("plug_in_maze", &mvals, sizeof (MazeValues)); gimp_set_data ("plug_in_maze", &mvals, sizeof (MazeValues));
} else { } else {
status = STATUS_EXECUTION_ERROR; status = STATUS_EXECUTION_ERROR;
@ -328,7 +277,6 @@ maze( GDrawable * drawable)
gpointer pr; gpointer pr;
gchar *maz; gchar *maz;
gint i;
/* Gets the input area... */ /* Gets the input area... */
gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2); gimp_drawable_mask_bounds (drawable->id, &x1, &y1, &x2, &y2);
@ -344,7 +292,7 @@ maze( GDrawable * drawable)
/* Maze Stuff Happens Here */ /* Maze Stuff Happens Here */
mw = (x2-x1) / mvals.width; mw = (x2-x1) / mvals.width;
mh = (y2-y1) / mvals.width; mh = (y2-y1) / mvals.height;
if (!mvals.tile) { if (!mvals.tile) {
mw -= !(mw & 1); /* mazegen doesn't work with even-sized mazes. */ mw -= !(mw & 1); /* mazegen doesn't work with even-sized mazes. */
@ -357,18 +305,18 @@ maze( GDrawable * drawable)
/* It will really suck if your tileable maze ends up with this dead /* It will really suck if your tileable maze ends up with this dead
space around it. Oh well, life is hard. */ space around it. Oh well, life is hard. */
deadx = ((x2-x1) - mw * mvals.width)/2; deadx = ((x2-x1) - mw * mvals.width)/2;
deady = ((y2-y1) - mh * mvals.width)/2; deady = ((y2-y1) - mh * mvals.height)/2;
maz = g_malloc(mw * mh); maz = g_malloc0(mw * mh);
for (i = 0; i < (mw * mh); ++i)
maz[i] = 0;
#ifdef MAZE_DEBUG #ifdef MAZE_DEBUG
printf("x: %d\ty: %d\nmw: %d\tmh: %d\ndx: %d\tdy: %d\nwidth:%d\n", printf("x: %d\ty: %d\nmw: %d\tmh: %d\ndx: %d\tdy: %d\nwidth:%d\theight: %d\n",
(x2-x1),(y2-y1),mw,mh,deadx,deady,mvals.width); (x2-x1),(y2-y1),mw,mh,deadx,deady,mvals.width, mvals.height);
#endif #endif
if (mvals.timeseed)
mvals.seed = time(NULL);
if (mvals.tile) { if (mvals.tile) {
(void) mazegen_tileable((mw+1), maz, mw, mh, mvals.seed); (void) mazegen_tileable((mw+1), maz, mw, mh, mvals.seed);
} else { } else {
@ -389,9 +337,9 @@ maze( GDrawable * drawable)
unbeknownst to us. */ unbeknownst to us. */
dx = mvals.width - (x % mvals.width); dx = mvals.width - (x % mvals.width);
dy = mvals.width - (y % mvals.width); dy = mvals.height - (y % mvals.height);
foo = x/mvals.width; foo = x/mvals.width;
bar = mw * (y/mvals.width); bar = mw * (y/mvals.height);
/* Draws the upper-left [split] box */ /* Draws the upper-left [split] box */
drawbox(&dest_rgn,0,0,dx,dy, drawbox(&dest_rgn,0,0,dx,dy,
@ -399,32 +347,26 @@ maze( GDrawable * drawable)
baz=foo+1; baz=foo+1;
/* Draw the top row [split] boxes */ /* Draw the top row [split] boxes */
for(xx=dx/*1*/; xx < dest_rgn.w; xx+=mvals.width/*+1*/) for(xx=dx; xx < dest_rgn.w; xx+=mvals.width)
{ drawbox(&dest_rgn,xx,0,mvals.width,dy, { drawbox(&dest_rgn,xx,0,mvals.width,dy,
maz[bar + baz++] ? fg : bg ); } maz[bar + baz++] ? fg : bg ); }
baz=bar+mw; baz=bar+mw;
/* Left column */ /* Left column */
for(yy=dy/*+1*/; yy < dest_rgn.h; yy+=mvals.width/*+1*/) { for(yy=dy; yy < dest_rgn.h; yy+=mvals.height) {
drawbox(&dest_rgn,0,yy,dx,mvals.width, drawbox(&dest_rgn,0,yy,dx,mvals.height,
maz[foo + baz] ? fg : bg ); maz[foo + baz] ? fg : bg );
baz += mw; baz += mw;
} }
foo++; foo++;
/* Everything else */ /* Everything else */
for(yy=dy/*+1*/; yy < dest_rgn.h; yy+=mvals.width/*+1*/) { for(yy=dy; yy < dest_rgn.h; yy+=mvals.height) {
baz = foo; bar+=mw; baz = foo; bar+=mw;
for(xx=dx/*+1*/; xx < dest_rgn.w; xx+=mvals.width/*+1*/) for(xx=dx; xx < dest_rgn.w; xx+=mvals.width)
{ {
#ifdef MAZE_DEBUG drawbox(&dest_rgn,xx,yy,mvals.width,mvals.height,
putchar(maz[bar+baz] ? '#' : '.');
#endif
drawbox(&dest_rgn,xx,yy,mvals.width,mvals.width,
maz[bar + baz++] ? fg : bg ); } maz[bar + baz++] ? fg : bg ); }
#ifdef MAZE_DEBUG
putchar('\n');
#endif
} }
progress += dest_rgn.w * dest_rgn.h; progress += dest_rgn.w * dest_rgn.h;
@ -438,9 +380,10 @@ maze( GDrawable * drawable)
gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1)); gimp_drawable_update (drawable->id, x1, y1, (x2 - x1), (y2 - y1));
} }
void drawbox( GPixelRgn *dest_rgn, static void
guint x, guint y, guint w, guint h, drawbox( GPixelRgn *dest_rgn,
guint8 clr[4]) guint x, guint y, guint w, guint h,
guint8 clr[4])
{ {
guint xx,yy, foo, bar; guint xx,yy, foo, bar;
guint8 bp; guint8 bp;
@ -542,9 +485,8 @@ gchar *maz;
#define ABSMOD(A,B) ( ((A) < 0) ? (((B) + (A)) % (B)) : ((A) % (B)) ) #define ABSMOD(A,B) ( ((A) < 0) ? (((B) + (A)) % (B)) : ((A) % (B)) )
gint mazegen_tileable(pos, maz, x, y, rnd) /* Tileable mazes are my creation, based on the routine above. */
gint pos, x, y, rnd; static gint mazegen_tileable(gint pos, gchar *maz, gint x, gint y, gint rnd)
gchar *maz;
{ {
gchar d, i; gchar d, i;
gint c=0, j=1, npos=2; gint c=0, j=1, npos=2;
@ -698,7 +640,7 @@ get_colors (GDrawable *drawable, guint8 *fg, guint8 *bg)
break; break;
case INDEXEDA_IMAGE: case INDEXEDA_IMAGE:
case INDEXED_IMAGE: /* FIXME: Should use current fg/bg colors. */ case INDEXED_IMAGE: /* FIXME: Should use current fg/bg colors. */
fputs("Maze: Using indexed colors 15 and 0 to draw maze.",stderr); g_warning("maze: get_colors: Indexed image. Using colors 15 and 0.\n");
fg[0] = 15; /* As a plugin, I protest. *I* shouldn't be the */ fg[0] = 15; /* As a plugin, I protest. *I* shouldn't be the */
bg[0] = 0; /* one who has to deal with this colormapcrap. */ bg[0] = 0; /* one who has to deal with this colormapcrap. */
break; break;
@ -706,360 +648,3 @@ get_colors (GDrawable *drawable, guint8 *fg, guint8 *bg)
break; break;
} }
} }
static gint maze_dialog()
{
GtkWidget *dlg;
GtkWidget *frame;
GtkWidget *table;
GtkWidget *button;
GtkWidget *label;
GtkWidget *entry;
GtkWidget *notebook;
GtkWidget *tilecheck;
gchar **argv;
gint argc;
gchar buffer[32];
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("maze");
gtk_init (&argc, &argv);
dlg = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dlg), MAZE_TITLE);
gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
(GtkSignalFunc) maze_close_callback,
NULL);
/* Action area */
button = gtk_button_new_with_label ("OK");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) maze_ok_callback,
dlg);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_grab_default (button);
gtk_widget_show (button);
button = gtk_button_new_with_label ("Cancel");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (dlg));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
/* Create notebook */
notebook = gtk_notebook_new ();
gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), notebook, TRUE, TRUE, 0);
gtk_widget_show (notebook);
/* Set up Options page */
frame = gtk_frame_new ("Maze Options");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 10);
/* gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0); */
table = gtk_table_new (3, 2, FALSE);
gtk_container_border_width (GTK_CONTAINER (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
/* Seed input box */
label = gtk_label_new ("Seed");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, 0, 5, 0 );
gtk_widget_show (label);
entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0 );
gtk_widget_set_usize( entry, ENTRY_WIDTH, 0 );
sprintf( buffer, "%d", mvals.seed );
gtk_entry_set_text (GTK_ENTRY (entry), buffer );
gtk_signal_connect (GTK_OBJECT (entry), "changed",
(GtkSignalFunc) maze_entry_callback,
&mvals.seed);
gtk_widget_show (entry);
/* entscale == Entry and Scale pair function found in pixelize.c */
entscale_int_new (table, 0, 1, "Width:", &mvals.width,
1, 64, FALSE,
NULL, NULL);
tilecheck = gtk_check_button_new_with_label ("Tileable?");
gtk_signal_connect (GTK_OBJECT (tilecheck), "clicked",
GTK_SIGNAL_FUNC (tile_toggle_callback), NULL);
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (tilecheck), mvals.tile);
gtk_table_attach (GTK_TABLE (table), tilecheck, 0, 2, 2, 3, GTK_FILL, 0, 5, 0 );
gtk_widget_show (tilecheck);
/* Add Options page to notebook */
gtk_widget_show (frame);
gtk_widget_show (table);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame,
gtk_label_new ("Options"));
/* Set up other page */
frame = gtk_frame_new ("Don't change these");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 10);
/* gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0); */
table = gtk_table_new (2, 2, FALSE);
gtk_container_border_width (GTK_CONTAINER (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
/* Multiple input box */
label = gtk_label_new ("Multiple (57)");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, 0, 5, 0 );
gtk_widget_show (label);
entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0 );
gtk_widget_set_usize( entry, ENTRY_WIDTH, 0 );
sprintf( buffer, "%d", mvals.multiple );
gtk_entry_set_text (GTK_ENTRY (entry), buffer );
gtk_signal_connect (GTK_OBJECT (entry), "changed",
(GtkSignalFunc) maze_entry_callback,
&mvals.multiple);
gtk_widget_show (entry);
/* Offset input box */
label = gtk_label_new ("Offset (1)");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, 0, 5, 0 );
gtk_widget_show (label);
entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0 );
gtk_widget_set_usize( entry, ENTRY_WIDTH, 0 );
sprintf( buffer, "%d", mvals.offset );
gtk_entry_set_text (GTK_ENTRY (entry), buffer );
gtk_signal_connect (GTK_OBJECT (entry), "changed",
(GtkSignalFunc) maze_entry_callback,
&mvals.offset);
gtk_widget_show (entry);
/* Add Advanced page to notebook */
gtk_widget_show (frame);
gtk_widget_show (table);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame,
gtk_label_new ("Advanced"));
gtk_widget_show (dlg);
gtk_main ();
gdk_flush ();
return mint.run;
}
/* Maze Interface Functions */
static void
maze_close_callback (GtkWidget *widget,
gpointer data)
{
gtk_main_quit ();
}
static void
maze_ok_callback (GtkWidget *widget,
gpointer data)
{
mint.run = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void
maze_entry_callback (GtkWidget *widget,
gpointer data)
{
gint *text_val;
text_val = (gint *) data;
*text_val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
}
static void
tile_toggle_callback (GtkWidget *widget, gpointer data)
{
mvals.tile = GTK_TOGGLE_BUTTON (widget)->active;
}
/* ==================================================================== */
/* As found in pixelize.c */
/*
Entry and Scale pair 1.03
TODO:
- Do the proper thing when the user changes value in entry,
so that callback should not be called when value is actually not changed.
- Update delay
*/
/*
* entscale: create new entscale with label. (int)
* 1 row and 2 cols of table are needed.
* Input:
* x, y: starting row and col in table
* caption: label string
* intvar: pointer to variable
* min, max: the boundary of scale
* constraint: (bool) true iff the value of *intvar should be constraint
* by min and max
* callback: called when the value is actually changed
* call_data: data for callback func
*/
void
entscale_int_new ( GtkWidget *table, gint x, gint y,
gchar *caption, gint *intvar,
gint min, gint max, gint constraint,
EntscaleIntCallbackFunc callback,
gpointer call_data)
{
EntscaleIntData *userdata;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *entry;
GtkWidget *scale;
GtkObject *adjustment;
gchar buffer[256];
gint constraint_val;
userdata = g_new ( EntscaleIntData, 1 );
label = gtk_label_new (caption);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
/*
If the first arg of gtk_adjustment_new() isn't between min and
max, it is automatically corrected by gtk later with
"value_changed" signal. I don't like this, since I want to leave
*intvar untouched when `constraint' is false.
The lines below might look oppositely, but this is OK.
*/
userdata->constraint = constraint;
if( constraint )
constraint_val = *intvar;
else
constraint_val = ( *intvar < min ? min : *intvar > max ? max : *intvar );
userdata->adjustment = adjustment =
gtk_adjustment_new ( constraint_val, min, max, 1.0, 1.0, 0.0);
scale = gtk_hscale_new ( GTK_ADJUSTMENT(adjustment) );
gtk_widget_set_usize (scale, ENTSCALE_INT_SCALE_WIDTH, 0);
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
userdata->entry = entry = gtk_entry_new ();
gtk_widget_set_usize (entry, ENTSCALE_INT_ENTRY_WIDTH, 0);
sprintf( buffer, "%d", *intvar );
gtk_entry_set_text( GTK_ENTRY (entry), buffer );
userdata->callback = callback;
userdata->call_data = call_data;
/* userdata is done */
gtk_object_set_user_data (GTK_OBJECT(adjustment), userdata);
gtk_object_set_user_data (GTK_OBJECT(entry), userdata);
/* now ready for signals */
gtk_signal_connect (GTK_OBJECT (entry), "changed",
(GtkSignalFunc) entscale_int_entry_update,
intvar);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
(GtkSignalFunc) entscale_int_scale_update,
intvar);
gtk_signal_connect (GTK_OBJECT (entry), "destroy",
(GtkSignalFunc) entscale_int_destroy_callback,
userdata );
/* start packing */
hbox = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, TRUE, 0);
gtk_table_attach (GTK_TABLE (table), label, x, x+1, y, y+1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table), hbox, x+1, x+2, y, y+1,
GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (label);
gtk_widget_show (entry);
gtk_widget_show (scale);
gtk_widget_show (hbox);
}
/* when destroyed, userdata is destroyed too */
static void
entscale_int_destroy_callback (GtkWidget *widget,
gpointer data)
{
EntscaleIntData *userdata;
userdata = data;
g_free ( userdata );
}
static void
entscale_int_scale_update (GtkAdjustment *adjustment,
gpointer data)
{
EntscaleIntData *userdata;
GtkEntry *entry;
gchar buffer[256];
gint *intvar = data;
gint new_val;
userdata = gtk_object_get_user_data (GTK_OBJECT (adjustment));
new_val = (gint) adjustment->value;
*intvar = new_val;
entry = GTK_ENTRY( userdata->entry );
sprintf (buffer, "%d", (int) new_val );
/* avoid infinite loop (scale, entry, scale, entry ...) */
gtk_signal_handler_block_by_data ( GTK_OBJECT(entry), data );
gtk_entry_set_text ( entry, buffer);
gtk_signal_handler_unblock_by_data ( GTK_OBJECT(entry), data );
if (userdata->callback)
(*userdata->callback) (*intvar, userdata->call_data);
}
static void
entscale_int_entry_update (GtkWidget *widget,
gpointer data)
{
EntscaleIntData *userdata;
GtkAdjustment *adjustment;
int new_val, constraint_val;
int *intvar = data;
userdata = gtk_object_get_user_data (GTK_OBJECT (widget));
adjustment = GTK_ADJUSTMENT( userdata->adjustment );
new_val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
constraint_val = new_val;
if ( constraint_val < adjustment->lower )
constraint_val = adjustment->lower;
if ( constraint_val > adjustment->upper )
constraint_val = adjustment->upper;
if ( userdata->constraint )
*intvar = constraint_val;
else
*intvar = new_val;
adjustment->value = constraint_val;
gtk_signal_handler_block_by_data ( GTK_OBJECT(adjustment), data );
gtk_signal_emit_by_name ( GTK_OBJECT(adjustment), "value_changed");
gtk_signal_handler_unblock_by_data ( GTK_OBJECT(adjustment), data );
if (userdata->callback)
(*userdata->callback) (*intvar, userdata->call_data);
}

14
plug-ins/maze/maze.h Normal file
View file

@ -0,0 +1,14 @@
#define MAZE_TITLE "Maze 0.6.1"
#include "gtk/gtk.h"
typedef struct {
gint width;
gint height;
gint seed;
gboolean tile;
gint multiple;
gint offset;
/* Interface options. */
gboolean timeseed;
} MazeValues;

797
plug-ins/maze/maze_face.c Normal file
View file

@ -0,0 +1,797 @@
/* maze_face.c, version 0.6.0, Feb 14, 1998.
* User interface for plug-in-maze.
*
* Implemented as a GIMP 0.99 Plugin by
* Kevin Turner <kevint@poboxes.com>
* http://www.poboxes.com/kevint/gimp/maze.html
*/
/*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifdef MAZE_DEBUG
#include <stdio.h>
#include <stdlib.h>
#endif /* MAZE_DEBUG */
#include "maze.h"
#include "libgimp/gimp.h"
#include "libgimp/gimpui.h"
#define BORDER_TOLERANCE 1.00 /* maximum ratio of (max % divs) to width */
#define ENTRY_WIDTH 75
/* entscale stuff begin */
#define ENTSCALE_INT_SCALE_WIDTH 125
#define ENTSCALE_INT_ENTRY_WIDTH 40
typedef void (*EntscaleIntCallbackFunc) (gint value, gpointer data);
typedef struct {
GtkObject *adjustment;
GtkWidget *entry;
gint constraint;
EntscaleIntCallbackFunc callback;
gpointer call_data;
} EntscaleIntData;
/* entscale stuff end */
gint maze_dialog (void);
static void maze_msg (gchar *msg);
static void maze_close_callback (GtkWidget *widget, gpointer data);
static void maze_ok_callback (GtkWidget *widget, gpointer data);
static void maze_entry_callback (GtkWidget *widget, gpointer data);
/* Looking back, it would probably have been easier to completely
* re-write the whole entry/scale thing to work with the divbox stuff.
* It would undoubtably be cleaner code. But since I already *had*
* the entry/scale routines, I was under the (somewhat mistaken)
* impression that it would be easier to work with them... */
/* Now, it goes like this:
To update entscale (width) when div_entry changes:
entscale_int_new has been slightly modified to return a pointer to
its entry widget.
This is fed to divbox_new as a "friend", which is in turn fed to
the div_entry_callback routine. And that's not really so bad,
except...
Oh, well, maybe it isn't so bad. We can play with our friend's
userdata to block his callbacks so we don't get feedback loops,
that works nicely enough.
To update div_entry when entscale (width) changes:
The entry/scale setup graciously provides for callbacks. However,
this means we need to know about div_entry when we set up
entry/scale, which we don't... Chicken and egg problem. So we
set up a pointer to where div_entry will be, and pass this
through to divbox_new when it happens.
We need to block signal handlers for div_entry this time. We
happen to know that div_entry's callback data is our old
"friend", so we pull our friend out from where we stuck him in
the entry's userdata... Hopefully that does it. */
/* Questions:
Gosh that was dumb. Is there a way to
signal_handler_block_by_name?
That would make life so much nicer.
Pointing to static variables "less" and "more" (for the buttons
in divbox_new) is stupid. Is there a way to store integer values
in userdata or use intergers as parameters to callbacks? The
only alternative I could think of was seperate "button_less" and
"button_more" callbacks, which did nothing but pass data on to
what is now the div_button_callback function with an additional
-1 or 1 parameter... And that idea was at least as brain-damaged.
*/
static void div_button_callback (GtkWidget *button, GtkWidget *entry);
static void div_entry_callback (GtkWidget *entry, GtkWidget *friend);
static void height_width_callback (gint width, GtkWidget **div_entry);
static void toggle_callback (GtkWidget *widget, gboolean *data);
static GtkWidget* divbox_new (guint *max,
GtkWidget *friend,
GtkWidget **div_entry);
#if 0
static void div_buttonl_callback (GtkObject *object);
static void div_buttonr_callback (GtkObject *object);
#endif
/* entscale stuff begin */
static GtkWidget* entscale_int_new ( GtkWidget *table, gint x, gint y,
gchar *caption, gint *intvar,
gint min, gint max, gint constraint,
EntscaleIntCallbackFunc callback,
gpointer data );
static void entscale_int_destroy_callback (GtkWidget *widget,
gpointer data);
static void entscale_int_scale_update (GtkAdjustment *adjustment,
gpointer data);
static void entscale_int_entry_update (GtkWidget *widget,
gpointer data);
/* entscale stuff end */
extern MazeValues mvals;
extern guint sel_w, sel_h;
static gint maze_run=FALSE;
static GtkWidget *msg_label;
/* I only deal with setting up a few widgets at a time, so I could get
by on a handful of generic GtkWidget variables. But I've noticed
that's not the way things are done around here... I read it
enhances optimization or some such thing. Oh well. Pointers are
cheap, right? */
gint maze_dialog()
{
GtkWidget *dlg;
GtkWidget *msg_frame;
GtkWidget *frame;
GtkWidget *table;
gint trow;
GtkWidget *button;
GtkWidget *label;
GtkWidget *entry;
GtkWidget *notebook;
GtkWidget *tilecheck;
GtkWidget *width_entry, *height_entry;
GtkWidget *seed_hbox, *seed_entry, *time_button;
GtkWidget *div_x_hbox, *div_y_hbox;
GtkWidget *div_x_label, *div_y_label, *div_x_entry, *div_y_entry;
gchar **argv;
gint argc;
gchar buffer[32];
argc = 1;
argv = g_new (gchar *, 1);
argv[0] = g_strdup ("maze");
gtk_init (&argc, &argv);
dlg = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dlg), MAZE_TITLE);
gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
(GtkSignalFunc) maze_close_callback,
NULL);
/* Action area */
button = gtk_button_new_with_label ("OK");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) maze_ok_callback,
dlg);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_grab_default (button);
gtk_widget_show (button);
button = gtk_button_new_with_label ("Cancel");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) gtk_widget_destroy,
GTK_OBJECT (dlg));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
/* Create notebook */
notebook = gtk_notebook_new ();
gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), notebook, FALSE, FALSE, 0);
gtk_widget_show (notebook);
msg_frame = gtk_frame_new(MAZE_TITLE);
gtk_frame_set_shadow_type (GTK_FRAME (msg_frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (msg_frame), 5);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), msg_frame, FALSE, FALSE, 0);
sprintf(buffer,"Selection is %dx%d",sel_w, sel_h);
msg_label = gtk_label_new (buffer);
gtk_container_add (GTK_CONTAINER(msg_frame), msg_label);
gtk_widget_show (msg_label);
gtk_widget_show (msg_frame);
/* Set up Options page */
frame = gtk_frame_new ("Maze Options");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 5);
table = gtk_table_new (5, 2, FALSE);
gtk_container_border_width (GTK_CONTAINER (table), 5);
gtk_container_add (GTK_CONTAINER (frame), table);
trow = 0;
/* Tileable checkbox */
tilecheck = gtk_check_button_new_with_label ("Tileable?");
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (tilecheck), mvals.tile);
gtk_signal_connect (GTK_OBJECT (tilecheck), "clicked",
GTK_SIGNAL_FUNC (toggle_callback), &mvals.tile);
gtk_table_attach (GTK_TABLE (table), tilecheck, 0, 2, trow, trow+1,
GTK_FILL, 0, 5, 0 );
gtk_widget_show (tilecheck);
trow++;
/* entscale == Entry and Scale pair function found in pixelize.c */
width_entry = entscale_int_new (table, 0, trow, "Width (pixels):",
&mvals.width,
1, sel_w/4, TRUE,
(EntscaleIntCallbackFunc) height_width_callback,
&div_x_entry);
/* Number of Divisions entry */
trow++;
div_x_label = gtk_label_new("Pieces:");
gtk_table_attach (GTK_TABLE (table), div_x_label, 0,1, trow, trow+1,
0, 0, 5, 5);
gtk_widget_show(div_x_label);
div_x_hbox = divbox_new(&sel_w,
width_entry,
&div_x_entry);
sprintf(buffer, "%d", (sel_w / mvals.width) );
gtk_entry_set_text(GTK_ENTRY(div_x_entry), buffer);
gtk_table_attach (GTK_TABLE (table), div_x_hbox, 1, 2, trow, trow+1,
0, 0, 5, 5);
gtk_widget_show (div_x_hbox);
trow++;
height_entry = entscale_int_new (table, 0, trow, "Height (pixels):",
&mvals.height,
1, sel_h/4, TRUE,
(EntscaleIntCallbackFunc) height_width_callback,
&div_y_entry);
trow++;
div_y_label = gtk_label_new("Pieces:");
gtk_table_attach (GTK_TABLE (table), div_y_label, 0, 1, trow, trow+1,
0, 0, 5, 5);
gtk_widget_show(div_y_label);
div_y_hbox = divbox_new(&sel_h,
height_entry,
&div_y_entry);
sprintf(buffer, "%d", (sel_h / mvals.height) );
gtk_entry_set_text(GTK_ENTRY(div_y_entry), buffer);
gtk_table_attach (GTK_TABLE (table), div_y_hbox, 1, 2, trow, trow+1,
0, 0, 5, 5);
gtk_widget_show (div_y_hbox);
/* Add Options page to notebook */
gtk_widget_show (frame);
gtk_widget_show (table);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame,
gtk_label_new ("Options"));
/* Set up other page */
frame = gtk_frame_new ("Don't change these");
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 10);
/* gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0); */
table = gtk_table_new (3, 2, FALSE);
gtk_container_border_width (GTK_CONTAINER (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
/* Multiple input box */
label = gtk_label_new ("Multiple (57)");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, 0, 5, 0 );
gtk_widget_show (label);
entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0 );
gtk_widget_set_usize( entry, ENTRY_WIDTH, 0 );
sprintf( buffer, "%d", mvals.multiple );
gtk_entry_set_text (GTK_ENTRY (entry), buffer );
gtk_signal_connect (GTK_OBJECT (entry), "changed",
(GtkSignalFunc) maze_entry_callback,
&mvals.multiple);
gtk_widget_show (entry);
/* Offset input box */
label = gtk_label_new ("Offset (1)");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, 0, 5, 0 );
gtk_widget_show (label);
entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0 );
gtk_widget_set_usize( entry, ENTRY_WIDTH, 0 );
sprintf( buffer, "%d", mvals.offset );
gtk_entry_set_text (GTK_ENTRY (entry), buffer );
gtk_signal_connect (GTK_OBJECT (entry), "changed",
(GtkSignalFunc) maze_entry_callback,
&mvals.offset);
gtk_widget_show (entry);
/* Seed input box */
label = gtk_label_new ("Seed");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_FILL, 0, 5, 5);
gtk_widget_show (label);
seed_hbox = gtk_hbox_new(FALSE, 2);
gtk_table_attach (GTK_TABLE (table), seed_hbox, 1, 2, 2, 3,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 5);
seed_entry = gtk_entry_new ();
gtk_widget_set_usize( seed_entry, ENTRY_WIDTH, 0 );
sprintf( buffer, "%d", mvals.seed );
gtk_entry_set_text (GTK_ENTRY (seed_entry), buffer );
gtk_signal_connect (GTK_OBJECT (seed_entry), "changed",
(GtkSignalFunc) maze_entry_callback,
&mvals.seed);
gtk_box_pack_start(GTK_BOX(seed_hbox), seed_entry, TRUE, TRUE, 0);
gtk_widget_show (seed_entry);
time_button = gtk_toggle_button_new_with_label ("Time");
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(time_button),mvals.timeseed);
gtk_signal_connect (GTK_OBJECT (time_button), "clicked",
(GtkSignalFunc) toggle_callback,
&mvals.timeseed);
gtk_box_pack_end (GTK_BOX (seed_hbox), time_button, FALSE, FALSE, 0);
gtk_widget_show (time_button);
gtk_widget_show (seed_hbox);
/* Add Advanced page to notebook */
gtk_widget_show (frame);
gtk_widget_show (table);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame,
gtk_label_new ("Advanced"));
gtk_widget_show (dlg);
gtk_main ();
gdk_flush ();
return maze_run;
}
static GtkWidget*
divbox_new (guint *max, GtkWidget *friend, GtkWidget **div_entry)
{
GtkWidget *div_hbox;
GtkWidget *arrowl, *arrowr, *buttonl, *buttonr;
static gshort less= -1, more= 1;
div_hbox=gtk_hbox_new(FALSE, 0);
arrowl=gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_IN);
arrowr=gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_IN);
buttonl=gtk_button_new();
buttonr=gtk_button_new();
gtk_object_set_data(GTK_OBJECT(buttonl), "direction", &less);
gtk_object_set_data(GTK_OBJECT(buttonr), "direction", &more);
*div_entry= gtk_entry_new();
gtk_object_set_data(GTK_OBJECT(*div_entry), "max", max);
gtk_object_set_data(GTK_OBJECT(*div_entry), "friend", friend);
gtk_container_add(GTK_CONTAINER(buttonl),arrowl);
gtk_container_add(GTK_CONTAINER(buttonr),arrowr);
gtk_misc_set_padding(GTK_MISC(arrowl),2,2);
gtk_misc_set_padding(GTK_MISC(arrowr),2,2);
gtk_widget_set_usize( *div_entry, ENTRY_WIDTH, 0 );
gtk_box_pack_start(GTK_BOX(div_hbox), buttonl, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(div_hbox), *div_entry, FALSE, FALSE, 2);
gtk_box_pack_start(GTK_BOX(div_hbox), buttonr, FALSE, FALSE, 0);
gtk_widget_show (arrowl); gtk_widget_show (arrowr);
gtk_widget_show (*div_entry);
gtk_widget_show (buttonl); gtk_widget_show (buttonr);
gtk_signal_connect(GTK_OBJECT(buttonl), "clicked",
(GtkSignalFunc) div_button_callback,
*div_entry);
gtk_signal_connect(GTK_OBJECT(buttonr), "clicked",
(GtkSignalFunc) div_button_callback,
*div_entry);
gtk_signal_connect(GTK_OBJECT(*div_entry), "changed",
(GtkSignalFunc) div_entry_callback,
friend);
return div_hbox;
}
static void
div_button_callback (GtkWidget *button, GtkWidget *entry)
{
guint max, divs, even;
gchar *text, *text2;
gshort direction;
direction = *((gshort*) gtk_object_get_data(GTK_OBJECT(button), "direction"));
max = *((guint*) gtk_object_get_data(GTK_OBJECT(entry), "max"));
/* Tileable mazes shall have only an even number of divisions.
Other mazes have odd. */
/* Logic games!
If BIT1 is and "even" is then add:
FALSE TRUE 0
TRUE TRUE 1
FALSE FALSE 1
TRUE FALSE 0
That's where the +((foo & 1) == even) stuff comes from. */
/* Sanity check: */
if (mvals.tile && (max & 1)) {
maze_msg("Selection size is not even. \nTileable maze won't work perfectly.");
return;
}
even = mvals.tile ? 1 : 0;
text = gtk_entry_get_text (GTK_ENTRY (entry));
divs=atoi(text);
if (divs <= 3) {
divs= max - ((max & 1) == even);
} else if (divs > max) {
divs= 5 + even;
}
/* Makes sure we're appropriately even or odd, adjusting in the
proper direction. */
divs += direction * ((divs & 1) == even);
if (mvals.tile) {
if (direction > 0) {
do {
divs += 2;
if (divs > max)
divs = 4;
} while (max % divs);
} else { /* direction < 0 */
do {
divs -= 2;
if (divs < 4)
divs = max - (max & 1);
} while (max % divs);
} /* endif direction < 0 */
} else { /* If not tiling, having a non-zero remainder doesn't bother us much. */
if (direction > 0) {
do {
divs += 2;
} while ((max % divs > max / divs * BORDER_TOLERANCE ) && divs < max);
} else { /* direction < 0 */
do {
divs -= 2;
} while ((max % divs > max / divs * BORDER_TOLERANCE) && divs > 5);
} /* endif direction < 0 */
} /* endif not tiling */
if (divs <= 3) {
divs= max - ((max & 1) == even);
} else if (divs > max) {
divs= 5 - even;
} /* endif divs > max */
text2 = g_new(gchar, 16);
sprintf (text2,"%d",divs);
gtk_entry_set_text (GTK_ENTRY(entry),text2);
return;
}
static void
div_entry_callback (GtkWidget *entry, GtkWidget *friend)
{
guint divs, width, max;
gchar *buffer;
EntscaleIntData *userdata;
EntscaleIntCallbackFunc friend_callback;
divs = atoi(gtk_entry_get_text (GTK_ENTRY (entry)));
if (divs < 4) /* If this is under 4 (e.g. 0), something's weird. */
return; /* But it'll probably be ok, so just return and ignore. */
max = *((guint*) gtk_object_get_data(GTK_OBJECT(entry), "max"));
buffer = g_new(gchar, 16);
/* I say "width" here, but it could be height.*/
width = max/divs;
sprintf (buffer,"%d", width );
/* No tagbacks from our friend... */
userdata = gtk_object_get_user_data (GTK_OBJECT (friend));
friend_callback = userdata->callback;
userdata->callback = NULL;
gtk_entry_set_text(GTK_ENTRY(friend), buffer);
userdata->callback = friend_callback;
}
static void
height_width_callback (gint width, GtkWidget **div_entry)
{
guint divs, max;
gpointer data;
gchar *buffer;
max = *((guint*) gtk_object_get_data(GTK_OBJECT(*div_entry), "max"));
divs = max / width;
buffer = g_new(gchar, 16);
sprintf (buffer,"%d", divs );
data = gtk_object_get_data(GTK_OBJECT(*div_entry), "friend");
gtk_signal_handler_block_by_data ( GTK_OBJECT(*div_entry), data );
gtk_entry_set_text(GTK_ENTRY(*div_entry), buffer);
gtk_signal_handler_unblock_by_data ( GTK_OBJECT(*div_entry), data );
}
static void
maze_close_callback (GtkWidget *widget,
gpointer data)
{
gtk_main_quit ();
}
static void
maze_msg (gchar *msg)
{
gtk_label_set(GTK_LABEL(msg_label), msg);
}
static void
maze_ok_callback (GtkWidget *widget,
gpointer data)
{
maze_run = TRUE;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void
maze_entry_callback (GtkWidget *widget,
gpointer data)
{
gint *text_val;
text_val = (gint *) data;
*text_val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
}
static void
toggle_callback (GtkWidget *widget, gboolean *data)
{
*data = GTK_TOGGLE_BUTTON (widget)->active;
}
/* ==================================================================== */
/* As found in pixelize.c,
* hacked to return a pointer to the entry widget. */
/*
Entry and Scale pair 1.03
TODO:
- Do the proper thing when the user changes value in entry,
so that callback should not be called when value is actually not changed.
- Update delay
*/
/*
* entscale: create new entscale with label. (int)
* 1 row and 2 cols of table are needed.
* Input:
* x, y: starting row and col in table
* caption: label string
* intvar: pointer to variable
* min, max: the boundary of scale
* constraint: (bool) true iff the value of *intvar should be constraint
* by min and max
* callback: called when the value is actually changed
* call_data: data for callback func
*/
static GtkWidget*
entscale_int_new ( GtkWidget *table, gint x, gint y,
gchar *caption, gint *intvar,
gint min, gint max, gint constraint,
EntscaleIntCallbackFunc callback,
gpointer call_data)
{
EntscaleIntData *userdata;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *entry;
GtkWidget *scale;
GtkObject *adjustment;
gchar buffer[256];
gint constraint_val;
userdata = g_new ( EntscaleIntData, 1 );
label = gtk_label_new (caption);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
/*
If the first arg of gtk_adjustment_new() isn't between min and
max, it is automatically corrected by gtk later with
"value_changed" signal. I don't like this, since I want to leave
*intvar untouched when `constraint' is false.
The lines below might look oppositely, but this is OK.
*/
userdata->constraint = constraint;
if( constraint )
constraint_val = *intvar;
else
constraint_val = ( *intvar < min ? min : *intvar > max ? max : *intvar );
userdata->adjustment = adjustment =
gtk_adjustment_new ( constraint_val, min, max, 1.0, 1.0, 0.0);
scale = gtk_hscale_new ( GTK_ADJUSTMENT(adjustment) );
gtk_widget_set_usize (scale, ENTSCALE_INT_SCALE_WIDTH, 0);
gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
userdata->entry = entry = gtk_entry_new ();
gtk_widget_set_usize (entry, ENTSCALE_INT_ENTRY_WIDTH, 0);
sprintf( buffer, "%d", *intvar );
gtk_entry_set_text( GTK_ENTRY (entry), buffer );
userdata->callback = callback;
userdata->call_data = call_data;
/* userdata is done */
gtk_object_set_user_data (GTK_OBJECT(adjustment), userdata);
gtk_object_set_user_data (GTK_OBJECT(entry), userdata);
/* now ready for signals */
gtk_signal_connect (GTK_OBJECT (entry), "changed",
(GtkSignalFunc) entscale_int_entry_update,
intvar);
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
(GtkSignalFunc) entscale_int_scale_update,
intvar);
gtk_signal_connect (GTK_OBJECT (entry), "destroy",
(GtkSignalFunc) entscale_int_destroy_callback,
userdata );
/* start packing */
hbox = gtk_hbox_new (FALSE, 5);
gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, TRUE, 0);
gtk_table_attach (GTK_TABLE (table), label, x, x+1, y, y+1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_table_attach (GTK_TABLE (table), hbox, x+1, x+2, y, y+1,
GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (label);
gtk_widget_show (entry);
gtk_widget_show (scale);
gtk_widget_show (hbox);
return entry;
}
/* when destroyed, userdata is destroyed too */
static void
entscale_int_destroy_callback (GtkWidget *widget,
gpointer data)
{
EntscaleIntData *userdata;
userdata = data;
g_free ( userdata );
}
static void
entscale_int_scale_update (GtkAdjustment *adjustment,
gpointer data)
{
EntscaleIntData *userdata;
GtkEntry *entry;
gchar buffer[256];
gint *intvar = data;
gint new_val;
userdata = gtk_object_get_user_data (GTK_OBJECT (adjustment));
new_val = (gint) adjustment->value;
*intvar = new_val;
entry = GTK_ENTRY( userdata->entry );
sprintf (buffer, "%d", (int) new_val );
/* avoid infinite loop (scale, entry, scale, entry ...) */
gtk_signal_handler_block_by_data ( GTK_OBJECT(entry), data );
gtk_entry_set_text ( entry, buffer);
gtk_signal_handler_unblock_by_data ( GTK_OBJECT(entry), data );
if (userdata->callback)
(*userdata->callback) (*intvar, userdata->call_data);
}
static void
entscale_int_entry_update (GtkWidget *widget,
gpointer data)
{
EntscaleIntData *userdata;
GtkAdjustment *adjustment;
int new_val, constraint_val;
int *intvar = data;
userdata = gtk_object_get_user_data (GTK_OBJECT (widget));
adjustment = GTK_ADJUSTMENT( userdata->adjustment );
new_val = atoi (gtk_entry_get_text (GTK_ENTRY (widget)));
constraint_val = new_val;
if ( constraint_val < adjustment->lower )
constraint_val = adjustment->lower;
if ( constraint_val > adjustment->upper )
constraint_val = adjustment->upper;
if ( userdata->constraint )
*intvar = constraint_val;
else
*intvar = new_val;
adjustment->value = constraint_val;
gtk_signal_handler_block_by_data ( GTK_OBJECT(adjustment), data );
gtk_signal_emit_by_name ( GTK_OBJECT(adjustment), "value_changed");
gtk_signal_handler_unblock_by_data ( GTK_OBJECT(adjustment), data );
if (userdata->callback)
(*userdata->callback) (*intvar, userdata->call_data);
}

View file

@ -27,6 +27,19 @@
*/ */
/* Version 1.0:
* This is the follow-up release. It contains a few minor changes, the
* most major being that the first time I released the wrong version of
* the code, and this time the changes have been fixed. I also added
* tooltips to the dialog.
*
* Feel free to email me if you have any comments or suggestions on this
* plugin.
* --Daniel Dunbar
* ddunbar@diads.com
*/
/* Version .5: /* Version .5:
* This is the first version publicly released, it will probably be the * This is the first version publicly released, it will probably be the
* last also unless i can think of some features i want to add. * last also unless i can think of some features i want to add.
@ -73,9 +86,9 @@
typedef struct { typedef struct {
gdouble circle; gdouble circle;
gdouble angle; gdouble angle;
gint8 backwards; gint backwards;
gint8 inverse; gint inverse;
gint8 polrec; gint polrec;
} polarize_vals_t; } polarize_vals_t;
typedef struct { typedef struct {
@ -129,9 +142,8 @@ static void dialog_close_callback(GtkWidget *widget, gpointer data);
static void dialog_ok_callback(GtkWidget *widget, gpointer data); static void dialog_ok_callback(GtkWidget *widget, gpointer data);
static void dialog_cancel_callback(GtkWidget *widget, gpointer data); static void dialog_cancel_callback(GtkWidget *widget, gpointer data);
static void backwards_toggled(GtkWidget *widget, gpointer data); static void polar_toggle_callback(GtkWidget *widget, gpointer data);
static void top_toggled(GtkWidget *widget, gpointer data); static void set_tooltip (GtkTooltips *tooltips, GtkWidget *widget, const char *desc);
static void pr_toggled(GtkWidget *widget, gpointer data);
/***** Variables *****/ /***** Variables *****/
@ -142,22 +154,22 @@ GPlugInInfo PLUG_IN_INFO = {
run /* run_proc */ run /* run_proc */
}; /* PLUG_IN_INFO */ }; /* PLUG_IN_INFO */
static polarize_vals_t wpvals = { static polarize_vals_t pcvals = {
100.0, /* circle */ 100.0, /* circle */
0.0, /* angle */ 0.0, /* angle */
0, /* backwards */ 0, /* backwards */
1, /* inverse */ 1, /* inverse */
1 /* polar to rectangular? */ 1 /* polar to rectangular? */
}; /* wpvals */ }; /* pcvals */
static polarize_interface_t wpint = { static polarize_interface_t pcint = {
NULL, /* preview */ NULL, /* preview */
NULL, /* check_row_0 */ NULL, /* check_row_0 */
NULL, /* check_row_1 */ NULL, /* check_row_1 */
NULL, /* image */ NULL, /* image */
NULL, /* dimage */ NULL, /* dimage */
FALSE /* run */ FALSE /* run */
}; /* wpint */ }; /* pcint */
static GDrawable *drawable; static GDrawable *drawable;
@ -289,7 +301,7 @@ run(char *name,
case RUN_INTERACTIVE: case RUN_INTERACTIVE:
/* Possibly retrieve data */ /* Possibly retrieve data */
gimp_get_data(PLUG_IN_NAME, &wpvals); gimp_get_data(PLUG_IN_NAME, &pcvals);
/* Get information from the dialog */ /* Get information from the dialog */
@ -305,11 +317,11 @@ run(char *name,
status = STATUS_CALLING_ERROR; status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS) { if (status == STATUS_SUCCESS) {
wpvals.circle = param[3].data.d_float; pcvals.circle = param[3].data.d_float;
wpvals.angle = param[4].data.d_float; pcvals.angle = param[4].data.d_float;
wpvals.backwards = param[5].data.d_int8; pcvals.backwards = param[5].data.d_int8;
wpvals.inverse = param[6].data.d_int8; pcvals.inverse = param[6].data.d_int8;
wpvals.polrec = param[7].data.d_int8; pcvals.polrec = param[7].data.d_int8;
} /* if */ } /* if */
break; break;
@ -317,7 +329,7 @@ run(char *name,
case RUN_WITH_LAST_VALS: case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */ /* Possibly retrieve data */
gimp_get_data(PLUG_IN_NAME, &wpvals); gimp_get_data(PLUG_IN_NAME, &pcvals);
break; break;
default: default:
@ -345,7 +357,7 @@ run(char *name,
/* Store data */ /* Store data */
if (run_mode == RUN_INTERACTIVE) if (run_mode == RUN_INTERACTIVE)
gimp_set_data(PLUG_IN_NAME, &wpvals, sizeof(polarize_vals_t)); gimp_set_data(PLUG_IN_NAME, &pcvals, sizeof(polarize_vals_t));
} else if (status == STATUS_SUCCESS) } else if (status == STATUS_SUCCESS)
status = STATUS_EXECUTION_ERROR; status = STATUS_EXECUTION_ERROR;
@ -472,11 +484,11 @@ calc_undistorted_coords(double wx, double wy,
ydiff = y2 - y1; ydiff = y2 - y1;
xm = xdiff / 2.0; xm = xdiff / 2.0;
ym = ydiff / 2.0; ym = ydiff / 2.0;
circle = wpvals.circle; circle = pcvals.circle;
angle = wpvals.angle; angle = pcvals.angle;
angl = (double)angle / 180.0 * M_PI; angl = (double)angle / 180.0 * M_PI;
if (wpvals.polrec) { if (pcvals.polrec) {
if (wx >= cen_x) { if (wx >= cen_x) {
if (wy > cen_y) { if (wy > cen_y) {
phi = M_PI - atan (((double)(wx - cen_x))/((double)(wy - cen_y))); phi = M_PI - atan (((double)(wx - cen_x))/((double)(wy - cen_y)));
@ -526,12 +538,12 @@ calc_undistorted_coords(double wx, double wy,
phi = fmod (phi + angl, 2*M_PI); phi = fmod (phi + angl, 2*M_PI);
if (wpvals.backwards) if (pcvals.backwards)
x_calc = x2 - 1 - (x2 - x1 - 1)/(2*M_PI) * phi; x_calc = x2 - 1 - (x2 - x1 - 1)/(2*M_PI) * phi;
else else
x_calc = (x2 - x1 - 1)/(2*M_PI) * phi + x1; x_calc = (x2 - x1 - 1)/(2*M_PI) * phi + x1;
if (wpvals.inverse) if (pcvals.inverse)
y_calc = (y2 - y1)/rmax * r + y1; y_calc = (y2 - y1)/rmax * r + y1;
else else
y_calc = y2 - (y2 - y1)/rmax * r; y_calc = y2 - (y2 - y1)/rmax * r;
@ -549,7 +561,7 @@ calc_undistorted_coords(double wx, double wy,
} }
} else { } else {
if (wpvals.backwards) if (pcvals.backwards)
phi = (2 * M_PI) * (x2 - wx) / xdiff; phi = (2 * M_PI) * (x2 - wx) / xdiff;
else else
phi = (2 * M_PI) * (wx - x1) / xdiff; phi = (2 * M_PI) * (wx - x1) / xdiff;
@ -598,7 +610,7 @@ calc_undistorted_coords(double wx, double wy,
rmax = (rmax - t) / 100.0 * (100 - circle) + t; rmax = (rmax - t) / 100.0 * (100 - circle) + t;
if (wpvals.inverse) if (pcvals.inverse)
r = rmax * (double)((wy - y1) / (double)(ydiff)); r = rmax * (double)((wy - y1) / (double)(ydiff));
else else
r = rmax * (double)((y2 - wy) / (double)(ydiff)); r = rmax * (double)((y2 - wy) / (double)(ydiff));
@ -778,10 +790,10 @@ build_preview_source_image(void)
guchar pixel[4]; guchar pixel[4];
pixel_fetcher_t *pf; pixel_fetcher_t *pf;
wpint.check_row_0 = g_malloc(preview_width * sizeof(guchar)); pcint.check_row_0 = g_malloc(preview_width * sizeof(guchar));
wpint.check_row_1 = g_malloc(preview_width * sizeof(guchar)); pcint.check_row_1 = g_malloc(preview_width * sizeof(guchar));
wpint.image = g_malloc(preview_width * preview_height * 4 * sizeof(guchar)); pcint.image = g_malloc(preview_width * preview_height * 4 * sizeof(guchar));
wpint.dimage = g_malloc(preview_width * preview_height * 3 * sizeof(guchar)); pcint.dimage = g_malloc(preview_width * preview_height * 3 * sizeof(guchar));
left = sel_x1; left = sel_x1;
right = sel_x2 - 1; right = sel_x2 - 1;
@ -795,7 +807,7 @@ build_preview_source_image(void)
pf = pixel_fetcher_new(drawable); pf = pixel_fetcher_new(drawable);
p = wpint.image; p = pcint.image;
for (y = 0; y < preview_height; y++) { for (y = 0; y < preview_height; y++) {
px = left; px = left;
@ -804,11 +816,11 @@ build_preview_source_image(void)
/* Checks */ /* Checks */
if ((x / CHECK_SIZE) & 1) { if ((x / CHECK_SIZE) & 1) {
wpint.check_row_0[x] = CHECK_DARK; pcint.check_row_0[x] = CHECK_DARK;
wpint.check_row_1[x] = CHECK_LIGHT; pcint.check_row_1[x] = CHECK_LIGHT;
} else { } else {
wpint.check_row_0[x] = CHECK_LIGHT; pcint.check_row_0[x] = CHECK_LIGHT;
wpint.check_row_1[x] = CHECK_DARK; pcint.check_row_1[x] = CHECK_DARK;
} /* else */ } /* else */
/* Thumbnail image */ /* Thumbnail image */
@ -854,6 +866,8 @@ polarize_dialog(void)
GtkWidget *button; GtkWidget *button;
GtkWidget *toggle; GtkWidget *toggle;
GtkWidget *hbox; GtkWidget *hbox;
GtkTooltips *tips;
GdkColor tips_fg, tips_bg;
gint argc; gint argc;
gchar **argv; gchar **argv;
guchar *color_cube; guchar *color_cube;
@ -894,6 +908,21 @@ polarize_dialog(void)
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), top_table, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), top_table, FALSE, FALSE, 0);
gtk_widget_show(top_table); gtk_widget_show(top_table);
/* Initialize Tooltips */
/* use black as foreground: */
tips = gtk_tooltips_new ();
tips_fg.red = 0;
tips_fg.green = 0;
tips_fg.blue = 0;
/* postit yellow (khaki) as background: */
gdk_color_alloc (gtk_widget_get_colormap (dialog), &tips_fg);
tips_bg.red = 61669;
tips_bg.green = 59113;
tips_bg.blue = 35979;
gdk_color_alloc (gtk_widget_get_colormap (dialog), &tips_bg);
gtk_tooltips_set_colors (tips,&tips_bg,&tips_fg);
/* Preview */ /* Preview */
frame = gtk_frame_new(NULL); frame = gtk_frame_new(NULL);
@ -901,10 +930,10 @@ polarize_dialog(void)
gtk_table_attach(GTK_TABLE(top_table), frame, 1, 2, 0, 1, 0, 0, 0, 0); gtk_table_attach(GTK_TABLE(top_table), frame, 1, 2, 0, 1, 0, 0, 0, 0);
gtk_widget_show(frame); gtk_widget_show(frame);
wpint.preview = gtk_preview_new(GTK_PREVIEW_COLOR); pcint.preview = gtk_preview_new(GTK_PREVIEW_COLOR);
gtk_preview_size(GTK_PREVIEW(wpint.preview), preview_width, preview_height); gtk_preview_size(GTK_PREVIEW(pcint.preview), preview_width, preview_height);
gtk_container_add(GTK_CONTAINER(frame), wpint.preview); gtk_container_add(GTK_CONTAINER(frame), pcint.preview);
gtk_widget_show(wpint.preview); gtk_widget_show(pcint.preview);
/* Controls */ /* Controls */
@ -913,8 +942,8 @@ polarize_dialog(void)
gtk_table_attach(GTK_TABLE(top_table), table, 0, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(top_table), table, 0, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0);
gtk_widget_show(table); gtk_widget_show(table);
dialog_create_value("Circle depth in percent", GTK_TABLE(table), 0, &wpvals.circle, 0, 100.0, 1.0); dialog_create_value("Circle depth in percent", GTK_TABLE(table), 0, &pcvals.circle, 0, 100.0, 1.0);
dialog_create_value("Offset angle", GTK_TABLE(table), 1, &wpvals.angle, 0, 359, 1.0); dialog_create_value("Offset angle", GTK_TABLE(table), 1, &pcvals.angle, 0, 359, 1.0);
/* togglebuttons for backwards, top, polar->rectangular */ /* togglebuttons for backwards, top, polar->rectangular */
@ -923,23 +952,32 @@ polarize_dialog(void)
gtk_table_attach( GTK_TABLE(top_table), hbox, 0, 3, 2, 3, gtk_table_attach( GTK_TABLE(top_table), hbox, 0, 3, 2, 3,
GTK_FILL, 0 , 0, 0); GTK_FILL, 0 , 0, 0);
toggle = gtk_toggle_button_new_with_label("Map Backwards"); toggle = gtk_check_button_new_with_label("Map Backwards");
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), wpvals.backwards); gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), pcvals.backwards);
gtk_signal_connect( GTK_OBJECT(toggle), "clicked", (GtkSignalFunc)backwards_toggled,NULL); gtk_signal_connect(GTK_OBJECT(toggle), "clicked",
(GtkSignalFunc) polar_toggle_callback,
&pcvals.backwards);
gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0); gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0);
gtk_widget_show(toggle); gtk_widget_show(toggle);
set_tooltip(tips,toggle,"If checked the mapping will begin at the right side, as opposed to beginning at the left.");
toggle = gtk_toggle_button_new_with_label("Map from Top"); toggle = gtk_check_button_new_with_label("Map from Top");
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), wpvals.inverse); gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), pcvals.inverse);
gtk_signal_connect( GTK_OBJECT(toggle), "clicked", (GtkSignalFunc)top_toggled, NULL); gtk_signal_connect( GTK_OBJECT(toggle), "clicked",
(GtkSignalFunc) polar_toggle_callback,
&pcvals.inverse);
gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0); gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0);
gtk_widget_show(toggle); gtk_widget_show(toggle);
set_tooltip(tips,toggle,"If unchecked the mapping will put the bottom row in the middle and the top row on the outside. If checked it will be the opposite.");
toggle = gtk_toggle_button_new_with_label("Polar to Rectangular"); toggle = gtk_check_button_new_with_label("Polar to Rectangular");
gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), wpvals.polrec); gtk_toggle_button_set_state( GTK_TOGGLE_BUTTON(toggle), pcvals.polrec);
gtk_signal_connect( GTK_OBJECT(toggle), "clicked", (GtkSignalFunc)pr_toggled, NULL); gtk_signal_connect( GTK_OBJECT(toggle), "clicked",
(GtkSignalFunc) polar_toggle_callback,
&pcvals.polrec);
gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0); gtk_box_pack_start( GTK_BOX (hbox), toggle, TRUE, TRUE, 0);
gtk_widget_show(toggle); gtk_widget_show(toggle);
set_tooltip(tips,toggle,"If unchecked the image will be circularly mapped onto a rectangle. If checked the image will be mapped onto a circle.");
gtk_widget_show(hbox); gtk_widget_show(hbox);
@ -970,14 +1008,15 @@ polarize_dialog(void)
dialog_update_preview(); dialog_update_preview();
gtk_main(); gtk_main();
gtk_object_unref(GTK_OBJECT(tips));
gdk_flush(); gdk_flush();
g_free(wpint.check_row_0); g_free(pcint.check_row_0);
g_free(wpint.check_row_1); g_free(pcint.check_row_1);
g_free(wpint.image); g_free(pcint.image);
g_free(wpint.dimage); g_free(pcint.dimage);
return wpint.run; return pcint.run;
} /* polarize_dialog */ } /* polarize_dialog */
@ -1019,16 +1058,16 @@ dialog_update_preview(void)
py = top; py = top;
p_ul = wpint.dimage; p_ul = pcint.dimage;
/* p_lr = wpint.dimage + 3 * (preview_width * preview_height - 1);*/ /* p_lr = pcint.dimage + 3 * (preview_width * preview_height - 1);*/
for (y = 0; y < preview_height; y++) { for (y = 0; y < preview_height; y++) {
px = left; px = left;
if ((y / CHECK_SIZE) & 1) if ((y / CHECK_SIZE) & 1)
check_ul = wpint.check_row_0; check_ul = pcint.check_row_0;
else else
check_ul = wpint.check_row_1; check_ul = pcint.check_row_1;
for (x = 0; x < preview_width; x++) { for (x = 0; x < preview_width; x++) {
calc_undistorted_coords(px, py, &cx, &cy); calc_undistorted_coords(px, py, &cx, &cy);
@ -1043,7 +1082,7 @@ dialog_update_preview(void)
if ((ix >= 0) && (ix < preview_width) && if ((ix >= 0) && (ix < preview_width) &&
(iy >= 0) && (iy < preview_height)) (iy >= 0) && (iy < preview_height))
i = wpint.image + 4 * (preview_width * iy + ix); i = pcint.image + 4 * (preview_width * iy + ix);
else else
i = outside; i = outside;
@ -1059,15 +1098,15 @@ dialog_update_preview(void)
py += dy; py += dy;
} /* for */ } /* for */
p = wpint.dimage; p = pcint.dimage;
for (y = 0; y < img_height; y++) { for (y = 0; y < img_height; y++) {
gtk_preview_draw_row(GTK_PREVIEW(wpint.preview), p, 0, y, preview_width); gtk_preview_draw_row(GTK_PREVIEW(pcint.preview), p, 0, y, preview_width);
p += preview_width * 3; p += preview_width * 3;
} /* for */ } /* for */
gtk_widget_draw(wpint.preview, NULL); gtk_widget_draw(pcint.preview, NULL);
gdk_flush(); gdk_flush();
} /* dialog_update_preview */ } /* dialog_update_preview */
@ -1183,7 +1222,7 @@ dialog_close_callback(GtkWidget *widget, gpointer data)
static void static void
dialog_ok_callback(GtkWidget *widget, gpointer data) dialog_ok_callback(GtkWidget *widget, gpointer data)
{ {
wpint.run = TRUE; pcint.run = TRUE;
gtk_widget_destroy(GTK_WIDGET(data)); gtk_widget_destroy(GTK_WIDGET(data));
} /* dialog_ok_callback */ } /* dialog_ok_callback */
@ -1196,25 +1235,23 @@ dialog_cancel_callback(GtkWidget *widget, gpointer data)
gtk_widget_destroy(GTK_WIDGET(data)); gtk_widget_destroy(GTK_WIDGET(data));
} /* dialog_cancel_callback */ } /* dialog_cancel_callback */
static void static void polar_toggle_callback (GtkWidget *widget, gpointer data)
backwards_toggled(GtkWidget *widget, gpointer data)
{ {
wpvals.backwards ^= 1; int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON (widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
dialog_update_preview(); dialog_update_preview();
} }
static void static void
top_toggled(GtkWidget *widget, gpointer data) set_tooltip (GtkTooltips *tooltips, GtkWidget *widget, const char *desc)
{ {
wpvals.inverse ^= 1; if (desc && desc[0])
dialog_update_preview(); gtk_tooltips_set_tips (tooltips, widget, (char *) desc);
} }
static void
pr_toggled(GtkWidget *widget, gpointer data)
{
wpvals.polrec ^= 1;
dialog_update_preview();
}

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
psd

View file

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = psd
psd_SOURCES = \
psd.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
psd_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = randomize pluginlib_PROGRAMS = randomize
randomize_SOURCES = \ randomize_SOURCES = \
randomize.c randomize.c gpc.c gpc.h
INCLUDES = \ INCLUDES = \
$(X_CFLAGS) \ $(X_CFLAGS) \

206
plug-ins/randomize/gpc.c Normal file
View file

@ -0,0 +1,206 @@
/****************************************************************************
* This is a convenience library for plugins for the GIMP v 0.99.8 or later.
* Documentation is available at http://www.rru.com/~meo/gimp/ .
*
* Copyright (C) 1997 Miles O'Neal <meo@rru.com> http://www.rru.com/~meo/
* Blur code Copyright (C) 1995 Spencer Kimball and Peter Mattis
* GUI based on GTK code from:
* alienmap (Copyright (C) 1996, 1997 Daniel Cotting)
* plasma (Copyright (C) 1996 Stephen Norris),
* oilify (Copyright (C) 1996 Torsten Martinsen),
* ripple (Copyright (C) 1997 Brian Degenhardt) and
* whirl (Copyright (C) 1997 Federico Mena Quintero).
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
****************************************************************************/
/****************************************************************************
* gpc:
*
* gpc version 1.1 (3 Feb 1998, MEO)
* history
* 1.1 - 3 Feb 1998 MEO
* removed tooltips from action buttons
* 1.0 - 2 Feb 1998 MEO
* FCS
*
* Please send any patches or suggestions to the author: meo@rru.com .
*
****************************************************************************/
#include <stdlib.h>
#include <time.h>
#include "libgimp/gimp.h"
#include "gtk/gtk.h"
/*
* TOGGLE UPDATE callback
*/
static void
gpc_toggle_update(GtkWidget *widget, gpointer data) {
int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON(widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
}
/*
* DESTROY callback
*/
void
gpc_close_callback(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
/*
* CANCEL BUTTON callback
*/
void
gpc_cancel_callback(GtkWidget *widget, gpointer data) {
gtk_widget_destroy(GTK_WIDGET(data));
}
/*
* SCALE UPDATE callback
*/
void
gpc_scale_update(GtkAdjustment *adjustment, double *scale_val) {
*scale_val = adjustment->value;
}
/*
* TEXT UPDATE callback
*/
void
gpc_text_update(GtkWidget *widget, gpointer data) {
gint *text_val;
text_val = (gint *) data;
*text_val = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
}
/*
* TOOLTIPS ROUTINES
*/
static GtkTooltips *tips;
void
gpc_setup_tooltips(GtkWidget *parent)
{
static GdkColor tips_fg, tips_bg;
tips = gtk_tooltips_new();
/* black as foreground: */
tips_fg.red = 0;
tips_fg.green = 0;
tips_fg.blue = 0;
gdk_color_alloc(gtk_widget_get_colormap(parent), &tips_fg);
/* postit yellow (khaki) as background: */
tips_bg.red = 61669;
tips_bg.green = 59113;
tips_bg.blue = 35979;
gdk_color_alloc(gtk_widget_get_colormap(parent), &tips_bg);
gtk_tooltips_set_colors(tips, &tips_bg, &tips_fg);
}
void
gpc_set_tooltip(GtkWidget *widget, const char *tip)
{
if (tip && tip[0])
gtk_tooltips_set_tips(tips, widget, (char *) tip);
}
void
gpc_add_action_button(char *label, GtkSignalFunc callback, GtkWidget *dialog
/* , char *tip */ )
{
GtkWidget *button;
button = gtk_button_new_with_label(label);
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
gtk_signal_connect(GTK_OBJECT(button), "clicked", callback, dialog);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area),
button, TRUE, TRUE, 0);
gtk_widget_grab_default(button);
gtk_widget_show(button);
/* gpc_set_tooltip(button, tip); */
}
void
gpc_add_radio_button(GSList **group, char *label, GtkWidget *box,
gint *value, char *tip)
{
GtkWidget *toggle;
toggle = gtk_radio_button_new_with_label(*group, label);
*group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle));
gtk_box_pack_start(GTK_BOX(box), toggle, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
(GtkSignalFunc) gpc_toggle_update, value);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), *value);
gtk_widget_show(toggle);
gtk_widget_show(box);
gpc_set_tooltip(toggle, tip);
}
void
gpc_add_label(char *value, GtkWidget *table, int left, int right,
int top, int bottom)
{
GtkWidget *label;
label = gtk_label_new(value);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, left, right, top, bottom,
GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show(label);
}
void
gpc_add_hscale(GtkWidget *table, int width, float low, float high,
gdouble *val, int left, int right, int top, int bottom, char *tip)
{
GtkWidget *scale;
GtkObject *scale_data;
scale_data = gtk_adjustment_new(*val, low, high, 1.0, 1.0, 0.0);
scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data));
gtk_widget_set_usize(scale, width, 0);
gtk_table_attach(GTK_TABLE(table), scale, left, right, top, bottom,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
gtk_scale_set_digits(GTK_SCALE(scale), 0);
gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_DELAYED);
gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed",
(GtkSignalFunc) gpc_scale_update, val);
gtk_widget_show(scale);
gpc_set_tooltip(scale, tip);
}

76
plug-ins/randomize/gpc.h Normal file
View file

@ -0,0 +1,76 @@
/****************************************************************************
* This is a convenience library for plugins for the GIMP v 0.99.8 or later.
* Documentation is available at http://www.rru.com/~meo/gimp/ .
*
* Copyright (C) 1997 Miles O'Neal <meo@rru.com> http://www.rru.com/~meo/
* Blur code Copyright (C) 1995 Spencer Kimball and Peter Mattis
* GUI based on GTK code from:
* alienmap (Copyright (C) 1996, 1997 Daniel Cotting)
* plasma (Copyright (C) 1996 Stephen Norris),
* oilify (Copyright (C) 1996 Torsten Martinsen),
* ripple (Copyright (C) 1997 Brian Degenhardt) and
* whirl (Copyright (C) 1997 Federico Mena Quintero).
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
****************************************************************************/
/****************************************************************************
* gpc:
*
* gpc version 1.1 (3 Feb 1998, MEO)
* history
* 1.1 - 3 Feb 1998 MEO
* removed tooltips from action buttons
* 1.0 - 2 Feb 1998 MEO
* FCS
*
* Please send any patches or suggestions to the author: meo@rru.com .
*
****************************************************************************/
void
gpc_close_callback(GtkWidget *widget, gpointer data);
void
gpc_cancel_callback(GtkWidget *widget, gpointer data);
void
gpc_scale_update(GtkAdjustment *adjustment, double *scale_val);
void
gpc_text_update(GtkWidget *widget, gpointer data);
void
gpc_setup_tooltips(GtkWidget *parent);
void
gpc_set_tooltip(GtkWidget *widget, const char *tip);
void
gpc_add_action_button(char *label, GtkSignalFunc callback, GtkWidget *dialog
/* , char *tip */ );
void
gpc_add_radio_button(GSList **group, char *label, GtkWidget *box,
gint *value, char *tip);
void
gpc_add_label(char *value, GtkWidget *parent, int left, int right,
int top, int bottom);
void
gpc_add_hscale(GtkWidget *table, int width, float low, float high,
gdouble *val, int left, int right, int top, int bottom, char *tip);

View file

@ -30,8 +30,19 @@
/**************************************************************************** /****************************************************************************
* Randomize: * Randomize:
* *
* randomize version 1.0 (19 Oct 1997, MEO) * randomize version 1.4 (3 Feb 1998, MEO)
* history * history
* 1.4 - 3 Feb 1998 MEO
* added details to PDB parameter help strings
* 1.3 - 3 Feb 1998 MEO
* removed tooltips from action buttons
* fixed param[5] type (was int32, should have been float)
* 1.2 - 2 Feb 1998 MEO
* converted macro'd functions from 0.5 to inline functions
* 2 casts added for portability by 0.99.18 release coordinator
* moved from Distorts to Noise menu
* went to GUI convenience routines as much as reasonable
* broke out GUI convenience routines into gpc.h and gpc.c
* 1.1 - 30 Nov 1997 MEO * 1.1 - 30 Nov 1997 MEO
* added tooltips * added tooltips
* 1.0 - 19 Nov 1997 MEO * 1.0 - 19 Nov 1997 MEO
@ -120,6 +131,7 @@
#include <time.h> #include <time.h>
#include "libgimp/gimp.h" #include "libgimp/gimp.h"
#include "gtk/gtk.h" #include "gtk/gtk.h"
#include "gpc.h"
/********************************* /*********************************
* *
@ -127,11 +139,6 @@
* *
********************************/ ********************************/
/*
* Set this to 1 for faster processing, to 0 if for some
* reason you want all functions to be subroutines
*/
#define OPTIMIZE_SUBS 0
/* /*
* progress meter update frequency * progress meter update frequency
@ -139,11 +146,11 @@
#define PROG_UPDATE_TIME ((row % 10) == 0) #define PROG_UPDATE_TIME ((row % 10) == 0)
#define PLUG_IN_NAME "plug_in_randomize" #define PLUG_IN_NAME "plug_in_randomize"
#define RNDM_VERSION "Randomize 1.1" #define RNDM_VERSION "Randomize 1.4"
#define RNDM_BLUR 1 #define RNDM_BLUR 1
#define RNDM_PICK 2 #define RNDM_HURL 2
#define RNDM_HURL 3 #define RNDM_PICK 3
#define RNDM_SLUR 4 #define RNDM_SLUR 4
#define SEED_TIME 10 #define SEED_TIME 10
@ -208,52 +215,21 @@ GPlugInInfo PLUG_IN_INFO = {
static void randomize(GDrawable *drawable); static void randomize(GDrawable *drawable);
#if (OPTIMIZE_SUBS == 0) static inline void randomize_prepare_row(
static void randomize_prepare_row( GPixelRgn *pixel_rgn,
GPixelRgn *pixel_rgn, guchar *data,
guchar *data, int x,
int x, int y,
int y, int w
int w );
);
#endif
static gint randomize_dialog(); static gint randomize_dialog();
static void randomize_close_callback(
GtkWidget *widget,
gpointer data
);
static void randomize_ok_callback( static void randomize_ok_callback(
GtkWidget *widget, GtkWidget *widget,
gpointer data gpointer data
); );
static void randomize_cancel_callback(
GtkWidget *widget,
gpointer data
);
static void randomize_scale_update(
GtkAdjustment *adjustment,
double *scale_val
);
static void randomize_toggle_update(
GtkWidget *widget,
gpointer data
);
static void randomize_text_update(
GtkWidget *widget,
gpointer data
);
static void set_tooltip(
GtkWidget *widget,
const char *tip
);
static void setup_tooltips();
static GtkTooltips *tips;
/************************************ Guts ***********************************/ /************************************ Guts ***********************************/
@ -274,9 +250,10 @@ query()
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" }, { PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image (unused)" }, { PARAM_IMAGE, "image", "Input image (unused)" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" }, { PARAM_DRAWABLE, "drawable", "Input drawable" },
{ PARAM_INT32, "rndm_type", "Randomization type" }, { PARAM_INT32, "rndm_type",
{ PARAM_FLOAT, "rndm_pct", "Randomization percentage" }, "Randomization type (1=blur 2=hurl 3=pick 4=slur)" },
{ PARAM_FLOAT, "rndm_rcount", "Repeat count" }, { PARAM_FLOAT, "rndm_pct", "Randomization percentage (1 - 100)" },
{ PARAM_FLOAT, "rndm_rcount", "Repeat count(1 - 100)" },
}; };
static GParamDef *return_vals = NULL; static GParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof (args[0]); static int nargs = sizeof(args) / sizeof (args[0]);
@ -307,12 +284,14 @@ query()
* candidate, although in the spirit of randomity * candidate, although in the spirit of randomity
* we could pick one at random! * we could pick one at random!
*/ */
#define FIX_INDEX_BLUR() \ void
if (gimp_drawable_indexed(drawable->id)) { \ fix_index_blur(GDrawable *drawable) {
is_indexed_drawable = TRUE; \ if (gimp_drawable_indexed(drawable->id)) {
if (pivals.rndm_type == RNDM_BLUR) { \ is_indexed_drawable = TRUE;
pivals.rndm_type = RNDM_PICK; \ if (pivals.rndm_type == RNDM_BLUR) {
} \ pivals.rndm_type = RNDM_PICK;
}
}
} }
@ -358,7 +337,7 @@ run(char *name, int nparams, GParam *param, int *nreturn_vals,
* If we're running interactively, pop up the dialog box. * If we're running interactively, pop up the dialog box.
*/ */
case RUN_INTERACTIVE: case RUN_INTERACTIVE:
FIX_INDEX_BLUR(); fix_index_blur(drawable);
gimp_get_data(PLUG_IN_NAME, &pivals); gimp_get_data(PLUG_IN_NAME, &pivals);
if (!randomize_dialog()) /* return on Cancel */ if (!randomize_dialog()) /* return on Cancel */
return; return;
@ -370,14 +349,14 @@ run(char *name, int nparams, GParam *param, int *nreturn_vals,
* parameters have legitimate values. * parameters have legitimate values.
*/ */
case RUN_NONINTERACTIVE: case RUN_NONINTERACTIVE:
FIX_INDEX_BLUR(); fix_index_blur(drawable);
if (nparams != 6) { if (nparams != 6) {
status = STATUS_CALLING_ERROR; status = STATUS_CALLING_ERROR;
} }
if (status == STATUS_SUCCESS) { if (status == STATUS_SUCCESS) {
pivals.rndm_type = (gint) param[3].data.d_int32; pivals.rndm_type = (gint) param[3].data.d_int32;
pivals.rndm_pct = (gdouble) param[4].data.d_float; pivals.rndm_pct = (gdouble) param[4].data.d_float;
pivals.rndm_rcount = (gdouble) param[5].data.d_int32; pivals.rndm_rcount = (gdouble) param[5].data.d_float;
} }
if (status == STATUS_SUCCESS && if (status == STATUS_SUCCESS &&
((pivals.rndm_type != RNDM_PICK && ((pivals.rndm_type != RNDM_PICK &&
@ -401,39 +380,41 @@ run(char *name, int nparams, GParam *param, int *nreturn_vals,
default: default:
break; break;
} }
if (status == STATUS_SUCCESS) {
/* /*
* JUST DO IT! * JUST DO IT!
*/ */
switch (pivals.rndm_type) { switch (pivals.rndm_type) {
case RNDM_BLUR: rndm_type_str = "blur"; break; case RNDM_BLUR: rndm_type_str = "blur"; break;
case RNDM_HURL: rndm_type_str = "hurl"; break; case RNDM_HURL: rndm_type_str = "hurl"; break;
case RNDM_PICK: rndm_type_str = "pick"; break; case RNDM_PICK: rndm_type_str = "pick"; break;
case RNDM_SLUR: rndm_type_str = "slur"; break; case RNDM_SLUR: rndm_type_str = "slur"; break;
} }
sprintf(prog_label, "%s (%s)", RNDM_VERSION, rndm_type_str); sprintf(prog_label, "%s (%s)", RNDM_VERSION, rndm_type_str);
gimp_progress_init(prog_label); gimp_progress_init(prog_label);
gimp_tile_cache_ntiles(2 * (drawable->width / gimp_tile_width() + 1)); gimp_tile_cache_ntiles(2 * (drawable->width / gimp_tile_width() + 1));
/* /*
* Initialize the rand() function seed * Initialize the rand() function seed
*/ */
if (pivals.seed_type == SEED_TIME) if (pivals.seed_type == SEED_TIME)
srand(time(NULL)); srand(time(NULL));
else else
srand(pivals.rndm_seed); srand(pivals.rndm_seed);
randomize(drawable); randomize(drawable);
/* /*
* If we ran interactively (even repeating) update the display. * If we ran interactively (even repeating) update the display.
*/ */
if (run_mode != RUN_NONINTERACTIVE) { if (run_mode != RUN_NONINTERACTIVE) {
gimp_displays_flush(); gimp_displays_flush();
} }
/* /*
* If we use the dialog popup, set the data for future use. * If we use the dialog popup, set the data for future use.
*/ */
if (run_mode == RUN_INTERACTIVE) { if (run_mode == RUN_INTERACTIVE) {
gimp_set_data(PLUG_IN_NAME, &pivals, sizeof(RandomizeVals)); gimp_set_data(PLUG_IN_NAME, &pivals, sizeof(RandomizeVals));
} }
}
} else { } else {
/* /*
* If we got the wrong drawable type, we need to complain. * If we got the wrong drawable type, we need to complain.
@ -458,8 +439,7 @@ run(char *name, int nparams, GParam *param, int *nreturn_vals,
* *
********************************/ ********************************/
#if (OPTIMIZE_SUBS == 0) static inline void
static void
randomize_prepare_row(GPixelRgn *pixel_rgn, guchar *data, int x, int y, int w) randomize_prepare_row(GPixelRgn *pixel_rgn, guchar *data, int x, int y, int w)
{ {
int b; int b;
@ -479,27 +459,6 @@ randomize_prepare_row(GPixelRgn *pixel_rgn, guchar *data, int x, int y, int w)
data[w * pixel_rgn->bpp + b] = data[(w - 1) * pixel_rgn->bpp + b]; data[w * pixel_rgn->bpp + b] = data[(w - 1) * pixel_rgn->bpp + b];
} }
} }
#else
#define randomize_prepare_row(pixel_rgn, data, x, y, w) \
{ \
int b; \
\
if (y == 0) { \
gimp_pixel_rgn_get_row(pixel_rgn, data, x, (y + 1), w); \
} else if (y == (pixel_rgn)->h) { \
gimp_pixel_rgn_get_row(pixel_rgn, data, x, (y - 1), w); \
} else { \
gimp_pixel_rgn_get_row(pixel_rgn, data, x, y, w); \
} \
/* \
* Fill in edge pixels \
*/ \
for (b = 0; b < (pixel_rgn)->bpp; b++) { \
data[-(gint)(pixel_rgn)->bpp + b] = data[b]; \
data[w * (pixel_rgn)->bpp + b] = data[(w - 1) * (pixel_rgn)->bpp + b]; \
} \
}
#endif
/********************************* /*********************************
* *
@ -711,34 +670,6 @@ randomize(GDrawable *drawable)
* *
********************************/ ********************************/
#define randomize_add_action_button(label, callback, dialog, tip) \
{ \
GtkWidget *button; \
\
button = gtk_button_new_with_label(label); \
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); \
gtk_signal_connect(GTK_OBJECT(button), "clicked", callback, dialog); \
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->action_area), \
button, TRUE, TRUE, 0); \
gtk_widget_grab_default(button); \
gtk_widget_show(button); \
set_tooltip(button, tip); \
}
#define randomize_add_radio_button(group, label, box, callback, value, tip) \
{ \
GtkWidget *toggle; \
\
toggle = gtk_radio_button_new_with_label(group, label); \
group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle)); \
gtk_box_pack_start(GTK_BOX(box), toggle, FALSE, FALSE, 0); \
gtk_signal_connect(GTK_OBJECT(toggle), "toggled", \
(GtkSignalFunc) callback, value); \
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), *value); \
gtk_widget_show(toggle); \
gtk_widget_show(box); \
set_tooltip(toggle, tip); \
}
/********************************* /*********************************
* *
@ -749,9 +680,8 @@ randomize(GDrawable *drawable)
static gint static gint
randomize_dialog() randomize_dialog()
{ {
GtkWidget *dlg, *entry, *frame, *label, *scale, GtkWidget *dlg, *entry, *frame,
*seed_hbox, *seed_vbox, *table, *toggle_hbox; *seed_hbox, *seed_vbox, *table, *toggle_hbox;
GtkObject *scale_data;
GSList *type_group = NULL; GSList *type_group = NULL;
GSList *seed_group = NULL; GSList *seed_group = NULL;
gchar **argv; gchar **argv;
@ -781,7 +711,7 @@ randomize_dialog()
gtk_window_set_title(GTK_WINDOW(dlg), RNDM_VERSION); gtk_window_set_title(GTK_WINDOW(dlg), RNDM_VERSION);
gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE); gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dlg), "destroy", gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
(GtkSignalFunc) randomize_close_callback, NULL); (GtkSignalFunc) gpc_close_callback, NULL);
/* /*
* Parameter settings * Parameter settings
* *
@ -795,24 +725,18 @@ randomize_dialog()
gtk_container_border_width(GTK_CONTAINER(table), 10); gtk_container_border_width(GTK_CONTAINER(table), 10);
gtk_container_add(GTK_CONTAINER(frame), table); gtk_container_add(GTK_CONTAINER(frame), table);
gtk_widget_show(table); gtk_widget_show(table);
setup_tooltips(table); gpc_setup_tooltips(table);
/* /*
* Action area OK & Cancel buttons * Action area OK & Cancel buttons
*/ */
randomize_add_action_button("OK", gpc_add_action_button("OK", (GtkSignalFunc) randomize_ok_callback, dlg
(GtkSignalFunc) randomize_ok_callback, dlg, /* , "Accept settings and apply filter to image" */);
"Accept settings and apply filter to image"); gpc_add_action_button("Cancel", (GtkSignalFunc) gpc_cancel_callback, dlg
randomize_add_action_button("Cancel", /* , "Close plug-in without making any changes" */);
(GtkSignalFunc) randomize_cancel_callback, dlg,
"Close plug-in without making any changes");
/* /*
* Randomization Type - label & radio buttons * Randomization Type - label & radio buttons
*/ */
label = gtk_label_new("Randomization Type:"); gpc_add_label("Randomization Type:", table, 0, 1, 0, 1);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 0);
gtk_widget_show(label);
toggle_hbox = gtk_hbox_new(FALSE, 5); toggle_hbox = gtk_hbox_new(FALSE, 5);
gtk_container_border_width(GTK_CONTAINER(toggle_hbox), 5); gtk_container_border_width(GTK_CONTAINER(toggle_hbox), 5);
@ -823,29 +747,22 @@ randomize_dialog()
* don't allow blur as an option) * don't allow blur as an option)
*/ */
if (! is_indexed_drawable) { if (! is_indexed_drawable) {
randomize_add_radio_button(type_group, "Blur", toggle_hbox, gpc_add_radio_button(&type_group, "Blur", toggle_hbox, &do_blur,
(GtkSignalFunc) randomize_toggle_update, &do_blur,
"Blur each pixel by averaging its value with those of its neighbors"); "Blur each pixel by averaging its value with those of its neighbors");
} }
/* /*
* Hurl, Pick and Slur buttons * Hurl, Pick and Slur buttons
*/ */
randomize_add_radio_button(type_group, "Hurl", toggle_hbox, gpc_add_radio_button(&type_group, "Hurl", toggle_hbox, &do_hurl,
(GtkSignalFunc) randomize_toggle_update, &do_hurl,
"Hurl random colors onto pixels"); "Hurl random colors onto pixels");
randomize_add_radio_button(type_group, "Pick", toggle_hbox, gpc_add_radio_button(&type_group, "Pick", toggle_hbox, &do_pick,
(GtkSignalFunc) randomize_toggle_update, &do_pick,
"Pick at random from neighboring pixels"); "Pick at random from neighboring pixels");
randomize_add_radio_button(type_group, "Slur", toggle_hbox, gpc_add_radio_button(&type_group, "Slur", toggle_hbox, &do_slur,
(GtkSignalFunc) randomize_toggle_update, &do_slur,
"Simplistic melt"); "Simplistic melt");
/* /*
* Randomization seed initialization controls * Randomization seed initialization controls
*/ */
label = gtk_label_new("Randomization Seed"); gpc_add_label("Randomization Seed:", table, 0, 1, 1, 2);
gtk_misc_set_alignment(GTK_MISC (label), 0.0, 0.5);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, 0, 5, 0);
gtk_widget_show(label);
/* /*
* Box to hold seed initialization radio buttons * Box to hold seed initialization radio buttons
*/ */
@ -856,8 +773,7 @@ randomize_dialog()
/* /*
* Time button * Time button
*/ */
randomize_add_radio_button(seed_group, "Current Time", seed_vbox, gpc_add_radio_button(&seed_group, "Current Time", seed_vbox, &do_time,
(GtkSignalFunc) randomize_toggle_update, &do_time,
"Seed random number generator from the current time - this guarantees a reasonable randomization"); "Seed random number generator from the current time - this guarantees a reasonable randomization");
/* /*
* Box to hold seed user initialization controls * Box to hold seed user initialization controls
@ -868,8 +784,7 @@ randomize_dialog()
/* /*
* User button * User button
*/ */
randomize_add_radio_button(seed_group, "Other Value", seed_hbox, gpc_add_radio_button(&seed_group, "Other Value", seed_hbox, &do_user,
(GtkSignalFunc) randomize_toggle_update, &do_user,
"Enable user-entered value for random number generator seed - this allows you to repeat a given \"random\" operation"); "Enable user-entered value for random number generator seed - this allows you to repeat a given \"random\" operation");
/* /*
* Randomization seed number (text) * Randomization seed number (text)
@ -880,54 +795,26 @@ randomize_dialog()
sprintf(buffer, "%d", pivals.rndm_seed); sprintf(buffer, "%d", pivals.rndm_seed);
gtk_entry_set_text(GTK_ENTRY(entry), buffer); gtk_entry_set_text(GTK_ENTRY(entry), buffer);
gtk_signal_connect(GTK_OBJECT(entry), "changed", gtk_signal_connect(GTK_OBJECT(entry), "changed",
(GtkSignalFunc) randomize_text_update, &pivals.rndm_seed); (GtkSignalFunc) gpc_text_update, &pivals.rndm_seed);
gtk_widget_show(entry); gtk_widget_show(entry);
set_tooltip(entry, "Value for seeding the random number generator"); gpc_set_tooltip(entry, "Value for seeding the random number generator");
gtk_widget_show(seed_hbox); gtk_widget_show(seed_hbox);
/* /*
* Randomization percentage label & scale (1 to 100) * Randomization percentage label & scale (1 to 100)
*/ */
label = gtk_label_new("Randomization %:"); gpc_add_label("Randomization %:", table, 0, 1, 2, 3);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gpc_add_hscale(table, SCALE_WIDTH,
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, 1.0, 100.0, &pivals.rndm_pct, 1, 2, 2, 3,
GTK_FILL | GTK_EXPAND, GTK_FILL, 5, 0); "Percentage of pixels to be filtered");
scale_data = gtk_adjustment_new(pivals.rndm_pct,
1.0, 100.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data));
gtk_widget_set_usize(scale, SCALE_WIDTH, 0);
gtk_table_attach(GTK_TABLE(table), scale, 1, 2, 2, 3,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
gtk_scale_set_digits(GTK_SCALE(scale), 0);
gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_DELAYED);
gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed",
(GtkSignalFunc) randomize_scale_update, &pivals.rndm_pct);
gtk_widget_show(label);
gtk_widget_show(scale);
set_tooltip(scale, "Percentage of pixels to be filtered");
/* /*
* Repeat count label & scale (1 to 100) * Repeat count label & scale (1 to 100)
*/ */
label = gtk_label_new("Repeat"); gpc_add_label("Repeat:", table, 0, 1, 3, 4);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gpc_add_hscale(table, SCALE_WIDTH,
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, 1.0, 100.0, &pivals.rndm_rcount, 1, 2, 3, 4,
GTK_FILL, 0, 5, 0); "Number of times to apply filter");
scale_data = gtk_adjustment_new(pivals.rndm_rcount,
1.0, 100.0, 1.0, 1.0, 0.0);
scale = gtk_hscale_new(GTK_ADJUSTMENT(scale_data));
gtk_widget_set_usize(scale, SCALE_WIDTH, 0);
gtk_table_attach(GTK_TABLE(table), scale, 1, 2, 3, 4,
GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
gtk_scale_set_value_pos(GTK_SCALE(scale), GTK_POS_TOP);
gtk_scale_set_digits(GTK_SCALE(scale), 0);
gtk_range_set_update_policy(GTK_RANGE(scale), GTK_UPDATE_DELAYED);
gtk_signal_connect(GTK_OBJECT(scale_data), "value_changed",
(GtkSignalFunc) randomize_scale_update, &pivals.rndm_rcount);
gtk_widget_show(label);
gtk_widget_show(scale);
set_tooltip(scale, "Number of times to apply filter");
/* /*
* Display everything. * Display everything.
*/ */
@ -935,7 +822,6 @@ randomize_dialog()
gtk_widget_show(dlg); gtk_widget_show(dlg);
gtk_main(); gtk_main();
gtk_object_unref (GTK_OBJECT (tips));
gdk_flush(); gdk_flush();
/* /*
* Figure out which type of randomization to apply. * Figure out which type of randomization to apply.
@ -962,103 +848,8 @@ randomize_dialog()
} }
/*********************************
*
* GUI accessories (callbacks, etc)
*
********************************/
/*
* DESTROY callback
*/
static void
randomize_close_callback(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
/*
* OK BUTTON callback
*/
static void static void
randomize_ok_callback(GtkWidget *widget, gpointer data) { randomize_ok_callback(GtkWidget *widget, gpointer data) {
rndm_int.run = TRUE; rndm_int.run = TRUE;
gtk_widget_destroy(GTK_WIDGET(data)); gtk_widget_destroy(GTK_WIDGET(data));
} }
/*
* CANCEL BUTTON callback
*/
static void
randomize_cancel_callback(GtkWidget *widget, gpointer data) {
gtk_widget_destroy(GTK_WIDGET(data));
}
/*
* SCALE UPDATE callback
*/
static void
randomize_scale_update(GtkAdjustment *adjustment, double *scale_val) {
*scale_val = adjustment->value;
}
/*
* TOGGLE UPDATE callback
*/
static void
randomize_toggle_update(GtkWidget *widget, gpointer data) {
int *toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON(widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
}
/*
* TEXT UPDATE callback
*/
static void
randomize_text_update(GtkWidget *widget, gpointer data) {
gint *text_val;
text_val = (gint *) data;
*text_val = atoi(gtk_entry_get_text(GTK_ENTRY(widget)));
}
/*
* TOOLTIPS ROUTINES
*/
void setup_tooltips(GtkWidget *parent)
{
static GdkColor tips_fg, tips_bg;
tips = gtk_tooltips_new();
/* black as foreground: */
tips_fg.red = 0;
tips_fg.green = 0;
tips_fg.blue = 0;
gdk_color_alloc(gtk_widget_get_colormap(parent), &tips_fg);
/* postit yellow (khaki) as background: */
tips_bg.red = 61669;
tips_bg.green = 59113;
tips_bg.blue = 35979;
gdk_color_alloc(gtk_widget_get_colormap(parent), &tips_bg);
gtk_tooltips_set_colors(tips, &tips_bg, &tips_fg);
}
void set_tooltip(GtkWidget *widget, const char *tip)
{
if (tip && tip[0])
gtk_tooltips_set_tips(tips, widget, (char *) tip);
}

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
sharpen

View file

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = sharpen
sharpen_SOURCES = \
sharpen.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
sharpen_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
stereogram

View file

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = stereogram
stereogram_SOURCES = \
stereogram.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
stereogram_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View file

@ -1,586 +0,0 @@
/* Stereogram 0.5 --- image filter plug-in for The Gimp
* Copyright (C) 1997 Francisco Bustamante
* pointnclick@geocities.com
* http://www.geocities.com/SiliconValley/Lakes/4813/index.html
*
* The Gimp -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
*/
/* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* This plug-in based on information from the Stereogram FAQ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#define SIRDS 1
#define SIS 2
#define TILE_CACHE_SIZE 16
typedef struct {
gint run;
} StereogramInterface;
static StereogramInterface sint = {
FALSE
};
static void query (void);
static void run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals);
static gint create_stereogram(GDrawable *heightdrawable,
guchar *pixels,
GDrawable *patterndrawable,
int type);
static gint stereogram_dialog(void);
static void stereogram_close_callback(GtkWidget *widget,
gpointer data);
static void stereogram_ok_callback(GtkWidget *widget,
gpointer data);
static void stereogram_drawable_callback (gint32 id,
gpointer data);
static void stereogram_toggle_update(GtkWidget *widget,
gpointer data);
static gint stereogram_constrain (gint32 image_id,
gint32 drawable_id,
gpointer data);
typedef struct {
int t; /* Stereogram type */
gint32 patID; /* Pattern Drawable ID*/
} StereogramVals;
static StereogramVals svals =
{
SIRDS, /* type */
-1 /* patID */
};
GPlugInInfo PLUG_IN_INFO =
{
NULL, /*init_proc*/
NULL, /*quit_proc*/
query, /*query_proc*/
run, /*run_proc*/
};
MAIN()
static void
query(void)
{
static GParamDef args[] =
{
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input Image" },
{ PARAM_DRAWABLE, "heightmap", "Height Map" },
{ PARAM_INT32, "type", "Type of stereogram" },
{ PARAM_DRAWABLE, "pat", "Pattern to use for stereogram" },
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof(args[0]);
static int nreturn_vals = 0;
gimp_install_procedure("plug_in_stereogram",
"Creates SIS (Single Image Stereograms) and SIRDS (Single Image Random Dot Stereogram)",
"Based on the Stereogram FAQ",
"Francisco Bustamante",
"Francisco Bustamante",
"1997",
"<Image>/Filters/Misc/Stereogram",
"GRAY",
PROC_PLUG_IN,
nargs, nreturn_vals,
args, return_vals);
} /*query*/
static void
run (char *name,
int nparams,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
GRunModeType run_mode;
static GParam values[1];
GDrawable *heightdrawable;
GDrawable *patterndrawable;
GDrawable *destdrawable;
GStatusType status = STATUS_SUCCESS;
GPixelRgn destrgn;
guchar *dest_pixels;
static gint32 DestImageID;
gint32 layerID;
run_mode = param[0].data.d_int32;
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
switch(run_mode) {
case RUN_INTERACTIVE :
/*Retrieve data */
gimp_get_data("plug_in_stereogram", &svals);
if(!stereogram_dialog())
return;
break;
case RUN_NONINTERACTIVE :
if((nparams < 4) || ((nparams != 5) && (param[3].data.d_int32 == SIS)))
status = STATUS_CALLING_ERROR;
if (status == STATUS_SUCCESS) {
svals.t = param[3].data.d_int32;
if(nparams == 5)
svals.patID = param[4].data.d_drawable;
}
case RUN_WITH_LAST_VALS :
/* Retrieve data */
gimp_get_data("plug_in_stereogram", &svals);
break;
default:
break;
}
heightdrawable = gimp_drawable_get(param[2].data.d_drawable);
DestImageID = gimp_image_new(heightdrawable->width, heightdrawable->height, RGB);
layerID = gimp_layer_new(DestImageID, "Background", heightdrawable->width,
heightdrawable->height,
RGB, 100, NORMAL_MODE);
gimp_image_add_layer(DestImageID, layerID, 0);
destdrawable = gimp_drawable_get(layerID);
dest_pixels = (guchar *) g_malloc((destdrawable->width) * (destdrawable->height) * 3);
if(status == STATUS_SUCCESS) {
if(gimp_drawable_gray(param[2].data.d_drawable)) {
gimp_progress_init("Stereogramming...");
gimp_tile_cache_ntiles(TILE_CACHE_SIZE);
patterndrawable = NULL;
if(svals.patID != -1)
patterndrawable = gimp_drawable_get(svals.patID);
create_stereogram(heightdrawable, dest_pixels,
patterndrawable, svals.t);
if(patterndrawable)
gimp_drawable_detach(patterndrawable);
if(run_mode == RUN_INTERACTIVE)
gimp_set_data("plug_in_stereogram", &svals, sizeof(StereogramVals));
}
}
gimp_pixel_rgn_init(&destrgn, destdrawable, 0, 0,
destdrawable->width,
destdrawable->height,
FALSE, FALSE);
gimp_pixel_rgn_set_rect(&destrgn, dest_pixels, 0, 0,
destdrawable->width,
destdrawable->height);
gimp_drawable_detach(destdrawable);
gimp_drawable_detach(heightdrawable);
gimp_display_new(DestImageID);
values[0].data.d_status = status;
}
guchar red[6] = {0, 170, 20, 60, 135, 255};
guchar green[6] = {0, 32, 56, 153, 23, 255};
guchar blue[6] = {0, 200, 140, 40, 100, 255};
static void
set_to_zeros(gint *buf, gint len)
{
gint i;
for( i = 0; i < len; i ++) {
buf[i] = -1;
}
}
static void
pixel_set(gint * buf, gint position, gint value)
{
buf[position] = value;
}
static gint
is_pixel_set(gint *buf, gint position)
{
if(buf[position] != -1)
return TRUE;
else
return FALSE;
}
static void
put_pixel_in_blank(guchar *pattern, gint pat_width,
gint pat_height, guchar *dest,
gint offset, gint dest_line, gint *set)
{
guchar *temp;
guchar *temp_pat;
gint pat_x, pat_y;
gint tempx;
tempx = offset;
while((set[tempx] == -1) && (tempx > 0))
tempx--;
if(tempx == 0) {
set[tempx] = 0;
pat_x = set[tempx];
pat_y = dest_line % pat_height;
temp = dest + tempx * 3;
temp_pat = pattern + (pat_y * pat_width * 3) + (pat_x * 3);
*temp++ = *temp_pat++;
*temp++ = *temp_pat++;
*temp = *temp_pat;
tempx++;
}
tempx ++;
while(tempx <= offset) {
set[tempx] = ((set[tempx - 1] + 1) % pat_width);
pat_x = set[tempx];
pat_y = dest_line % pat_height;
temp = dest + tempx * 3;
temp_pat = pattern + (pat_y * pat_width * 3) + (pat_x * 3);
*temp++ = *temp_pat++;
*temp++ = *temp_pat++;
*temp = *temp_pat;
tempx++;
}
}
void
line_fill(guchar *pattern, gint pat_width,
gint pat_height, guchar *dest,
gint dest_line, gint *set,
gint line_width)
{
gint cur_x;
for(cur_x = 0; cur_x < line_width; cur_x ++) {
if(set[cur_x] == -1) {
put_pixel_in_blank(pattern, pat_width,
pat_height, dest,
cur_x, dest_line, set);
}
}
}
static gint
create_stereogram(GDrawable *heightdrawable,
guchar *pixels,
GDrawable *patterndrawable,
int type)
{
int E;
int dist_to_screen;
GPixelRgn patrgn;
GPixelRgn hgtrgn;
gint src_height, src_width;
gint pat_height, pat_width;
gint dest_height, dest_width;
guchar *pattern = NULL;
guchar *final_line;
guchar *temp;
guchar *source_line;
guchar *temp_source;
gint cur_progress = 0, max_progress = heightdrawable->height;
gint cur_x = 0, cur_y = 0, curpat_y = 0;
gint separation;
int i, left, right;
gint *set;
dest_width = src_width = heightdrawable->width;
dest_height = src_height = heightdrawable->height;
source_line = (guchar *) g_malloc(heightdrawable->width);
gimp_pixel_rgn_init(&hgtrgn, heightdrawable, 0, 0,
src_width,
src_height,
FALSE, FALSE);
set = (gint *) g_malloc(dest_width * sizeof(gint));
if(svals.t == SIS) {
pat_width = patterndrawable->width;
pat_height = patterndrawable->height;
gimp_pixel_rgn_init(&patrgn, patterndrawable, 0, 0,
pat_width,
pat_height,
FALSE, FALSE);
pattern = (guchar *) g_malloc(pat_height * pat_width * 3);
gimp_pixel_rgn_get_rect(&patrgn, pattern, 0, 0, pat_width, pat_height);
}
else {
pat_width = 80;
pat_height = 80;
pattern = (guchar *) g_malloc(pat_height * pat_width * 3);
for(cur_y = 0; cur_y < pat_height; cur_y++) {
for(cur_x = 0; cur_x < pat_width; cur_x++) {
temp = pattern + ((cur_y * pat_width) + cur_x) * 3;
i = rand() % 6;
*temp++ = red[i];
*temp++ = green[i];
*temp = blue[i];
}
}
}
E = 192;
dist_to_screen = 900;
curpat_y = 0;
for(cur_y = 0; cur_y < src_height; cur_y++) {
set_to_zeros(set, dest_width);
gimp_pixel_rgn_get_row(&hgtrgn, source_line, 0, cur_y, src_width);
final_line = pixels + (cur_y * dest_width * 3);
for(cur_x = 0; cur_x < src_width; cur_x++) {
temp_source = source_line + cur_x;
separation = ((800 - *temp_source) * E) / ( dist_to_screen + (800 - *temp_source));
left = cur_x - (separation / 2);
right = left + separation;
if((right < dest_width) && (left >= 0)) {
if(is_pixel_set(set, left) == FALSE) {
put_pixel_in_blank(pattern, pat_width,
pat_height, final_line,
left, cur_y, set);
}
temp = final_line + left * 3;
*(final_line + (right * 3)) = *temp;
*(final_line + (right * 3 + 1)) = *++temp;
*(final_line + (right * 3 + 2)) = *++temp;
pixel_set(set, right, set[left]);
}
}
line_fill(pattern, pat_width,
pat_height, final_line,
cur_y, set,
src_width);
cur_progress++;
if((cur_progress % 10) == 0) {
gimp_progress_update((gdouble) cur_progress / (gdouble) max_progress);
}
}
if(pattern)
g_free(pattern);
return 1;
} /*create_stereogram*/
static gint
stereogram_dialog(void)
{
GtkWidget *dlg;
GtkWidget *label;
GtkWidget *optionmenu;
GtkWidget *menu;
GtkWidget *button;
GtkWidget *table;
GtkWidget *frame;
GtkWidget *toggle;
GtkWidget *toggle_hbox;
GSList *group = NULL;
gchar **argv;
gint argc;
gint sis = (svals.t == SIS);
gint sirds = (svals.t == SIRDS);
argc = 1;
argv = g_new(gchar *, 1);
argv[0] = g_strdup("stereogram");
gtk_init(&argc, &argv);
dlg = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dlg), "Stereogram");
gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
(GtkSignalFunc) stereogram_close_callback,
NULL);
button = gtk_button_new_with_label("OK");
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
(GtkSignalFunc) stereogram_ok_callback,
dlg);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_grab_default(button);
gtk_widget_show(button);
button = gtk_button_new_with_label("Cancel");
GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
(GtkSignalFunc) stereogram_close_callback,
GTK_OBJECT(dlg));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show(button);
frame = gtk_frame_new("Stereogram Options");
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
gtk_container_border_width(GTK_CONTAINER(frame), 10);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), frame, TRUE, TRUE, 0);
table = gtk_table_new(3, 8, FALSE);
gtk_container_border_width(GTK_CONTAINER(table), 5);
gtk_container_add(GTK_CONTAINER(frame), table);
gtk_table_set_row_spacing (GTK_TABLE (table), 0, 10);
gtk_table_set_row_spacing (GTK_TABLE (table), 1, 10);
gtk_table_set_col_spacing (GTK_TABLE (table), 0, 10);
gtk_table_set_col_spacing (GTK_TABLE (table), 1, 10);
label = gtk_label_new("Stereogram Pattern: ");
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_widget_show(label);
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
optionmenu = gtk_option_menu_new();
menu = gimp_drawable_menu_new(stereogram_constrain,
stereogram_drawable_callback,
NULL, svals.patID);
gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu);
gtk_table_attach(GTK_TABLE(table), optionmenu, 1, 3, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(optionmenu);
toggle_hbox = gtk_hbox_new(FALSE, 10);
gtk_container_border_width(GTK_CONTAINER(toggle_hbox), 5);
gtk_table_attach(GTK_TABLE(table), toggle_hbox, 0, 3, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
label = gtk_label_new("Stereogram type: ");
gtk_box_pack_start(GTK_BOX(toggle_hbox), label, FALSE, FALSE, 0);
gtk_widget_show(label);
toggle = gtk_radio_button_new_with_label(group, "SIS");
group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle));
gtk_box_pack_start(GTK_BOX(toggle_hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
(GtkSignalFunc) stereogram_toggle_update,
&sis);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), sis);
gtk_widget_show(toggle);
toggle = gtk_radio_button_new_with_label(group, "SIRDS");
group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle));
gtk_box_pack_start(GTK_BOX(toggle_hbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
(GtkSignalFunc) stereogram_toggle_update,
&sirds);
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), sirds);
gtk_widget_show(toggle);
gtk_widget_show(toggle_hbox);
gtk_widget_show(table);
gtk_widget_show(frame);
gtk_widget_show(dlg);
gtk_main();
gdk_flush();
if(sis)
svals.t = SIS;
else
svals.t = SIRDS;
return sint.run;
}
static void
stereogram_close_callback(GtkWidget *widget,
gpointer data)
{
gtk_main_quit();
}
static void
stereogram_ok_callback(GtkWidget *widget,
gpointer data)
{
sint.run = TRUE;
gtk_widget_destroy(GTK_WIDGET(data));
}
static void
stereogram_toggle_update(GtkWidget *widget,
gpointer data)
{
int * toggle_val;
toggle_val = (int *) data;
if (GTK_TOGGLE_BUTTON (widget)->active)
*toggle_val = TRUE;
else
*toggle_val = FALSE;
}
static gint
stereogram_constrain (gint32 image_id,
gint32 drawable_id,
gpointer data)
{
if (drawable_id == -1)
return TRUE;
return (gimp_drawable_color (drawable_id));
}
static void
stereogram_drawable_callback (gint32 id,
gpointer data)
{
svals.patID = id;
}

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
universal

View file

@ -1,39 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = universal
universal_SOURCES = \
universal.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
\
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
universal_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

File diff suppressed because it is too large Load diff

View file

@ -1,6 +0,0 @@
Makefile.in
Makefile
.deps
_libs
.libs
user_filter

View file

@ -1 +0,0 @@
Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>

View file

@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View file

@ -1,5 +0,0 @@
A "make" should be enough, "make install" copies the binary to
$(HOME)/.gimp/plug-ins.
This plug-in requires GNU flex and bison. I haven't tested, if normal lex
and yacc work.

View file

@ -1,38 +0,0 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = #STD#
#STD#_SOURCES = \
#STD#.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
#STD#_DEPENDENCIES = $(DEPS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

View file

@ -1,36 +0,0 @@
CC=gcc
LINK=gcc
INCDIR=
LIBDIR=-L/usr/X11/lib
LDLIBS=-lgdk -lgtk -lglib -lgimp -lm -lfl
OPTFLAGS= -m486 -O3 -fomit-frame-pointer -funroll-loops -ffast-math -Wall
DEST=user_filter
#DEFINES=-DYYDEBUG
OBJS=user_filter.o afslex.o afsparse.tab.o
SRCS=user_filter.c afslex.l afsparse.y
CFLAGS= $(OPTFLAGS) $(DEFINES) $(INCDIR)
LFLAGS= $(LIBDIR) $(LDLIBS)
$(DEST) : $(OBJS)
$(LINK) $(CFLAGS) -o $@ $(OBJS) $(LFLAGS)
tar: $(DEST) $(SRCS) README INSTALL
tar -czvf user_filter-1.0.0.tgz README INSTALL $(DEST) $(SRCS)
install: $(DEST)
cp $(DEST) $(HOME)/.gimp/plug-ins
.c.o:
$(CC) $(CFLAGS) -c $<
afsparse.tab.c: afsparse.y
bison --defines --verbose afsparse.y
afslex.c: afslex.l afsparse.tab.c
flex -Cem -oafslex.c afslex.l
user_filter.o: user_filter.c
afsparse.tab.o: afsparse.tab.c
afslex.o: afslex.c

View file

@ -1,6 +0,0 @@
There was a comment, that there was already a "math plugin". I hope,
everyone notices, that this is mainly directed to compatibility with
EXISTING filters of another program, and not to be the "general and best
solution for user filters".
I think a macro-recorder, that produces script-fu or C code would create
much better results.

View file

@ -1,36 +0,0 @@
User Filter Pluginv0.1ß
-----------------------
This is far from beeing complete, or correct.
But you can experiment with it.
For information about usage, look at:
http://www.fhd-stuttgart.de/~ws01/fffaq.htm
-or-
http://pluginhead.eyecandy.com/ffc.htm
-or-
http://www.netins.net/showcase/wolf359/fffaq.htm
For bug-reports, comments, suggestions and feature-requests write to
Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>
I added two .afs files for first experiments:
(could someone with windoze and Ph*t*sh*p verify the results ?)
shadow.afs:
Category: Neology
Title: Shadowcaster
Copyright: (c) 1997 by Werner D. Streidt 100526.16@compuserve.com
Author: Werner D. Streidt
Filename: shadow.afs
dart.afs:
Category: Render
Title: Dart
Copyright: c't magazine
Author: c't magazine
Filename: dart.afs
-- This isn't ready to be added to the main GIMP distribution --

View file

@ -1,13 +0,0 @@
- external converter, to build stand-alone plugins
- converter for "compiled" plug-ins, to keep author-information
- a simple parser for <name>.txt files, for "copyright:" or "author:" lines.
- the pdb-interface
- use some features of libgck
- optimize parser + lexer, error-correction
- entryfields next to the sliders, to enter values directly
- clean up internal structúre -> as it will be a base for a lot of plug-ins,
I should spend some time on code-quality and performance.
- "About" dialog box.
- RGB -> YUV conversion, to initialise i,u and v with correct values.
- as sin, cos and tan are only used on a limited set of values, I could use
precalculated tables for them.

View file

@ -1,93 +0,0 @@
%{
/*
* Written 1997 Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <string.h>
#include <ctype.h>
#include "afstree.h"
#include "afsparse.h"
#include "afsparse.tab.h"
int depth;
%}
%%
"&&" return t_and;
"||" return t_or;
"==" return t_eq;
"!=" return t_neq;
"<=" return t_le;
">=" return t_be;
"<<" return t_shl;
">>" return t_shr;
"dmin" return t_dmin;
"mmin" return t_mmin;
"abs" return t_abs;
"add" return t_add;
"cnv" return t_cnv;
"ctl" return t_ctl;
"dif" return t_dif;
"get" return t_get;
"put" return t_put;
"max" return t_max;
"min" return t_min;
"mix" return t_mix;
"rnd" return t_rnd;
"scl" return t_scl;
"sqr" return t_sqr;
"src" return t_src;
"sub" return t_sub;
"val" return t_val;
"c2d" return t_c2d;
"c2m" return t_c2m;
"cos" return t_cos;
"r2x" return t_r2x;
"r2y" return t_r2y;
"rad" return t_rad;
"sin" return t_sin;
"tan" return t_tan;
[\r\n\t" "] /* ignore NL/CR/TAB/SPACE */
[0-9]+ {
yylval=malloc(sizeof(s_afstree));
yylval->op_type=OP_CONST;
yylval->value=atoi(yytext);
yylval->nodes=NULL;
return v_int;
}
"(" { depth++; return yytext[0]; }
")" { if (depth>0) depth--; return yytext[0]; }
"," { if (depth>0) return yytext[0]; else return t_comma; }
. return yytext[0];
%%
void do_parse(char *s)
{
YY_BUFFER_STATE yy_buffer_state;
depth=0;
yy_buffer_state=yy_scan_string(s);
yyparse();
yy_delete_buffer(yy_buffer_state);
}

View file

@ -1,34 +0,0 @@
/*
* Written 1997 Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef AFSPARSE_H
#define AFSPARSE_H
#define YYSTYPE s_afstree *
#ifdef YYDEBUG
extern int yydebug;
#endif
s_afstree *get_afstree(char *s);
void free_tree(s_afstree *a);
void do_parse(char *s);
int yylex();
int yyparse();
#endif

View file

@ -1,636 +0,0 @@
%{
/*
* Written 1997 Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "afstree.h"
#include "afsparse.h"
#define YYSTYPE s_afstree *
s_afstree *afs_root;
int yyerror(char *s)
{
return 0;
}
s_afstree *get_afstree(char *s)
{
do_parse(s);
return afs_root;
}
%}
%left t_comma
%right '?' ':'
%right t_abs
%right t_add
%right t_cnv
%right t_ctl
%right t_dif
%right t_get
%right t_put
%right t_max
%right t_min
%right t_mix
%right t_rnd
%right t_scl
%right t_sqr
%right t_src
%right t_sub
%right t_val
%right t_c2d
%right t_c2m
%right t_cos
%right t_r2x
%right t_r2y
%right t_rad
%right t_sin
%right t_tan
%left '&' '|' '^'
%right t_and
%right t_or
%right t_eq
%right t_neq
%right t_le
%right t_be
%right t_shl
%right t_shr
%left LE BE NE '<' '>'
%left '+' '-'
%left '*' '/' '%'
%left ','
%token '(' ')'
%left t_sign '!' '~'
%token 'r' 'g' 'b' 'a' 'c' 'x' 'y' 'X' 'Y' 'i' 'u' 'v' 'z' 'Z' 'd' 'D' 'm' 'M' t_mmin t_dmin
%token v_int
%%
/****************************************************************************/
input: {
afs_root=NULL;
YYABORT;
}
| exp {
afs_root=$1;
YYACCEPT;
}
;
exp: v_int { $$ = $1; }
| 'r' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_r;
$$->value=0;
$$->nodes=NULL;
}
| 'g' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_g;
$$->value=0;
$$->nodes=NULL;
}
| 'b' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_b;
$$->value=0;
$$->nodes=NULL;
}
| 'a' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_a;
$$->value=0;
$$->nodes=NULL;
}
| 'c' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_c;
$$->value=0;
$$->nodes=NULL;
}
| 'x' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_x;
$$->value=0;
$$->nodes=NULL;
}
| 'y' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_y;
$$->value=0;
$$->nodes=NULL;
}
| 'z' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_z;
$$->value=0;
$$->nodes=NULL;
}
| 'X' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_X;
$$->value=0;
$$->nodes=NULL;
}
| 'Y' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_Y;
$$->value=0;
$$->nodes=NULL;
}
| 'Z' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_Z;
$$->value=0;
$$->nodes=NULL;
}
| 'i' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_i;
$$->value=0;
$$->nodes=NULL;
}
| 'u' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_u;
$$->value=0;
$$->nodes=NULL;
}
| 'v' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_v;
$$->value=0;
$$->nodes=NULL;
}
| 'd' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_d;
$$->value=0;
$$->nodes=NULL;
}
| 'D' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_D;
$$->value=0;
$$->nodes=NULL;
}
| 'm' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_m;
$$->value=0;
$$->nodes=NULL;
}
| 'M' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_M;
$$->value=0;
$$->nodes=NULL;
}
| t_dmin {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_dmin;
$$->value=0;
$$->nodes=NULL;
}
| t_mmin {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_VAR_mmin;
$$->value=0;
$$->nodes=NULL;
}
| exp '+' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_ADD;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '-' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_SUB;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '*' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_MUL;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '/' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_DIV;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '%' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_MOD;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '^' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_B_XOR;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '&' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_B_AND;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '|' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_B_OR;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| '~' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_B_NOT;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$2;
}
| '-' exp %prec t_sign {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_SUB;
$$->value=2;
$$->nodes=malloc(2*sizeof(s_afstree *));
$$->nodes[0]=malloc(sizeof(s_afstree));
$$->nodes[0]->op_type=OP_CONST;
$$->nodes[0]->value=0;
$$->nodes[0]->nodes=NULL;
$$->nodes[1]=$2;
}
| exp '?' exp ':' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_COND;
$$->value=3;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
$$->nodes[2]=$5;
}
| exp t_and exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_AND;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp t_or exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_OR;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp t_eq exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_EQ;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp t_neq exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_NEQ;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp t_le exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_LE;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp t_be exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_BE;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '<' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_LT;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp '>' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_BT;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| '!' exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_NOT;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$2;
}
| exp t_shl exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_SHL;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp t_shr exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_SHR;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| exp t_comma exp {
$$ = malloc(sizeof(s_afstree));
$$->op_type=OP_COMMA ;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$1;
$$->nodes[1]=$3;
}
| t_src '(' exp ',' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_SRC;
$$->value=3;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
$$->nodes[2]=$7;
}
| t_rad '(' exp ',' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_RAD;
$$->value=3;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
$$->nodes[2]=$7;
}
| t_cnv '(' exp ',' exp ',' exp ',' exp ',' exp ',' exp ',' exp ',' exp ',' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_CNV;
$$->value=10;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
$$->nodes[2]=$7;
$$->nodes[3]=$9;
$$->nodes[4]=$11;
$$->nodes[5]=$13;
$$->nodes[6]=$15;
$$->nodes[7]=$17;
$$->nodes[8]=$19;
$$->nodes[9]=$21;
}
| t_ctl '(' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_CTL;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
}
| t_abs '(' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_ABS;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
}
| t_dif '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_DIF;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_scl '(' exp ',' exp ','exp ',' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_SCL;
$$->value=5;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
$$->nodes[2]=$7;
$$->nodes[3]=$9;
$$->nodes[4]=$11;
}
| t_val '(' exp ',' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_VAL;
$$->value=3;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
$$->nodes[2]=$7;
}
| t_add '(' exp ',' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_ADD;
$$->value=3;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
$$->nodes[2]=$7;
}
| t_sub '(' exp ',' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_SUB;
$$->value=3;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
$$->nodes[2]=$7;
}
| t_mix '(' exp ',' exp ',' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_MIX;
$$->value=4;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
$$->nodes[2]=$7;
$$->nodes[3]=$9;
}
| t_rnd '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_RND;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_c2d '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_C2D;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_c2m '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_C2M;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_r2x '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_R2X;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_r2y '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_R2Y;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_min '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_MIN;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_max '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_MAX;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_put '(' exp ',' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_PUT;
$$->value=2;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
$$->nodes[1]=$5;
}
| t_get '(' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_GET;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
}
| t_sin '(' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_SIN;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
}
| t_cos '(' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_COS;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
}
| t_tan '(' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_TAN;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
}
| t_sqr '(' exp ')' {
$$ = malloc(sizeof(s_afstree));
$$->op_type=F_SQR;
$$->value=1;
$$->nodes=malloc(($$->value)*sizeof(s_afstree *));
$$->nodes[0]=$3;
}
| '(' exp ')' { $$=$2; }
;
%%
void free_tree(s_afstree *a)
{
int i;
if (a==NULL) return;
if (a->op_type==OP_CONST) return;
for (i=0; i<a->value; i++) {
free_tree(a->nodes[i]);
}
free(a->nodes);
free(a);
return;
}

View file

@ -1,96 +0,0 @@
/*
* Written 1997 Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef AFSTREE_H
typedef struct _afstree {
int op_type; /* symbol for operation */
int value; /* constant for OP_CONST or number of nodes */
struct _afstree **nodes; /* nodes, if neccessary */
} s_afstree;
/* operators */
#define OP_CONST 0
#define OP_VAR_r 1
#define OP_VAR_g 2
#define OP_VAR_b 3
#define OP_VAR_a 4
#define OP_VAR_c 5
#define OP_VAR_x 6
#define OP_VAR_y 7
#define OP_VAR_z 8
#define OP_VAR_X 9
#define OP_VAR_Y 10
#define OP_VAR_Z 11
#define OP_VAR_i 12
#define OP_VAR_u 13
#define OP_VAR_v 14
#define OP_VAR_d 15
#define OP_VAR_D 16
#define OP_VAR_m 17
#define OP_VAR_M 18
#define OP_VAR_dmin 19
#define OP_VAR_mmin 20
#define OP_ADD 21
#define OP_SUB 22
#define OP_MUL 23
#define OP_DIV 24
#define OP_MOD 25
#define OP_B_AND 26
#define OP_B_OR 27
#define OP_B_XOR 28
#define OP_B_NOT 29
#define OP_COND 30
#define OP_AND 31
#define OP_OR 32
#define OP_NOT 33
#define OP_EQ 34
#define OP_NEQ 35
#define OP_LE 36
#define OP_BE 37
#define OP_LT 38
#define OP_BT 39
#define OP_SHL 41
#define OP_SHR 42
#define F_SRC 43
#define F_RAD 44
#define F_CNV 45
#define F_CTL 46
#define F_ABS 47
#define F_DIF 48
#define F_SCL 49
#define F_VAL 50
#define F_ADD 51
#define F_SUB 52
#define F_MIX 53
#define F_RND 54
#define F_C2D 55
#define F_C2M 56
#define F_R2X 57
#define F_R2Y 58
#define F_MIN 59
#define F_MAX 60
#define F_PUT 61
#define F_GET 62
#define F_SIN 63
#define F_COS 64
#define F_TAN 65
#define F_SQR 66
#define OP_COMMA 67
#endif

View file

@ -1 +0,0 @@
%RGB-1.0 19 128 128 128 128 128 128 128 (((m*ctl(0)) % 512) > 255) ? r : 255-r (((m*ctl(0)) % 512) > 255) ? g : 255-g (((m*ctl(0)) % 512) > 255) ? b : 255-b (((m*ctl(0)) % 512) > 255) ? a : 255-a

View file

@ -1,2 +0,0 @@
%RGB-1.0 22 74 72 72 0 0 0 0 (x>ctl(0)-1 && y>ctl(0)-1) ? src(x-ctl(0),y-ctl(0),z) : (x<ctl(0) && y>ctl(0)-1 )?scl(x,0,ctl(0)-1,ctl(1),255) *src(x-ctl(0),y-ctl(0),z)/255: (x>ctl(0)-1 && y<ctl(0) ) ? scl(y,0,ctl(0)-1,ctl(1),255) * src(x-ctl(0),y-ctl(0),z)/255 : min(scl(x,0,ctl(0)-1,ctl(1),255),scl(y,0,ctl(0)-1,ctl(1),255))*src(x-ctl(0),y-ctl(0), z)/255 (x>ctl(0)-1 && y>ctl(0)-1) ? src(x-ctl(0),y-ctl(0),z) :(x<ctl(0) && y>ctl(0)-1) ? scl(x,0,ctl(0)-1,ctl(2),255) * src(x-ctl(0),y-ctl(0),z)/255 : (x>ctl(0)-1 && y<ctl(0) ) ? scl(y,0,ctl(0)-1,ctl(2),255) *src(x-ctl(0),y-ctl(0),z)/255 : min(scl(x,0,ctl(0)-1,ctl(2),255),scl(y,0,ctl(0)-1,ctl(2),255))*src(x-ctl(0),y-ctl(0), z)/255
(x>ctl(0)-1 && y>ctl(0)-1) ? src(x-ctl(0),y-ctl(0),z) :(x<ctl(0) && y>ctl(0)-1) ? scl(x,0,ctl(0)-1,ctl(3),255) *src(x-ctl(0),y-ctl(0),z)/255 :(x>ctl(0)-1 && y<ctl(0) ) ? scl(y,0,ctl(0)-1,ctl(3),255) *src(x-ctl(0),y-ctl(0),z)/255 :min(scl(x,0,ctl(0)-1,ctl(3),255),scl(y,0,ctl(0)-1,ctl(3),255))*src(x-ctl(0),y-ctl(0), z)/255 a

View file

@ -1,985 +0,0 @@
/*
* Written 1997 Jens Ch. Restemeier <jchrr@hrz.uni-bielefeld.de>
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#include "afstree.h"
#include "afsparse.h"
/*
* PLUG-IN information
*/
#define NUM_SLIDERS 8
#define PLUG_IN_NAME "User Filter"
#define PLUG_IN_PLACE "Generic"
#define PLUG_IN_VERSION "1.0"
#define PLUG_IN_TYPE "<Image>/Filters/" PLUG_IN_PLACE "/" PLUG_IN_NAME
#define PREVIEW_SIZE 128
/*
* Interface to GIMP
*/
int sel_x1,sel_y1,sel_x2,sel_y2;
int img_height, img_width, img_bpp, img_has_alpha;
int tile_width, tile_height;
int read_tile_col, read_tile_row;
GTile *read_tile;
guchar bg_color[4];
GDrawable *drawable;
int dialog_create();
void load_afs(char *s);
void save_afs(char *s);
typedef struct _envir {
/* environment */
int storage[256]; /* 256 byte storage for put+get */
int r; /* red at pixel position */
int g; /* green at pixel position */
int b; /* blue at pixel position */
int a; /* alpha at pixel postion */
int c; /* current color (=src(x,y,z)) */
int i, u, v; /* color int YUV space */
int x; /* x position */
int y; /* y position */
int z; /* current channel: 0=red, 1= green, 2=blue, 3=alpha */
int X; /* X-width of image */
int Y; /* Y-width of image */
int Z; /* number of channels of image */
int d; /* direction from center of the pic (-512 to 512) */
int m; /* distance to center of the pic */
int M; /* maximum distance from the center */
} s_envir;
/* functions */
inline int p_src(s_envir *e, int x, int y, int z);
inline int p_rad(s_envir *e, int d, int m, int z);
inline int p_val(s_envir *e, int i, int a, int b);
inline int p_ctl(s_envir *e, int i);
inline int p_dif(s_envir *e, int a, int b);
inline int p_put(s_envir *e, int v, int i);
inline int p_get(s_envir *e, int i);
inline int p_sin(s_envir *e, int i);
inline int p_cos(s_envir *e, int i);
inline int p_tan(s_envir *e, int i);
inline int p_sqr(s_envir *e, int i);
inline int p_cnv(s_envir *e, int m11, int m12, int m13, int m21, int m22, int m23, int m31, int m32, int m33, int d);
inline int p_div(s_envir *e, int a, int b);
inline int p_mod(s_envir *e, int a, int b);
inline int p_abs(s_envir *e, int a);
inline int p_rnd(s_envir *e, int a, int b);
inline int p_min(s_envir *e, int a, int b);
inline int p_max(s_envir *e, int a, int b);
inline int p_scl(s_envir *e, int a, int il, int ih, int ol, int oh);
inline int p_add(s_envir *e, int a, int b, int c);
inline int p_mix(s_envir *e, int a, int b, int n, int d);
inline int p_sub(s_envir *e, int a, int b, int c);
inline int p_c2d(s_envir *e, int x, int y);
inline int p_c2m(s_envir *e, int x, int y);
inline int p_r2x(s_envir *e, int d, int m);
inline int p_r2y(s_envir *e, int d, int m);
struct _data {
int control[NUM_SLIDERS];
/* #ifndef COMPACT_MODE */
char form[4][2048];
/* #endif */
} data;
/* formula for red/green/blue/alpha */
s_afstree *function_tree[4];
int calc_tree(s_envir *e, s_afstree *f)
{
if (f==NULL) return 0;
switch (f->op_type) {
case OP_CONST: return f->value;
case OP_ADD: return calc_tree(e, f->nodes[0]) + calc_tree(e, f->nodes[1]);
case OP_SUB: return calc_tree(e, f->nodes[0]) - calc_tree(e, f->nodes[1]);
case OP_MUL: return calc_tree(e, f->nodes[0]) * calc_tree(e, f->nodes[1]);
case OP_AND: return calc_tree(e, f->nodes[0]) && calc_tree(e, f->nodes[1]);
case OP_OR: return calc_tree(e, f->nodes[0]) || calc_tree(e, f->nodes[1]);
case OP_EQ: return calc_tree(e, f->nodes[0]) == calc_tree(e, f->nodes[1]);
case OP_NEQ: return calc_tree(e, f->nodes[0]) != calc_tree(e, f->nodes[1]);
case OP_LT: return calc_tree(e, f->nodes[0]) < calc_tree(e, f->nodes[1]);
case OP_LE: return calc_tree(e, f->nodes[0]) <= calc_tree(e, f->nodes[1]);
case OP_BT: return calc_tree(e, f->nodes[0]) > calc_tree(e, f->nodes[1]);
case OP_BE: return calc_tree(e, f->nodes[0]) >= calc_tree(e, f->nodes[1]);
case OP_B_AND: return calc_tree(e, f->nodes[0]) & calc_tree(e, f->nodes[1]);
case OP_B_OR: return calc_tree(e, f->nodes[0]) | calc_tree(e, f->nodes[1]);
case OP_B_XOR: return calc_tree(e, f->nodes[0]) ^ calc_tree(e, f->nodes[1]);
case OP_B_NOT: return ~calc_tree(e, f->nodes[0]);
case OP_VAR_r: return e->r;
case OP_VAR_g: return e->g;
case OP_VAR_b: return e->b;
case OP_VAR_a: return e->a;
case OP_VAR_c: return e->c;
case OP_VAR_i: return e->i;
case OP_VAR_u: return e->u;
case OP_VAR_v: return e->v;
case OP_VAR_x: return e->x;
case OP_VAR_y: return e->y;
case OP_VAR_z: return e->z;
case OP_VAR_X: return e->X;
case OP_VAR_Y: return e->Y;
case OP_VAR_Z: return e->Z;
case OP_VAR_d: return e->d;
case OP_VAR_D: return 1024;
case OP_VAR_m: return e->m;
case OP_VAR_M: return e->M;
case OP_VAR_mmin: return 0;
case OP_VAR_dmin: return 0;
case OP_NOT: return !calc_tree(e, f->nodes[0]);
case F_SIN: return p_sin(e, calc_tree(e, f->nodes[0]));
case F_COS: return p_cos(e, calc_tree(e, f->nodes[0]));
case F_TAN: return p_tan(e, calc_tree(e, f->nodes[0]));
case F_SQR: return p_sqr(e, calc_tree(e, f->nodes[0]));
case F_CTL: return p_ctl(e, calc_tree(e, f->nodes[0]));
case F_GET: return p_get(e, calc_tree(e, f->nodes[0]));
case F_ABS: return p_abs(e, calc_tree(e, f->nodes[0]));
case F_C2D: return p_c2d(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_C2M: return p_c2m(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_R2X: return p_r2x(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_R2Y: return p_r2y(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case OP_DIV: return p_div(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case OP_MOD: return p_mod(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_PUT: return p_put(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_ADD: return p_add(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]),calc_tree(e, f->nodes[2]));
case F_MIX: return p_mix(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]),calc_tree(e, f->nodes[2]),calc_tree(e, f->nodes[3]));
case F_SUB: return p_sub(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]),calc_tree(e, f->nodes[2]));
case F_MIN: return p_min(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_MAX: return p_max(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_RND: return p_rnd(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_DIF: return p_dif(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]));
case F_VAL: return p_val(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]),calc_tree(e, f->nodes[2]));
case F_SRC: return p_src(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]),calc_tree(e, f->nodes[2]));
case F_RAD: return p_rad(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]),calc_tree(e, f->nodes[2]));
case OP_COND: return calc_tree(e, f->nodes[0]) ? calc_tree(e, f->nodes[1]) : calc_tree(e, f->nodes[2]);
case F_SCL: return p_scl(e, calc_tree(e, f->nodes[0]),calc_tree(e, f->nodes[1]),calc_tree(e, f->nodes[2]),calc_tree(e, f->nodes[3]),calc_tree(e, f->nodes[4]));
case F_CNV: return p_cnv(e,
calc_tree(e, f->nodes[0]), calc_tree(e, f->nodes[1]), calc_tree(e, f->nodes[2]),
calc_tree(e, f->nodes[3]), calc_tree(e, f->nodes[4]), calc_tree(e, f->nodes[5]),
calc_tree(e, f->nodes[6]), calc_tree(e, f->nodes[7]), calc_tree(e, f->nodes[8]),
calc_tree(e, f->nodes[9]));
case OP_COMMA: {
calc_tree(e, f->nodes[0]);
return calc_tree(e, f->nodes[1]);
}
}
return 0;
}
/* calculate all pixel-relative information of the envir */
inline void calc_envir(s_envir *e)
{
e->d=p_c2d(e, e->x, e->y);
e->m=p_c2m(e, e->x, e->y);
e->r=p_src(e, e->x,e->y,0);
e->g=p_src(e, e->x,e->y,1);
e->b=p_src(e, e->x,e->y,2);
e->a=p_src(e, e->x,e->y,3);
}
inline int calc(s_envir *e, int channel)
{
int v;
/* prepare channel-specific values of envir */
e->z=channel;
e->c=p_src(e, e->x, e->y, e->z);
v=calc_tree(e, function_tree[channel]);
/* scale */
if (v<0) v=0;
if (v>255) v=255;
return v;
}
inline int p_src(s_envir *e, int xx, int yy, int zz)
{
int col, row;
int coloff, rowoff;
guchar *p;
xx+=sel_x1; yy+=sel_y1;
/* if outside visible image, use background color */
if ((xx < 0) || (xx >= img_width) || (yy < 0) || (yy >= img_height)) {
return(bg_color[zz]);
}
col = xx / tile_width;
coloff = xx % tile_width;
row = yy / tile_height;
rowoff = yy % tile_height;
if ((col != read_tile_col) || (row != read_tile_row) || (read_tile == NULL)) {
if (read_tile != NULL) gimp_tile_unref(read_tile, FALSE);
read_tile = gimp_drawable_get_tile(drawable, FALSE, row, col);
gimp_tile_ref(read_tile);
read_tile_col = col;
read_tile_row = row;
}
p = read_tile->data + img_bpp * (read_tile->ewidth * rowoff + coloff);
if (zz < img_bpp)
return p[zz];
else
return bg_color[zz];
}
inline int p_rad(s_envir *e, int dd, int mm, int zz)
{
return p_src(e, p_r2x(e,dd,mm), p_r2y(e,dd,mm), zz);
}
inline int p_cnv(s_envir *e, int m11, int m12, int m13, int m21, int m22, int m23, int m31, int m32, int m33, int dd)
{
if (dd==0) return 255;
return (m11*p_src(e, e->x-1,e->y-1, e->z) + m12*p_src(e, e->x,e->y-1,e->z) + m13*p_src(e, e->x+1,e->y-1,e->z) +
m21*p_src(e, e->x-1,e->y , e->z) + m22*p_src(e, e->x,e->y ,e->z) + m23*p_src(e, e->x+1,e->y ,e->z) +
m31*p_src(e, e->x-1,e->y+1, e->z) + m32*p_src(e, e->x,e->y+1,e->z) + m33*p_src(e, e->x+1,e->y+1,e->z)) / dd;
}
inline int p_val(s_envir *e, int i, int a, int b)
{
return ((data.control[i % NUM_SLIDERS]*(b-a))/255)+a;
}
inline int p_ctl(s_envir *e, int i)
{
return data.control[i%NUM_SLIDERS];
}
inline int p_dif(s_envir *e, int a, int b)
{
return abs(a-b);
}
inline int p_put(s_envir *e, int v, int i)
{
e->storage[i % 256]=v;
return v;
}
inline int p_get(s_envir *e, int i)
{
return e->storage[i % 256];
}
inline int p_sin(s_envir *e, int i)
{
return (sin(M_PI * ((float)i / 512.0))*512.0);
}
inline int p_cos(s_envir *e, int i)
{
return (cos(M_PI * ((float)i / 512.0))*512.0);
}
inline int p_tan(s_envir *e, int i)
{
/* This is "Windows mode" ! A Macintosh would return -1024-1024 ! */
switch (i % 512) {
case 0: return 0;
case 256: return 512;
}
return (tan(M_PI * ((float)i / 512.0))*512.0);
}
inline int p_sqr(s_envir *e, int i)
{
if (i<0) return 0;
return sqrt(i);
}
inline int p_div(s_envir *e, int a, int b)
{
return (b) ? a / b : 1;
}
inline int p_mod(s_envir *e, int a, int b)
{
return (b) ? a % b : 0;
}
inline int p_abs(s_envir *e, int a)
{
return a>0 ? a : -a;
}
inline int p_min(s_envir *e, int a, int b)
{
return (a<b) ? a : b;
}
inline int p_max(s_envir *e, int a, int b)
{
return (a>b) ? a : b;
}
inline int p_rnd(s_envir *e, int a, int b)
{
if (a==b) return a;
return (rand() % (b-a)) + a;
}
inline int p_scl(s_envir *e, int a, int il, int ih, int ol, int oh)
{
return (((a-il)*(oh-ol))/(ih-il))+ol;
}
inline int p_add(s_envir *e, int a, int b, int c)
{
return p_min(e, a+b, c);
}
inline int p_mix(s_envir *e, int a, int b, int n, int d)
{
if (d==0) return 0;
return a*n/d+b*(d-n)/d;
}
inline int p_sub(s_envir *e, int a, int b, int c)
{
return p_max(e, p_dif(e,a,b), c);
}
inline int p_c2d(s_envir *e, int x, int y)
{
int xm, ym, d;
xm=x-(e->X>>1); ym=y-(e->Y>>1);
d=(ym>0) ? 512 : 0;
if (xm!=0) d=(256.0 * (atan((float)ym / (float)abs(xm))/(M_PI/2.0)))+256;
return (xm>0) ? d : -d;
}
inline int p_c2m(s_envir *e, int x, int y)
{
int xm, ym;
xm=x-(e->X>>1); ym=y-(e->Y>>1);
return sqrt(xm*xm+ym*ym)+1;
}
inline int p_r2x(s_envir *e, int dd, int mm)
{
return (e->X>>1) + (sin(M_PI * (float)dd / 512.0 )*(float)mm);
}
inline int p_r2y(s_envir *e, int dd, int mm)
{
return (e->Y>>1) - (cos(M_PI * (float)dd / 512.0 )*(float)mm);
}
/*
* GIMP interface
*/
void query(void)
{
static GParamDef args[] = {
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
{ PARAM_IMAGE, "image", "Input image (unused)" },
{ PARAM_DRAWABLE, "drawable", "Input drawable" }
};
static GParamDef *return_vals = NULL;
static int nargs = sizeof(args) / sizeof(args[0]);
static int nreturn_vals = 0;
gimp_install_procedure(PLUG_IN_NAME,
"",
"",
"",
"",
PLUG_IN_VERSION,
PLUG_IN_TYPE,
"RGB*,GRAY*",
PROC_PLUG_IN,
nargs,
nreturn_vals,
args,
return_vals);
}
gint g_min(gint a, gint b)
{
return (a<b) ? a : b;
}
gint g_max(gint a, gint b)
{
return (a>b) ? a : b;
}
void run(char *name, int nparams, GParam *param, int *nreturn_vals, GParam **return_vals)
{
GParam values[1];
GRunModeType run_mode;
GStatusType status;
int c;
status = STATUS_SUCCESS;
run_mode = param[0].data.d_int32;
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
*nreturn_vals = 1;
*return_vals = values;
drawable = gimp_drawable_get(param[2].data.d_drawable);
img_width = gimp_drawable_width(drawable->id);
img_height = gimp_drawable_height(drawable->id);
img_bpp = gimp_drawable_bpp(drawable->id);
img_has_alpha = gimp_drawable_has_alpha(drawable->id);
gimp_palette_get_background(&(bg_color[0]), &(bg_color[1]), &(bg_color[2]));
bg_color[3]=0;
tile_width = gimp_tile_width ();
tile_height = gimp_tile_height ();
read_tile_col=read_tile_row=0;
/* Set the tile cache size */
gimp_tile_cache_ntiles(2 * (drawable->width + gimp_tile_width() - 1) / gimp_tile_width());
gimp_drawable_mask_bounds(drawable->id, &sel_x1, &sel_y1, &sel_x2, &sel_y2);
/* init function-trees */
for (c=0; c<4; c++)
function_tree[4]=NULL;
/* Possibly retrieve data */
strcpy(data.form[0], "r");
strcpy(data.form[1], "g");
strcpy(data.form[2], "b");
strcpy(data.form[3], "a");
for (c=0; c<NUM_SLIDERS; c++)
data.control[c]=0;
gimp_get_data(PLUG_IN_NAME, &data);
switch (run_mode) {
case RUN_INTERACTIVE: {
/* Get information from the dialog */
if (!dialog_create()) {
return;
}
break;
}
case RUN_NONINTERACTIVE:
break;
case RUN_WITH_LAST_VALS:
/* Possibly retrieve data */
gimp_get_data(PLUG_IN_NAME, &data);
break;
default:
break;
}
if ((status == STATUS_SUCCESS) && gimp_drawable_color(drawable->id)) {
int max_progress, progress;
int i,j,k;
int xs, ys;
int write_tile_col, write_tile_row;
s_envir e;
GTile *write_tile;
gimp_progress_init ("Filter plugin ...");
max_progress=sel_y2-sel_y1;
progress=0;
/* translate formula into tree */
for (i=0; i<4; i++) {
function_tree[i]=get_afstree(data.form[i]);
}
xs=sel_x2-sel_x1; ys=sel_y2-sel_y1;
e.M=sqrt(xs*xs+ys*ys)/2;
e.X=xs;
e.Y=ys;
e.Z=img_bpp;
max_progress=((sel_y2-sel_y1) / tile_height) * ((sel_x2-sel_x1) / tile_width);
progress=0;
for (write_tile_row=(sel_y1 / tile_height); write_tile_row<=((sel_y2-1) / tile_height); write_tile_row++) {
for (write_tile_col=(sel_x1 / tile_width); write_tile_col<=((sel_x2-1) / tile_width); write_tile_col++) {
gint t_max_x, t_min_x, t_max_y, t_min_y;
write_tile = gimp_drawable_get_tile( drawable, TRUE, write_tile_row, write_tile_col );
gimp_tile_ref(write_tile);
t_min_x=g_max(0, sel_x1 - (write_tile_col * tile_height));
t_max_x=g_min(write_tile->ewidth, sel_x2 - (write_tile_col * tile_width));
t_min_y=g_max(0, sel_y1 - (write_tile_row * tile_height));
t_max_y=g_min(write_tile->eheight, sel_y2 - (write_tile_row * tile_height));
for (i=t_min_y; i<t_max_y; i++) {
for (j=t_min_x; j<t_max_x; j++) {
guchar *c;
c=write_tile->data+(((i * write_tile->ewidth)+j) * img_bpp);
e.x=j+(write_tile_col*tile_width)-sel_x1;
e.y=i+(write_tile_row*tile_height)-sel_y1;
calc_envir(&e);
for (k=0; k<img_bpp;k++) {
if (k<4) {
c[k]=calc(&e, k);
} else {
c[k]=bg_color[k];
}
}
}
}
gimp_progress_update((double)progress / (double)max_progress);
progress++;
gimp_tile_unref (write_tile, TRUE);
}
}
/* destroy tree */
for (i=0; i<4; i++) {
if (function_tree[i]!=NULL)
free_tree(function_tree[i]);
}
gimp_drawable_flush (drawable);
gimp_drawable_merge_shadow (drawable->id, TRUE);
gimp_drawable_update (drawable->id, sel_x1, sel_y1, (sel_x2 - sel_x1), (sel_y2 - sel_y1));
/* If run mode is interactive, flush displays */
if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush();
/* Store data */
if (run_mode == RUN_INTERACTIVE)
gimp_set_data(PLUG_IN_NAME, &data, sizeof(data));
} else if (status == STATUS_SUCCESS)
status = STATUS_EXECUTION_ERROR;
values[0].data.d_status = status;
if (read_tile!=NULL)
gimp_tile_unref(read_tile, FALSE);
gimp_drawable_detach(drawable);
}
GPlugInInfo PLUG_IN_INFO = {
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run /* run_proc */
};
MAIN();
/*
* GTK user interface
*/
GtkWidget *dialog;
GtkObject *adjustment[NUM_SLIDERS];
GtkWidget *preview;
GtkWidget *entry[4];
int result, preview_enable;
/* prototypes for signals */
void dialog_update_preview(GtkWidget *widget, gpointer data);
void file_selection_load(GtkWidget *widget, GtkWidget *file_select);
void file_selection_save(GtkWidget *widget, GtkWidget *file_select);
void dialog_load(GtkWidget *widget, gpointer d);
void dialog_save(GtkWidget *widget, gpointer d);
void dialog_close(GtkWidget *widget, gpointer data);
void dialog_cancel(GtkWidget *widget, gpointer data);
void dialog_button_preview_update (GtkWidget *widget, gpointer data);
void dialog_ok(GtkWidget *widget, gpointer data);
void dialog_slider_update (GtkWidget *widget, int *data);
void file_selection_load(GtkWidget *widget, GtkWidget *file_select)
{
int tmp_preview_enable;
gtk_widget_set_sensitive (dialog, TRUE);
tmp_preview_enable=preview_enable; preview_enable=0;
load_afs(gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_select)));
preview_enable=tmp_preview_enable;
gtk_widget_destroy(file_select);
dialog_update_preview(preview, NULL);
}
void file_selection_save(GtkWidget *widget, GtkWidget *file_select)
{
gtk_widget_set_sensitive (dialog, TRUE);
save_afs(gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_select)));
gtk_widget_destroy(file_select);
}
void file_selection_cancel(GtkWidget *widget, GtkWidget *file_select)
{
gtk_widget_destroy(file_select);
gtk_widget_set_sensitive (dialog, TRUE);
}
void dialog_reset(GtkWidget *widget, gpointer d)
{
int n, tmp_preview_enable;
tmp_preview_enable=preview_enable;
preview_enable=0;
for (n=0; n<NUM_SLIDERS; n++) {
GTK_ADJUSTMENT(adjustment[n])->value=0;
gtk_signal_emit_by_name(GTK_OBJECT(adjustment[n]),"value_changed");
}
gtk_entry_set_text(GTK_ENTRY(entry[0]), "r");
gtk_entry_set_text(GTK_ENTRY(entry[1]), "g");
gtk_entry_set_text(GTK_ENTRY(entry[2]), "b");
gtk_entry_set_text(GTK_ENTRY(entry[3]), "a");
preview_enable=tmp_preview_enable;
dialog_update_preview(preview, NULL);
}
void dialog_load(GtkWidget *widget, gpointer d)
{
GtkWidget *file_select;
file_select = gtk_file_selection_new ("Load AFS file...");
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->ok_button),
"clicked", (GtkSignalFunc) file_selection_load,
(gpointer)file_select);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->cancel_button),
"clicked", (GtkSignalFunc) file_selection_cancel,
(gpointer)file_select);
gtk_widget_show(file_select);
gtk_widget_set_sensitive (dialog, FALSE);
}
void dialog_save(GtkWidget *widget, gpointer d)
{
GtkWidget *file_select;
file_select = gtk_file_selection_new ("Load AFS file...");
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->ok_button),
"clicked", (GtkSignalFunc) file_selection_save,
(gpointer)file_select);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (file_select)->cancel_button),
"clicked", (GtkSignalFunc) file_selection_cancel,
(gpointer)file_select);
gtk_widget_show(file_select);
gtk_widget_set_sensitive (dialog, FALSE);
}
void load_afs(char *s)
{
FILE *f;
char buffer[2048];
int i,c,n;
if ((f=fopen(s, "r"))==NULL)
return;
/* read header */
c=0; while ((i=fgetc(f))!='\r') { buffer[c++]=i; if (feof(f)) return; } buffer[c]=0;
/* read sliders */
for (n=0; n<8; n++) {
c=0; while ((i=fgetc(f))!='\r') { buffer[c++]=i; if (feof(f)) return; } buffer[c]=0;
GTK_ADJUSTMENT(adjustment[n])->value=atoi(buffer);
gtk_signal_emit_by_name(GTK_OBJECT(adjustment[n]),"value_changed");
}
/* read channels */
for (n=0; n<4; n++) {
c=0;
do {
i=fgetc(f);
/* one \r -> skip, two \r -> end of line */
if (i=='\r') i=fgetc(f);
if (i!='\r') buffer[c++]=i;
if (feof(f)) return;
} while (i!='\r');
buffer[c]=0;
gtk_entry_set_text(GTK_ENTRY(entry[n]), buffer);
}
}
void save_afs(char *s)
{
FILE *f;
int i;
if ((f=fopen(s, "w"))==NULL)
return;
/* write header */
fprintf(f, "%%RGB-1.0\r");
/* write sliders */
for (i=0; i<8; i++) {
if (i<NUM_SLIDERS) {
int w;
w=GTK_ADJUSTMENT(adjustment[i])->value;
fprintf(f,"%i\r", w);
} else {
fprintf(f,"0\r");
}
}
/* write channels */
for (i=0; i<4; i++) {
fprintf(f, "%s\r\r", gtk_entry_get_text(GTK_ENTRY(entry[i])));
}
fclose(f);
}
void dialog_close(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}
void dialog_cancel(GtkWidget *widget, gpointer data)
{
result=FALSE;
gtk_widget_destroy(GTK_WIDGET(data));
}
void dialog_ok(GtkWidget *widget, gpointer data)
{
result=TRUE;
gtk_widget_destroy(GTK_WIDGET(data));
}
void dialog_button_preview_update (GtkWidget *widget, gpointer data)
{
preview_enable=GTK_TOGGLE_BUTTON(widget)->active;
}
void dialog_update_preview(GtkWidget *widget, gpointer unused)
{
int i,j;
guchar buf[PREVIEW_SIZE*3];
s_envir e;
for (i=0; i<4; i++) {
function_tree[i]=get_afstree(data.form[i]);
}
e.X=e.Y=PREVIEW_SIZE;
e.Z=img_bpp;
e.M=sqrt(PREVIEW_SIZE*PREVIEW_SIZE*2)/2;
for (i = 0; i < PREVIEW_SIZE; i++) {
for (j=0; j < PREVIEW_SIZE; j++) {
e.x=j; e.y=i;
calc_envir(&e);
buf[j*3+0]=calc(&e, 0);
buf[j*3+1]=calc(&e, 1);
buf[j*3+2]=calc(&e, 2);
}
gtk_preview_draw_row (GTK_PREVIEW (preview), buf, 0, i, PREVIEW_SIZE);
}
for (i=0; i<4; i++) {
if (function_tree[i]!=NULL)
free_tree(function_tree[i]);
}
gtk_widget_draw(preview, NULL);
gdk_flush();
}
void dialog_slider_update (GtkWidget *widget, int *data)
{
*data=GTK_ADJUSTMENT(widget)->value;
if (preview_enable)
dialog_update_preview(preview, NULL);
}
void dialog_entry_update (GtkWidget *widget, char *data)
{
strcpy(data, gtk_entry_get_text(GTK_ENTRY(widget)));
}
int dialog_create()
{
GtkWidget *button;
GtkWidget *hbox, *vbox;
GtkWidget *frame;
guchar *color_cube;
char **argv;
int argc;
int i;
srandom(time(NULL));
argc = 1;
argv = g_new (char *, 1);
argv[0] = g_strdup ("video");
gtk_init (&argc, &argv);
gtk_rc_parse (gimp_gtkrc ());
gdk_set_use_xshm (gimp_use_xshm ());
gtk_preview_set_gamma (gimp_gamma ());
gtk_preview_set_install_cmap (gimp_install_cmap ());
color_cube = gimp_color_cube ();
gtk_preview_set_color_cube (color_cube[0], color_cube[1],
color_cube[2], color_cube[3]);
gtk_widget_set_default_visual (gtk_preview_get_visual ());
gtk_widget_set_default_colormap (gtk_preview_get_cmap ());
dialog=gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW(dialog), PLUG_IN_NAME);
gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
(GtkSignalFunc) dialog_close,
NULL);
hbox=gtk_hbox_new(FALSE, 5);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show(hbox);
/*
* Preview area
*/
frame=gtk_frame_new("Preview");
gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, FALSE, 0);
gtk_widget_show(frame);
vbox=gtk_vbox_new(FALSE,5);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gtk_widget_show(vbox);
button=gtk_button_new();
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) dialog_update_preview, NULL);
gtk_box_pack_start (GTK_BOX (vbox), button , FALSE, FALSE, 0);
gtk_widget_show(button);
preview=gtk_preview_new(GTK_PREVIEW_COLOR);
gtk_preview_size(GTK_PREVIEW(preview), PREVIEW_SIZE, PREVIEW_SIZE);
gtk_container_add(GTK_CONTAINER(button), preview);
gtk_widget_show (preview);
button=gtk_check_button_new_with_label("enable update");
gtk_signal_connect (GTK_OBJECT (button),
"toggled",
(GtkSignalFunc) dialog_button_preview_update,
0);
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
preview_enable=1;
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(button), preview_enable);
/*
* Slider area
*/
frame=gtk_frame_new("Values");
gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0);
gtk_widget_set_usize(frame, 256, -1);
gtk_widget_show(frame);
vbox=gtk_vbox_new(FALSE,5);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gtk_widget_show(vbox);
for (i=0; i<NUM_SLIDERS; i++) {
GtkWidget *scale;
adjustment[i]=gtk_adjustment_new (data.control[i], 0.0, 255.0, 1.0, 1.0, 0.0);
gtk_signal_connect(GTK_OBJECT(adjustment[i]),
"value_changed",
(GtkSignalFunc)dialog_slider_update ,
(gpointer)&(data.control[i]));
scale = gtk_hscale_new (GTK_ADJUSTMENT (adjustment[i]));
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
gtk_scale_set_draw_value(GTK_SCALE(scale), TRUE);
gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 0);
gtk_widget_show(scale);
}
/* #ifndef COMPACT_MODE */
/* entry area for formula */
for (i=0; i<4; i++) {
entry[i]=gtk_entry_new();
gtk_signal_connect(GTK_OBJECT(entry[i]),
"changed",
(GtkSignalFunc)dialog_entry_update ,
(gpointer)(data.form[i]));
gtk_entry_set_text(GTK_ENTRY(entry[i]), data.form[i]);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), entry[i], FALSE, FALSE, 0);
gtk_widget_show(entry[i]);
}
hbox=gtk_hbox_new(FALSE, 5);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show(hbox);
button = gtk_button_new_with_label ("Reset");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) dialog_reset, (gpointer) dialog);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
button = gtk_button_new_with_label ("Load...");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) dialog_load, (gpointer) dialog);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
button = gtk_button_new_with_label ("Save ...");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) dialog_save, (gpointer) dialog);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
/* #endif */
button = gtk_button_new_with_label ("OK");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) dialog_ok, (gpointer) dialog);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
button = gtk_button_new_with_label ("Cancel");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) dialog_cancel, (gpointer) dialog);
gtk_box_pack_end (GTK_BOX (GTK_DIALOG(dialog)->action_area), button, TRUE, TRUE, 0);
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_widget_grab_default (button);
gtk_widget_show (button);
gtk_widget_show(dialog);
dialog_update_preview(preview, NULL);
result=0;
gtk_main();
gdk_flush();
return result;
}