new, improved, still buggy iscissors! correctly hide the file selector a

* app/iscissors.c: new, improved, still buggy iscissors!
* app/fileops.c: correctly hide the file selector
* app/transform_core.c: a better fix for the display artifacts
* added aa plugin back in

-Yosh
This commit is contained in:
Manish Singh 1998-03-15 02:46:15 +00:00
parent 568c015b53
commit 9610c8c901
16 changed files with 926 additions and 48 deletions

View File

@ -1,3 +1,13 @@
Sat Mar 14 18:38:26 PST 1998 Manish Singh <yosh@gimp.org>
* app/iscissors.c: new, improved, still buggy iscissors!
* app/fileops.c: correctly hide the file selector
* app/transform_core.c: a better fix for the display artifacts
* added aa plugin back in
Sat Mar 14 20:52:06 EST 1998 Adrian Likins <adrian@gimp.org>
* doc/gimp.1

View File

@ -95,6 +95,7 @@ static char *scroll_text[] =
"Ian Tester",
"James Wang",
"Kris Wehner",
"Matthew Wilson",
};
static int nscroll_texts = sizeof (scroll_text) / sizeof (scroll_text[0]);
static int scroll_text_widths[100] = { 0 };

View File

@ -95,6 +95,7 @@ static char *scroll_text[] =
"Ian Tester",
"James Wang",
"Kris Wehner",
"Matthew Wilson",
};
static int nscroll_texts = sizeof (scroll_text) / sizeof (scroll_text[0]);
static int scroll_text_widths[100] = { 0 };

View File

@ -70,7 +70,7 @@ static void file_save_ok_callback (GtkWidget *w,
gpointer client_data);
static void file_dialog_show (GtkWidget *filesel);
static void file_dialog_hide (GtkWidget *filesel);
static int file_dialog_hide (GtkWidget *filesel);
static void file_update_name (PlugInProcDef *proc,
GtkWidget *filesel);
static void file_load_type_callback (GtkWidget *w,
@ -474,13 +474,14 @@ file_open_callback (GtkWidget *w,
gtk_window_set_wmclass (GTK_WINDOW (fileload), "load_image", "Gimp");
gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (fileload)->cancel_button),
"clicked",
GTK_SIGNAL_FUNC (gtk_widget_hide),
GTK_SIGNAL_FUNC (file_dialog_hide),
GTK_OBJECT (fileload));
gtk_signal_connect (GTK_OBJECT (fileload),
"delete_event",
GTK_SIGNAL_FUNC (gtk_widget_hide_on_delete),
GTK_SIGNAL_FUNC (file_dialog_hide),
NULL);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileload)->ok_button), "clicked", (GtkSignalFunc) file_open_ok_callback, fileload);
gtk_quit_add (1, (GtkFunction) gtk_widget_destroy, fileload);
}
else
{
@ -563,13 +564,14 @@ file_save_as_callback (GtkWidget *w,
gtk_window_position (GTK_WINDOW (filesave), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesave)->cancel_button),
"clicked",
GTK_SIGNAL_FUNC (gtk_widget_hide),
GTK_SIGNAL_FUNC (file_dialog_hide),
GTK_OBJECT (filesave));
gtk_signal_connect (GTK_OBJECT (filesave),
"delete_event",
GTK_SIGNAL_FUNC (gtk_widget_hide_on_delete),
GTK_SIGNAL_FUNC (file_dialog_hide),
NULL);
gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filesave)->ok_button), "clicked", (GtkSignalFunc) file_save_ok_callback, filesave);
gtk_quit_add (1, (GtkFunction) gtk_widget_destroy, filesave);
}
else
{
@ -914,7 +916,7 @@ file_dialog_show (GtkWidget *filesel)
gtk_widget_show (filesel);
}
static void
static int
file_dialog_hide (GtkWidget *filesel)
{
gtk_widget_hide (filesel);
@ -923,6 +925,8 @@ file_dialog_hide (GtkWidget *filesel)
menus_set_sensitive ("<Image>/File/Open", TRUE);
menus_set_sensitive ("<Image>/File/Save", TRUE);
menus_set_sensitive ("<Image>/File/Save as", TRUE);
return TRUE;
}
static void

View File

@ -95,6 +95,7 @@ static char *scroll_text[] =
"Ian Tester",
"James Wang",
"Kris Wehner",
"Matthew Wilson",
};
static int nscroll_texts = sizeof (scroll_text) / sizeof (scroll_text[0]);
static int scroll_text_widths[100] = { 0 };

View File

@ -502,6 +502,7 @@ iscissors_button_press (Tool *tool,
&iscissors->x, &iscissors->y, FALSE, TRUE);
/* If the tool was being used in another image...reset it */
if (tool->state == ACTIVE && gdisp_ptr != tool->gdisp_ptr)
{
draw_core_stop (iscissors->core, tool);
@ -544,8 +545,8 @@ iscissors_button_press (Tool *tool,
drawable_height(drawable));
iscissors->num_segs = 0;
x = bevent->x;
y = bevent->y;
x = iscissors->x;
y = iscissors->y;
add_segment (&(iscissors->num_segs), x, y);
@ -671,12 +672,17 @@ iscissors_motion (Tool *tool,
gdisp = (GDisplay *) gdisp_ptr;
iscissors = (Iscissors *) tool->private;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&iscissors->x, &iscissors->y, FALSE, TRUE);
switch (iscissors->state)
{
case FREE_SELECT_MODE:
x = mevent->x;
y = mevent->y;
if (add_segment (&(iscissors->num_segs), x, y))
gdk_draw_segments (iscissors->core->win, iscissors->core->gc,
segs + (iscissors->num_segs - 1), 1);
break;
@ -735,6 +741,7 @@ iscissors_draw_CR (GDisplay *gdisp,
double d, d2, d3;
int lastx, lasty;
int newx, newy;
int tx, ty;
int index;
int i;
@ -754,10 +761,16 @@ iscissors_draw_CR (GDisplay *gdisp,
geometry[i][1] = pts[indices[i]].dy * SUPERSAMPLE;
break;
case SCREEN_COORDS:
/*gdisplay_transform_coords_f (gdisp, , &x, &y, TRUE);*/
gdisplay_untransform_coords_f (gdisp, (int) pts[indices[i]].dx, (int) pts[indices[i]].dy,
/* gdisplay_transform_coords_f (gdisp, , &x, &y, TRUE);
gdisplay_transform_coords (gdisp, points->x, points->y,
&points->sx, &points->sy, 0);
*/
/*
gdisplay_untransform_coords_f (gdisp, (int) pts[indices[i]].dx, (int) pts[indices[i]].dy,
&x, &y, TRUE);
*/
geometry[i][0] = x;
geometry[i][1] = y;
/*g_print("%f %f\n", x, y);*/
@ -826,10 +839,13 @@ iscissors_draw_CR (GDisplay *gdisp,
if ((lastx != newx) || (lasty != newy))
{
/* add the point to the point buffer */
gdk_points[index].x = newx;
gdk_points[index].y = newy;
index++;
gdisplay_transform_coords (gdisp, newx, newy, &tx, &ty,1 );
gdk_points[index].x = tx;
gdk_points[index].y = ty;
index++;
/* if the point buffer is full put it to the screen and zero it out */
if (index >= npoints)
{
@ -1275,7 +1291,7 @@ shape_of_boundary (Tool *tool)
double weight;
int left, right;
int i, j;
/* int x, y; */
int x, y;
/* This function determines the kinkiness at each point in the
* original free-hand curve by finding the dotproduct between
@ -1383,9 +1399,7 @@ process_kinks (Tool *tool)
for (i = 0; i < iscissors->num_kinks; i++)
{
/* transform from screen to image coordinates */
gdisplay_untransform_coords (gdisp, kinks[i].x, kinks[i].y,
&x, &y, FALSE, TRUE);
/*FIXME*/
kinks[i].x = BOUNDS (kinks[i].x, 0, (drawable_width(drawable) - 1));
kinks[i].y = BOUNDS (kinks[i].y, 0, (drawable_height(drawable) - 1));

View File

@ -502,6 +502,7 @@ iscissors_button_press (Tool *tool,
&iscissors->x, &iscissors->y, FALSE, TRUE);
/* If the tool was being used in another image...reset it */
if (tool->state == ACTIVE && gdisp_ptr != tool->gdisp_ptr)
{
draw_core_stop (iscissors->core, tool);
@ -544,8 +545,8 @@ iscissors_button_press (Tool *tool,
drawable_height(drawable));
iscissors->num_segs = 0;
x = bevent->x;
y = bevent->y;
x = iscissors->x;
y = iscissors->y;
add_segment (&(iscissors->num_segs), x, y);
@ -671,12 +672,17 @@ iscissors_motion (Tool *tool,
gdisp = (GDisplay *) gdisp_ptr;
iscissors = (Iscissors *) tool->private;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&iscissors->x, &iscissors->y, FALSE, TRUE);
switch (iscissors->state)
{
case FREE_SELECT_MODE:
x = mevent->x;
y = mevent->y;
if (add_segment (&(iscissors->num_segs), x, y))
gdk_draw_segments (iscissors->core->win, iscissors->core->gc,
segs + (iscissors->num_segs - 1), 1);
break;
@ -735,6 +741,7 @@ iscissors_draw_CR (GDisplay *gdisp,
double d, d2, d3;
int lastx, lasty;
int newx, newy;
int tx, ty;
int index;
int i;
@ -754,10 +761,16 @@ iscissors_draw_CR (GDisplay *gdisp,
geometry[i][1] = pts[indices[i]].dy * SUPERSAMPLE;
break;
case SCREEN_COORDS:
/*gdisplay_transform_coords_f (gdisp, , &x, &y, TRUE);*/
gdisplay_untransform_coords_f (gdisp, (int) pts[indices[i]].dx, (int) pts[indices[i]].dy,
/* gdisplay_transform_coords_f (gdisp, , &x, &y, TRUE);
gdisplay_transform_coords (gdisp, points->x, points->y,
&points->sx, &points->sy, 0);
*/
/*
gdisplay_untransform_coords_f (gdisp, (int) pts[indices[i]].dx, (int) pts[indices[i]].dy,
&x, &y, TRUE);
*/
geometry[i][0] = x;
geometry[i][1] = y;
/*g_print("%f %f\n", x, y);*/
@ -826,10 +839,13 @@ iscissors_draw_CR (GDisplay *gdisp,
if ((lastx != newx) || (lasty != newy))
{
/* add the point to the point buffer */
gdk_points[index].x = newx;
gdk_points[index].y = newy;
index++;
gdisplay_transform_coords (gdisp, newx, newy, &tx, &ty,1 );
gdk_points[index].x = tx;
gdk_points[index].y = ty;
index++;
/* if the point buffer is full put it to the screen and zero it out */
if (index >= npoints)
{
@ -1275,7 +1291,7 @@ shape_of_boundary (Tool *tool)
double weight;
int left, right;
int i, j;
/* int x, y; */
int x, y;
/* This function determines the kinkiness at each point in the
* original free-hand curve by finding the dotproduct between
@ -1383,9 +1399,7 @@ process_kinks (Tool *tool)
for (i = 0; i < iscissors->num_kinks; i++)
{
/* transform from screen to image coordinates */
gdisplay_untransform_coords (gdisp, kinks[i].x, kinks[i].y,
&x, &y, FALSE, TRUE);
/*FIXME*/
kinks[i].x = BOUNDS (kinks[i].x, 0, (drawable_width(drawable) - 1));
kinks[i].y = BOUNDS (kinks[i].y, 0, (drawable_height(drawable) - 1));

View File

@ -502,6 +502,7 @@ iscissors_button_press (Tool *tool,
&iscissors->x, &iscissors->y, FALSE, TRUE);
/* If the tool was being used in another image...reset it */
if (tool->state == ACTIVE && gdisp_ptr != tool->gdisp_ptr)
{
draw_core_stop (iscissors->core, tool);
@ -544,8 +545,8 @@ iscissors_button_press (Tool *tool,
drawable_height(drawable));
iscissors->num_segs = 0;
x = bevent->x;
y = bevent->y;
x = iscissors->x;
y = iscissors->y;
add_segment (&(iscissors->num_segs), x, y);
@ -671,12 +672,17 @@ iscissors_motion (Tool *tool,
gdisp = (GDisplay *) gdisp_ptr;
iscissors = (Iscissors *) tool->private;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
&iscissors->x, &iscissors->y, FALSE, TRUE);
switch (iscissors->state)
{
case FREE_SELECT_MODE:
x = mevent->x;
y = mevent->y;
if (add_segment (&(iscissors->num_segs), x, y))
gdk_draw_segments (iscissors->core->win, iscissors->core->gc,
segs + (iscissors->num_segs - 1), 1);
break;
@ -735,6 +741,7 @@ iscissors_draw_CR (GDisplay *gdisp,
double d, d2, d3;
int lastx, lasty;
int newx, newy;
int tx, ty;
int index;
int i;
@ -754,10 +761,16 @@ iscissors_draw_CR (GDisplay *gdisp,
geometry[i][1] = pts[indices[i]].dy * SUPERSAMPLE;
break;
case SCREEN_COORDS:
/*gdisplay_transform_coords_f (gdisp, , &x, &y, TRUE);*/
gdisplay_untransform_coords_f (gdisp, (int) pts[indices[i]].dx, (int) pts[indices[i]].dy,
/* gdisplay_transform_coords_f (gdisp, , &x, &y, TRUE);
gdisplay_transform_coords (gdisp, points->x, points->y,
&points->sx, &points->sy, 0);
*/
/*
gdisplay_untransform_coords_f (gdisp, (int) pts[indices[i]].dx, (int) pts[indices[i]].dy,
&x, &y, TRUE);
*/
geometry[i][0] = x;
geometry[i][1] = y;
/*g_print("%f %f\n", x, y);*/
@ -826,10 +839,13 @@ iscissors_draw_CR (GDisplay *gdisp,
if ((lastx != newx) || (lasty != newy))
{
/* add the point to the point buffer */
gdk_points[index].x = newx;
gdk_points[index].y = newy;
index++;
gdisplay_transform_coords (gdisp, newx, newy, &tx, &ty,1 );
gdk_points[index].x = tx;
gdk_points[index].y = ty;
index++;
/* if the point buffer is full put it to the screen and zero it out */
if (index >= npoints)
{
@ -1275,7 +1291,7 @@ shape_of_boundary (Tool *tool)
double weight;
int left, right;
int i, j;
/* int x, y; */
int x, y;
/* This function determines the kinkiness at each point in the
* original free-hand curve by finding the dotproduct between
@ -1383,9 +1399,7 @@ process_kinks (Tool *tool)
for (i = 0; i < iscissors->num_kinks; i++)
{
/* transform from screen to image coordinates */
gdisplay_untransform_coords (gdisp, kinks[i].x, kinks[i].y,
&x, &y, FALSE, TRUE);
/*FIXME*/
kinks[i].x = BOUNDS (kinks[i].x, 0, (drawable_width(drawable) - 1));
kinks[i].y = BOUNDS (kinks[i].y, 0, (drawable_height(drawable) - 1));

View File

@ -205,7 +205,7 @@ transform_core_button_release (tool, bevent, gdisp_ptr)
TransformUndo *tu;
int first_transform;
int new_layer;
int i;
int i, x, y;
gdisp = (GDisplay *) gdisp_ptr;
transform_core = (TransformCore *) tool->private;
@ -267,9 +267,24 @@ transform_core_button_release (tool, bevent, gdisp_ptr)
undo_push_group_end (gdisp->gimage);
/* Flush the gdisplays */
/* FIXME: this expose is a performance drag, but it prevents display
artifacts */
gdisplay_expose_area (gdisp, 0, 0, gdisp->disp_width, gdisp->disp_height);
if (gdisp->disp_xoffset || gdisp->disp_yoffset)
{
gdk_window_get_size (gdisp->canvas->window, &x, &y);
if (gdisp->disp_yoffset)
{
gdisplay_expose_area (gdisp, 0, 0, gdisp->disp_width,
gdisp->disp_yoffset);
gdisplay_expose_area (gdisp, 0, gdisp->disp_yoffset + y,
gdisp->disp_width, gdisp->disp_height);
}
if (gdisp->disp_xoffset)
{
gdisplay_expose_area (gdisp, 0, 0, gdisp->disp_xoffset,
gdisp->disp_height);
gdisplay_expose_area (gdisp, gdisp->disp_xoffset + x, 0,
gdisp->disp_width, gdisp->disp_height);
}
}
gdisplays_flush ();
}
else

View File

@ -205,7 +205,7 @@ transform_core_button_release (tool, bevent, gdisp_ptr)
TransformUndo *tu;
int first_transform;
int new_layer;
int i;
int i, x, y;
gdisp = (GDisplay *) gdisp_ptr;
transform_core = (TransformCore *) tool->private;
@ -267,9 +267,24 @@ transform_core_button_release (tool, bevent, gdisp_ptr)
undo_push_group_end (gdisp->gimage);
/* Flush the gdisplays */
/* FIXME: this expose is a performance drag, but it prevents display
artifacts */
gdisplay_expose_area (gdisp, 0, 0, gdisp->disp_width, gdisp->disp_height);
if (gdisp->disp_xoffset || gdisp->disp_yoffset)
{
gdk_window_get_size (gdisp->canvas->window, &x, &y);
if (gdisp->disp_yoffset)
{
gdisplay_expose_area (gdisp, 0, 0, gdisp->disp_width,
gdisp->disp_yoffset);
gdisplay_expose_area (gdisp, 0, gdisp->disp_yoffset + y,
gdisp->disp_width, gdisp->disp_height);
}
if (gdisp->disp_xoffset)
{
gdisplay_expose_area (gdisp, 0, 0, gdisp->disp_xoffset,
gdisp->disp_height);
gdisplay_expose_area (gdisp, gdisp->disp_xoffset + x, 0,
gdisp->disp_width, gdisp->disp_height);
}
}
gdisplays_flush ();
}
else

View File

@ -42,7 +42,7 @@ fi)
AC_DEFUN(AC_GIMP_CHECK,
[
AM_PATH_GTK(0.99.5,,
AM_PATH_GTK(0.99.6,,
AC_MSG_ERROR(Cannot include/link gtk/gdk/glib--check CFLAGS/LDFLAGS))
X_LIBS=$GTK_LIBS
X_CFLAGS=$GTK_CFLAGS
@ -99,6 +99,13 @@ dnl Test for Xmu
AC_MSG_WARN(*** webbrowser plug-in will not be built ***), -lXt), -lXt, -lSM, -lICE)
fi
dnl Test for libaa
if test -z "$LIBAA_LIB"; then
AC_CHECK_LIB(aa, aa_printf,
AA='aa'; LIBAA_LIB='-laa',
AC_MSG_WARN(*** AA plug-in will not be built ***))
fi
dnl Test for libtiff
if test -z "$LIBTIFF_LIB"; then
AC_CHECK_LIB(tiff, TIFFReadScanline,
@ -242,6 +249,8 @@ AC_SUBST(JPEG)
AC_SUBST(LIBJPEG_LIB)
AC_SUBST(PNG)
AC_SUBST(LIBPNG_LIB)
AC_SUBST(AA)
AC_SUBST(LIBAA_LIB)
AC_SUBST(MPEG)
AC_SUBST(LIBMPEG_LIB)
AC_SUBST(XD)
@ -315,6 +324,7 @@ plug-ins/script-fu/Makefile
plug-ins/script-fu/scripts/Makefile
plug-ins/jpeg/Makefile
plug-ins/mpeg/Makefile
plug-ins/aa/Makefile
plug-ins/png/Makefile
plug-ins/tiff/Makefile
plug-ins/xd/Makefile

View File

@ -7,6 +7,7 @@ SUBDIRS = \
script-fu \
struc \
@WEBBROWSER@ \
@AA@ \
@TIFF@ \
@JPEG@ \
@PNG@ \

6
plug-ins/aa/.cvsignore Normal file
View File

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

38
plug-ins/aa/Makefile.am Normal file
View File

@ -0,0 +1,38 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
pluginlib_PROGRAMS = aa
aa_SOURCES = aa.c
INCLUDES = \
$(X_CFLAGS) \
-I$(top_srcdir) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(X_LIBS) \
@LIBAA_LIB@
-lc
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
aa_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

367
plug-ins/aa/aa.c Normal file
View File

@ -0,0 +1,367 @@
/**
* aa.c version 1.0
* A plugin that uses libaa (ftp://ftp.ta.jcu.cz/pub/aa) to save images as
* ASCII.
* NOTE: This plugin *requires* aalib 1.2 or later. Earlier versions will
* not work.
* Code copied from all over the GIMP source.
* Tim Newsome <nuisance@cmu.edu>
*/
#include <aalib.h>
#include <string.h>
#include <libgimp/gimp.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
/*
* Declare some local functions.
*/
static void query(void);
static void run(char *name, int nparams, GParam * param, int *nreturn_vals,
GParam ** return_vals);
static gint aa_savable(gint32 drawable_ID);
static gint save_aa(int output_type, char *filename, gint32 image,
gint32 drawable);
static gint gimp2aa(gint32 image, gint32 drawable_ID, aa_context * context);
static gint type_dialog(int selected);
static void type_dialog_close_callback(GtkWidget *widget, gpointer data);
static void type_dialog_ok_callback (GtkWidget *widget, gpointer data);
static void type_dialog_toggle_update (GtkWidget *widget, gpointer data);
static void type_dialog_cancel_callback (GtkWidget *widget, gpointer data);
/*
* Some global variables.
*/
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
/**
* Type the user selected. (Global for easier UI coding.
*/
static int selected_type = 0;
MAIN()
/**
* Called by the GIMP to figure out what this plugin does.
*/
static void query()
{
static GParamDef save_args[] =
{
{PARAM_INT32, "run_mode", "Interactive, non-interactive"},
{PARAM_IMAGE, "image", "Input image"},
{PARAM_DRAWABLE, "drawable", "Drawable to save"},
{PARAM_STRING, "filename", "The name of the file to save the image in"},
{PARAM_STRING, "raw_filename", "The name entered"},
{PARAM_STRING, "file_type", "File type to use"}
};
static int nsave_args = sizeof(save_args) / sizeof(save_args[0]);
gimp_install_procedure("file_aa_save",
"Saves files in various text formats",
"Saves files in various text formats",
"Tim Newsome <nuisance@cmu.edu>",
"Tim Newsome <nuisance@cmu.edu>",
"1997",
"<Save>/AA",
"GRAY*", /* support grayscales */
PROC_PLUG_IN,
nsave_args, 0,
save_args, NULL);
gimp_register_save_handler("file_aa_save", "ansi,txt,text,html", "");
}
/**
* Searches aa_formats defined by aalib to find the index of the type
* specified by string.
* -1 means it wasn't found.
*/
static int get_type_from_string(char *string)
{
int type = 0;
aa_format **p = aa_formats;
while (*p && strcmp((*p)->formatname, string)) {
p++;
type++;
}
if (*p == NULL)
return -1;
return type;
}
/**
* Called by the GIMP to run the actual plugin.
*/
static void run(char *name, int nparams, GParam * param, int *nreturn_vals,
GParam ** return_vals)
{
static GParam values[2];
GStatusType status = STATUS_SUCCESS;
GRunModeType run_mode;
int output_type = 0;
static int last_type = 0;
/* Set us up to return a status. */
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = STATUS_CALLING_ERROR;
if (!aa_savable(param[2].data.d_int32)) {
values[0].data.d_status = STATUS_CALLING_ERROR;
return;
}
run_mode = param[0].data.d_int32;
switch (run_mode) {
case RUN_INTERACTIVE:
gimp_get_data("file_aa_save", &last_type);
output_type = type_dialog(last_type);
break;
case RUN_NONINTERACTIVE:
/* Make sure all the arguments are there! */
if (nparams != 6)
status = STATUS_CALLING_ERROR;
else
output_type = get_type_from_string(param[5].data.d_string);
break;
case RUN_WITH_LAST_VALS:
gimp_get_data("file_aa_save", &last_type);
output_type = last_type;
break;
default:
break;
}
if (output_type < 0) {
status = STATUS_CALLING_ERROR;
return;
}
if (save_aa(output_type, param[3].data.d_string, param[1].data.d_int32,
param[2].data.d_int32))
values[0].data.d_status = STATUS_EXECUTION_ERROR;
else
values[0].data.d_status = STATUS_SUCCESS;
last_type = output_type;
gimp_set_data("file_aa_save", &last_type, sizeof(last_type));
}
/**
* The actual save function. What it's all about.
* The image type has to be GRAY.
*/
static gint save_aa(int output_type, char *filename, gint32 image,
gint32 drawable_ID)
{
aa_savedata savedata =
{NULL, NULL};
aa_context *context = NULL;
aa_format format;
GDrawable *drawable = NULL;
/*fprintf(stderr, "save %s\n", filename); */
drawable = gimp_drawable_get(drawable_ID);
memcpy(&format, aa_formats[output_type], sizeof(format));
format.width = drawable->width / 2;
format.height = drawable->height / 2;
/*fprintf(stderr, "save_aa %i x %i\n", format.width, format.height); */
/* Get a libaa context which will save its output to filename. */
savedata.name = filename;
savedata.format = &format;
context = aa_init(&save_d, &aa_defparams, &savedata);
if (context == NULL)
return 1;
gimp2aa(image, drawable_ID, context);
aa_flush(context);
aa_close(context);
/*fprintf(stderr, "Success!\n"); */
return 0;
}
static gint gimp2aa(gint32 image, gint32 drawable_ID, aa_context * context)
{
int width, height, x, y;
guchar *buffer;
GDrawable *drawable = NULL;
GPixelRgn pixel_rgn;
aa_renderparams *renderparams = NULL;
int bpp;
width = aa_imgwidth(context);
height = aa_imgheight(context);
/*fprintf(stderr, "gimp2aa %i x %i\n", width, height); */
drawable = gimp_drawable_get(drawable_ID);
bpp = drawable->bpp;
buffer = g_new(guchar, width * bpp);
if (buffer == NULL)
return 1;
gimp_pixel_rgn_init(&pixel_rgn, drawable, 0, 0, drawable->width,
drawable->height, FALSE, FALSE);
for (y = 0; y < height; y++) {
gimp_pixel_rgn_get_row(&pixel_rgn, buffer, 0, y, width);
for (x = 0; x < width; x++) {
/* Just copy one byte. If it's indexed that's all we need. Otherwise
* it'll be the most significant one. */
aa_putpixel(context, x, y, buffer[x * bpp]);
}
}
renderparams = aa_getrenderparams();
renderparams->dither = AA_FLOYD_S;
aa_render(context, renderparams, 0, 0, aa_scrwidth(context),
aa_scrheight(context));
return 0;
}
static gint aa_savable(gint32 drawable_ID)
{
GDrawableType drawable_type;
drawable_type = gimp_drawable_type(drawable_ID);
if (drawable_type != GRAY_IMAGE && drawable_type != GRAYA_IMAGE)
return 0;
return 1;
}
/*
* User Interface dialog thingie.
*/
static gint type_dialog(int selected) {
GtkWidget *dlg;
GtkWidget *button;
GtkWidget *toggle;
GtkWidget *frame;
GtkWidget *toggle_vbox;
GSList *group;
gchar **argv;
gint argc;
argc = 1;
argv = g_new(gchar *, 1);
argv[0] = g_strdup("save");
gtk_init(&argc, &argv);
gtk_rc_parse(gimp_gtkrc());
/* Create the actual window. */
dlg = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dlg), "Save as text");
gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
(GtkSignalFunc) type_dialog_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) type_dialog_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) type_dialog_cancel_callback,
GTK_OBJECT(dlg));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area), button,
TRUE, TRUE, 0);
gtk_widget_show(button);
/* file save type */
frame = gtk_frame_new("Data Formatting");
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, FALSE, TRUE, 0);
toggle_vbox = gtk_vbox_new(FALSE, 5);
gtk_container_border_width(GTK_CONTAINER(toggle_vbox), 5);
gtk_container_add(GTK_CONTAINER(frame), toggle_vbox);
group = NULL;
{
aa_format **p = aa_formats;
int current = 0;
while (*p != NULL) {
toggle = gtk_radio_button_new_with_label(group, (*p)->formatname);
group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle));
gtk_box_pack_start (GTK_BOX (toggle_vbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
(GtkSignalFunc) type_dialog_toggle_update,
(*p)->formatname);
if (current == selected)
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), 1);
else
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), 0);
gtk_widget_show(toggle);
p++;
current++;
}
}
gtk_widget_show(toggle_vbox);
gtk_widget_show(frame);
gtk_widget_show(dlg);
gtk_main();
gdk_flush();
return selected_type;
}
/*
* Callbacks for the dialog.
*/
static void type_dialog_close_callback(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
static void type_dialog_ok_callback (GtkWidget *widget, gpointer data) {
gtk_widget_destroy (GTK_WIDGET (data));
}
static void type_dialog_cancel_callback (GtkWidget *widget, gpointer data) {
selected_type = -1;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void type_dialog_toggle_update (GtkWidget *widget, gpointer data) {
selected_type = get_type_from_string((char *)data);
}

367
plug-ins/common/aa.c Normal file
View File

@ -0,0 +1,367 @@
/**
* aa.c version 1.0
* A plugin that uses libaa (ftp://ftp.ta.jcu.cz/pub/aa) to save images as
* ASCII.
* NOTE: This plugin *requires* aalib 1.2 or later. Earlier versions will
* not work.
* Code copied from all over the GIMP source.
* Tim Newsome <nuisance@cmu.edu>
*/
#include <aalib.h>
#include <string.h>
#include <libgimp/gimp.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
/*
* Declare some local functions.
*/
static void query(void);
static void run(char *name, int nparams, GParam * param, int *nreturn_vals,
GParam ** return_vals);
static gint aa_savable(gint32 drawable_ID);
static gint save_aa(int output_type, char *filename, gint32 image,
gint32 drawable);
static gint gimp2aa(gint32 image, gint32 drawable_ID, aa_context * context);
static gint type_dialog(int selected);
static void type_dialog_close_callback(GtkWidget *widget, gpointer data);
static void type_dialog_ok_callback (GtkWidget *widget, gpointer data);
static void type_dialog_toggle_update (GtkWidget *widget, gpointer data);
static void type_dialog_cancel_callback (GtkWidget *widget, gpointer data);
/*
* Some global variables.
*/
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
/**
* Type the user selected. (Global for easier UI coding.
*/
static int selected_type = 0;
MAIN()
/**
* Called by the GIMP to figure out what this plugin does.
*/
static void query()
{
static GParamDef save_args[] =
{
{PARAM_INT32, "run_mode", "Interactive, non-interactive"},
{PARAM_IMAGE, "image", "Input image"},
{PARAM_DRAWABLE, "drawable", "Drawable to save"},
{PARAM_STRING, "filename", "The name of the file to save the image in"},
{PARAM_STRING, "raw_filename", "The name entered"},
{PARAM_STRING, "file_type", "File type to use"}
};
static int nsave_args = sizeof(save_args) / sizeof(save_args[0]);
gimp_install_procedure("file_aa_save",
"Saves files in various text formats",
"Saves files in various text formats",
"Tim Newsome <nuisance@cmu.edu>",
"Tim Newsome <nuisance@cmu.edu>",
"1997",
"<Save>/AA",
"GRAY*", /* support grayscales */
PROC_PLUG_IN,
nsave_args, 0,
save_args, NULL);
gimp_register_save_handler("file_aa_save", "ansi,txt,text,html", "");
}
/**
* Searches aa_formats defined by aalib to find the index of the type
* specified by string.
* -1 means it wasn't found.
*/
static int get_type_from_string(char *string)
{
int type = 0;
aa_format **p = aa_formats;
while (*p && strcmp((*p)->formatname, string)) {
p++;
type++;
}
if (*p == NULL)
return -1;
return type;
}
/**
* Called by the GIMP to run the actual plugin.
*/
static void run(char *name, int nparams, GParam * param, int *nreturn_vals,
GParam ** return_vals)
{
static GParam values[2];
GStatusType status = STATUS_SUCCESS;
GRunModeType run_mode;
int output_type = 0;
static int last_type = 0;
/* Set us up to return a status. */
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
values[0].data.d_status = STATUS_CALLING_ERROR;
if (!aa_savable(param[2].data.d_int32)) {
values[0].data.d_status = STATUS_CALLING_ERROR;
return;
}
run_mode = param[0].data.d_int32;
switch (run_mode) {
case RUN_INTERACTIVE:
gimp_get_data("file_aa_save", &last_type);
output_type = type_dialog(last_type);
break;
case RUN_NONINTERACTIVE:
/* Make sure all the arguments are there! */
if (nparams != 6)
status = STATUS_CALLING_ERROR;
else
output_type = get_type_from_string(param[5].data.d_string);
break;
case RUN_WITH_LAST_VALS:
gimp_get_data("file_aa_save", &last_type);
output_type = last_type;
break;
default:
break;
}
if (output_type < 0) {
status = STATUS_CALLING_ERROR;
return;
}
if (save_aa(output_type, param[3].data.d_string, param[1].data.d_int32,
param[2].data.d_int32))
values[0].data.d_status = STATUS_EXECUTION_ERROR;
else
values[0].data.d_status = STATUS_SUCCESS;
last_type = output_type;
gimp_set_data("file_aa_save", &last_type, sizeof(last_type));
}
/**
* The actual save function. What it's all about.
* The image type has to be GRAY.
*/
static gint save_aa(int output_type, char *filename, gint32 image,
gint32 drawable_ID)
{
aa_savedata savedata =
{NULL, NULL};
aa_context *context = NULL;
aa_format format;
GDrawable *drawable = NULL;
/*fprintf(stderr, "save %s\n", filename); */
drawable = gimp_drawable_get(drawable_ID);
memcpy(&format, aa_formats[output_type], sizeof(format));
format.width = drawable->width / 2;
format.height = drawable->height / 2;
/*fprintf(stderr, "save_aa %i x %i\n", format.width, format.height); */
/* Get a libaa context which will save its output to filename. */
savedata.name = filename;
savedata.format = &format;
context = aa_init(&save_d, &aa_defparams, &savedata);
if (context == NULL)
return 1;
gimp2aa(image, drawable_ID, context);
aa_flush(context);
aa_close(context);
/*fprintf(stderr, "Success!\n"); */
return 0;
}
static gint gimp2aa(gint32 image, gint32 drawable_ID, aa_context * context)
{
int width, height, x, y;
guchar *buffer;
GDrawable *drawable = NULL;
GPixelRgn pixel_rgn;
aa_renderparams *renderparams = NULL;
int bpp;
width = aa_imgwidth(context);
height = aa_imgheight(context);
/*fprintf(stderr, "gimp2aa %i x %i\n", width, height); */
drawable = gimp_drawable_get(drawable_ID);
bpp = drawable->bpp;
buffer = g_new(guchar, width * bpp);
if (buffer == NULL)
return 1;
gimp_pixel_rgn_init(&pixel_rgn, drawable, 0, 0, drawable->width,
drawable->height, FALSE, FALSE);
for (y = 0; y < height; y++) {
gimp_pixel_rgn_get_row(&pixel_rgn, buffer, 0, y, width);
for (x = 0; x < width; x++) {
/* Just copy one byte. If it's indexed that's all we need. Otherwise
* it'll be the most significant one. */
aa_putpixel(context, x, y, buffer[x * bpp]);
}
}
renderparams = aa_getrenderparams();
renderparams->dither = AA_FLOYD_S;
aa_render(context, renderparams, 0, 0, aa_scrwidth(context),
aa_scrheight(context));
return 0;
}
static gint aa_savable(gint32 drawable_ID)
{
GDrawableType drawable_type;
drawable_type = gimp_drawable_type(drawable_ID);
if (drawable_type != GRAY_IMAGE && drawable_type != GRAYA_IMAGE)
return 0;
return 1;
}
/*
* User Interface dialog thingie.
*/
static gint type_dialog(int selected) {
GtkWidget *dlg;
GtkWidget *button;
GtkWidget *toggle;
GtkWidget *frame;
GtkWidget *toggle_vbox;
GSList *group;
gchar **argv;
gint argc;
argc = 1;
argv = g_new(gchar *, 1);
argv[0] = g_strdup("save");
gtk_init(&argc, &argv);
gtk_rc_parse(gimp_gtkrc());
/* Create the actual window. */
dlg = gtk_dialog_new();
gtk_window_set_title(GTK_WINDOW(dlg), "Save as text");
gtk_window_position(GTK_WINDOW(dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect(GTK_OBJECT(dlg), "destroy",
(GtkSignalFunc) type_dialog_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) type_dialog_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) type_dialog_cancel_callback,
GTK_OBJECT(dlg));
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->action_area), button,
TRUE, TRUE, 0);
gtk_widget_show(button);
/* file save type */
frame = gtk_frame_new("Data Formatting");
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, FALSE, TRUE, 0);
toggle_vbox = gtk_vbox_new(FALSE, 5);
gtk_container_border_width(GTK_CONTAINER(toggle_vbox), 5);
gtk_container_add(GTK_CONTAINER(frame), toggle_vbox);
group = NULL;
{
aa_format **p = aa_formats;
int current = 0;
while (*p != NULL) {
toggle = gtk_radio_button_new_with_label(group, (*p)->formatname);
group = gtk_radio_button_group(GTK_RADIO_BUTTON(toggle));
gtk_box_pack_start (GTK_BOX (toggle_vbox), toggle, FALSE, FALSE, 0);
gtk_signal_connect(GTK_OBJECT(toggle), "toggled",
(GtkSignalFunc) type_dialog_toggle_update,
(*p)->formatname);
if (current == selected)
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), 1);
else
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(toggle), 0);
gtk_widget_show(toggle);
p++;
current++;
}
}
gtk_widget_show(toggle_vbox);
gtk_widget_show(frame);
gtk_widget_show(dlg);
gtk_main();
gdk_flush();
return selected_type;
}
/*
* Callbacks for the dialog.
*/
static void type_dialog_close_callback(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
static void type_dialog_ok_callback (GtkWidget *widget, gpointer data) {
gtk_widget_destroy (GTK_WIDGET (data));
}
static void type_dialog_cancel_callback (GtkWidget *widget, gpointer data) {
selected_type = -1;
gtk_widget_destroy (GTK_WIDGET (data));
}
static void type_dialog_toggle_update (GtkWidget *widget, gpointer data) {
selected_type = get_type_from_string((char *)data);
}