1999-08-23 03:02:52 +08:00
|
|
|
/* Plug-in to save .gpb (GIMP Pixmap Brush) files.
|
Overhaul of pixmap brushes and pipes: No separate pixmap pipe
brush tool any longer. The paintbrush, airbrush and pencil
tools, which already knew how to handle the single-pixmap
brushes now also handle the pipes as well.
* app/pixmapbrush.{h,c}
* app/gimpbrushpixmap.{h,c}: Removed these files.
* app/Makefile.am
* app/makefile.{cygwin,msc}: Remove from here, too.
* app/gimpbrushpipe.{h,c}: Total overhaul.
* app/paint_core.h
* app/apptypes.h: Some more types moved to apptypes.h
* app/context_manager.c
* app/tool_options.c
* app/tools.c
* app/toolsF.h: Remove PIXMAPBRUSH tool.
* app/gimpbrush.h: New method: select_brush. Used to change the
brush in paint_core, for pipe brushes.
* app/gimpbrush.c: Add gimp_brush_select_brush, which is dummy for
the normal brushes (returns the same brush).
* app/paint_core.c: Call the brush's select_brush method to get a
potential new brush before calling the paint_func.
* app/gimpbrushlist.c: Various changes related to the pixmap and
pipe overhaul.
* app/airbrush.c
* app/pencil.c: Reorder code a bit in the tool motion function to
avoid executing unnecessary code in the case of a pixmap brush.
Other changes in the same commit:
* app/install.c: Make quote_spaces extern.
* app/appenv.h: Declare it.
* libgimp/gimpui.def: Add missing entry points.
* libgimp/makefile.{cygwin,msc}: Add missing objects to gimpui.
1999-08-26 08:54:30 +08:00
|
|
|
* The format for pixmap brushes might well change, and this will have to
|
|
|
|
* be updated.
|
1999-08-23 03:02:52 +08:00
|
|
|
*
|
|
|
|
* Copyright (C) 1999 Tor Lillqvist
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
/* set to the level of debugging output you want, 0 for none */
|
|
|
|
#define GPB_DEBUG 0
|
|
|
|
|
|
|
|
#define IFDBG(level) if (GPB_DEBUG >= level)
|
|
|
|
|
1999-08-23 03:02:52 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
1999-08-24 13:30:14 +08:00
|
|
|
#include <stdlib.h>
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <libgimp/gimp.h>
|
1999-09-02 08:01:41 +08:00
|
|
|
#include <libgimp/parasiteio.h>
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
#include "app/brush_header.h"
|
|
|
|
#include "app/pattern_header.h"
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
#define DUMMY_PATTERN_NAME "x"
|
1999-08-23 03:02:52 +08:00
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
#define MAXDESCLEN 256
|
1999-08-23 03:02:52 +08:00
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
/* Parameters applicable each time we save a gpb or gih, saved
|
|
|
|
* in the main gimp application between invocations of this plug-in.
|
|
|
|
*/
|
|
|
|
static struct {
|
|
|
|
/* Use by both gpb and gih: */
|
|
|
|
guint spacing;
|
|
|
|
guchar description[MAXDESCLEN+1];
|
|
|
|
} info =
|
|
|
|
/* Initialize to this, change if non-interactive later */
|
|
|
|
{
|
1999-08-23 03:02:52 +08:00
|
|
|
10,
|
|
|
|
"GIMP Pixmap Brush"
|
|
|
|
};
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
static gint run_flag = 0;
|
|
|
|
static gint num_layers_with_alpha;
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
static PixPipeParams gihparms;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
GOrientation orientation;
|
|
|
|
gint32 image;
|
|
|
|
gint32 toplayer;
|
|
|
|
gint nguides;
|
|
|
|
gint32 *guides;
|
|
|
|
gint *value;
|
|
|
|
GtkWidget *count_label; /* Corresponding count adjustment, */
|
|
|
|
gint *count; /* cols or rows */
|
|
|
|
gint *other_count; /* And the other one */
|
|
|
|
GtkObject *ncells;
|
|
|
|
GtkObject *rank0;
|
|
|
|
GtkWidget *warning_label;
|
|
|
|
} SizeAdjustmentData;
|
|
|
|
|
|
|
|
static gint32 *vguides, *hguides;
|
|
|
|
static gint nvguides = 0, nhguides = 0;
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
/* Declare some local functions.
|
|
|
|
*/
|
1999-08-24 13:30:14 +08:00
|
|
|
static void query (void);
|
|
|
|
static void run (char *name,
|
|
|
|
int nparams,
|
|
|
|
GParam *param,
|
|
|
|
int *nreturn_vals,
|
|
|
|
GParam **return_vals);
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
GPlugInInfo PLUG_IN_INFO =
|
|
|
|
{
|
|
|
|
NULL, /* init_proc */
|
|
|
|
NULL, /* quit_proc */
|
|
|
|
query, /* query_proc */
|
|
|
|
run, /* run_proc */
|
|
|
|
};
|
|
|
|
|
|
|
|
MAIN ()
|
|
|
|
|
|
|
|
static void
|
|
|
|
query ()
|
|
|
|
{
|
1999-08-24 13:30:14 +08:00
|
|
|
static GParamDef gpb_save_args[] =
|
1999-08-23 03:02:52 +08:00
|
|
|
{
|
|
|
|
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
|
|
|
{ PARAM_IMAGE, "image", "Input image" },
|
|
|
|
{ PARAM_DRAWABLE, "drawable", "Drawable to save" },
|
1999-08-24 13:30:14 +08:00
|
|
|
{ PARAM_STRING, "filename", "The name of the file to save the brush in" },
|
|
|
|
{ PARAM_STRING, "raw_filename", "The name of the file to save the brush in" },
|
1999-08-23 03:02:52 +08:00
|
|
|
{ PARAM_INT32, "spacing", "Spacing of the brush" },
|
|
|
|
{ PARAM_STRING, "description", "Short description of the brush" },
|
|
|
|
};
|
1999-08-24 13:30:14 +08:00
|
|
|
static int ngpb_save_args = sizeof (gpb_save_args)
|
|
|
|
/ sizeof (gpb_save_args[0]);
|
|
|
|
|
|
|
|
static GParamDef gih_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 brush pipe in" },
|
|
|
|
{ PARAM_STRING, "raw_filename", "The name of the file to save the brush pipe in" },
|
|
|
|
{ PARAM_INT32, "spacing", "Spacing of the brush" },
|
|
|
|
{ PARAM_STRING, "description", "Short description of the brush pipe" },
|
|
|
|
};
|
|
|
|
static int ngih_save_args = sizeof (gih_save_args)
|
|
|
|
/ sizeof (gih_save_args[0]);
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
gimp_install_procedure ("file_gpb_save",
|
1999-08-24 13:30:14 +08:00
|
|
|
"saves images in GIMP pixmap brush format",
|
|
|
|
"This plug-in saves a layer of an image in "
|
|
|
|
"the GIMP pixmap brush format. "
|
|
|
|
"The image must have an alpha channel.",
|
1999-08-23 03:02:52 +08:00
|
|
|
"Tor Lillqvist",
|
|
|
|
"Tor Lillqvist",
|
|
|
|
"1999",
|
|
|
|
"<Save>/GPB",
|
|
|
|
"RGBA",
|
|
|
|
PROC_PLUG_IN,
|
1999-08-24 13:30:14 +08:00
|
|
|
ngpb_save_args, 0,
|
|
|
|
gpb_save_args, NULL);
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
gimp_register_save_handler ("file_gpb_save", "gpb", "");
|
1999-08-24 13:30:14 +08:00
|
|
|
|
|
|
|
gimp_install_procedure ("file_gih_save",
|
|
|
|
"saves images in GIMP pixmap brush pipe format",
|
|
|
|
"This plug-in saves an image in "
|
|
|
|
"the GIMP pixmap brush pipe format. "
|
|
|
|
"The image must have an alpha channel."
|
|
|
|
"The image can be multi-layered, "
|
|
|
|
"and additionally the layers can be divided into "
|
|
|
|
"a rectangular array of brushes.",
|
|
|
|
"Tor Lillqvist",
|
|
|
|
"Tor Lillqvist",
|
|
|
|
"1999",
|
|
|
|
"<Save>/GIH",
|
|
|
|
"RGBA",
|
|
|
|
PROC_PLUG_IN,
|
|
|
|
ngih_save_args, 0,
|
|
|
|
gih_save_args, NULL);
|
|
|
|
|
|
|
|
gimp_register_save_handler ("file_gih_save", "gih", "");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
adjustment_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
*((gint *) data) = GTK_ADJUSTMENT (widget)->value;
|
1999-08-23 03:02:52 +08:00
|
|
|
}
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
static void
|
|
|
|
size_adjustment_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
/* Unfortunately this doesn't work, sigh. The guides don't show up unless
|
|
|
|
* you manually force a redraw of the image.
|
|
|
|
*/
|
|
|
|
int i;
|
|
|
|
int size;
|
|
|
|
int newn;
|
|
|
|
SizeAdjustmentData *adj = (SizeAdjustmentData *) data;
|
|
|
|
char buf[10];
|
|
|
|
|
|
|
|
for (i = 0; i < adj->nguides; i++)
|
|
|
|
gimp_image_delete_guide (adj->image, adj->guides[i]);
|
|
|
|
g_free (adj->guides);
|
|
|
|
adj->guides = NULL;
|
|
|
|
gimp_displays_flush ();
|
|
|
|
|
|
|
|
*(adj->value) = GTK_ADJUSTMENT (widget)->value;
|
|
|
|
|
|
|
|
if (adj->orientation == ORIENTATION_VERTICAL)
|
|
|
|
{
|
|
|
|
size = gimp_image_width (adj->image);
|
|
|
|
newn = size / *(adj->value);
|
|
|
|
adj->nguides = newn - 1;
|
|
|
|
adj->guides = g_new (gint32, adj->nguides);
|
|
|
|
for (i = 0; i < adj->nguides; i++)
|
|
|
|
adj->guides[i] = gimp_image_add_vguide (adj->image,
|
|
|
|
*(adj->value) * (i+1));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
size = gimp_image_height (adj->image);
|
|
|
|
newn = size / *(adj->value);
|
|
|
|
adj->nguides = newn - 1;
|
|
|
|
adj->guides = g_new (gint32, adj->nguides);
|
|
|
|
for (i = 0; i < adj->nguides; i++)
|
|
|
|
adj->guides[i] = gimp_image_add_hguide (adj->image,
|
|
|
|
*(adj->value) * (i+1));
|
|
|
|
}
|
|
|
|
gimp_displays_flush ();
|
|
|
|
sprintf (buf, "%2d", newn);
|
|
|
|
gtk_label_set_text (GTK_LABEL (adj->count_label), buf);
|
|
|
|
*(adj->count) = newn;
|
|
|
|
if (newn * *(adj->value) != size)
|
|
|
|
gtk_widget_show (GTK_WIDGET (adj->warning_label));
|
|
|
|
else
|
|
|
|
gtk_widget_hide (GTK_WIDGET (adj->warning_label));
|
|
|
|
if (adj->ncells != NULL)
|
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (adj->ncells),
|
|
|
|
*(adj->other_count) * *(adj->count));
|
|
|
|
if (adj->rank0 != NULL)
|
|
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (adj->rank0),
|
|
|
|
*(adj->other_count) * *(adj->count));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-08-23 03:02:52 +08:00
|
|
|
static void
|
1999-08-24 13:30:14 +08:00
|
|
|
entry_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
1999-08-23 03:02:52 +08:00
|
|
|
{
|
1999-08-24 13:30:14 +08:00
|
|
|
if (data == info.description)
|
|
|
|
{
|
|
|
|
strncpy (info.description, gtk_entry_get_text (GTK_ENTRY (widget)), MAXDESCLEN);
|
|
|
|
info.description[MAXDESCLEN] = 0;
|
|
|
|
}
|
1999-08-23 03:02:52 +08:00
|
|
|
}
|
|
|
|
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
static void
|
|
|
|
cb_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
*((char **) data) = gtk_entry_get_text (GTK_ENTRY (widget));
|
|
|
|
}
|
|
|
|
|
1999-08-23 03:02:52 +08:00
|
|
|
static void
|
|
|
|
close_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
|
|
|
{
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_main_quit ();
|
1999-08-23 03:02:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ok_callback (GtkWidget *widget,
|
|
|
|
gpointer data)
|
|
|
|
{
|
|
|
|
run_flag = 1;
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (data));
|
|
|
|
}
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
static void
|
|
|
|
common_save_dialog (GtkWidget *dlg,
|
|
|
|
GtkWidget *table)
|
1999-08-23 03:02:52 +08:00
|
|
|
{
|
|
|
|
GtkWidget *button;
|
|
|
|
GtkWidget *label;
|
1999-08-24 13:30:14 +08:00
|
|
|
GtkObject *adjustment;
|
|
|
|
GtkWidget *box;
|
|
|
|
GtkWidget *spinbutton;
|
1999-08-23 03:02:52 +08:00
|
|
|
GtkWidget *entry;
|
|
|
|
gchar buffer[12];
|
|
|
|
|
|
|
|
/* Action area */
|
|
|
|
button = gtk_button_new_with_label ("OK");
|
|
|
|
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
1999-08-23 03:02:52 +08:00
|
|
|
(GtkSignalFunc) ok_callback, dlg);
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0);
|
1999-08-23 03:02:52 +08:00
|
|
|
gtk_widget_grab_default (button);
|
|
|
|
gtk_widget_show (button);
|
|
|
|
|
|
|
|
button = gtk_button_new_with_label ("Cancel");
|
1999-08-24 13:30:14 +08:00
|
|
|
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
|
|
|
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
1999-08-23 03:02:52 +08:00
|
|
|
(GtkSignalFunc) gtk_widget_destroy,
|
|
|
|
GTK_OBJECT (dlg));
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (button);
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
gtk_table_set_row_spacings (GTK_TABLE (table), 10);
|
|
|
|
gtk_table_set_col_spacings (GTK_TABLE (table), 10);
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Spacing: __
|
|
|
|
*/
|
|
|
|
gtk_table_resize (GTK_TABLE (table),
|
|
|
|
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Spacing (percent):");
|
1999-08-23 03:02:52 +08:00
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
1999-08-23 03:02:52 +08:00
|
|
|
gtk_widget_show (label);
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
adjustment = gtk_adjustment_new (info.spacing, 1, 1000, 1, 10, 10);
|
|
|
|
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
|
|
|
|
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
|
|
|
|
GTK_SHADOW_NONE);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
|
|
gtk_widget_set_usize (spinbutton, 75, 0);
|
|
|
|
box = gtk_hbox_new (FALSE, 0);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, TRUE, 0);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
|
|
|
(GtkSignalFunc) adjustment_callback, &info.spacing);
|
|
|
|
gtk_widget_show (spinbutton);
|
|
|
|
gtk_widget_show (box);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Description: ___________
|
|
|
|
*/
|
|
|
|
gtk_table_resize (GTK_TABLE (table),
|
|
|
|
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
label = gtk_label_new ("Description:");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
1999-08-23 03:02:52 +08:00
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
entry = gtk_entry_new ();
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_table_attach (GTK_TABLE (table), entry, 1, 2,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
1999-08-23 03:02:52 +08:00
|
|
|
gtk_widget_set_usize (entry, 200, 0);
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (entry), info.description);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (entry), "changed",
|
1999-08-24 13:30:14 +08:00
|
|
|
(GtkSignalFunc) entry_callback, info.description);
|
1999-08-23 03:02:52 +08:00
|
|
|
gtk_widget_show (entry);
|
1999-08-24 13:30:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
gpb_save_dialog ()
|
|
|
|
{
|
|
|
|
GtkWidget *dlg;
|
|
|
|
GtkWidget *table;
|
|
|
|
GtkWidget *entry;
|
|
|
|
gchar **argv;
|
|
|
|
gint argc;
|
|
|
|
gchar buffer[100];
|
|
|
|
|
|
|
|
argc = 1;
|
|
|
|
argv = g_new (gchar *, 1);
|
|
|
|
argv[0] = g_strdup ("gpb_save");
|
|
|
|
|
|
|
|
gtk_init (&argc, &argv);
|
|
|
|
gtk_rc_parse (gimp_gtkrc ());
|
|
|
|
|
|
|
|
dlg = gtk_dialog_new ();
|
|
|
|
gtk_window_set_title (GTK_WINDOW (dlg), "Save As Pixmap Brush");
|
|
|
|
gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
|
|
|
|
(GtkSignalFunc) close_callback, NULL);
|
|
|
|
|
|
|
|
/* The main table */
|
|
|
|
table = gtk_table_new (2, 0, FALSE);
|
|
|
|
gtk_container_border_width (GTK_CONTAINER (table), 10);
|
|
|
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), table, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (table);
|
|
|
|
|
|
|
|
common_save_dialog (dlg, table);
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
gtk_widget_show (dlg);
|
|
|
|
|
|
|
|
gtk_main ();
|
|
|
|
gdk_flush ();
|
|
|
|
|
|
|
|
return run_flag;
|
|
|
|
}
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
static gint
|
1999-09-02 08:01:41 +08:00
|
|
|
gih_save_dialog (gint32 image_ID)
|
1999-08-24 13:30:14 +08:00
|
|
|
{
|
|
|
|
GtkWidget *dlg;
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
GtkWidget *table, *dimtable;
|
1999-08-24 13:30:14 +08:00
|
|
|
GtkWidget *label;
|
|
|
|
GtkObject *adjustment;
|
|
|
|
GtkWidget *spinbutton;
|
|
|
|
GtkWidget *entry;
|
|
|
|
GtkWidget *box;
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
GtkWidget *cb;
|
|
|
|
GList *cbitems = NULL;
|
1999-08-24 13:30:14 +08:00
|
|
|
gint i;
|
|
|
|
gchar **argv;
|
|
|
|
gint argc;
|
|
|
|
gchar buffer[100];
|
1999-09-02 08:01:41 +08:00
|
|
|
SizeAdjustmentData cellw_adjust, cellh_adjust;
|
|
|
|
gint32 *layer_ID;
|
|
|
|
gint32 nlayers;
|
1999-08-24 13:30:14 +08:00
|
|
|
|
|
|
|
/* Setup default values */
|
|
|
|
if (gihparms.rows >= 1 && gihparms.cols >= 1)
|
|
|
|
gihparms.ncells = num_layers_with_alpha * gihparms.rows * gihparms.cols;
|
|
|
|
else
|
1999-09-02 08:01:41 +08:00
|
|
|
gihparms.ncells = num_layers_with_alpha;
|
|
|
|
|
|
|
|
if (gihparms.cellwidth == 1 && gihparms.cellheight == 1)
|
|
|
|
{
|
|
|
|
gihparms.cellwidth = gimp_image_width (image_ID) / gihparms.cols;
|
|
|
|
gihparms.cellheight = gimp_image_height (image_ID) / gihparms.rows;
|
|
|
|
}
|
1999-08-24 13:30:14 +08:00
|
|
|
|
|
|
|
argc = 1;
|
|
|
|
argv = g_new (gchar *, 1);
|
|
|
|
argv[0] = g_strdup ("gpb_save");
|
|
|
|
|
|
|
|
gtk_init (&argc, &argv);
|
|
|
|
gtk_rc_parse (gimp_gtkrc ());
|
|
|
|
|
|
|
|
dlg = gtk_dialog_new ();
|
|
|
|
gtk_window_set_title (GTK_WINDOW (dlg), "Save As Pixmap Brush Pipe");
|
|
|
|
gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
|
|
|
|
(GtkSignalFunc) close_callback, NULL);
|
|
|
|
|
|
|
|
/* The main table */
|
|
|
|
table = gtk_table_new (2, 0, FALSE);
|
|
|
|
gtk_container_border_width (GTK_CONTAINER (table), 10);
|
|
|
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), table, TRUE, TRUE, 0);
|
|
|
|
gtk_widget_show (table);
|
|
|
|
|
|
|
|
common_save_dialog (dlg, table);
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
/*
|
|
|
|
* Cell size: __ x __ pixels
|
|
|
|
*/
|
|
|
|
|
|
|
|
gtk_table_resize (GTK_TABLE (table),
|
|
|
|
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Cell size:");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
box = gtk_hbox_new (FALSE, 0);
|
|
|
|
|
|
|
|
adjustment = gtk_adjustment_new (gihparms.cellwidth,
|
|
|
|
2, gimp_image_width (image_ID), 1, 1, 1);
|
|
|
|
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
|
|
|
|
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
|
|
|
|
GTK_SHADOW_NONE);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
|
|
gtk_widget_set_usize (spinbutton, 75, 0);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, FALSE, 0);
|
|
|
|
|
|
|
|
layer_ID = gimp_image_get_layers (image_ID, &nlayers);
|
|
|
|
cellw_adjust.orientation = ORIENTATION_VERTICAL;
|
|
|
|
cellw_adjust.image = image_ID;
|
|
|
|
cellw_adjust.toplayer = layer_ID[nlayers-1];
|
|
|
|
cellw_adjust.nguides = 0;
|
|
|
|
cellw_adjust.guides = NULL;
|
|
|
|
cellw_adjust.value = &gihparms.cellwidth;
|
|
|
|
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
|
|
|
(GtkSignalFunc) size_adjustment_callback,
|
|
|
|
&cellw_adjust);
|
|
|
|
gtk_widget_show (spinbutton);
|
|
|
|
|
|
|
|
label = gtk_label_new (" x ");
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
adjustment = gtk_adjustment_new (gihparms.cellheight,
|
|
|
|
2, gimp_image_height (image_ID), 1, 1, 1);
|
|
|
|
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
|
|
|
|
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
|
|
|
|
GTK_SHADOW_NONE);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
|
|
gtk_widget_set_usize (spinbutton, 75, 0);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, FALSE, 0);
|
|
|
|
cellh_adjust.orientation = ORIENTATION_HORIZONTAL;
|
|
|
|
cellh_adjust.image = image_ID;
|
|
|
|
cellh_adjust.toplayer = layer_ID[nlayers-1];
|
|
|
|
cellh_adjust.nguides = 0;
|
|
|
|
cellh_adjust.guides = NULL;
|
|
|
|
cellh_adjust.value = &gihparms.cellheight;
|
|
|
|
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
|
|
|
(GtkSignalFunc) size_adjustment_callback,
|
|
|
|
&cellh_adjust);
|
|
|
|
gtk_widget_show (spinbutton);
|
|
|
|
|
|
|
|
label = gtk_label_new (" pixels");
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (box);
|
|
|
|
|
|
|
|
g_free (layer_ID);
|
|
|
|
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
/*
|
|
|
|
* Number of cells: ___
|
|
|
|
*/
|
|
|
|
|
|
|
|
gtk_table_resize (GTK_TABLE (table),
|
|
|
|
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Number of cells:");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
adjustment = gtk_adjustment_new (gihparms.ncells, 1, 1000, 1, 10, 10);
|
|
|
|
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
|
|
|
|
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
|
|
|
|
GTK_SHADOW_NONE);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
|
|
gtk_widget_set_usize (spinbutton, 75, 0);
|
|
|
|
box = gtk_hbox_new (FALSE, 0);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, TRUE, 0);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
|
|
|
(GtkSignalFunc) adjustment_callback, &gihparms.ncells);
|
|
|
|
gtk_widget_show (spinbutton);
|
|
|
|
gtk_widget_show (box);
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
if (gihparms.dim == 1)
|
|
|
|
cellw_adjust.ncells = cellh_adjust.ncells = adjustment;
|
|
|
|
else
|
|
|
|
cellw_adjust.ncells = cellh_adjust.ncells = NULL;
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
/*
|
|
|
|
* Display as: __ rows x __ cols
|
|
|
|
*/
|
|
|
|
gtk_table_resize (GTK_TABLE (table),
|
|
|
|
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Display as:");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
box = gtk_hbox_new (FALSE, 0);
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
sprintf (buffer, "%2d", gihparms.rows);
|
|
|
|
label = gtk_label_new (buffer);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
|
|
|
cellh_adjust.count_label = label;
|
|
|
|
cellh_adjust.count = &gihparms.rows;
|
|
|
|
cellh_adjust.other_count = &gihparms.cols;
|
|
|
|
gtk_widget_show (label);
|
1999-08-24 13:30:14 +08:00
|
|
|
|
|
|
|
label = gtk_label_new (" rows of ");
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
sprintf (buffer, "%2d", gihparms.cols);
|
|
|
|
label = gtk_label_new (buffer);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
|
|
|
cellw_adjust.count_label = label;
|
|
|
|
cellw_adjust.count = &gihparms.cols;
|
|
|
|
cellw_adjust.other_count = &gihparms.rows;
|
|
|
|
gtk_widget_show (label);
|
1999-08-24 13:30:14 +08:00
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
label = gtk_label_new (" columns on each layer");
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
label = gtk_label_new (" (width mismatch!) ");
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
|
|
|
cellw_adjust.warning_label = label;
|
|
|
|
|
|
|
|
label = gtk_label_new (" (height mismatch!) ");
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
|
|
|
|
cellh_adjust.warning_label = label;
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (box);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dimension: ___
|
|
|
|
*/
|
|
|
|
|
|
|
|
gtk_table_resize (GTK_TABLE (table),
|
|
|
|
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Dimension:");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
adjustment = gtk_adjustment_new (gihparms.dim, 1, 5, 1, 1, 1);
|
|
|
|
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
|
|
|
|
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
|
|
|
|
GTK_SHADOW_NONE);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
|
|
gtk_widget_set_usize (spinbutton, 75, 0);
|
|
|
|
box = gtk_hbox_new (FALSE, 0);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, FALSE, 0);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
|
|
|
(GtkSignalFunc) adjustment_callback, &gihparms.dim);
|
|
|
|
gtk_widget_show (spinbutton);
|
|
|
|
gtk_widget_show (box);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Ranks: __ __ __ __ __
|
|
|
|
*/
|
|
|
|
|
|
|
|
gtk_table_resize (GTK_TABLE (table),
|
|
|
|
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Ranks:");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
dimtable = gtk_table_new (PIXPIPE_MAXDIM, 1, FALSE);
|
|
|
|
for (i = 0; i < PIXPIPE_MAXDIM; i++)
|
1999-08-24 13:30:14 +08:00
|
|
|
{
|
|
|
|
adjustment = gtk_adjustment_new (gihparms.rank[i], 0, 100, 1, 1, 1);
|
|
|
|
spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (adjustment), 1, 0);
|
|
|
|
gtk_spin_button_set_shadow_type (GTK_SPIN_BUTTON (spinbutton),
|
|
|
|
GTK_SHADOW_NONE);
|
|
|
|
gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE);
|
|
|
|
gtk_widget_set_usize (spinbutton, 75, 0);
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
box = gtk_hbox_new (FALSE, 0);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), spinbutton, FALSE, TRUE, 0);
|
|
|
|
gtk_table_attach (GTK_TABLE (dimtable), box, i, i + 1, 0, 1,
|
|
|
|
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 3, 0);
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
|
|
|
|
(GtkSignalFunc) adjustment_callback, &gihparms.rank[i]);
|
|
|
|
gtk_widget_show (spinbutton);
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
gtk_widget_show (box);
|
1999-09-02 08:01:41 +08:00
|
|
|
if (i == 0)
|
|
|
|
if (gihparms.dim == 1)
|
|
|
|
cellw_adjust.rank0 = cellh_adjust.rank0 = adjustment;
|
|
|
|
else
|
|
|
|
cellw_adjust.rank0 = cellh_adjust.rank0 = NULL;
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
}
|
|
|
|
gtk_table_attach (GTK_TABLE (table), dimtable, 1, 2,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (dimtable);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Selection: ______ ______ ______ ______ ______
|
|
|
|
*/
|
|
|
|
|
|
|
|
gtk_table_resize (GTK_TABLE (table),
|
|
|
|
GTK_TABLE (table)->nrows + 1, GTK_TABLE (table)->ncols);
|
|
|
|
|
|
|
|
label = gtk_label_new ("Selection:");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
|
|
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_FILL, GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (label);
|
|
|
|
|
|
|
|
cbitems = g_list_append (cbitems, "incremental");
|
|
|
|
cbitems = g_list_append (cbitems, "angular");
|
|
|
|
cbitems = g_list_append (cbitems, "random");
|
|
|
|
cbitems = g_list_append (cbitems, "velocity");
|
|
|
|
cbitems = g_list_append (cbitems, "pressure");
|
|
|
|
cbitems = g_list_append (cbitems, "xtilt");
|
|
|
|
cbitems = g_list_append (cbitems, "ytilt");
|
|
|
|
|
|
|
|
box = gtk_hbox_new (FALSE, 0);
|
1999-09-02 08:01:41 +08:00
|
|
|
for (i = 0; i < PIXPIPE_MAXDIM; i++)
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
{
|
|
|
|
cb = gtk_combo_new ();
|
|
|
|
gtk_combo_set_popdown_strings (GTK_COMBO (cb), cbitems);
|
|
|
|
if (gihparms.selection[i])
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (cb)->entry), gihparms.selection[i]);
|
1999-09-01 00:49:46 +08:00
|
|
|
else
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (GTK_COMBO (cb)->entry), "random");
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (cb)->entry), FALSE);
|
|
|
|
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), cb, FALSE, TRUE, 2);
|
|
|
|
gtk_signal_connect (GTK_OBJECT (GTK_COMBO (cb)->entry), "changed",
|
|
|
|
(GtkSignalFunc) cb_callback, &gihparms.selection[i]);
|
|
|
|
gtk_widget_show (cb);
|
1999-08-24 13:30:14 +08:00
|
|
|
}
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_table_attach (GTK_TABLE (table), box, 1, 2,
|
|
|
|
GTK_TABLE (table)->nrows - 1, GTK_TABLE (table)->nrows,
|
|
|
|
GTK_SHRINK, GTK_EXPAND | GTK_FILL, 0, 0);
|
|
|
|
gtk_widget_show (box);
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
gtk_widget_show (dlg);
|
|
|
|
|
|
|
|
gtk_main ();
|
|
|
|
gdk_flush ();
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
for (i = 0; i < cellw_adjust.nguides; i++)
|
|
|
|
gimp_image_delete_guide (image_ID, cellw_adjust.guides[i]);
|
|
|
|
for (i = 0; i < cellh_adjust.nguides; i++)
|
|
|
|
gimp_image_delete_guide (image_ID, cellh_adjust.guides[i]);
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
if (run_flag)
|
|
|
|
{
|
|
|
|
/* Fix up bogus values */
|
|
|
|
gihparms.ncells =
|
|
|
|
MIN (gihparms.ncells,
|
|
|
|
num_layers_with_alpha * gihparms.rows * gihparms.cols);
|
|
|
|
}
|
|
|
|
return run_flag;
|
|
|
|
}
|
|
|
|
|
1999-08-23 03:02:52 +08:00
|
|
|
static gboolean
|
|
|
|
try_fwrite (gpointer buffer,
|
|
|
|
guint size,
|
|
|
|
guint nitems,
|
|
|
|
FILE *file)
|
|
|
|
{
|
|
|
|
if (fwrite (buffer, size, nitems, file) < nitems)
|
|
|
|
{
|
|
|
|
g_message ("GPB: write error");
|
|
|
|
fclose (file);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
1999-08-24 13:30:14 +08:00
|
|
|
save_one_gpb (FILE *file,
|
|
|
|
GPixelRgn *pixel_rgn,
|
|
|
|
int index,
|
|
|
|
int total)
|
1999-08-23 03:02:52 +08:00
|
|
|
{
|
|
|
|
BrushHeader brushheader;
|
|
|
|
PatternHeader patternheader;
|
1999-08-24 13:30:14 +08:00
|
|
|
guint y, x;
|
|
|
|
guchar *buffer;
|
|
|
|
guint width, height;
|
|
|
|
|
|
|
|
width = pixel_rgn->w;
|
|
|
|
height = pixel_rgn->h;
|
|
|
|
|
|
|
|
brushheader.header_size = g_htonl (sizeof (brushheader) + strlen (info.description) + 1);
|
|
|
|
brushheader.version = g_htonl (2);
|
|
|
|
brushheader.width = g_htonl (width);
|
|
|
|
brushheader.height = g_htonl (height);
|
|
|
|
brushheader.bytes = g_htonl (1);
|
|
|
|
brushheader.magic_number = g_htonl (GBRUSH_MAGIC);
|
|
|
|
brushheader.spacing = g_htonl (info.spacing);
|
|
|
|
|
|
|
|
if (!try_fwrite (&brushheader, sizeof (brushheader), 1, file))
|
|
|
|
return FALSE;
|
|
|
|
if (!try_fwrite (info.description, strlen (info.description) + 1, 1, file))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
IFDBG(3) g_message ("saving gpb %d of %d: %dx%d, offset %d,%d stride %d drawable %d ",
|
|
|
|
index+1, total,
|
|
|
|
width, height, pixel_rgn->x, pixel_rgn->y,
|
|
|
|
pixel_rgn->rowstride, pixel_rgn->drawable->id);
|
|
|
|
|
|
|
|
buffer = g_malloc (width * pixel_rgn->bpp);
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
/* No; the brushes don't have to be the same size, of course. */
|
|
|
|
if (y >= pixel_rgn->h)
|
|
|
|
{
|
|
|
|
if (y == pixel_rgn->h)
|
|
|
|
memset (buffer, 0, width);
|
|
|
|
if (!try_fwrite (buffer, width, 1, file))
|
|
|
|
{
|
|
|
|
g_free (buffer);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
gimp_pixel_rgn_get_row (pixel_rgn, buffer,
|
|
|
|
0 + pixel_rgn->x, y + pixel_rgn->y,
|
|
|
|
pixel_rgn->w);
|
|
|
|
for (x = 0; x < pixel_rgn->w; x++)
|
|
|
|
if (!try_fwrite (buffer + x*pixel_rgn->bpp + 3, 1, 1, file))
|
|
|
|
{
|
|
|
|
g_free (buffer);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
if (width > pixel_rgn->w)
|
|
|
|
{
|
|
|
|
memset (buffer, 0, width - pixel_rgn->w);
|
|
|
|
if (!try_fwrite (buffer, width - pixel_rgn->w, 1, file))
|
|
|
|
{
|
|
|
|
g_free (buffer);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
if (y % 10 == 0)
|
|
|
|
gimp_progress_update
|
|
|
|
(((double) index + 0.5 * y / pixel_rgn->h) / total);
|
|
|
|
}
|
|
|
|
|
|
|
|
gimp_progress_update (((double) index + 0.5) / total);
|
|
|
|
|
|
|
|
patternheader.header_size = g_htonl (sizeof (patternheader) + strlen (DUMMY_PATTERN_NAME) + 1 );
|
|
|
|
patternheader.version = g_htonl (1);
|
|
|
|
patternheader.width = g_htonl (width);
|
|
|
|
patternheader.height = g_htonl (height);
|
|
|
|
patternheader.bytes = g_htonl (3);
|
|
|
|
patternheader.magic_number = g_htonl (GPATTERN_MAGIC);
|
|
|
|
|
|
|
|
if (!try_fwrite (&patternheader, sizeof (patternheader), 1, file))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/* Pattern name is irrelevant */
|
|
|
|
if (!try_fwrite (DUMMY_PATTERN_NAME, strlen (DUMMY_PATTERN_NAME) + 1, 1, file))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
if (y >= pixel_rgn->h)
|
|
|
|
{
|
|
|
|
if (y == pixel_rgn->h)
|
|
|
|
memset (buffer, 0, width * 3);
|
|
|
|
if (!try_fwrite (buffer, width*3, 1, file))
|
|
|
|
{
|
|
|
|
g_free (buffer);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
gimp_pixel_rgn_get_row (pixel_rgn, buffer,
|
|
|
|
0 + pixel_rgn->x, y + pixel_rgn->y, pixel_rgn->w);
|
|
|
|
for (x = 0; x < pixel_rgn->w; x++)
|
|
|
|
if (!try_fwrite (buffer + x*pixel_rgn->bpp, 3, 1, file))
|
|
|
|
return FALSE;
|
|
|
|
#if 0
|
|
|
|
if (width > pixel_rgn->w)
|
|
|
|
{
|
|
|
|
memset (buffer, 0, (width - pixel_rgn->w) * 3);
|
|
|
|
if (!try_fwrite (buffer, (width - pixel_rgn->w) * 3, 1, file))
|
|
|
|
{
|
|
|
|
g_free (buffer);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y % 10 == 0)
|
|
|
|
gimp_progress_update
|
|
|
|
(((double) index + 0.5 + 0.5 * y / pixel_rgn->h) / total);
|
|
|
|
}
|
|
|
|
g_free (buffer);
|
|
|
|
|
|
|
|
gimp_progress_update (((double) index + 1.0) / total);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gpb_save_image (char *filename,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID)
|
|
|
|
{
|
1999-08-23 03:02:52 +08:00
|
|
|
GDrawable *drawable;
|
1999-08-24 13:30:14 +08:00
|
|
|
GPixelRgn pixel_rgn;
|
1999-08-23 03:02:52 +08:00
|
|
|
FILE *file;
|
|
|
|
gchar *temp;
|
|
|
|
|
|
|
|
g_assert (gimp_drawable_has_alpha (drawable_ID));
|
|
|
|
|
|
|
|
drawable = gimp_drawable_get (drawable_ID);
|
|
|
|
gimp_tile_cache_size (gimp_tile_height () * drawable->width * 4);
|
|
|
|
|
|
|
|
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
|
|
|
|
|
|
|
|
temp = g_strdup_printf ("Saving %s:", filename);
|
|
|
|
gimp_progress_init (temp);
|
|
|
|
g_free (temp);
|
|
|
|
|
|
|
|
file = fopen (filename, "wb");
|
|
|
|
|
|
|
|
if (file == NULL)
|
|
|
|
{
|
|
|
|
g_message ("GPB: can't open \"%s\"", filename);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
if (!save_one_gpb (file, &pixel_rgn, 0, 1))
|
1999-08-23 03:02:52 +08:00
|
|
|
return FALSE;
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
fclose (file);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gih_save_image (char *filename,
|
|
|
|
gint32 image_ID,
|
|
|
|
gint32 drawable_ID)
|
|
|
|
{
|
|
|
|
GDrawable *drawable;
|
|
|
|
GPixelRgn pixel_rgn;
|
|
|
|
FILE *file;
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
Parasite *pipe_parasite;
|
1999-09-02 08:01:41 +08:00
|
|
|
gchar *msg, *parstring, *ncells;
|
1999-08-24 13:30:14 +08:00
|
|
|
gint32 *layer_ID;
|
|
|
|
gint nlayers, layer, row, col;
|
|
|
|
gint imagew, imageh, offsetx, offsety;
|
|
|
|
gint k, x, y, thisx, thisy, xnext, ynext, thisw, thish;
|
|
|
|
|
|
|
|
imagew = gimp_image_width (image_ID);
|
|
|
|
imageh = gimp_image_height (image_ID);
|
|
|
|
gimp_tile_cache_size (gimp_tile_height () * imagew * 4);
|
|
|
|
|
|
|
|
msg = g_strdup_printf ("Saving %s:", filename);
|
|
|
|
gimp_progress_init (msg);
|
|
|
|
g_free (msg);
|
|
|
|
|
|
|
|
file = fopen (filename, "wb");
|
|
|
|
|
|
|
|
if (file == NULL)
|
|
|
|
{
|
|
|
|
g_message ("GPB: can't open \"%s\"", filename);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
parstring = pixpipeparams_build (&gihparms);
|
|
|
|
IFDBG(2) g_message ("parameter string: %s", parstring);
|
1999-08-24 13:30:14 +08:00
|
|
|
ncells = g_strdup_printf ("%d ", gihparms.ncells);
|
|
|
|
if (!(try_fwrite (info.description, strlen (info.description), 1, file)
|
|
|
|
&& try_fwrite ("\n", 1, 1, file)
|
|
|
|
&& try_fwrite (ncells, strlen (ncells), 1, file)
|
1999-09-02 08:01:41 +08:00
|
|
|
&& try_fwrite (parstring, strlen (parstring), 1, file)
|
1999-08-24 13:30:14 +08:00
|
|
|
&& try_fwrite ("\n", 1, 1, file)))
|
1999-08-23 03:02:52 +08:00
|
|
|
{
|
1999-09-02 08:01:41 +08:00
|
|
|
g_free (parstring);
|
1999-08-24 13:30:14 +08:00
|
|
|
g_free (ncells);
|
|
|
|
return FALSE;
|
1999-08-23 03:02:52 +08:00
|
|
|
}
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
|
|
|
|
pipe_parasite = parasite_new ("gimp-brush-pipe-parameters",
|
|
|
|
PARASITE_PERSISTENT,
|
1999-09-02 08:01:41 +08:00
|
|
|
strlen (parstring) + 1, parstring);
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
gimp_image_attach_parasite (image_ID, pipe_parasite);
|
|
|
|
parasite_free (pipe_parasite);
|
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
g_free (parstring);
|
1999-08-24 13:30:14 +08:00
|
|
|
g_free (ncells);
|
|
|
|
|
|
|
|
layer_ID = gimp_image_get_layers (image_ID, &nlayers);
|
|
|
|
|
|
|
|
k = 0;
|
|
|
|
for (layer = 0; layer < nlayers; layer++)
|
|
|
|
{
|
|
|
|
if (!gimp_drawable_has_alpha (layer_ID[layer]))
|
|
|
|
continue;
|
|
|
|
drawable = gimp_drawable_get (layer_ID[layer]);
|
|
|
|
gimp_drawable_offsets(layer_ID[layer], &offsetx, &offsety);
|
1999-08-23 03:02:52 +08:00
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
for (row = 0; row < gihparms.rows; row++)
|
|
|
|
{
|
|
|
|
y = (row * imageh) / gihparms.rows ;
|
|
|
|
ynext = ((row + 1) * imageh / gihparms.rows);
|
|
|
|
/* Assume layer is offset to positive direction in x and y.
|
|
|
|
* That's reasonable, as otherwise all of the layer
|
|
|
|
* won't be visible.
|
|
|
|
* thisy and thisx are in the drawable's coordinate space.
|
|
|
|
*/
|
|
|
|
thisy = MAX (0, y - offsety);
|
|
|
|
thish = (ynext - offsety) - thisy;
|
|
|
|
thish = MIN (thish, drawable->height - thisy);
|
|
|
|
for (col = 0; col < gihparms.cols; col++)
|
|
|
|
{
|
|
|
|
x = (col * imagew / gihparms.cols);
|
|
|
|
xnext = ((col + 1) * imagew / gihparms.cols);
|
|
|
|
thisx = MAX (0, x - offsetx);
|
|
|
|
thisw = (xnext - offsetx) - thisx;
|
|
|
|
thisw = MIN (thisw, drawable->width - thisx);
|
|
|
|
IFDBG(3) g_message ("gimp_pixel_rgn_init %d %d %d %d",
|
|
|
|
thisx, thisy, thisw, thish);
|
|
|
|
gimp_pixel_rgn_init (&pixel_rgn, drawable, thisx, thisy,
|
|
|
|
thisw, thish, FALSE, FALSE);
|
|
|
|
if (!save_one_gpb (file, &pixel_rgn, k, gihparms.ncells))
|
|
|
|
return FALSE;
|
|
|
|
k++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
1999-08-23 03:02:52 +08:00
|
|
|
gimp_progress_update (1.0);
|
|
|
|
|
|
|
|
fclose (file);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
run (char *name,
|
|
|
|
int nparams,
|
|
|
|
GParam *param,
|
|
|
|
int *nreturn_vals,
|
|
|
|
GParam **return_vals)
|
|
|
|
{
|
|
|
|
static GParam values[1];
|
|
|
|
GRunModeType run_mode;
|
|
|
|
GStatusType status = STATUS_SUCCESS;
|
1999-08-24 13:30:14 +08:00
|
|
|
Parasite *pipe_parasite;
|
|
|
|
gint32 image_ID, *layer_ID;
|
|
|
|
gint nlayers, layer;
|
|
|
|
gchar *layer_name;
|
1999-08-23 03:02:52 +08:00
|
|
|
|
|
|
|
run_mode = param[0].data.d_int32;
|
|
|
|
|
|
|
|
*return_vals = values;
|
|
|
|
*nreturn_vals = 1;
|
|
|
|
values[0].type = PARAM_STATUS;
|
|
|
|
values[0].data.d_status = STATUS_CALLING_ERROR;
|
|
|
|
|
|
|
|
if (strcmp (name, "file_gpb_save") == 0)
|
|
|
|
{
|
|
|
|
switch (run_mode) {
|
|
|
|
case RUN_INTERACTIVE:
|
|
|
|
/* Possibly retrieve data */
|
|
|
|
gimp_get_data ("file_gpb_save", &info);
|
1999-08-24 13:30:14 +08:00
|
|
|
if (!gpb_save_dialog ())
|
1999-08-23 03:02:52 +08:00
|
|
|
return;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RUN_NONINTERACTIVE: /* FIXME - need a real RUN_NONINTERACTIVE */
|
|
|
|
if (nparams != 7)
|
|
|
|
status = STATUS_CALLING_ERROR;
|
|
|
|
if (status == STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
info.spacing = param[5].data.d_int32;
|
1999-08-24 13:30:14 +08:00
|
|
|
strncpy (info.description, param[6].data.d_string, MAXDESCLEN);
|
|
|
|
info.description[MAXDESCLEN] = 0;
|
1999-08-23 03:02:52 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RUN_WITH_LAST_VALS:
|
|
|
|
gimp_get_data ("file_gpb_save", &info);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1999-08-24 13:30:14 +08:00
|
|
|
if (gpb_save_image (param[3].data.d_string, param[1].data.d_int32, param[2].data.d_int32))
|
1999-08-23 04:08:15 +08:00
|
|
|
{
|
|
|
|
gimp_set_data ("file_gpb_save", &info, sizeof (info));
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
}
|
1999-08-23 03:02:52 +08:00
|
|
|
else
|
|
|
|
status = STATUS_EXECUTION_ERROR;
|
|
|
|
}
|
1999-08-24 13:30:14 +08:00
|
|
|
else if (strcmp (name, "file_gih_save") == 0)
|
|
|
|
{
|
|
|
|
image_ID = param[1].data.d_int32;
|
|
|
|
layer_ID = gimp_image_get_layers (image_ID, &nlayers);
|
|
|
|
num_layers_with_alpha = 0;
|
|
|
|
for (layer = 0; layer < nlayers; layer++)
|
|
|
|
{
|
|
|
|
if (!gimp_drawable_has_alpha (layer_ID[layer]))
|
|
|
|
{
|
|
|
|
layer_name = gimp_layer_get_name (layer_ID[layer]);
|
|
|
|
g_message ("Layer %s doesn't have an alpha channel, skipped",
|
|
|
|
layer_name);
|
|
|
|
g_free (layer_name);
|
|
|
|
}
|
|
|
|
num_layers_with_alpha++;
|
|
|
|
}
|
|
|
|
|
|
|
|
IFDBG(2) g_message ("nlayers:%d num_layers_with_alpha:%d",
|
|
|
|
nlayers, num_layers_with_alpha);
|
|
|
|
switch (run_mode)
|
|
|
|
{
|
|
|
|
case RUN_INTERACTIVE:
|
|
|
|
/* Possibly retrieve data */
|
|
|
|
gimp_get_data ("file_gih_save", &info);
|
|
|
|
pipe_parasite = gimp_image_find_parasite (image_ID, "gimp-brush-pipe-parameters");
|
1999-09-02 08:01:41 +08:00
|
|
|
pixpipeparams_init (&gihparms);
|
1999-08-24 13:30:14 +08:00
|
|
|
if (pipe_parasite)
|
1999-09-02 08:01:41 +08:00
|
|
|
pixpipeparams_parse (pipe_parasite->data, &gihparms);
|
Implement the selection of brush based on cursor direction, pressure,
1999-08-28 Tor Lillqvist <tml@iki.fi>
* app/gimpbrushpipe.c: Implement the selection of brush based on
cursor direction, pressure, tilt, or a random value. (Hmm, forgot
velocity, later.) (In addition to just incrementally stepping.)
Read the brush pipe parameters from the gih file's second line.
There is no way to tune the parameters in the GIMP, they must
currently be set when saving the gih file (in the gpb plug-in).
* app/gimpbrushpipe.h
* app/gimpbrushpipeP.h: Move the PipeSelectModes enum to the
"private" header. Add a stride array to GimpBrushPipe to make
indexing easier.
* plug-ins/common/gpb.c: Add selection mode fields to the dialog.
Attach the pipe parameters entered as a parasite, too.
* docs/parasites.txt
* plug-ins/common/psp.c: Use "placement", not "spacing" (which
means another thing).
1999-08-28 09:14:42 +08:00
|
|
|
|
1999-09-02 08:01:41 +08:00
|
|
|
if (!gih_save_dialog (image_ID))
|
1999-08-24 13:30:14 +08:00
|
|
|
return;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RUN_NONINTERACTIVE: /* FIXME - need a real RUN_NONINTERACTIVE */
|
|
|
|
if (nparams != 7)
|
|
|
|
status = STATUS_CALLING_ERROR;
|
|
|
|
if (status == STATUS_SUCCESS)
|
|
|
|
{
|
|
|
|
info.spacing = param[5].data.d_int32;
|
|
|
|
strncpy (info.description, param[6].data.d_string, MAXDESCLEN);
|
|
|
|
info.description[MAXDESCLEN] = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RUN_WITH_LAST_VALS:
|
|
|
|
gimp_get_data ("file_gih_save", &info);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gih_save_image (param[3].data.d_string, param[1].data.d_int32, param[2].data.d_int32))
|
|
|
|
{
|
|
|
|
gimp_set_data ("file_gih_save", &info, sizeof (info));
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
status = STATUS_EXECUTION_ERROR;
|
|
|
|
}
|
1999-08-23 03:02:52 +08:00
|
|
|
values[0].data.d_status = status;
|
|
|
|
}
|