1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 05:22:40 +02:00

plug-ins/gimpressionist/Makefile.am applied patch from Shlomi Fish that

2004-07-02  Michael Natterer  <mitch@gimp.org>

	* plug-ins/gimpressionist/Makefile.am
	* plug-ins/gimpressionist/*.[ch]: applied patch from Shlomi Fish
	that massively cleans up gimppressionist (touching all files and
	addding some new ones) and adds a simple PDB interface for
	selecting one of the previously created presets.
	Fixes bugs #145191, #144913 and #144922.
This commit is contained in:
Michael Natterer
2004-07-02 13:31:25 +00:00
committed by Michael Natterer
parent ccff34dc48
commit 9d19bf2a3e
26 changed files with 1565 additions and 1135 deletions

View File

@@ -1,3 +1,12 @@
2004-07-02 Michael Natterer <mitch@gimp.org>
* plug-ins/gimpressionist/Makefile.am
* plug-ins/gimpressionist/*.[ch]: applied patch from Shlomi Fish
that massively cleans up gimppressionist (touching all files and
addding some new ones) and adds a simple PDB interface for
selecting one of the previously created presets.
Fixes bugs #145191, #144913 and #144922.
2004-07-01 Sven Neumann <sven@gimp.org>
* configure.in: bumped version number to 2.1.2.

View File

@@ -28,23 +28,29 @@ libexec_PROGRAMS = gimpressionist
gimpressionist_sources = \
brush.c \
color.h \
color.c \
general.h \
general.c \
gimp.c \
gimpressionist.c \
gimpressionist.h \
globals.c \
orientation.c \
orientmap.c \
paper.c \
placement.h \
placement.c \
plasma.c \
ppmtool.c \
ppmtool.h \
presets.c \
preview.h \
preview.c \
repaint.c \
size.c \
sizemap.c
sizemap.c \
utils.c
gimpressionist_built_sources = logo-pixbuf.h
gimpressionist.c: logo-pixbuf.h

View File

@@ -28,24 +28,41 @@
#include <libgimp/stdplugins-intl.h>
GtkWidget *brushlist = NULL;
GtkObject *brushreliefadjust = NULL;
GtkObject *brushaspectadjust = NULL;
GtkObject *brushgammaadjust = NULL;
gint brushfile = 2;
ppm_t brushppm = {0, 0, NULL};
static GtkWidget *brushprev = NULL;
static GtkListStore *brushstore = NULL;
static GtkWidget *brushlist = NULL;
static GtkObject *brushreliefadjust = NULL;
static GtkObject *brushaspectadjust = NULL;
static GtkObject *brushgammaadjust = NULL;
void brush_restore(void)
{
reselect (brushlist, pcvals.selectedbrush);
gtk_adjustment_set_value (GTK_ADJUSTMENT(brushgammaadjust), pcvals.brushgamma);
gtk_adjustment_set_value (GTK_ADJUSTMENT(brushreliefadjust), pcvals.brushrelief);
gtk_adjustment_set_value (GTK_ADJUSTMENT(brushaspectadjust), pcvals.brushaspect);
}
void brush_store(void)
{
pcvals.brushgamma = GTK_ADJUSTMENT(brushgammaadjust)->value;
}
static void updatebrushprev (const char *fn);
static gboolean colorfile (const char *fn)
static gboolean file_is_color (const char *fn)
{
return fn && strstr(fn, ".ppm");
}
void set_colorbrushes (const gchar *fn)
{
pcvals.colorbrushes = file_is_color(fn);
}
static void
brushdmenuselect (GtkWidget *widget,
gpointer data)
@@ -58,7 +75,7 @@ brushdmenuselect (GtkWidget *widget,
gint x, y;
ppm_t *p;
gint x1, y1, x2, y2;
gint row, col;
gint row;
GimpDrawable *drawable;
gint rowstride;
@@ -72,7 +89,9 @@ brushdmenuselect (GtkWidget *widget,
if (brushfile)
{
/* unselectall(brushlist); */
#if 0
unselectall(brushlist);
#endif
if (GTK_IS_WIDGET (presetsavebutton))
gtk_widget_set_sensitive (GTK_WIDGET (presetsavebutton), FALSE);
}
@@ -105,43 +124,23 @@ brushdmenuselect (GtkWidget *widget,
gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
memcpy(p->col + row*rowstride, src_row, bpr);
}
} else if(bpp > 3) { /* RGBA */
} else { /* RGBA (bpp > 3) GrayA (bpp == 2) or Gray */
gboolean is_gray = ((bpp > 3) ? TRUE : FALSE);
for(row = 0, y = y1; y < y2; row++, y++) {
guchar *tmprow = p->col + row * rowstride;
guchar *tmprow_ptr;
gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
src = src_row;
for (col = 0, x = x1; x < x2; col++, x++) {
int k = col * 3;
tmprow[k+0] = src[0];
tmprow[k+1] = src[1];
tmprow[k+2] = src[2];
src += src_rgn.bpp;
}
}
} else if(bpp == 2) { /* GrayA */
for(row = 0, y = y1; y < y2; row++, y++) {
guchar *tmprow = p->col + row * rowstride;
gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
src = src_row;
for (col = 0, x = x1; x < x2; col++, x++) {
int k = col * 3;
tmprow[k+0] = src[0];
tmprow[k+1] = src[0];
tmprow[k+2] = src[0];
src += src_rgn.bpp;
}
}
} else { /* Gray */
for(row = 0, y = y1; y < y2; row++, y++) {
guchar *tmprow = p->col + row * rowstride;
gimp_pixel_rgn_get_row (&src_rgn, src_row, x1, y, (x2 - x1));
src = src_row;
for (col = 0, x = x1; x < x2; col++, x++) {
int k = col * 3;
tmprow[k+0] = src[0];
tmprow[k+1] = src[0];
tmprow[k+2] = src[0];
src += src_rgn.bpp;
tmprow_ptr = tmprow;
/* Possible micro-optimization here:
* src_end = src + src_rgn.bpp * (x2-x1);
* for( ; src < src_end ; src += src_rgn.bpp)
* */
for (x = x1; x < x2; x++) {
*(tmprow_ptr++) = src[0];
*(tmprow_ptr++) = src[is_gray ? 1 : 0];
*(tmprow_ptr++) = src[is_gray ? 2 : 0];
src += src_rgn.bpp;
}
}
}
@@ -154,6 +153,7 @@ brushdmenuselect (GtkWidget *widget,
updatebrushprev(NULL);
}
#if 0
void dummybrushdmenuselect(GtkWidget *w, gpointer data)
{
if(brushppm.col)
@@ -162,6 +162,7 @@ void dummybrushdmenuselect(GtkWidget *w, gpointer data)
brushfile = 0;
updatebrushprev(NULL);
}
#endif
static void
brushlistrefresh (void)
@@ -237,6 +238,10 @@ validdrawable (gint32 imageid,
gimp_drawable_is_gray (drawableid));
}
/*
* This function caches the last result. Call it with fn as NULL, to
* free the arguments.
* */
void
reloadbrush (const gchar *fn,
ppm_t *p)
@@ -244,13 +249,21 @@ reloadbrush (const gchar *fn,
static char lastfn[256] = "";
static ppm_t cache = {0,0,NULL};
if (fn == NULL)
{
killppm(&cache);
lastfn[0] = '\0';
return;
}
if (strcmp(fn, lastfn))
{
g_strlcpy (lastfn, fn, sizeof (lastfn));
killppm(&cache);
loadppm (fn, &cache);
}
copyppm(&cache, p);
pcvals.colorbrushes = colorfile(fn);
set_colorbrushes(fn);
}
static void
@@ -263,7 +276,7 @@ padbrush (ppm_t *p,
int right = (width - p->width) - left;
int top = (height - p->height) / 2;
int bottom = (height - p->height) - top;
pad(p, left, right, top, bottom, black);
ppm_pad(p, left, right, top, bottom, black);
}
static void
@@ -291,7 +304,7 @@ updatebrushprev (const gchar *fn)
else if(brushppm.col)
copyppm(&brushppm, &p);
pcvals.colorbrushes = colorfile(fn);
set_colorbrushes(fn);
sc = GTK_ADJUSTMENT(brushgammaadjust)->value;
if(sc != 1.0)

View File

@@ -10,6 +10,7 @@
#include <libgimp/gimpui.h>
#include "gimpressionist.h"
#include "color.h"
#include "libgimp/stdplugins-intl.h"
@@ -17,12 +18,14 @@
#define NUMCOLORRADIO 2
static GtkWidget *colorradio[NUMCOLORRADIO];
GtkObject *colornoiseadjust = NULL;
void colorchange(int num)
void color_type_restore(void)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(colorradio[num]), TRUE);
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON(colorradio[pcvals.colortype]),
TRUE
);
}
void create_colorpage(GtkNotebook *notebook)
@@ -42,24 +45,23 @@ void create_colorpage(GtkNotebook *notebook)
&pcvals.colortype, 0,
_("A_verage under brush"),
0, &colorradio[0],
COLOR_TYPE_AVERAGE, &colorradio[COLOR_TYPE_AVERAGE],
_("C_enter of brush"),
1, &colorradio[1],
COLOR_TYPE_CENTER, &colorradio[COLOR_TYPE_CENTER],
NULL);
gimp_help_set_help_data
(colorradio[0],
(colorradio[COLOR_TYPE_AVERAGE],
_("Color is computed from the average of all pixels under the brush"),
NULL);
gimp_help_set_help_data
(colorradio[1],
(colorradio[COLOR_TYPE_CENTER],
_("Samples the color from the pixel in the center of the brush"), NULL);
gtk_box_pack_start(GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show(frame);
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (colorradio[pcvals.colortype]), TRUE);
color_type_restore();
table = gtk_table_new (1, 3, FALSE);
gtk_table_set_col_spacings (GTK_TABLE (table), 6);
@@ -74,7 +76,7 @@ void create_colorpage(GtkNotebook *notebook)
TRUE, 0, 0,
_("Adds random noise to the color"),
NULL);
g_signal_connect (brushdensityadjust, "value_changed",
g_signal_connect (colornoiseadjust, "value_changed",
G_CALLBACK (gimp_double_adjustment_update),
&pcvals.colornoise);

View File

@@ -0,0 +1,14 @@
#ifndef __COLOR_H
#define __COLOR_H
enum COLOR_TYPE_ENUM
{
COLOR_TYPE_AVERAGE = 0,
COLOR_TYPE_CENTER = 1,
};
void color_type_restore(void);
#endif /* #ifndef __COLOR_H */

View File

@@ -13,46 +13,82 @@
#define COLORBUTTONWIDTH 30
#define COLORBUTTONHEIGHT 20
GtkObject *generaldarkedgeadjust = NULL;
GtkWidget *generalpaintedges = NULL;
GtkWidget *generaltileable = NULL;
GtkWidget *generaldropshadow = NULL;
GtkWidget *generalcolbutton;
GtkObject *generalshadowadjust = NULL;
GtkObject *generalshadowdepth = NULL;
GtkObject *generalshadowblur = NULL;
GtkObject *devthreshadjust = NULL;
#define NUMGENERALBGRADIO 4
static GtkWidget *generalbgradio[NUMGENERALBGRADIO];
static GtkWidget *generalpaintedges = NULL;
static GtkObject *generaldarkedgeadjust = NULL;
static GtkWidget *generaltileable;
static GtkWidget *generaldropshadow = NULL;
static GtkWidget *generalcolbutton;
static GtkObject *generalshadowadjust = NULL;
static GtkObject *generalshadowdepth = NULL;
static GtkObject *generalshadowblur = NULL;
void generalbgchange(GtkWidget *wg, void *d, int num)
static int normalize_bg(int n)
{
int n;
return (!img_has_alpha && (n == 3)) ? 1 : n;
}
if(wg) {
n = GPOINTER_TO_INT (d);
if(!img_has_alpha && (n == 3))
n = 1;
pcvals.generalbgtype = n;
} else {
n = num;
if(!img_has_alpha && (n == 3))
n = 1;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(generalbgradio[n]), TRUE);
}
static void general_bg_store(GtkWidget *wg, void *d)
{
pcvals.generalbgtype = normalize_bg (GPOINTER_TO_INT (d));
}
void general_store(void)
{
pcvals.generalpaintedges = GTK_TOGGLE_BUTTON(generalpaintedges)->active;
pcvals.generaldarkedge = GTK_ADJUSTMENT(generaldarkedgeadjust)->value;
pcvals.generaltileable = GTK_TOGGLE_BUTTON(generaltileable)->active;
pcvals.generaldropshadow = GTK_TOGGLE_BUTTON(generaldropshadow)->active;
pcvals.generalshadowdarkness = GTK_ADJUSTMENT(generalshadowadjust)->value;
pcvals.generalshadowdepth = GTK_ADJUSTMENT(generalshadowdepth)->value;
pcvals.generalshadowblur = GTK_ADJUSTMENT(generalshadowblur)->value;
}
void general_restore(void)
{
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON (
generalbgradio[normalize_bg (pcvals.generalbgtype)]
),
TRUE
);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(generalpaintedges), pcvals.generalpaintedges);
gtk_adjustment_set_value(GTK_ADJUSTMENT(generaldarkedgeadjust), pcvals.generaldarkedge);
gtk_adjustment_set_value(GTK_ADJUSTMENT(generalshadowadjust), pcvals.generalshadowdarkness);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(generaldropshadow), pcvals.generaldropshadow);
gtk_adjustment_set_value(GTK_ADJUSTMENT(generalshadowdepth), pcvals.generalshadowdepth);
gtk_adjustment_set_value(GTK_ADJUSTMENT(generalshadowblur), pcvals.generalshadowblur);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(generaltileable), pcvals.generaltileable);
gimp_color_button_set_color (GIMP_COLOR_BUTTON(generalcolbutton),
&pcvals.color);
}
static void selectcolor(GtkWidget *widget, gpointer data)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(generalbgradio[0]), TRUE);
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON(generalbgradio[BG_TYPE_SOLID]),
TRUE
);
}
static GtkWidget *create_general_button (GtkWidget *box, int idx,
gchar *label, gchar *help_string,
GSList **radio_group
)
{
return create_radio_button (box, idx, general_bg_store, label,
help_string, radio_group, generalbgradio);
}
void create_generalpage(GtkNotebook *notebook)
{
GtkWidget *box1, *box2, *box3, *box4, *thispage;
GtkWidget *label, *tmpw, *frame, *table;
GSList * radio_group = NULL;
label = gtk_label_new_with_mnemonic (_("_General"));
@@ -68,34 +104,25 @@ void create_generalpage(GtkNotebook *notebook)
gtk_container_add (GTK_CONTAINER(frame), box3);
gtk_widget_show (box3);
generalbgradio[1] = tmpw = gtk_radio_button_new_with_label(NULL,
_("Keep original"));
gtk_widget_show(tmpw);
gtk_box_pack_start(GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
g_signal_connect(tmpw, "clicked",
G_CALLBACK (generalbgchange), GINT_TO_POINTER (1));
gimp_help_set_help_data
(tmpw, _("Preserve the original image as a background"), NULL);
create_general_button(box3, BG_TYPE_KEEP_ORIGINAL, _("Keep original"),
_("Preserve the original image as a background"),
&radio_group
);
generalbgradio[2] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("From paper"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked",
G_CALLBACK (generalbgchange), GINT_TO_POINTER (2));
gimp_help_set_help_data
(tmpw, _("Copy the texture of the selected paper as a background"), NULL);
create_general_button(box3, BG_TYPE_FROM_PAPER, _("From paper"),
_("Copy the texture of the selected paper as a background"),
&radio_group
);
box4 = gtk_hbox_new (FALSE, 6);
gtk_box_pack_start(GTK_BOX(box3), box4, FALSE, FALSE, 0);
gtk_widget_show(box4);
generalbgradio[0] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("Solid"));
gtk_box_pack_start(GTK_BOX(box4), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked",
G_CALLBACK (generalbgchange), GINT_TO_POINTER (0));
gimp_help_set_help_data
(tmpw, _("Solid colored background"), NULL);
create_general_button(box4, BG_TYPE_SOLID, _("Solid"),
_("Solid colored background"),
&radio_group
);
generalcolbutton = gimp_color_button_new (_("Color"),
COLORBUTTONWIDTH,
@@ -110,13 +137,12 @@ void create_generalpage(GtkNotebook *notebook)
gtk_box_pack_start(GTK_BOX(box4), generalcolbutton, FALSE, FALSE, 0);
gtk_widget_show (generalcolbutton);
generalbgradio[3] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(generalbgradio[0])), _("Transparent"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked",
G_CALLBACK (generalbgchange), GINT_TO_POINTER (3));
gimp_help_set_help_data
(tmpw, _("Use a transparent background; Only the strokes painted will be visible"), NULL);
tmpw =
create_general_button(box3, BG_TYPE_TRANSPARENT, _("Transparent"),
_("Use a transparent background; Only the strokes painted will be visible"),
&radio_group
);
if(!img_has_alpha)
gtk_widget_set_sensitive (tmpw, FALSE);

View File

@@ -0,0 +1,7 @@
#ifndef __GENERAL_H
#define __GENERAL_H
void general_restore(void);
void general_store(void);
#endif /* #ifndef __GENERAL_H */

View File

@@ -11,6 +11,7 @@
#include "ppmtool.h"
#include "gimpressionist.h"
#include "preview.h"
#include "libgimp/stdplugins-intl.h"
@@ -22,10 +23,6 @@ static void run (const gchar *name,
GimpParam **return_vals);
static void gimpressionist_main (void);
void repaint (ppm_t *p, ppm_t *a);
int create_gimpressionist (void);
gboolean img_has_alpha = FALSE;
GimpPlugInInfo PLUG_IN_INFO = {
NULL, /* init_proc */
@@ -34,57 +31,6 @@ GimpPlugInInfo PLUG_IN_INFO = {
run /* run_proc */
}; /* PLUG_IN_INFO */
gimpressionist_vals_t pcvals;
gimpressionist_vals_t defaultpcvals = {
4,
0.0,
60.0,
0,
12.0,
20.0,
20.0,
1.0,
1,
0.1,
0.0,
30.0,
0,
0,
"defaultbrush.pgm",
"defaultpaper.pgm",
{0,0,0,1.0},
1,
0,
{ { 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0 } },
1,
0,
0.0,
0.0,
1.0,
0,
0,
0,
0,
0,
20.0,
1,
10.0,
20.0,
0,
0.1,
{ { 0.5, 0.5, 50.0, 1.0 } },
1,
1.0,
0,
10,
4,
0, 0.0
};
static GimpDrawable *drawable;
MAIN()
@@ -97,6 +43,7 @@ query(void)
{ GIMP_PDB_INT32, "run_mode", "Interactive" },
{ GIMP_PDB_IMAGE, "image", "Input image" },
{ GIMP_PDB_DRAWABLE, "drawable", "Input drawable" },
{ GIMP_PDB_STRING, "preset", "Preset Name" },
};
gimp_install_procedure (PLUG_IN_NAME,
@@ -116,10 +63,10 @@ query(void)
}
static void
gimpressionist_get_data (char *name, gpointer ptr)
gimpressionist_get_data (void)
{
pcvals = defaultpcvals;
gimp_get_data (name, ptr);
restore_default_values();
gimp_get_data (PLUG_IN_NAME, &pcvals);
}
static void
@@ -132,9 +79,21 @@ run (const gchar *name,
static GimpParam values[1];
GimpRunMode run_mode;
GimpPDBStatusType status;
gboolean with_specified_preset;
gchar *preset_name;
status = GIMP_PDB_SUCCESS;
run_mode = param[0].data.d_int32;
with_specified_preset = FALSE;
if (nparams > 3)
{
preset_name = param[3].data.d_string;
if (strcmp(preset_name, ""))
{
with_specified_preset = TRUE;
}
}
values[0].type = GIMP_PDB_STATUS;
values[0].data.d_status = status;
@@ -153,17 +112,20 @@ run (const gchar *name,
switch (run_mode)
{
/*
* Note: there's a limitation here. Running this plug-in before the
* interactive plug-in was run will cause it to crash, because the
* data is uninitialized.
* */
case GIMP_RUN_INTERACTIVE:
gimpressionist_get_data(PLUG_IN_NAME, &pcvals);
if(!create_gimpressionist())
return;
break;
case GIMP_RUN_NONINTERACTIVE:
g_message ("GIMP_RUN_NONINTERACTIVE not implemented yet!");
status = GIMP_PDB_EXECUTION_ERROR;
break;
case GIMP_RUN_WITH_LAST_VALS:
gimpressionist_get_data(PLUG_IN_NAME, &pcvals);
case GIMP_RUN_WITH_LAST_VALS:
gimpressionist_get_data();
if (run_mode == GIMP_RUN_INTERACTIVE)
{
if(!create_gimpressionist())
return;
}
break;
default:
status = GIMP_PDB_EXECUTION_ERROR;
@@ -173,18 +135,49 @@ run (const gchar *name,
(gimp_drawable_is_rgb(drawable->drawable_id) ||
gimp_drawable_is_gray(drawable->drawable_id)))
{
gimpressionist_main();
gimp_displays_flush ();
if (run_mode == GIMP_RUN_INTERACTIVE)
gimp_set_data(PLUG_IN_NAME, &pcvals, sizeof(gimpressionist_vals_t));
if (with_specified_preset)
{
/* If select_preset fails - set to an error */
if (select_preset(preset_name))
{
status = GIMP_PDB_EXECUTION_ERROR;
}
}
/* It seems that the value of the run variable is stored in
* the preset. I don't know if it's a bug or a feature, but
* I just work here and am anxious to get a working version.
* So I'm setting it to the correct value here.
*
* It also seems that defaultpcvals have this erroneous
* value as well, so it gets set to FALSE as well. Thus it
* is always set to TRUE upon a non-interactive run.
* -- Shlomi Fish
* */
if (run_mode == GIMP_RUN_NONINTERACTIVE)
{
pcvals.run = TRUE;
}
if (status == GIMP_PDB_SUCCESS)
{
gimpressionist_main();
gimp_displays_flush ();
if (run_mode == GIMP_RUN_INTERACTIVE)
gimp_set_data(PLUG_IN_NAME, &pcvals, sizeof(gimpressionist_vals_t));
}
}
else if (status == GIMP_PDB_SUCCESS)
{
status = GIMP_PDB_EXECUTION_ERROR;
}
/* Resources Cleanup */
g_rand_free (gr);
free_parsepath_cache();
reloadbrush(NULL, NULL);
preview_free_resources();
values[0].data.d_status = status;

View File

@@ -12,6 +12,15 @@
#include <libgimp/gimpui.h>
#include "gimpressionist.h"
/*
* The Page Specific Imports
* */
#include "color.h"
#include "general.h"
#include "placement.h"
#include "preview.h"
#include "size.h"
#include "ppmtool.h"
#include "logo-pixbuf.h"
@@ -24,269 +33,36 @@
static GtkWidget *dlg = NULL;
ppm_t infile = {0,0,NULL};
ppm_t inalpha = {0,0,NULL};
GRand *gr;
GList * parsepath (void)
{
static GList *lastpath = NULL;
gchar *gimpdatasubdir, *defaultpath, *tmps;
if (lastpath)
return lastpath;
gimpdatasubdir = g_build_filename (gimp_data_directory (),
"gimpressionist", NULL);
defaultpath = g_build_filename (gimp_directory (),
"gimpressionist", gimpdatasubdir, NULL);
tmps = gimp_gimprc_query ("gimpressionist-path");
if (!tmps)
{
if (!g_file_test (gimpdatasubdir, G_FILE_TEST_IS_DIR))
{
/* No gimpressionist-path parameter,
and the default doesn't exist */
gchar *path = g_strconcat ("${gimp_dir}",
G_DIR_SEPARATOR_S,
"gimpressionist",
G_SEARCHPATH_SEPARATOR_S,
"${gimp_data_dir}",
G_DIR_SEPARATOR_S,
"gimpressionist",
NULL);
/* don't translate the gimprc entry */
g_message (_("It is highly recommended to add\n"
" (gimpressionist-path \"%s\")\n"
"(or similar) to your gimprc file."), path);
g_free (path);
}
tmps = g_strdup (defaultpath);
}
lastpath = gimp_path_parse (tmps, 16, FALSE, NULL);
g_free (tmps);
return lastpath;
}
gchar *
findfile (const gchar *fn)
{
static GList *rcpath = NULL;
GList *thispath;
gchar *filename;
g_return_val_if_fail (fn != NULL, NULL);
if (!rcpath)
rcpath = parsepath ();
thispath = rcpath;
while (rcpath && thispath)
{
filename = g_build_filename (thispath->data, fn, NULL);
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
return filename;
g_free (filename);
thispath = thispath->next;
}
return NULL;
}
void storevals(void)
{
pcvals.brushgamma = GTK_ADJUSTMENT(brushgammaadjust)->value;
pcvals.generaldarkedge = GTK_ADJUSTMENT(generaldarkedgeadjust)->value;
pcvals.paperinvert = GTK_TOGGLE_BUTTON(paperinvert)->active;
pcvals.generalpaintedges = GTK_TOGGLE_BUTTON(generalpaintedges)->active;
pcvals.generaltileable = GTK_TOGGLE_BUTTON(generaltileable)->active;
pcvals.generaldropshadow = GTK_TOGGLE_BUTTON(generaldropshadow)->active;
pcvals.generalshadowdarkness = GTK_ADJUSTMENT(generalshadowadjust)->value;
pcvals.generalshadowdepth = GTK_ADJUSTMENT(generalshadowdepth)->value;
pcvals.generalshadowblur = GTK_ADJUSTMENT(generalshadowblur)->value;
paper_store();
brush_store();
general_store();
pcvals.devthresh = GTK_ADJUSTMENT(devthreshadjust)->value;
pcvals.placecenter = GTK_TOGGLE_BUTTON(placecenter)->active;
pcvals.paperoverlay = GTK_TOGGLE_BUTTON(paperoverlay)->active;
}
void restorevals(void)
{
reselect(brushlist, pcvals.selectedbrush);
reselect(paperlist, pcvals.selectedpaper);
brush_restore();
paper_restore();
gtk_adjustment_set_value(GTK_ADJUSTMENT(orientnumadjust), pcvals.orientnum);
gtk_adjustment_set_value(GTK_ADJUSTMENT(orientfirstadjust), pcvals.orientfirst);
gtk_adjustment_set_value(GTK_ADJUSTMENT(orientlastadjust), pcvals.orientlast);
orientchange(NULL, NULL, pcvals.orienttype);
orientation_restore();
gtk_adjustment_set_value(GTK_ADJUSTMENT(sizenumadjust), pcvals.sizenum);
gtk_adjustment_set_value(GTK_ADJUSTMENT(sizefirstadjust), pcvals.sizefirst);
gtk_adjustment_set_value(GTK_ADJUSTMENT(sizelastadjust), pcvals.sizelast);
sizechange(NULL, NULL, pcvals.sizetype);
size_restore();
placechange(pcvals.placetype);
generalbgchange(NULL, NULL, pcvals.generalbgtype);
gtk_adjustment_set_value(GTK_ADJUSTMENT(brushgammaadjust), pcvals.brushgamma);
gtk_adjustment_set_value(GTK_ADJUSTMENT(brushreliefadjust), pcvals.brushrelief);
gtk_adjustment_set_value(GTK_ADJUSTMENT(brushaspectadjust), pcvals.brushaspect);
gtk_adjustment_set_value(GTK_ADJUSTMENT(brushdensityadjust), pcvals.brushdensity);
gtk_adjustment_set_value(GTK_ADJUSTMENT(generaldarkedgeadjust), pcvals.generaldarkedge);
gtk_adjustment_set_value(GTK_ADJUSTMENT(generalshadowadjust), pcvals.generalshadowdarkness);
place_restore();
general_restore();
gtk_adjustment_set_value(GTK_ADJUSTMENT(devthreshadjust), pcvals.devthresh);
gtk_adjustment_set_value(GTK_ADJUSTMENT(paperreliefadjust), pcvals.paperrelief);
gtk_adjustment_set_value(GTK_ADJUSTMENT(paperscaleadjust), pcvals.paperscale);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(paperinvert), pcvals.paperinvert);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(generalpaintedges), pcvals.generalpaintedges);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(generaltileable), pcvals.generaltileable);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(generaldropshadow), pcvals.generaldropshadow);
gtk_adjustment_set_value(GTK_ADJUSTMENT(generalshadowdepth), pcvals.generalshadowdepth);
gtk_adjustment_set_value(GTK_ADJUSTMENT(generalshadowblur), pcvals.generalshadowblur);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(placecenter), pcvals.placecenter);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(paperoverlay), pcvals.paperoverlay);
gimp_color_button_set_color (GIMP_COLOR_BUTTON(generalcolbutton),
&pcvals.color);
gtk_adjustment_set_value(GTK_ADJUSTMENT(colornoiseadjust), pcvals.colornoise);
colorchange(pcvals.colortype);
color_type_restore();
update_orientmap_dialog();
}
void
reselect (GtkWidget *view,
gchar *fname)
{
GtkTreeModel *model;
GtkTreeSelection *selection;
GtkTreeIter iter;
char *tmpfile;
tmpfile = strrchr(fname, '/');
if (tmpfile)
fname = ++tmpfile;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
if (gtk_tree_model_get_iter_first (model, &iter)) {
do {
gchar *name;
gtk_tree_model_get (model, &iter, 0, &name, -1);
if (!strcmp(name, fname)) {
gtk_tree_selection_select_iter (selection, &iter);
g_free (name);
break;
}
g_free (name);
} while (gtk_tree_model_iter_next (model, &iter));
}
}
static void readdirintolist_real(char *subdir, GtkWidget *view,
char *selected)
{
gchar *fpath;
const gchar *de;
GDir *dir;
GList *flist = NULL;
GtkTreeIter iter;
GtkListStore *store;
GtkTreeSelection *selection;
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
if (selected) {
if (!selected[0])
selected = NULL;
else {
char *nsel;
nsel = strrchr(selected, '/');
if (nsel) selected = ++nsel;
}
}
dir = g_dir_open (subdir, 0, NULL);
if (!dir)
return;
for(;;)
{
gboolean file_exists;
de = g_dir_read_name (dir);
if (!de)
break;
fpath = g_build_filename (subdir, de, NULL);
file_exists = g_file_test (fpath, G_FILE_TEST_IS_REGULAR);
g_free (fpath);
if (!file_exists)
continue;
flist = g_list_insert_sorted(flist, g_strdup(de),
(GCompareFunc)g_ascii_strcasecmp);
}
g_dir_close(dir);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
while (flist)
{
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, flist->data, -1);
if (selected)
{
if (!strcmp(flist->data, selected))
{
gtk_tree_selection_select_iter (selection, &iter);
}
}
g_free (flist->data);
flist = g_list_remove (flist, flist->data);
}
if (!selected)
{
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
gtk_tree_selection_select_iter (selection, &iter);
}
}
void readdirintolist(char *subdir, GtkWidget *view, char *selected)
{
char *tmpdir;
GList *thispath = parsepath();
while (thispath)
{
tmpdir = g_build_filename ((gchar *) thispath->data, subdir, NULL);
readdirintolist_real (tmpdir, view, selected);
g_free (tmpdir);
thispath = thispath->next;
}
}
GtkWidget *createonecolumnlist(GtkWidget *parent,
void (*changed_cb)
(GtkTreeSelection *selection, gpointer data))
void (*changed_cb)
(GtkTreeSelection *selection, gpointer data))
{
GtkListStore *store;
GtkTreeSelection *selection;
@@ -296,10 +72,10 @@ GtkWidget *createonecolumnlist(GtkWidget *parent,
swin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(swin),
GTK_SHADOW_IN);
GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (parent), swin, FALSE, FALSE, 0);
gtk_widget_show (swin);
gtk_widget_set_size_request(swin, 150,-1);
@@ -313,8 +89,8 @@ GtkWidget *createonecolumnlist(GtkWidget *parent,
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Preset", renderer,
"text", 0,
NULL);
"text", 0,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
gtk_container_add (GTK_CONTAINER (swin), view);
@@ -322,7 +98,7 @@ GtkWidget *createonecolumnlist(GtkWidget *parent,
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
g_signal_connect (selection, "changed", G_CALLBACK (changed_cb),
NULL);
NULL);
return view;
}
@@ -348,11 +124,11 @@ showabout (void)
window =
gimp_dialog_new (_("The GIMPressionist"), "gimpressionist",
NULL, 0,
gimp_standard_help_func, HELP_ID,
gimp_standard_help_func, HELP_ID,
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
NULL);
NULL);
g_signal_connect (window, "response",
G_CALLBACK (gtk_widget_destroy),
@@ -427,13 +203,13 @@ create_dialog (void)
dlg = gimp_dialog_new (_("Gimpressionist"), "gimpressionist",
NULL, 0,
gimp_standard_help_func, HELP_ID,
gimp_standard_help_func, HELP_ID,
_("A_bout"), RESPONSE_ABOUT,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
_("A_bout"), RESPONSE_ABOUT,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
NULL);
g_signal_connect (dlg, "response",
G_CALLBACK (dialog_response),

View File

@@ -1,4 +1,12 @@
#ifndef __GIMPRESSIONIST_H
#define __GIMPRESSIONIST_H
/* Includes necessary for the correct processing of this file. */
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
/* Defines */
#define PLUG_IN_NAME "plug_in_gimpressionist"
#define PLUG_IN_VERSION "v1.0, November 2003"
#define HELP_ID "plug-in-gimppressionist"
@@ -7,6 +15,9 @@
#define MAXORIENTVECT 50
#define MAXSIZEVECT 50
#define NUMORIENTRADIO 8
#define NUMSIZERADIO 8
/* Type declaration and definitions */
typedef struct vector
@@ -76,12 +87,33 @@ typedef struct
double colornoise;
} gimpressionist_vals_t;
/* Enumerations */
enum GENERAL_BG_TYPE_ENUM
{
BG_TYPE_SOLID = 0,
BG_TYPE_KEEP_ORIGINAL = 1,
BG_TYPE_FROM_PAPER = 2,
BG_TYPE_TRANSPARENT = 3,
};
enum ORIENTATION_ENUM
{
ORIENTATION_VALUE = 0,
ORIENTATION_RADIUS = 1,
ORIENTATION_RANDOM = 2,
ORIENTATION_RADIAL = 3,
ORIENTATION_FLOWING = 4,
ORIENTATION_HUE = 5,
ORIENTATION_ADAPTIVE = 6,
ORIENTATION_MANUAL = 7,
};
/* Globals */
extern char *standalone;
extern gimpressionist_vals_t pcvals;
extern gimpressionist_vals_t defaultpcvals;
extern char *path;
extern struct ppm infile;
extern struct ppm inalpha;
@@ -90,47 +122,11 @@ extern GtkWidget *window;
extern int brushfile;
extern struct ppm brushppm;
extern GtkWidget *brushlist;
extern GtkObject *brushscaleadjust;
extern GtkObject *brushaspectadjust;
extern GtkObject *brushreliefadjust;
extern GtkObject *brushdensityadjust;
extern GtkObject *brushgammaadjust;
extern GtkWidget *paperlist;
extern GtkObject *paperscaleadjust;
extern GtkObject *paperreliefadjust;
extern GtkWidget *paperinvert;
extern GtkWidget *paperoverlay;
extern GtkObject *orientnumadjust;
extern GtkObject *orientfirstadjust;
extern GtkObject *orientlastadjust;
extern int orientationtype;
extern GtkWidget *orientradio[];
extern GtkWidget *sizeradio[];
extern GtkObject *sizenumadjust;
extern GtkObject *sizefirstadjust;
extern GtkObject *sizelastadjust;
extern GtkObject *generaldarkedgeadjust;
extern int generalbgtype;
extern GtkWidget *generalpaintedges;
extern GtkWidget *generaltileable;
extern GtkWidget *generaldropshadow;
extern GtkWidget *generalcolbutton;
extern GtkObject *generalshadowadjust;
extern GtkObject *generalshadowdepth;
extern GtkObject *generalshadowblur;
extern GtkObject *devthreshadjust;
extern GtkWidget *colortype;
extern GtkObject *colornoiseadjust;
extern GtkWidget *placecenter;
extern GtkWidget *previewbutton;
extern GtkWidget *presetsavebutton;
@@ -141,20 +137,18 @@ extern GRand *gr;
/* Prototypes */
void remove_trailing_whitespace(char *buffer);
GList *parsepath(void);
void free_parsepath_cache(void);
void create_paperpage(GtkNotebook *);
void create_brushpage(GtkNotebook *);
void create_orientationpage(GtkNotebook *);
void create_sizepage(GtkNotebook *);
void create_generalpage(GtkNotebook *);
void create_presetpage(GtkNotebook *);
void create_placementpage(GtkNotebook *);
void create_colorpage(GtkNotebook *);
GtkWidget* create_preview (void);
void updatepreview (GtkWidget *wg, gpointer d);
void grabarea(void);
void storevals(void);
void restorevals(void);
@@ -163,11 +157,11 @@ gchar *findfile(const gchar *);
void unselectall(GtkWidget *list);
void reselect(GtkWidget *list, char *fname);
void readdirintolist(char *subdir, GtkWidget *view, char *selected);
void orientchange(GtkWidget *wg, void *d, int num);
void sizechange(GtkWidget *wg, void *d, int num);
void placechange(int num);
void colorchange(int num);
void generalbgchange(GtkWidget *wg, void *d, int num);
void orientation_restore(void);
void paper_store(void);
void paper_restore(void);
void brush_store(void);
void brush_restore(void);
GtkWidget *createonecolumnlist(GtkWidget *parent,
void (*changed_cb)
@@ -177,8 +171,35 @@ void reloadbrush(const gchar *fn, struct ppm *p);
void create_orientmap_dialog(void);
void update_orientmap_dialog(void);
int pixval(double dir);
double getdir(double x, double y, int from);
void create_sizemap_dialog(void);
double getsiz(double x, double y, int from);
double getsiz_proto (double x, double y, int n, smvector_t *vec,
double smstrexp, int voronoi);
enum SELECT_PRESET_RETURN_VALUES
{
SELECT_PRESET_OK = 0,
SELECT_PRESET_FILE_NOT_FOUND = -1,
SELECT_PRESET_LOAD_FAILED = -2,
};
int select_preset(char * preset);
void set_colorbrushes (const gchar *fn);
int create_gimpressionist (void);
double degtorad(double d);
double radtodeg(double d);
double dist(double x, double y, double dx, double dy);
void restore_default_values(void);
GtkWidget *create_radio_button (GtkWidget *box, int orienttype,
void (*callback)(GtkWidget *wg, void *d),
gchar *label, gchar *help_string,
GSList **radio_group,
GtkWidget **buttons_array
);
#endif /* #ifndef __GIMPRESSIONIST_H */

View File

@@ -0,0 +1,80 @@
#include "config.h"
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include "gimpressionist.h"
#include "ppmtool.h"
GtkWidget *presetsavebutton = NULL;
GtkWidget *presetdesctext = NULL;
GtkObject *devthreshadjust = NULL;
gint brushfile = 2;
ppm_t brushppm = {0, 0, NULL};
gboolean img_has_alpha = FALSE;
gimpressionist_vals_t pcvals;
ppm_t infile = {0,0,NULL};
ppm_t inalpha = {0,0,NULL};
GRand *gr;
GtkWidget *previewbutton = NULL;
GtkObject *colornoiseadjust = NULL;
/*
* The default values for the application, to be initialized at startup.
* */
static const gimpressionist_vals_t defaultpcvals = {
4,
0.0,
60.0,
0,
12.0,
20.0,
20.0,
1.0,
1,
0.1,
0.0,
30.0,
0,
0,
"defaultbrush.pgm",
"defaultpaper.pgm",
{0,0,0,1.0},
1,
0,
{ { 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0 } },
1,
0,
0.0,
0.0,
1.0,
0,
0,
0,
0,
0,
20.0,
1,
10.0,
20.0,
0,
0.1,
{ { 0.5, 0.5, 50.0, 1.0 } },
1,
1.0,
0,
10,
4,
0, 0.0
};
void restore_default_values(void)
{
pcvals = defaultpcvals;
}

View File

@@ -17,23 +17,53 @@
#include "libgimp/stdplugins-intl.h"
static GtkWidget *orientradio[NUMORIENTRADIO];
static GtkObject *orientnumadjust = NULL;
static GtkObject *orientfirstadjust = NULL;
static GtkObject *orientlastadjust = NULL;
GtkObject *orientnumadjust = NULL;
GtkObject *orientfirstadjust = NULL;
GtkObject *orientlastadjust = NULL;
#define NUMORIENTRADIO 8
GtkWidget *orientradio[NUMORIENTRADIO];
void
orientchange (GtkWidget *wg, void *d, int num)
static void orientation_store(GtkWidget *wg, void *d)
{
if (wg) {
pcvals.orienttype = GPOINTER_TO_INT (d);
} else {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(orientradio[num]), TRUE);
}
}
void orientation_restore(void)
{
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON(orientradio[pcvals.orienttype]),
TRUE
);
gtk_adjustment_set_value (
GTK_ADJUSTMENT(orientnumadjust),
pcvals.orientnum
);
gtk_adjustment_set_value(
GTK_ADJUSTMENT(orientfirstadjust),
pcvals.orientfirst
);
gtk_adjustment_set_value(
GTK_ADJUSTMENT(orientlastadjust),
pcvals.orientlast
);
}
static void create_orientmap_dialog_helper(void)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (orientradio[7]), TRUE);
create_orientmap_dialog();
return;
}
static void create_orientradio_button (GtkWidget *box, int orienttype,
gchar *label, gchar *help_string,
GSList **radio_group
)
{
create_radio_button (box, orienttype, orientation_store, label,
help_string, radio_group, orientradio);
return;
}
void
@@ -41,6 +71,7 @@ create_orientationpage (GtkNotebook *notebook)
{
GtkWidget *box2, *box3, *box4, *thispage;
GtkWidget *label, *tmpw, *table;
GSList *radio_group = NULL;
label = gtk_label_new_with_mnemonic (_("Or_ientation"));
@@ -106,101 +137,61 @@ create_orientationpage (GtkNotebook *notebook)
gtk_box_pack_start (GTK_BOX (box2), box3, FALSE, FALSE, 0);
gtk_widget_show (box3);
orientradio[0] = tmpw = gtk_radio_button_new_with_label (NULL, _("Value"));
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (orientchange), GINT_TO_POINTER (0));
gimp_help_set_help_data
(tmpw, _("Let the value (brightness) of the region determine the direction of the stroke"), NULL);
orientradio[1] = tmpw =
gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (tmpw)),
_("Radius"));
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (orientchange), GINT_TO_POINTER (1));
gimp_help_set_help_data
(tmpw, _("The distance from the center of the image determines the direction of the stroke"), NULL);
orientradio[2] = tmpw =
gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (tmpw)),
_("Random"));
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (orientchange), GINT_TO_POINTER (2));
gimp_help_set_help_data
(tmpw, _("Selects a random direction of each stroke"), NULL);
orientradio[3] = tmpw =
gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (tmpw)),
_("Radial"));
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (orientchange), GINT_TO_POINTER (3));
gimp_help_set_help_data
(tmpw, _("Let the direction from the center determine the direction of the stroke"), NULL);
create_orientradio_button (box3, ORIENTATION_VALUE, _("Value"),
_("Let the value (brightness) of the region determine the direction of the stroke"),
&radio_group
);
create_orientradio_button(box3, ORIENTATION_RADIUS, _("Radius"),
_("The distance from the center of the image determines the direction of the stroke"),
&radio_group
);
create_orientradio_button(box3, ORIENTATION_RANDOM, _("Random"),
_("Selects a random direction of each stroke"),
&radio_group
);
create_orientradio_button(box3, ORIENTATION_RADIAL, _("Radial"),
_("Let the direction from the center determine the direction of the stroke"),
&radio_group
);
box3 = gtk_vbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (box2), box3, FALSE, FALSE, 0);
gtk_widget_show (box3);
orientradio[4] = tmpw =
gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (tmpw)),
_("Flowing"));
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (orientchange), GINT_TO_POINTER (4));
gimp_help_set_help_data
(tmpw, _("The strokes follow a \"flowing\" pattern"), NULL);
create_orientradio_button(box3, ORIENTATION_FLOWING, _("Flowing"),
_("The strokes follow a \"flowing\" pattern"),
&radio_group
);
orientradio[5] = tmpw =
gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (tmpw)),
_("Hue"));
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (orientchange), GINT_TO_POINTER (5));
gimp_help_set_help_data
(tmpw, _("The hue of the region determines the direction of the stroke"),
NULL);
orientradio[6] = tmpw =
gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (tmpw)),
_("Adaptive"));
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (orientchange), GINT_TO_POINTER (6));
gimp_help_set_help_data
(tmpw, _("The direction that matches the original image the closest is selected"), NULL);
create_orientradio_button(box3, ORIENTATION_HUE, _("Hue"),
_("The hue of the region determines the direction of the stroke"),
&radio_group
);
create_orientradio_button(box3, ORIENTATION_ADAPTIVE, _("Adaptive"),
_("The direction that matches the original image the closest is selected"),
&radio_group
);
box4 = gtk_hbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (box3), box4, FALSE, FALSE, 0);
gtk_widget_show (box4);
orientradio[7] = tmpw =
gtk_radio_button_new_with_label (gtk_radio_button_get_group (GTK_RADIO_BUTTON (tmpw)),
_("Manual"));
gtk_box_pack_start (GTK_BOX (box4), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (orientchange), GINT_TO_POINTER (7));
gimp_help_set_help_data
(tmpw, _("Manually specify the stroke orientation"), NULL);
create_orientradio_button(box4, ORIENTATION_MANUAL, _("Manual"),
_("Manually specify the stroke orientation"),
&radio_group
);
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (orientradio[pcvals.orienttype]), TRUE);
orientation_restore();
tmpw = gtk_button_new_from_stock (GIMP_STOCK_EDIT);
gtk_box_pack_start (GTK_BOX (box4), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (create_orientmap_dialog), NULL);
G_CALLBACK (create_orientmap_dialog_helper), NULL);
gimp_help_set_help_data
(tmpw, _("Opens up the Orientation Map Editor"), NULL);

View File

@@ -18,6 +18,8 @@
#include "gimpressionist.h"
#include "ppmtool.h"
#include "preview.h"
#include "libgimp/stdplugins-intl.h"
#define NUMVECTYPES 4
@@ -30,15 +32,15 @@ static GtkWidget *prev_button;
static GtkWidget *next_button;
static GtkWidget *add_button;
static GtkWidget *kill_button;
static GtkObject *vectprevbrightadjust = NULL;
GtkObject *vectprevbrightadjust = NULL;
static GtkObject *angadjust = NULL;
GtkObject *stradjust = NULL;
GtkObject *strexpadjust = NULL;
GtkObject *angoffadjust = NULL;
static GtkObject *stradjust = NULL;
static GtkObject *orient_map_str_exp_adjust = NULL;
static GtkObject *angoffadjust = NULL;
static GtkWidget *vectypes[NUMVECTYPES];
GtkWidget *orientvoronoi = NULL;
static GtkWidget *orientvoronoi = NULL;
#define OMWIDTH 150
#define OMHEIGHT 150
@@ -47,32 +49,6 @@ static vector_t vector[MAXORIENTVECT];
static gint numvect = 0;
static gint vector_type;
static double degtorad(double d)
{
return d/180.0*G_PI;
}
double radtodeg(double d)
{
double v = d/G_PI*180.0;
if(v < 0.0) v += 360;
return v;
}
double dist(double x, double y, double dx, double dy)
{
double ax = dx - x;
double ay = dy - y;
return sqrt(ax * ax + ay * ay);
}
int pixval(double dir)
{
while(dir < 0.0) dir += 360.0;
while(dir >= 360.0) dir -= 360.0;
return dir * 255.0 / 360.0;
}
double getdir(double x, double y, int from)
{
int i;
@@ -87,7 +63,7 @@ double getdir(double x, double y, int from)
n = numvect;
vec = vector;
angoff = GTK_ADJUSTMENT(angoffadjust)->value;
strexp = GTK_ADJUSTMENT(strexpadjust)->value;
strexp = GTK_ADJUSTMENT(orient_map_str_exp_adjust)->value;
voronoi = GTK_TOGGLE_BUTTON(orientvoronoi)->active;
} else {
n = pcvals.numorientvector;
@@ -383,7 +359,7 @@ omresponse (GtkWidget *widget,
pcvals.orientvector[i] = vector[i];
pcvals.numorientvector = numvect;
pcvals.orientstrexp = GTK_ADJUSTMENT (strexpadjust)->value;
pcvals.orientstrexp = GTK_ADJUSTMENT (orient_map_str_exp_adjust)->value;
pcvals.orientangoff = GTK_ADJUSTMENT (angoffadjust)->value;
pcvals.orientvoronoi = GTK_TOGGLE_BUTTON (orientvoronoi)->active;
}
@@ -416,7 +392,7 @@ void update_orientmap_dialog(void)
initvectors();
gtk_adjustment_set_value(GTK_ADJUSTMENT(strexpadjust), pcvals.orientstrexp);
gtk_adjustment_set_value(GTK_ADJUSTMENT(orient_map_str_exp_adjust), pcvals.orientstrexp);
gtk_adjustment_set_value(GTK_ADJUSTMENT(angoffadjust), pcvals.orientangoff);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(orientvoronoi), pcvals.orientvoronoi);
@@ -431,8 +407,6 @@ void create_orientmap_dialog(void)
GtkWidget *frame;
GtkWidget *ebox, *hbox, *vbox;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (orientradio[7]), TRUE);
initvectors();
if (omwindow) {
@@ -605,7 +579,7 @@ void create_orientmap_dialog(void)
NULL);
g_signal_connect (stradjust, "value_changed", G_CALLBACK (stradjmove), NULL);
strexpadjust =
orient_map_str_exp_adjust =
gimp_scale_entry_new (GTK_TABLE(table2), 0, 3,
_("S_trength exp.:"),
150, 6, 1.0,
@@ -613,7 +587,7 @@ void create_orientmap_dialog(void)
TRUE, 0, 0,
_("Change the exponent of the strength"),
NULL);
g_signal_connect (strexpadjust, "value_changed",
g_signal_connect (orient_map_str_exp_adjust, "value_changed",
G_CALLBACK (strexpadjmove), NULL);
gtk_widget_show(omwindow);

View File

@@ -23,22 +23,22 @@
#include "libgimp/stdplugins-intl.h"
GtkWidget *paperlist = NULL;
GtkWidget *paperprev = NULL;
GtkObject *paperreliefadjust = NULL;
GtkObject *paperscaleadjust = NULL;
GtkWidget *paperinvert = NULL;
GtkWidget *paperoverlay = NULL;
static GtkWidget *paperprev = NULL;
static GtkListStore *paperstore;
static GtkWidget *paperinvert = NULL;
static GtkWidget *paperlist = NULL;
static GtkObject *paperreliefadjust = NULL;
static GtkObject *paperscaleadjust = NULL;
static GtkWidget *paperoverlay = NULL;
static void updatepaperprev(char *fn)
static void updatepaperprev(void)
{
gint i, j;
guchar buf[100];
gdouble sc;
ppm_t p = {0,0,NULL};
loadppm(fn, &p);
loadppm(pcvals.selectedpaper, &p);
sc = p.width > p.height ? p.width : p.height;
sc = 100.0 / sc;
resize(&p, p.width*sc,p.height*sc);
@@ -47,10 +47,10 @@ static void updatepaperprev(char *fn)
memset(buf, 0, 100);
if(i < p.height) {
for(j = 0; j < p.width; j++)
buf[j] = p.col[k + j * 3];
buf[j] = p.col[k + j * 3];
if (GTK_TOGGLE_BUTTON(paperinvert)->active)
for (j = 0; j < p.width; j++)
buf[j] = 255 - buf[j];
for (j = 0; j < p.width; j++)
buf[j] = 255 - buf[j];
}
gtk_preview_draw_row (GTK_PREVIEW (paperprev), buf, 0, i, 100);
}
@@ -77,7 +77,7 @@ static void selectpaper(GtkTreeSelection *selection, gpointer data)
g_strlcpy (pcvals.selectedpaper,
fname, sizeof (pcvals.selectedpaper));
updatepaperprev (fname);
updatepaperprev ();
g_free (fname);
g_free (paper);
@@ -85,6 +85,22 @@ static void selectpaper(GtkTreeSelection *selection, gpointer data)
}
}
void paper_restore(void)
{
reselect(paperlist, pcvals.selectedpaper);
gtk_adjustment_set_value(GTK_ADJUSTMENT(paperreliefadjust), pcvals.paperrelief);
gtk_adjustment_set_value(GTK_ADJUSTMENT(paperscaleadjust), pcvals.paperscale);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(paperinvert), pcvals.paperinvert);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(paperoverlay), pcvals.paperoverlay);
}
void paper_store(void)
{
pcvals.paperinvert = GTK_TOGGLE_BUTTON(paperinvert)->active;
pcvals.paperinvert = GTK_TOGGLE_BUTTON(paperinvert)->active;
pcvals.paperoverlay = GTK_TOGGLE_BUTTON(paperoverlay)->active;
}
void create_paperpage(GtkNotebook *notebook)
{
GtkWidget *box1, *thispage, *box2;

View File

@@ -13,6 +13,7 @@
#include <libgimp/gimpui.h>
#include "gimpressionist.h"
#include "placement.h"
#include "libgimp/stdplugins-intl.h"
@@ -20,12 +21,19 @@
#define NUMPLACERADIO 2
static GtkWidget *placeradio[NUMPLACERADIO];
GtkWidget *placecenter = NULL;
GtkObject *brushdensityadjust = NULL;
static GtkWidget *placecenter = NULL;
static GtkObject *brushdensityadjust = NULL;
void placechange(int num)
void place_restore()
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(placeradio[num]), TRUE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(placeradio[pcvals.placetype]), TRUE);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(placecenter), pcvals.placecenter);
gtk_adjustment_set_value (GTK_ADJUSTMENT(brushdensityadjust), pcvals.brushdensity);
}
void place_store()
{
pcvals.placecenter = GTK_TOGGLE_BUTTON(placecenter)->active;
}
void create_placementpage(GtkNotebook *notebook)
@@ -43,15 +51,19 @@ void create_placementpage(GtkNotebook *notebook)
G_CALLBACK (gimp_radio_button_update),
&pcvals.placetype, 0,
_("Randomly"), 0, &placeradio[0],
_("Evenly distributed"), 1, &placeradio[1],
_("Randomly"), PLACEMENT_TYPE_RANDOM,
&placeradio[PLACEMENT_TYPE_RANDOM],
_("Evenly distributed"), PLACEMENT_TYPE_EVEN_DIST,
&placeradio[PLACEMENT_TYPE_EVEN_DIST],
NULL);
gimp_help_set_help_data
(placeradio[0], _("Place strokes randomly around the image"), NULL);
(placeradio[PLACEMENT_TYPE_RANDOM],
_("Place strokes randomly around the image"), NULL);
gimp_help_set_help_data
(placeradio[1], _("The strokes are evenly distributed across the image"),
(placeradio[PLACEMENT_TYPE_EVEN_DIST],
_("The strokes are evenly distributed across the image"),
NULL);
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);

View File

@@ -0,0 +1,13 @@
#ifndef __PLACEMENT_H
#define __PLACEMENT_H
enum PLACEMENT_TYPE_ENUM
{
PLACEMENT_TYPE_RANDOM = 0,
PLACEMENT_TYPE_EVEN_DIST = 1,
};
void place_store(void);
void place_restore(void);
#endif

View File

@@ -20,14 +20,14 @@
int readline(FILE *f, char *buffer, int len)
{
again:
if(!fgets(buffer, len, f))
return -1;
if(*buffer == '#') {
goto again;
do
{
if(!fgets(buffer, len, f))
return -1;
}
while(strlen(buffer) && buffer[strlen(buffer)-1] <= ' ')
buffer[strlen(buffer)-1] = '\0';
while (buffer[0] == '#');
remove_trailing_whitespace(buffer);
return 0;
}
@@ -73,10 +73,25 @@ void getrgb(ppm_t *s, float xo, float yo, guchar *d)
int bail = 0;
int rowstride = s->width * 3;
if(xo < 0.0) bail=1;
else if(xo >= s->width-1) { xo = s->width-1; } /* bail=1; */
if(yo < 0.0) bail=1;
else if(yo >= s->height-1) { yo= s->height-1; } /* bail=1; */
if (xo < 0.0)
bail=1;
else if (xo >= s->width-1)
{
xo = s->width-1;
#if 0
bail=1;
#endif
}
if(yo < 0.0)
bail=1;
else if (yo >= s->height-1)
{
yo= s->height-1;
#if 0
bail=1;
#endif
}
if(bail) {
d[0] = d[1] = d[2] = 0;
@@ -86,16 +101,18 @@ void getrgb(ppm_t *s, float xo, float yo, guchar *d)
ix = (int)xo;
iy = (int)yo;
/*
#if 0
x1 = wrap(ix, s->width);
x2 = wrap(ix+1, s->width);
y1 = wrap(iy, s->height);
y2 = wrap(iy+1, s->height);
*/
#endif
x1 = ix; x2 = ix + 1;
y1 = iy; y2 = iy + 1;
/* printf("x1=%d y1=%d x2=%d y2=%d\n",x1,y1,x2,y2); */
#if 0
printf("x1=%d y1=%d x2=%d y2=%d\n",x1,y1,x2,y2);
#endif
x1y1 = (1.0-xo+ix)*(1.0-yo+iy);
x2y1 = (xo-ix)*(1.0-yo+iy);
@@ -188,6 +205,19 @@ void msb2lsb(unsigned int *i)
c = p[0]; p[0] = p[3]; p[3] = c;
}
static FILE * fopen_from_search_path(const gchar * fn, const char * mode)
{
FILE * f;
gchar * full_filename;
f = fopen(fn, mode);
if(!f) {
full_filename = findfile(fn);
f = fopen(full_filename, mode);
g_free(full_filename);
}
return f;
}
void loadgbr(const gchar *fn, ppm_t *p)
{
FILE *f;
@@ -195,12 +225,7 @@ void loadgbr(const gchar *fn, ppm_t *p)
gchar *ptr;
int x, y;
f = fopen(fn, "rb");
if(!f) {
ptr = findfile(fn);
f = fopen(ptr, "rb");
}
f = fopen_from_search_path(fn, "rb");
if(p->col) killppm(p);
if(!f) {
@@ -240,8 +265,7 @@ void loadppm(const char *fn, ppm_t *p)
return;
}
f = fopen(fn, "rb");
if(!f) f = fopen(findfile(fn), "rb");
f = fopen_from_search_path(fn, "rb");
if(p->col) killppm(p);
@@ -249,7 +273,9 @@ void loadppm(const char *fn, ppm_t *p)
fprintf(stderr, "loadppm: Unable to open file \"%s\"!\n", fn);
newppm(p, 10,10);
return;
/* fatal("Aborting!"); */
#if 0
fatal("Aborting!");
#endif
}
readline(f, line, 200);
@@ -259,7 +285,9 @@ void loadppm(const char *fn, ppm_t *p)
printf( "loadppm: File \"%s\" not PPM/PGM? (line=\"%s\")%c\n", fn, line, 7);
newppm(p, 10,10);
return;
/* fatal("Aborting!"); */
#if 0
fatal("Aborting!");
#endif
}
pgm = 1;
}
@@ -271,7 +299,9 @@ void loadppm(const char *fn, ppm_t *p)
printf ("loadppm: File \"%s\" not valid PPM/PGM? (line=\"%s\")%c\n", fn, line, 7);
newppm(p, 10,10);
return;
/* fatal("Aborting!"); */
#if 0
fatal("Aborting!");
#endif
}
p->col = g_malloc(p->height * p->width * 3);
@@ -315,8 +345,7 @@ void copyppm(ppm_t *s, ppm_t *p)
killppm(p);
p->width = s->width;
p->height = s->height;
p->col = g_malloc(p->width * 3 * p->height);
memcpy(p->col, s->col, p->width * 3 * p->height);
p->col = g_memdup(s->col, p->width * 3 * p->height);
}
void freerotate(ppm_t *p, double amount)
@@ -390,7 +419,9 @@ void autocrop(ppm_t *p, int room)
if(n) break;
}
if(n) ly = y;
/* printf("ly = %d\n", ly); */
#if 0
printf("ly = %d\n", ly);
#endif
/* lower */
memcpy(&tc, &p->col[(p->height-1)*rowstride], 3);
@@ -403,7 +434,9 @@ void autocrop(ppm_t *p, int room)
}
if(n) hy = y+1;
if(hy >= p->height) hy = p->height - 1;
/* printf("hy = %d\n", hy); */
#if 0
printf("hy = %d\n", hy);
#endif
/* left */
memcpy(&tc, &p->col[ly*rowstride], 3);
@@ -415,7 +448,9 @@ void autocrop(ppm_t *p, int room)
if(n) break;
}
if(n) lx = x;
/* printf("lx = %d\n", lx); */
#if 0
printf("lx = %d\n", lx);
#endif
/* right */
memcpy(&tc, &p->col[ly*rowstride + (p->width-1)*3], 3);
@@ -427,7 +462,9 @@ void autocrop(ppm_t *p, int room)
if(n) break;
}
if(n) hx = x+1;
/* printf("hx = %d\n", hx); */
#if 0
printf("hx = %d\n", hx);
#endif
lx -= room; if(lx<0) lx = 0;
ly -= room; if(ly<0) ly = 0;
@@ -446,7 +483,7 @@ void autocrop(ppm_t *p, int room)
p->height = tmp.height;
}
void pad(ppm_t *p, int left,int right, int top, int bottom, guchar *bg)
void ppm_pad(ppm_t *p, int left,int right, int top, int bottom, guchar *bg)
{
int x, y;
ppm_t tmp = {0,0,NULL};
@@ -496,6 +533,10 @@ void saveppm(ppm_t *p, const char *fn)
if (!f)
{
/*
* gimp_filename_to_utf8() and g_strerror() return temporary strings
* that need not and should not be freed. So this call is OK.
* */
g_message (_("Failed to save PPM file '%s': %s"),
gimp_filename_to_utf8 (fn), g_strerror (errno));
return;

View File

@@ -1,3 +1,6 @@
#ifndef __PPM_TOOL_H
#define __PPM_TOOL_H
#include <glib.h>
typedef struct ppm {
@@ -18,7 +21,7 @@ void saveppm(ppm_t *p, const char *fn);
void copyppm(ppm_t *s, ppm_t *p);
void fill(ppm_t *p, guchar *c);
void freerotate(ppm_t *p, double amount);
void pad(ppm_t *p, int left,int right, int top, int bottom, guchar *);
void ppm_pad(ppm_t *p, int left,int right, int top, int bottom, guchar *);
void edgepad(ppm_t *p, int left,int right, int top, int bottom);
void autocrop(ppm_t *p, int room);
void crop(ppm_t *p, int lx, int ly, int hx, int hy);
@@ -33,3 +36,6 @@ void repaint(ppm_t *p, ppm_t *a);
void blur(ppm_t *p, int xrad, int yrad);
void mkgrayplasma(ppm_t *p, float turb);
#endif /* #ifndef __PPM_TOOL_H */

View File

@@ -16,18 +16,16 @@
#include "libgimp/stdplugins-intl.h"
GtkWidget *presetnameentry = NULL;
GtkWidget *presetsavebutton = NULL;
static GtkWidget *presetnameentry = NULL;
static GtkWidget *presetlist = NULL;
GtkWidget *presetdesctext = NULL;
GtkWidget *presetdesclabel = NULL;
static GtkWidget *presetdesclabel = NULL;
static GtkListStore *store;
static char presetdesc[4096] = "";
static char *factory_defaults = "<Factory defaults>";
static void addfactorydefaults(GtkListStore *store)
static void addfactorydefaults(void)
{
GtkTreeIter iter;
@@ -38,7 +36,7 @@ static void addfactorydefaults(GtkListStore *store)
static void presetsrefresh(void)
{
gtk_list_store_clear (store);
addfactorydefaults (store);
addfactorydefaults ();
readdirintolist ("Presets", presetlist, NULL);
}
@@ -60,12 +58,6 @@ static int loadoldpreset(char *fname)
return 0;
}
static void chop(char *buffer)
{
while(strlen(buffer) && buffer[strlen(buffer)-1] <= ' ')
buffer[strlen(buffer)-1] = '\0';
}
static unsigned int hexval(char c)
{
c = g_ascii_tolower (c);
@@ -263,13 +255,15 @@ static int loadpreset(char *fn)
fclose(f);
return loadoldpreset(fn);
}
pcvals = defaultpcvals;
restore_default_values();
while(!feof(f)) {
char *tmps;
if(!fgets(line,1024,f)) break;
chop(line);
if(!fgets(line,1024,f))
break;
remove_trailing_whitespace(line);
tmps = strchr(line, '=');
if(!tmps) continue;
if(!tmps)
continue;
*tmps = '\0';
tmps++;
setval(line, tmps);
@@ -278,6 +272,44 @@ static int loadpreset(char *fn)
return 0;
}
int select_preset(char * preset)
{
int ret = SELECT_PRESET_OK;
/* I'm copying this behavior as is. As it seems applying the
* factory_defaults preset does nothing, which I'm not sure
* if that was what the author intended.
* -- Shlomi Fish
*/
if (strcmp (preset, factory_defaults))
{
gchar *rel = g_build_filename ("Presets", preset, NULL);
gchar *abs = findfile (rel);
g_free (rel);
if (abs)
{
if (loadpreset (abs))
{
ret = SELECT_PRESET_LOAD_FAILED;
}
g_free (abs);
}
else
{
ret = SELECT_PRESET_FILE_NOT_FOUND;
}
}
if (ret == SELECT_PRESET_OK)
{
/* This is so the colorbrushes param (that is not stored in the
* preset will be set correctly upon the preset loading.
* */
set_colorbrushes (pcvals.selectedbrush);
}
return ret;
}
static void applypreset(GtkWidget *w, GtkTreeSelection *selection)
{
GtkTreeIter iter;
@@ -289,19 +321,7 @@ static void applypreset(GtkWidget *w, GtkTreeSelection *selection)
gtk_tree_model_get (model, &iter, 0, &preset, -1);
if (strcmp (preset, factory_defaults))
{
gchar *rel = g_build_filename ("Presets", preset, NULL);
gchar *abs = findfile (rel);
g_free (rel);
if (abs)
{
loadpreset (abs);
g_free (abs);
}
}
select_preset(preset);
restorevals ();
@@ -383,10 +403,10 @@ create_savepreset (void)
window =
gimp_dialog_new (_("Save Current"), "gimpressionist",
NULL, 0,
gimp_standard_help_func, HELP_ID,
gimp_standard_help_func, HELP_ID,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
@@ -394,7 +414,7 @@ create_savepreset (void)
G_CALLBACK (savepresetresponse),
NULL);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_widget_destroyed),
G_CALLBACK (gtk_widget_destroyed),
&window);
box = gtk_vbox_new (FALSE, 6);
@@ -409,15 +429,15 @@ create_savepreset (void)
swin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW(swin),
GTK_SHADOW_IN);
GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER(box), swin);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(swin),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_show (swin);
buffer = gtk_text_buffer_new (NULL);
g_signal_connect (buffer, "changed",
G_CALLBACK (presetdesccallback), NULL);
G_CALLBACK (presetdesccallback), NULL);
gtk_text_buffer_set_text (buffer, presetdesc, -1);
text = gtk_text_view_new_with_buffer (buffer);
@@ -560,23 +580,22 @@ static void savepreset(void)
static void readdesc(const char *fn)
{
char *tmp;
char *rel_fname;
char *fname;
FILE *f;
fname = g_build_filename ("Presets", fn, NULL);
tmp = findfile (fname);
g_free (fname);
rel_fname = g_build_filename ("Presets", fn, NULL);
fname = findfile (rel_fname);
g_free (rel_fname);
if (!tmp)
if (!fname)
{
gtk_label_set_text (GTK_LABEL (presetdesclabel), "");
return;
}
fname = tmp;
f = fopen(fname, "rt");
g_free(fname);
if (f)
{
char line[4096];
@@ -609,7 +628,7 @@ static void selectpreset(GtkTreeSelection *selection, gpointer data)
gtk_tree_model_get (model, &iter, 0, &preset, -1);
if(strcmp(preset, factory_defaults))
gtk_entry_set_text (GTK_ENTRY(presetnameentry), preset);
gtk_entry_set_text (GTK_ENTRY(presetnameentry), preset);
readdesc (preset);
g_free (preset);
}
@@ -652,7 +671,7 @@ void create_presetpage(GtkNotebook *notebook)
presetlist = view = createonecolumnlist (box1, selectpreset);
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
addfactorydefaults (store);
addfactorydefaults ();
vbox = gtk_vbox_new (FALSE, 12);
gtk_box_pack_start (GTK_BOX (box1), vbox, FALSE, FALSE, 0);

View File

@@ -22,7 +22,6 @@
static GtkWidget *preview = NULL;
GtkWidget *previewbutton = NULL;
static void drawalpha(ppm_t *p, ppm_t *a)
@@ -35,7 +34,8 @@ static void drawalpha(ppm_t *p, ppm_t *a)
for (y = 0; y < p->height; y++) {
for (x = 0; x < p->width; x++) {
int k = y*rowstride + x*3;
if (!a->col[k]) continue;
if (!a->col[k])
continue;
v = 1.0 - a->col[k] / 255.0;
g = ((x/gridsize+y/gridsize)%2)*60+100;
p->col[k+0] *= v;
@@ -49,56 +49,74 @@ static void drawalpha(ppm_t *p, ppm_t *a)
}
}
static ppm_t preview_ppm = {0,0,NULL};
static ppm_t alpha_ppm = {0,0,NULL};
static ppm_t backup_ppm = {0,0,NULL};
static ppm_t alpha_backup_ppm = {0,0,NULL};
void preview_free_resources (void)
{
killppm (&preview_ppm);
killppm (&alpha_ppm);
killppm (&backup_ppm);
killppm (&alpha_backup_ppm);
}
void
updatepreview (GtkWidget *wg, gpointer d)
{
gint i;
guchar buf[PREVIEWSIZE*3];
static ppm_t p = {0,0,NULL};
static ppm_t a = {0,0,NULL};
static ppm_t backup = {0,0,NULL};
static ppm_t abackup = {0,0,NULL};
if(!infile.col && d) grabarea();
if(!infile.col && d)
grabarea();
if(!infile.col && !d) {
memset(buf, 0, PREVIEWSIZE*3);
for(i = 0; i < PREVIEWSIZE; i++) {
memset(buf, 0, sizeof(buf));
for(i = 0; i < PREVIEWSIZE; i++)
{
gtk_preview_draw_row (GTK_PREVIEW(preview), buf, 0, i, PREVIEWSIZE);
}
} else {
if(!backup.col) {
copyppm(&infile, &backup);
if((backup.width != PREVIEWSIZE) || (backup.height != PREVIEWSIZE))
resize_fast(&backup, PREVIEWSIZE, PREVIEWSIZE);
if(img_has_alpha) {
copyppm(&inalpha, &abackup);
if((abackup.width != PREVIEWSIZE) || (abackup.height != PREVIEWSIZE))
resize_fast(&abackup, PREVIEWSIZE, PREVIEWSIZE);
}
else
{
if(!backup_ppm.col)
{
copyppm(&infile, &backup_ppm);
if((backup_ppm.width != PREVIEWSIZE) || (backup_ppm.height != PREVIEWSIZE))
resize_fast(&backup_ppm, PREVIEWSIZE, PREVIEWSIZE);
if(img_has_alpha)
{
copyppm(&inalpha, &alpha_backup_ppm);
if((alpha_backup_ppm.width != PREVIEWSIZE) || (alpha_backup_ppm.height != PREVIEWSIZE))
resize_fast(&alpha_backup_ppm, PREVIEWSIZE, PREVIEWSIZE);
}
}
if(!p.col) {
copyppm(&backup, &p);
if(!preview_ppm.col)
{
copyppm(&backup_ppm, &preview_ppm);
if(img_has_alpha)
copyppm(&abackup, &a);
copyppm(&alpha_backup_ppm, &alpha_ppm);
}
if(d) {
if(d)
{
storevals();
if(GPOINTER_TO_INT(d) != 2)
repaint(&p, &a);
repaint(&preview_ppm, &alpha_ppm);
}
if(img_has_alpha)
drawalpha(&p, &a);
drawalpha(&preview_ppm, &alpha_ppm);
for(i = 0; i < PREVIEWSIZE; i++) {
for(i = 0; i < PREVIEWSIZE; i++)
{
gtk_preview_draw_row(GTK_PREVIEW(preview),
(guchar*) &p.col[i * PREVIEWSIZE * 3], 0, i,
PREVIEWSIZE);
(guchar*) &preview_ppm.col[i * PREVIEWSIZE * 3], 0, i,
PREVIEWSIZE);
}
killppm(&p);
killppm(&preview_ppm);
if(img_has_alpha)
killppm(&a);
killppm(&alpha_ppm);
}
gtk_widget_queue_draw (preview);
@@ -130,11 +148,11 @@ create_preview (void)
previewbutton = button = gtk_button_new_with_mnemonic( _("_Update"));
g_signal_connect (button, "clicked",
G_CALLBACK (updatepreview), (gpointer) 1);
G_CALLBACK (updatepreview), (gpointer) 1);
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
gimp_help_set_help_data (button,
_("Refresh the Preview window"), NULL);
_("Refresh the Preview window"), NULL);
button = gtk_button_new_from_stock (GIMP_STOCK_RESET);
g_signal_connect (button, "clicked",
@@ -142,7 +160,7 @@ create_preview (void)
gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
gtk_widget_show (button);
gimp_help_set_help_data (button,
_("Revert to the original image"), NULL);
_("Revert to the original image"), NULL);
return vbox;
}

View File

@@ -0,0 +1,8 @@
#ifndef __PREVIEW_H
#define __PREVIEW_H
GtkWidget* create_preview (void);
void updatepreview (GtkWidget *wg, gpointer d);
void preview_free_resources(void);
#endif /* #ifndef __PREVIEW_H */

View File

@@ -17,12 +17,27 @@
#include <libgimp/gimp.h>
#include "gimpressionist.h"
#include "placement.h"
#include "size.h"
#include "ppmtool.h"
#include <libgimp/stdplugins-intl.h>
static gimpressionist_vals_t runningvals;
static double get_siz_from_pcvals(double x, double y)
{
return getsiz_proto(x,y, pcvals.numsizevector, pcvals.sizevector,
pcvals.sizestrexp, pcvals.sizevoronoi);
}
static int pixval(double dir)
{
while(dir < 0.0) dir += 360.0;
while(dir >= 360.0) dir -= 360.0;
return dir * 255.0 / 360.0;
}
static void prepbrush(ppm_t *p)
{
int x, y;
@@ -56,6 +71,9 @@ static double sumbrush(ppm_t *p)
static int gethue(guchar *rgb)
{
double h, v, temp, diff;
/* TODO : There seems to be some typoes in the comments here.
* Ask vidar what he meant.
* */
if((rgb[0] == rgb[1]) && (rgb[0] == rgb[2])) /* Gray */
return 0;
v = (rgb[0] > rgb[1] ? rgb[0] : rgb[1]); /* v = st<F8>rste verdi */
@@ -75,8 +93,8 @@ static int gethue(guchar *rgb)
}
static int bestbrush(ppm_t *p, ppm_t *a, int tx, int ty,
ppm_t *brushes, int numbrush, double *brushsum,
int start, int step)
ppm_t *brushes, int numbrush, double *brushsum,
int start, int step)
{
double dev, thissum;
double bestdev = 0.0;
@@ -88,22 +106,26 @@ static int bestbrush(ppm_t *p, ppm_t *a, int tx, int ty,
for(i = start; i < numbrush; i += step) {
ppm_t *brush = &brushes[i];
/* thissum = 0.0; */
#if 0
thissum = 0.0;
#endif
thissum = brushsum[i];
r = g = b = 0.0;
for(y = 0; y < brush->height; y++) {
guchar *row = p->col + (ty+y)*p->width*3;
for(x = 0; x < brush->width; x++) {
int k = (tx+x)*3;
double v;
if((h = brush->col[(y*brush->width*3)+x*3])) {
/* thissum += h; */
v = h / 255.0;
r += row[k+0] * v;
g += row[k+1] * v;
b += row[k+2] * v;
}
int k = (tx+x)*3;
double v;
if((h = brush->col[(y*brush->width*3)+x*3])) {
#if 0
thissum += h;
#endif
v = h / 255.0;
r += row[k+0] * v;
g += row[k+1] * v;
b += row[k+2] * v;
}
}
}
r = r * 255.0 / thissum;
@@ -114,23 +136,23 @@ static int bestbrush(ppm_t *p, ppm_t *a, int tx, int ty,
for(y = 0; y < brush->height; y++) {
guchar *row = p->col + (ty+y)*p->width*3;
for(x = 0; x < brush->width; x++) {
int k = (tx+x)*3;
double v;
if((h = brush->col[(y*brush->width*3)+x*3])) {
v = h / 255.0;
dev += abs(row[k+0] - r) * v;
dev += abs(row[k+1] - g) * v;
dev += abs(row[k+2] - b) * v;
if(img_has_alpha)
dev += a->col[(ty+y)*a->width*3+(tx+x)*3] * v;
}
int k = (tx+x)*3;
double v;
if((h = brush->col[(y*brush->width*3)+x*3])) {
v = h / 255.0;
dev += abs(row[k+0] - r) * v;
dev += abs(row[k+1] - g) * v;
dev += abs(row[k+2] - b) * v;
if(img_has_alpha)
dev += a->col[(ty+y)*a->width*3+(tx+x)*3] * v;
}
}
}
dev /= thissum;
if((best == -1) || (dev < bestdev)) {
if(brlist)
g_list_free(brlist);
g_list_free(brlist);
brlist = NULL;
}
@@ -155,9 +177,9 @@ static int bestbrush(ppm_t *p, ppm_t *a, int tx, int ty,
}
static void applybrush(ppm_t *brush,
ppm_t *shadow,
ppm_t *p, ppm_t *a,
int tx, int ty, int r, int g, int b)
ppm_t *shadow,
ppm_t *p, ppm_t *a,
int tx, int ty, int r, int g, int b)
{
ppm_t tmp;
ppm_t atmp;
@@ -182,16 +204,16 @@ static void applybrush(ppm_t *brush,
row = tmp.col + (sy+y) * tmp.width * 3;
if(img_has_alpha) arow = atmp.col + (sy+y) * atmp.width * 3;
for(x = 0; x < shadow->width; x++) {
int k = (sx + x) * 3;
if((sx + x) < 0) continue;
if((sx + x) >= tmp.width) break;
h = shadow->col[y*shadow->width*3+x*3+2];
if(!h) continue;
v = 1.0 - (h / 255.0 * runningvals.generalshadowdarkness / 100.0);
row[k+0] *= v;
row[k+1] *= v;
row[k+2] *= v;
if(img_has_alpha) arow[k] *= v;
int k = (sx + x) * 3;
if((sx + x) < 0) continue;
if((sx + x) >= tmp.width) break;
h = shadow->col[y*shadow->width*3+x*3+2];
if(!h) continue;
v = 1.0 - (h / 255.0 * runningvals.generalshadowdarkness / 100.0);
row[k+0] *= v;
row[k+1] *= v;
row[k+2] *= v;
if(img_has_alpha) arow[k] *= v;
}
}
}
@@ -206,11 +228,11 @@ static void applybrush(ppm_t *brush,
if(!h) continue;
if(runningvals.colorbrushes) {
v = 1.0 - brush->col[y*brush->width*3+x*3+2] / 255.0;
row[k+0] *= v;
row[k+1] *= v;
row[k+2] *= v;
if(img_has_alpha) arow[(tx+x)*3] *= v;
v = 1.0 - brush->col[y*brush->width*3+x*3+2] / 255.0;
row[k+0] *= v;
row[k+1] *= v;
row[k+2] *= v;
if(img_has_alpha) arow[(tx+x)*3] *= v;
}
v = (1.0 - h / 255.0) * edgedarken;
row[k+0] *= v;
@@ -229,13 +251,13 @@ static void applybrush(ppm_t *brush,
for(y = 1; y < brush->height; y++) {
guchar *row = tmp.col + (ty+y)*tmp.width*3;
for(x = 1; x < brush->width; x++) {
int k = (tx + x) * 3;
h = brush->col[y*brush->width*3+x*3+1] * relief;
if(h < 0.001) continue;
if(h > 255) h = 255;
row[k+0] = (row[k+0] * (255-h) + 255 * h) / 255;
row[k+1] = (row[k+1] * (255-h) + 255 * h) / 255;
row[k+2] = (row[k+2] * (255-h) + 255 * h) / 255;
int k = (tx + x) * 3;
h = brush->col[y*brush->width*3+x*3+1] * relief;
if(h < 0.001) continue;
if(h > 255) h = 255;
row[k+0] = (row[k+0] * (255-h) + 255 * h) / 255;
row[k+1] = (row[k+1] * (255-h) + 255 * h) / 255;
row[k+2] = (row[k+2] * (255-h) + 255 * h) / 255;
}
}
}
@@ -287,7 +309,8 @@ void repaint(ppm_t *p, ppm_t *a)
density = runningvals.brushdensity;
if(runningvals.placetype == 1) density /= 3.0;
if(runningvals.placetype == PLACEMENT_TYPE_EVEN_DIST)
density /= 3.0;
bgamma = runningvals.brushgamma;
@@ -313,8 +336,8 @@ void repaint(ppm_t *p, ppm_t *a)
resize(&brushes[0], brushes[0].width * scale, brushes[0].height * scale);
i = 1 + sqrt(brushes[0].width * brushes[0].width +
brushes[0].height * brushes[0].height);
pad(&brushes[0], i-brushes[0].width, i-brushes[0].width,
brushes[0].height * brushes[0].height);
ppm_pad(&brushes[0], i-brushes[0].width, i-brushes[0].width,
i-brushes[0].height, i-brushes[0].height, back);
for(i = 1; i < numbrush; i++) {
@@ -330,20 +353,20 @@ void repaint(ppm_t *p, ppm_t *a)
for(j = 0; j < runningvals.orientnum; j++) {
h = j + i * runningvals.orientnum;
freerotate(&brushes[h],
startangle + j * anglespan / runningvals.orientnum);
startangle + j * anglespan / runningvals.orientnum);
rescale(&brushes[h], (sv * runningvals.sizefirst + (1.0-sv) * runningvals.sizelast) / runningvals.sizelast);
autocrop(&brushes[h],1);
}
}
/* Brush-debugging */
/*
#if 0
for(i = 0; i < numbrush; i++) {
char tmp[1000];
sprintf(tmp, "/tmp/_brush%03d.ppm", i);
saveppm(&brushes[i], tmp);
}
*/
#endif
for(i = 0; i < numbrush; i++) {
if(!runningvals.colorbrushes)
@@ -367,7 +390,7 @@ void repaint(ppm_t *p, ppm_t *a)
xp = maxbrushwidth - brushes[i].width;
yp = maxbrushheight - brushes[i].height;
if(xp || yp)
pad(&brushes[i], xp/2, xp-xp/2, yp/2, yp-yp/2, blk);
ppm_pad(&brushes[i], xp/2, xp-xp/2, yp/2, yp-yp/2, blk);
}
if(dropshadow) {
@@ -375,24 +398,26 @@ void repaint(ppm_t *p, ppm_t *a)
shadows[i].col = NULL;
copyppm(&brushes[i], &shadows[i]);
ppmgamma(&shadows[i], 0, 1,1,0);
pad(&shadows[i], shadowblur*2, shadowblur*2,
shadowblur*2, shadowblur*2, back);
ppm_pad(&shadows[i], shadowblur*2, shadowblur*2,
shadowblur*2, shadowblur*2, back);
for(j = 0; j < shadowblur; j++)
blur(&shadows[i], 2, 2);
/* autocrop(&shadows[i],1); */
blur(&shadows[i], 2, 2);
#if 0
autocrop(&shadows[i],1);
#endif
}
/*
#if 0
maxbrushwidth += shadowdepth*3;
maxbrushheight += shadowdepth*3;
*/
#endif
}
/* For extra annoying debugging :-) */
/*
#if 0
saveppm(brushes, "/tmp/__brush.ppm");
if(shadows) saveppm(shadows, "/tmp/__shadow.ppm");
system("xv /tmp/__brush.ppm & xv /tmp/__shadow.ppm & ");
*/
#endif
if(runningvals.generalpaintedges) {
edgepad(p, maxbrushwidth, maxbrushwidth, maxbrushheight, maxbrushheight);
@@ -402,7 +427,7 @@ void repaint(ppm_t *p, ppm_t *a)
if(img_has_alpha) {
/* Initially fully transparent */
if(runningvals.generalbgtype == 3) {
if(runningvals.generalbgtype == BG_TYPE_TRANSPARENT) {
guchar tmpcol[3] = {255,255,255};
newppm(&atmp, a->width, a->height);
fill(&atmp, tmpcol);
@@ -411,12 +436,12 @@ void repaint(ppm_t *p, ppm_t *a)
}
}
if(runningvals.generalbgtype == 0) {
if(runningvals.generalbgtype == BG_TYPE_SOLID) {
guchar tmpcol[3];
newppm(&tmp, p->width, p->height);
gimp_rgb_get_uchar(&runningvals.color, &tmpcol[0], &tmpcol[1], &tmpcol[2]);
fill(&tmp, tmpcol);
} else if(runningvals.generalbgtype == 1) {
} else if(runningvals.generalbgtype == BG_TYPE_KEEP_ORIGINAL) {
copyppm(p, &tmp);
} else {
scale = runningvals.paperscale / 100.0;
@@ -428,8 +453,8 @@ void repaint(ppm_t *p, ppm_t *a)
for(x = 0; x < tmp.width; x++) {
int rx = x % paperppm.width;
for(y = 0; y < tmp.height; y++) {
int ry = y % paperppm.height;
memcpy(&tmp.col[y*tmp.width*3+x*3], &paperppm.col[ry*paperppm.width*3+rx*3], 3);
int ry = y % paperppm.height;
memcpy(&tmp.col[y*tmp.width*3+x*3], &paperppm.col[ry*paperppm.width*3+rx*3], 3);
}
}
}
@@ -438,33 +463,38 @@ void repaint(ppm_t *p, ppm_t *a)
cy = p->height / 2;
maxdist = sqrt(cx*cx+cy*cy);
if(runningvals.orienttype == 0) { /* Value */
switch(runningvals.orienttype)
{
case ORIENTATION_VALUE:
newppm(&dirmap, p->width, p->height);
for(y = 0; y < dirmap.height; y++) {
guchar *dstrow = &dirmap.col[y*dirmap.width*3];
guchar *srcrow = &p->col[y*p->width*3];
for(x = 0; x < dirmap.width; x++) {
dstrow[x*3] = (srcrow[x*3] + srcrow[x*3+1] + srcrow[x*3+2]) / 3;
dstrow[x*3] = (srcrow[x*3] + srcrow[x*3+1] + srcrow[x*3+2]) / 3;
}
}
} else if(runningvals.orienttype == 1) { /* Radius */
break;
case ORIENTATION_RADIUS:
newppm(&dirmap, p->width, p->height);
for(y = 0; y < dirmap.height; y++) {
guchar *dstrow = &dirmap.col[y*dirmap.width*3];
double ysqr = (cy-y)*(cy-y);
for(x = 0; x < dirmap.width; x++) {
dstrow[x*3] = sqrt((cx-x)*(cx-x)+ysqr) * 255 / maxdist;
dstrow[x*3] = sqrt((cx-x)*(cx-x)+ysqr) * 255 / maxdist;
}
}
} else if(runningvals.orienttype == 3) { /* Radial */
break;
case ORIENTATION_RADIAL:
newppm(&dirmap, p->width, p->height);
for(y = 0; y < dirmap.height; y++) {
guchar *dstrow = &dirmap.col[y*dirmap.width*3];
for(x = 0; x < dirmap.width; x++) {
dstrow[x*3] = (G_PI + atan2(cy-y, cx-x)) * 255.0 / (G_PI*2);
dstrow[x*3] = (G_PI + atan2(cy-y, cx-x)) * 255.0 / (G_PI*2);
}
}
} else if(runningvals.orienttype == 4) { /* Flowing */
break;
case ORIENTATION_FLOWING:
newppm(&dirmap, p->width / 6 + 5, p->height / 6 + 5);
mkgrayplasma(&dirmap, 15);
blur(&dirmap, 2, 2);
@@ -473,59 +503,71 @@ void repaint(ppm_t *p, ppm_t *a)
blur(&dirmap, 2, 2);
if(runningvals.generalpaintedges)
edgepad(&dirmap, maxbrushwidth, maxbrushheight,maxbrushwidth, maxbrushheight);
} else if(runningvals.orienttype == 5) { /* Hue */
break;
case ORIENTATION_HUE:
newppm(&dirmap, p->width, p->height);
for(y = 0; y < dirmap.height; y++) {
guchar *dstrow = &dirmap.col[y*dirmap.width*3];
guchar *srcrow = &p->col[y*p->width*3];
for(x = 0; x < dirmap.width; x++) {
dstrow[x*3] = gethue(&srcrow[x*3]);
dstrow[x*3] = gethue(&srcrow[x*3]);
}
}
} else if(runningvals.orienttype == 6) {
guchar tmpcol[3] = {0,0,0};
newppm(&dirmap, p->width, p->height);
fill(&dirmap, tmpcol);
} else if(runningvals.orienttype == 7) { /* Manual */
break;
case ORIENTATION_ADAPTIVE:
{
guchar tmpcol[3] = {0,0,0};
newppm(&dirmap, p->width, p->height);
fill(&dirmap, tmpcol);
}
break;
case ORIENTATION_MANUAL:
newppm(&dirmap, p->width-maxbrushwidth*2, p->height-maxbrushheight*2);
for(y = 0; y < dirmap.height; y++) {
guchar *dstrow = &dirmap.col[y*dirmap.width*3];
double tmpy = y / (double)dirmap.height;
for(x = 0; x < dirmap.width; x++) {
dstrow[x*3] = pixval(90-getdir(x / (double)dirmap.width, tmpy, 1));
dstrow[x*3] = pixval(90-getdir(x / (double)dirmap.width, tmpy, 1));
}
}
edgepad(&dirmap, maxbrushwidth, maxbrushwidth, maxbrushheight, maxbrushheight);
break;
}
if(runningvals.sizetype == 0) { /* Value */
if(runningvals.sizetype == SIZE_TYPE_VALUE)
{
newppm(&sizmap, p->width, p->height);
for(y = 0; y < sizmap.height; y++) {
guchar *dstrow = &sizmap.col[y*sizmap.width*3];
guchar *srcrow = &p->col[y*p->width*3];
for(x = 0; x < sizmap.width; x++) {
dstrow[x*3] = (srcrow[x*3] + srcrow[x*3+1] + srcrow[x*3+2]) / 3;
dstrow[x*3] = (srcrow[x*3] + srcrow[x*3+1] + srcrow[x*3+2]) / 3;
}
}
} else if(runningvals.sizetype == 1) { /* Radius */
}
else if(runningvals.sizetype == SIZE_TYPE_RADIUS)
{
newppm(&sizmap, p->width, p->height);
for(y = 0; y < sizmap.height; y++) {
guchar *dstrow = &sizmap.col[y*sizmap.width*3];
double ysqr = (cy-y)*(cy-y);
for(x = 0; x < sizmap.width; x++) {
dstrow[x*3] = sqrt((cx-x)*(cx-x)+ysqr) * 255 / maxdist;
dstrow[x*3] = sqrt((cx-x)*(cx-x)+ysqr) * 255 / maxdist;
}
}
} else if(runningvals.sizetype == 3) { /* Radial */
}
else if(runningvals.sizetype == SIZE_TYPE_RADIAL)
{
newppm(&sizmap, p->width, p->height);
for(y = 0; y < sizmap.height; y++) {
guchar *dstrow = &sizmap.col[y*sizmap.width*3];
for(x = 0; x < sizmap.width; x++) {
dstrow[x*3] = (G_PI + atan2(cy-y, cx-x)) * 255.0 / (G_PI*2);
dstrow[x*3] = (G_PI + atan2(cy-y, cx-x)) * 255.0 / (G_PI*2);
}
}
} else if(runningvals.sizetype == 4) { /* Flowing */
}
else if(runningvals.sizetype == SIZE_TYPE_FLOWING)
{
newppm(&sizmap, p->width / 6 + 5, p->height / 6 + 5);
mkgrayplasma(&sizmap, 15);
blur(&sizmap, 2, 2);
@@ -534,42 +576,50 @@ void repaint(ppm_t *p, ppm_t *a)
blur(&sizmap, 2, 2);
if(runningvals.generalpaintedges)
edgepad(&sizmap, maxbrushwidth, maxbrushheight,maxbrushwidth, maxbrushheight);
} else if(runningvals.sizetype == 5) { /* Hue */
}
else if(runningvals.sizetype == SIZE_TYPE_HUE)
{
newppm(&sizmap, p->width, p->height);
for(y = 0; y < sizmap.height; y++) {
guchar *dstrow = &sizmap.col[y*sizmap.width*3];
guchar *srcrow = &p->col[y*p->width*3];
for(x = 0; x < sizmap.width; x++) {
dstrow[x*3] = gethue(&srcrow[x*3]);
dstrow[x*3] = gethue(&srcrow[x*3]);
}
}
} else if(runningvals.sizetype == 6) {
}
else if(runningvals.sizetype == SIZE_TYPE_ADAPTIVE)
{
guchar tmpcol[3] = {0,0,0};
newppm(&sizmap, p->width, p->height);
fill(&sizmap, tmpcol);
} else if(runningvals.sizetype == 7) { /* Manual */
}
else if(runningvals.sizetype == SIZE_TYPE_MANUAL)
{
newppm(&sizmap, p->width-maxbrushwidth*2, p->height-maxbrushheight*2);
for(y = 0; y < sizmap.height; y++) {
guchar *dstrow = &sizmap.col[y*sizmap.width*3];
double tmpy = y / (double)sizmap.height;
for(x = 0; x < sizmap.width; x++) {
dstrow[x*3] = 255 * (1.0 - getsiz(x / (double)sizmap.width, tmpy, 1));
dstrow[x*3] = 255 * (1.0 - get_siz_from_pcvals(x / (double)sizmap.width, tmpy));
}
}
edgepad(&sizmap, maxbrushwidth, maxbrushwidth, maxbrushheight, maxbrushheight);
}
/*
#if 0
saveppm(&sizmap, "/tmp/_sizmap.ppm");
*/
if(runningvals.placetype == 0) {
#endif
if(runningvals.placetype == PLACEMENT_TYPE_RANDOM) {
i = tmp.width * tmp.height / (maxbrushwidth * maxbrushheight);
i *= density;
} else if(runningvals.placetype == 1) {
} else if(runningvals.placetype == PLACEMENT_TYPE_EVEN_DIST) {
i = (int)(tmp.width * density / maxbrushwidth) *
(int)(tmp.height * density / maxbrushheight);
step = i;
/* fprintf(stderr, "step=%d i=%d\n", step, i); */
#if 0
fprintf(stderr, "step=%d i=%d\n", step, i);
#endif
}
if(i < 1) i = 1;
@@ -577,7 +627,7 @@ void repaint(ppm_t *p, ppm_t *a)
progstep = max_progress / 30;
if(progstep < 10) progstep = 10;
if(runningvals.placetype == 1) {
if(runningvals.placetype == PLACEMENT_TYPE_EVEN_DIST) {
int j;
xpos = g_new (int, i);
ypos = g_new (int, i);
@@ -600,20 +650,20 @@ void repaint(ppm_t *p, ppm_t *a)
if(runningvals.run) {
gimp_progress_update(0.8 - 0.8*((double)i / max_progress));
} else {
char tmps[40];
sprintf(tmps, "%.1f %%", 100 * (1.0 - ((double)i / max_progress)));
gtk_label_set_text(GTK_LABEL(GTK_BIN(previewbutton)->child), tmps);
while(gtk_events_pending())
gtk_main_iteration();
char tmps[40];
sprintf(tmps, "%.1f %%", 100 * (1.0 - ((double)i / max_progress)));
gtk_label_set_text(GTK_LABEL(GTK_BIN(previewbutton)->child), tmps);
while(gtk_events_pending())
gtk_main_iteration();
}
}
if(runningvals.placetype == 0) {
if(runningvals.placetype == PLACEMENT_TYPE_RANDOM) {
tx = g_rand_int_range (gr, maxbrushwidth/2,
tmp.width - maxbrushwidth/2);
ty = g_rand_int_range (gr, maxbrushheight/2,
tmp.height - maxbrushheight/2);
} else if(runningvals.placetype == 1) {
} else if(runningvals.placetype == PLACEMENT_TYPE_EVEN_DIST) {
tx = xpos[i-1];
ty = ypos[i-1];
}
@@ -626,32 +676,32 @@ void repaint(ppm_t *p, ppm_t *a)
if((tx < maxbrushwidth/2) || (ty < maxbrushwidth/2) ||
(tx + maxbrushwidth/2 >= p->width) ||
(ty + maxbrushheight/2 >= p->height)) {
/*
#if 0
fprintf(stderr, "Internal Error; invalid coords: (%d,%d) i=%d\n", tx, ty, i);
*/
#endif
continue;
}
if(img_has_alpha) {
if(a->col[ty*a->width*3+tx*3] > 128)
continue;
continue;
}
n = sn = on = 0;
switch(runningvals.orienttype) {
case 2: /* Random */
case ORIENTATION_RANDOM:
on = g_rand_int_range (gr, 0, runningvals.orientnum);
break;
case 0: /* Value */
case 1: /* Radius */
case 3: /* Radial */
case 4: /* Flowing */
case 5: /* Hue */
case 7: /* Manual */
case ORIENTATION_VALUE:
case ORIENTATION_RADIUS:
case ORIENTATION_RADIAL:
case ORIENTATION_FLOWING:
case ORIENTATION_HUE:
case ORIENTATION_MANUAL:
on = runningvals.orientnum * dirmap.col[ty*dirmap.width*3+tx*3] / 256;
break;
case 6: /* Adaptive */
case ORIENTATION_ADAPTIVE:
break; /* Handled below */
default:
fprintf(stderr, "Internal error; Unknown orientationtype\n");
@@ -660,18 +710,18 @@ void repaint(ppm_t *p, ppm_t *a)
}
switch(runningvals.sizetype) {
case 2: /* Random */
case SIZE_TYPE_RANDOM:
sn = g_rand_int_range (gr, 0, runningvals.sizenum);
break;
case 0: /* Value */
case 1: /* Radius */
case 3: /* Radial */
case 4: /* Flowing */
case 5: /* Hue */
case 7: /* Manual */
case SIZE_TYPE_VALUE:
case SIZE_TYPE_RADIUS:
case SIZE_TYPE_RADIAL:
case SIZE_TYPE_FLOWING:
case SIZE_TYPE_HUE:
case SIZE_TYPE_MANUAL:
sn = runningvals.sizenum * sizmap.col[ty*sizmap.width*3+tx*3] / 256;
break;
case 6: /* Adaptive */
case SIZE_TYPE_ADAPTIVE:
break; /* Handled below */
default:
fprintf(stderr, "Internal error; Unknown sizetype\n");
@@ -680,16 +730,19 @@ void repaint(ppm_t *p, ppm_t *a)
}
/* Handle Adaptive selections */
if((runningvals.orienttype == 6) && (runningvals.sizetype == 6)) {
/* TODO : Nest the ifs here. */
if((runningvals.orienttype == ORIENTATION_ADAPTIVE) &&
(runningvals.sizetype == SIZE_TYPE_ADAPTIVE))
{
n = bestbrush(p, a, tx-maxbrushwidth/2, ty-maxbrushheight/2,
brushes, numbrush, brushsum, 0, 1);
} else if(runningvals.orienttype == 6) {
brushes, numbrush, brushsum, 0, 1);
} else if(runningvals.orienttype == ORIENTATION_ADAPTIVE) {
int st = sn * runningvals.orientnum;
n = bestbrush(p, a, tx-maxbrushwidth/2, ty-maxbrushheight/2,
brushes, st+runningvals.orientnum, brushsum, st, 1);
} else if(runningvals.sizetype == 6) {
brushes, st+runningvals.orientnum, brushsum, st, 1);
} else if(runningvals.sizetype == SIZE_TYPE_ADAPTIVE) {
n = bestbrush(p, a, tx-maxbrushwidth/2, ty-maxbrushheight/2,
brushes, numbrush, brushsum, on, runningvals.orientnum);
brushes, numbrush, brushsum, on, runningvals.orientnum);
} else {
n = sn * runningvals.orientnum + on;
}
@@ -710,17 +763,17 @@ void repaint(ppm_t *p, ppm_t *a)
if(runningvals.colortype == 0) {
r = g = b = 0;
for(y = 0; y < brush->height; y++) {
guchar *row = &p->col[(ty+y)*p->width*3];
for(x = 0; x < brush->width; x++) {
int k = (tx+x) * 3;
double v;
if((h = brush->col[y*brush->width*3+x*3])) {
v = h / 255.0;
r += row[k+0] * v;
g += row[k+1] * v;
b += row[k+2] * v;
}
}
guchar *row = &p->col[(ty+y)*p->width*3];
for(x = 0; x < brush->width; x++) {
int k = (tx+x) * 3;
double v;
if((h = brush->col[y*brush->width*3+x*3])) {
v = h / 255.0;
r += row[k+0] * v;
g += row[k+1] * v;
b += row[k+2] * v;
}
}
}
r = r * 255.0 / thissum;
g = g * 255.0 / thissum;
@@ -739,12 +792,17 @@ void repaint(ppm_t *p, ppm_t *a)
}
if(runningvals.colornoise > 0.0) {
double v = runningvals.colornoise;
r = r + g_rand_double_range (gr, -v/2.0, v/2.0);
g = g + g_rand_double_range (gr, -v/2.0, v/2.0);
b = b + g_rand_double_range (gr, -v/2.0, v/2.0);
if(r < 0) r = 0; else if(r > 255) r = 255;
if(g < 0) g = 0; else if(g > 255) g = 255;
if(b < 0) b = 0; else if(b > 255) b = 255;
#define BOUNDS(a) (((a) < 0) ? (a) : ((a) > 255) ? 255 : (a))
#define MYASSIGN(a) \
{ \
a = a + g_rand_double_range (gr, -v/2.0, v/2.0); \
a = BOUNDS(a) ; \
}
MYASSIGN(r);
MYASSIGN(g);
MYASSIGN(b);
#undef BOUNDS
#undef MYASSIGN
}
applybrush(brush, shadow, &tmp, &atmp, tx,ty, r,g,b);
@@ -753,24 +811,24 @@ void repaint(ppm_t *p, ppm_t *a)
int origheight = tmp.height - 2 * maxbrushheight;
int dox = 0, doy = 0;
if(tx < maxbrushwidth) {
applybrush(brush, shadow, &tmp, &atmp, tx+origwidth,ty, r,g,b);
dox = -1;
applybrush(brush, shadow, &tmp, &atmp, tx+origwidth,ty, r,g,b);
dox = -1;
} else if(tx > origwidth) {
applybrush(brush, shadow, &tmp, &atmp, tx-origwidth,ty, r,g,b);
dox = 1;
applybrush(brush, shadow, &tmp, &atmp, tx-origwidth,ty, r,g,b);
dox = 1;
}
if(ty < maxbrushheight) {
applybrush(brush, shadow, &tmp, &atmp, tx,ty+origheight, r,g,b);
doy = 1;
applybrush(brush, shadow, &tmp, &atmp, tx,ty+origheight, r,g,b);
doy = 1;
} else if(ty > origheight) {
applybrush(brush, shadow, &tmp, &atmp, tx,ty-origheight, r,g,b);
doy = -1;
applybrush(brush, shadow, &tmp, &atmp, tx,ty-origheight, r,g,b);
doy = -1;
}
if(doy) {
if(dox < 0)
applybrush(brush, shadow, &tmp, &atmp, tx+origwidth,ty+doy*origheight,r,g,b);
if(dox > 0)
applybrush(brush, shadow, &tmp, &atmp, tx-origwidth,ty+doy*origheight,r,g,b);
if(dox < 0)
applybrush(brush, shadow, &tmp, &atmp, tx+origwidth,ty+doy*origheight,r,g,b);
if(dox > 0)
applybrush(brush, shadow, &tmp, &atmp, tx-origwidth,ty+doy*origheight,r,g,b);
}
}
}
@@ -814,31 +872,31 @@ void repaint(ppm_t *p, ppm_t *a)
loadppm(runningvals.selectedpaper, &tmp);
resize(&tmp, tmp.width * scale, tmp.height * scale);
if(runningvals.paperinvert)
ppmgamma(&tmp, -1.0, 1,1,1);
ppmgamma(&tmp, -1.0, 1,1,1);
}
for(x = 0; x < p->width; x++) {
double h, v;
int px = x % tmp.width, py;
for(y = 0; y < p->height; y++) {
int k = y * p->width * 3 + x * 3;
py = y % tmp.height;
if(runningvals.paperoverlay)
h = (tmp.col[py*tmp.width*3+px*3]-128) * relief;
else
h = (tmp.col[py*tmp.width*3+px*3] - (int)tmp.col[((py+1)%tmp.height)*tmp.width*3+((px+1)%tmp.width)*3]) / -2.0 * relief;
if(h <= 0.0) {
v = 1.0 + h/128.0;
if(v < 0.0) v = 0.0; else if(v > 1.0) v = 1.0;
p->col[k+0] *= v;
p->col[k+1] *= v;
p->col[k+2] *= v;
} else {
v = h/128.0;
if(v < 0.0) v = 0.0; else if(v > 1.0) v = 1.0;
p->col[k+0] = p->col[k+0] * (1.0-v) + 255 * v;
p->col[k+1] = p->col[k+1] * (1.0-v) + 255 * v;
p->col[k+2] = p->col[k+2] * (1.0-v) + 255 * v;
}
int k = y * p->width * 3 + x * 3;
py = y % tmp.height;
if(runningvals.paperoverlay)
h = (tmp.col[py*tmp.width*3+px*3]-128) * relief;
else
h = (tmp.col[py*tmp.width*3+px*3] - (int)tmp.col[((py+1)%tmp.height)*tmp.width*3+((px+1)%tmp.width)*3]) / -2.0 * relief;
if(h <= 0.0) {
v = 1.0 + h/128.0;
if(v < 0.0) v = 0.0; else if(v > 1.0) v = 1.0;
p->col[k+0] *= v;
p->col[k+1] *= v;
p->col[k+2] *= v;
} else {
v = h/128.0;
if(v < 0.0) v = 0.0; else if(v > 1.0) v = 1.0;
p->col[k+0] = p->col[k+0] * (1.0-v) + 255 * v;
p->col[k+1] = p->col[k+1] * (1.0-v) + 255 * v;
p->col[k+2] = p->col[k+2] * (1.0-v) + 255 * v;
}
}
}
killppm(&tmp);

View File

@@ -14,31 +14,56 @@
#include "gimpressionist.h"
#include "ppmtool.h"
#include "size.h"
#include "libgimp/stdplugins-intl.h"
static GtkObject *sizenumadjust = NULL;
static GtkObject *sizefirstadjust = NULL;
static GtkObject *sizelastadjust = NULL;
static GtkWidget *sizeradio[NUMSIZERADIO];
GtkObject *sizenumadjust = NULL;
GtkObject *sizefirstadjust = NULL;
GtkObject *sizelastadjust = NULL;
#define NUMSIZERADIO 8
GtkWidget *sizeradio[NUMSIZERADIO];
void sizechange(GtkWidget *wg, void *d, int num)
static void size_store(GtkWidget *wg, void *d)
{
if(wg) {
pcvals.sizetype = GPOINTER_TO_INT (d);
} else {
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(sizeradio[num]), TRUE);
}
pcvals.sizetype = GPOINTER_TO_INT (d);
}
static void size_type_restore(void)
{
gtk_toggle_button_set_active (
GTK_TOGGLE_BUTTON(sizeradio[pcvals.sizetype]),
TRUE
);
}
void size_restore(void)
{
size_type_restore();
gtk_adjustment_set_value(GTK_ADJUSTMENT(sizenumadjust), pcvals.sizenum);
gtk_adjustment_set_value(GTK_ADJUSTMENT(sizefirstadjust), pcvals.sizefirst);
gtk_adjustment_set_value(GTK_ADJUSTMENT(sizelastadjust), pcvals.sizelast);
}
static void create_sizemap_dialog_helper(void)
{
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sizeradio[7]), TRUE);
create_sizemap_dialog();
}
static void create_size_radio_button (GtkWidget *box, int orienttype,
gchar *label, gchar *help_string,
GSList **radio_group
)
{
create_radio_button (box, orienttype, size_store, label,
help_string, radio_group, sizeradio);
}
void create_sizepage(GtkNotebook *notebook)
{
GtkWidget *box2, *box3, *box4, *thispage;
GtkWidget *label, *tmpw, *table;
GSList * radio_group = NULL;
label = gtk_label_new_with_mnemonic (_("_Size"));
@@ -104,81 +129,62 @@ void create_sizepage(GtkNotebook *notebook)
gtk_box_pack_start(GTK_BOX(box2), box3, FALSE, FALSE, 0);
gtk_widget_show(box3);
sizeradio[0] = tmpw = gtk_radio_button_new_with_label(NULL, _("Value"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked", G_CALLBACK(sizechange),
GINT_TO_POINTER(0));
gimp_help_set_help_data (tmpw, _("Let the value (brightness) of the region determine the size of the stroke"), NULL);
sizeradio[1] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("Radius"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked", G_CALLBACK(sizechange),
GINT_TO_POINTER(1));
gimp_help_set_help_data (tmpw, _("The distance from the center of the image determines the size of the stroke"), NULL);
sizeradio[2] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("Random"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked", G_CALLBACK(sizechange),
GINT_TO_POINTER(2));
gimp_help_set_help_data (tmpw, _("Selects a random size for each stroke"), NULL);
sizeradio[3] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("Radial"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked", G_CALLBACK(sizechange),
GINT_TO_POINTER(3));
gimp_help_set_help_data (tmpw, _("Let the direction from the center determine the size of the stroke"), NULL);
create_size_radio_button (box3, SIZE_TYPE_VALUE, _("Value"),
_("Let the value (brightness) of the region determine the size of the stroke"),
&radio_group
);
create_size_radio_button (box3, SIZE_TYPE_RADIUS, _("Radius"),
_("The distance from the center of the image determines the size of the stroke"),
&radio_group
);
create_size_radio_button (box3, SIZE_TYPE_RANDOM, _("Random"),
_("Selects a random size for each stroke"),
&radio_group
);
create_size_radio_button (box3, SIZE_TYPE_RADIAL, _("Radial"),
_("Let the direction from the center determine the size of the stroke"),
&radio_group
);
box3 = gtk_vbox_new(FALSE, 6);
gtk_box_pack_start(GTK_BOX(box2), box3,FALSE,FALSE, 0);
gtk_widget_show(box3);
sizeradio[4] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("Flowing"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked", G_CALLBACK(sizechange),
GINT_TO_POINTER(4));
gimp_help_set_help_data
(tmpw, _("The strokes follow a \"flowing\" pattern"), NULL);
create_size_radio_button (box3, SIZE_TYPE_FLOWING, _("Flowing"),
_("The strokes follow a \"flowing\" pattern"),
&radio_group
);
create_size_radio_button (box3, SIZE_TYPE_HUE, _("Hue"),
_("The hue of the region determines the size of the stroke"),
&radio_group
);
sizeradio[5] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("Hue"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked", G_CALLBACK(sizechange),
GINT_TO_POINTER(5));
gimp_help_set_help_data
(tmpw, _("The hue of the region determines the size of the stroke"),
NULL);
create_size_radio_button (box3, SIZE_TYPE_ADAPTIVE, _("Adaptive"),
_("The brush-size that matches the original image the closest is selected"),
&radio_group
);
sizeradio[6] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("Adaptive"));
gtk_box_pack_start(GTK_BOX(box3), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked", G_CALLBACK(sizechange),
GINT_TO_POINTER(6));
gimp_help_set_help_data (tmpw, _("The brush-size that matches the original image the closest is selected"), NULL);
box4 = gtk_hbox_new(FALSE, 6);
gtk_box_pack_start(GTK_BOX(box3), box4, FALSE, FALSE, 0);
gtk_widget_show(box4);
sizeradio[7] = tmpw = gtk_radio_button_new_with_label(gtk_radio_button_get_group(GTK_RADIO_BUTTON(tmpw)), _("Manual"));
gtk_box_pack_start(GTK_BOX(box4), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked", G_CALLBACK(sizechange),
GINT_TO_POINTER(7));
gimp_help_set_help_data (tmpw, _("Manually specify the stroke size"), NULL);
gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (sizeradio[pcvals.sizetype]), TRUE);
create_size_radio_button (box4, SIZE_TYPE_MANUAL, _("Manual"),
_("Manually specify the stroke size"),
&radio_group
);
size_type_restore();
tmpw = gtk_button_new_from_stock (GIMP_STOCK_EDIT);
gtk_box_pack_start(GTK_BOX(box4), tmpw, FALSE, FALSE, 0);
gtk_widget_show(tmpw);
g_signal_connect(tmpw, "clicked",
G_CALLBACK(create_sizemap_dialog), NULL);
G_CALLBACK(create_sizemap_dialog_helper), NULL);
gimp_help_set_help_data (tmpw, _("Opens up the Size Map Editor"), NULL);
gtk_notebook_append_page_menu (notebook, thispage, label, NULL);

View File

@@ -0,0 +1,20 @@
#ifndef __SIZE_H
#define __SIZE_H
enum SIZE_TYPE_ENUM
{
SIZE_TYPE_VALUE = 0,
SIZE_TYPE_RADIUS = 1,
SIZE_TYPE_RANDOM = 2,
SIZE_TYPE_RADIAL = 3,
SIZE_TYPE_FLOWING = 4,
SIZE_TYPE_HUE = 5,
SIZE_TYPE_ADAPTIVE = 6,
SIZE_TYPE_MANUAL = 7,
};
void size_restore(void);
void create_sizepage(GtkNotebook *);
#endif /* #ifndef __SIZE_H */

View File

@@ -17,6 +17,9 @@
#include "gimpressionist.h"
#include "ppmtool.h"
#include "size.h"
#include "preview.h"
#include "libgimp/stdplugins-intl.h"
@@ -33,12 +36,12 @@ static GtkWidget *next_button;
static GtkWidget *add_button;
static GtkWidget *kill_button;
GtkObject *smvectprevbrightadjust = NULL;
static GtkObject *smvectprevbrightadjust = NULL;
GtkObject *sizadjust = NULL;
GtkObject *smstradjust = NULL;
GtkObject *smstrexpadjust = NULL;
GtkWidget *sizevoronoi = NULL;
static GtkObject *sizadjust = NULL;
static GtkObject *smstradjust = NULL;
static GtkObject *smstrexpadjust = NULL;
static GtkWidget *sizevoronoi = NULL;
#define OMWIDTH 150
#define OMHEIGHT 150
@@ -46,74 +49,14 @@ GtkWidget *sizevoronoi = NULL;
static smvector_t smvector[MAXSIZEVECT];
static int numsmvect = 0;
double dist(double x, double y, double dx, double dy);
double getsiz(double x, double y, int from)
static double getsiz_from_gui(double x, double y)
{
int i;
int n;
int voronoi;
double sum, ssum, dst;
smvector_t *vec;
double smstrexp;
int first = 0, last;
if((x < 0.0) || (x > 1.0)) printf("HUH? x = %f\n",x);
if (from == 0)
{
n = numsmvect;
vec = smvector;
smstrexp = GTK_ADJUSTMENT(smstrexpadjust)->value;
voronoi = GTK_TOGGLE_BUTTON(sizevoronoi)->active;
}
else
{
n = pcvals.numsizevector;
vec = pcvals.sizevector;
smstrexp = pcvals.sizestrexp;
voronoi = pcvals.sizevoronoi;
}
if (voronoi)
{
gdouble bestdist = -1.0;
for (i = 0; i < n; i++)
{
dst = dist(x, y, vec[i].x, vec[i].y);
if ((bestdist < 0.0) || (dst < bestdist))
{
bestdist = dst;
first = i;
}
}
last = first+1;
}
else
{
first = 0;
last = n;
}
sum = ssum = 0.0;
for (i = first; i < last; i++)
{
gdouble s = vec[i].str;
dst = dist(x,y,vec[i].x,vec[i].y);
dst = pow(dst, smstrexp);
if(dst < 0.0001) dst = 0.0001;
s = s / dst;
sum += vec[i].siz * s;
ssum += 1.0/dst;
}
sum = sum / ssum / 100.0;
return CLAMP(sum, 0.0, 1.0);
return getsiz_proto(x,y, numsmvect, smvector,
GTK_ADJUSTMENT(smstrexpadjust)->value,
GTK_TOGGLE_BUTTON(sizevoronoi)->active);
}
void updatesmpreviewprev(void)
static void updatesmpreviewprev(void)
{
gint x, y;
static ppm_t nsbuffer;
@@ -129,13 +72,14 @@ void updatesmpreviewprev(void)
for (y = 6; y < OMHEIGHT-4; y += 10)
{
for (x = 6; x < OMWIDTH-4; x += 10)
{
gdouble siz = 5 * getsiz(x/(double)OMWIDTH,y/(double)OMHEIGHT,0);
drawline (&nsbuffer, x-siz, y-siz, x+siz, y-siz, gray);
drawline (&nsbuffer, x+siz, y-siz, x+siz, y+siz, gray);
drawline (&nsbuffer, x+siz, y+siz, x-siz, y+siz, gray);
drawline (&nsbuffer, x-siz, y+siz, x-siz, y-siz, gray);
}
{
gdouble siz = 5 * getsiz_from_gui(x/(double)OMWIDTH,
y/(double)OMHEIGHT);
drawline (&nsbuffer, x-siz, y-siz, x+siz, y-siz, gray);
drawline (&nsbuffer, x+siz, y-siz, x+siz, y+siz, gray);
drawline (&nsbuffer, x+siz, y+siz, x-siz, y+siz, gray);
drawline (&nsbuffer, x-siz, y+siz, x-siz, y-siz, gray);
}
}
for (y = 0; y < OMHEIGHT; y++)
@@ -145,7 +89,7 @@ void updatesmpreviewprev(void)
static gint selectedsmvector = 0;
void updatesmvectorprev(void)
static void updatesmvectorprev(void)
{
static ppm_t backup = {0,0,NULL};
static ppm_t sbuffer = {0,0,NULL};
@@ -165,11 +109,11 @@ void updatesmvectorprev(void)
if(!ok || (val != lastval))
{
if(!infile.col)
updatepreview (NULL, (void *)2); /* Force grabarea() */
updatepreview (NULL, (void *)2); /* Force grabarea() */
copyppm(&infile, &backup);
ppmbrightness(&backup, val, 1,1,1);
if (backup.width != OMWIDTH || backup.height != OMHEIGHT)
resize_fast(&backup, OMWIDTH, OMHEIGHT);
resize_fast(&backup, OMWIDTH, OMHEIGHT);
ok = 1;
}
copyppm(&backup, &sbuffer);
@@ -178,12 +122,15 @@ void updatesmvectorprev(void)
{
x = smvector[i].x * OMWIDTH;
y = smvector[i].y * OMHEIGHT;
if (i == selectedsmvector) {
drawline (&sbuffer, x-5, y, x+5, y, red);
drawline (&sbuffer, x, y-5, x, y+5, red);
} else {
drawline (&sbuffer, x-5, y, x+5, y, gray);
drawline (&sbuffer, x, y-5, x, y+5, gray);
if (i == selectedsmvector)
{
drawline (&sbuffer, x-5, y, x+5, y, red);
drawline (&sbuffer, x, y-5, x, y+5, red);
}
else
{
drawline (&sbuffer, x-5, y, x+5, y, gray);
drawline (&sbuffer, x, y-5, x, y+5, gray);
}
putrgb (&sbuffer, x, y, white);
}
@@ -200,17 +147,17 @@ void updatesmvectorprev(void)
static gboolean smadjignore = FALSE;
void updatesmsliders(void)
static void updatesmsliders(void)
{
smadjignore = TRUE;
gtk_adjustment_set_value(GTK_ADJUSTMENT(sizadjust),
smvector[selectedsmvector].siz);
smvector[selectedsmvector].siz);
gtk_adjustment_set_value(GTK_ADJUSTMENT(smstradjust),
smvector[selectedsmvector].str);
smvector[selectedsmvector].str);
smadjignore = FALSE;
}
void smprevclick(GtkWidget *w, gpointer data)
static void smprevclick(GtkWidget *w, gpointer data)
{
selectedsmvector--;
if(selectedsmvector < 0) selectedsmvector = numsmvect-1;
@@ -218,7 +165,7 @@ void smprevclick(GtkWidget *w, gpointer data)
updatesmvectorprev();
}
void smnextclick(GtkWidget *w, gpointer data)
static void smnextclick(GtkWidget *w, gpointer data)
{
selectedsmvector++;
if(selectedsmvector == numsmvect) selectedsmvector = 0;
@@ -269,16 +216,17 @@ static void smmapclick(GtkWidget *w, GdkEventButton *event)
selectedsmvector = numsmvect;
numsmvect++;
updatesmsliders();
/*
} else if(event->button == 3) {
}
#if 0
else if(event->button == 3) {
double d;
d = atan2(OMWIDTH * smvector[selectedsmvector].x - event->x,
OMHEIGHT * smvector[selectedsmvector].y - event->y);
OMHEIGHT * smvector[selectedsmvector].y - event->y);
smvector[selectedsmvector].dir = radtodeg(d);
updatesmsliders();
*/
}
#endif
updatesmvectorprev();
updatesmpreviewprev();
}
@@ -338,7 +286,7 @@ smresponse (GtkWidget *widget,
gtk_widget_hide (widget);
}
void initsmvectors(void)
static void initsmvectors(void)
{
if (pcvals.numsizevector)
{
@@ -346,9 +294,9 @@ void initsmvectors(void)
numsmvect = pcvals.numsizevector;
for (i = 0; i < numsmvect; i++)
{
smvector[i] = pcvals.sizevector[i];
}
{
smvector[i] = pcvals.sizevector[i];
}
}
else
{
@@ -371,9 +319,9 @@ static void update_sizemap_dialog(void)
initsmvectors();
gtk_adjustment_set_value(GTK_ADJUSTMENT(smstrexpadjust),
pcvals.sizestrexp);
pcvals.sizestrexp);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sizevoronoi),
pcvals.sizevoronoi);
pcvals.sizevoronoi);
updatesmvectorprev();
updatesmpreviewprev();
@@ -388,8 +336,6 @@ void create_sizemap_dialog(void)
GtkWidget *table2;
GtkWidget *hbox;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sizeradio[7]), TRUE);
initsmvectors();
if (smwindow)
@@ -403,11 +349,11 @@ void create_sizemap_dialog(void)
smwindow =
gimp_dialog_new (_("Size Map Editor"), "gimpressionist",
NULL, 0,
gimp_standard_help_func, HELP_ID,
gimp_standard_help_func, HELP_ID,
GTK_STOCK_APPLY, RESPONSE_APPLY,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
GTK_STOCK_APPLY, RESPONSE_APPLY,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OK, GTK_RESPONSE_OK,
NULL);
@@ -415,7 +361,7 @@ void create_sizemap_dialog(void)
G_CALLBACK (smresponse),
NULL);
g_signal_connect (smwindow, "destroy",
G_CALLBACK (gtk_widget_destroyed),
G_CALLBACK (gtk_widget_destroyed),
&smwindow);
table1 = gtk_table_new(2, 5, FALSE);
@@ -481,21 +427,21 @@ void create_sizemap_dialog(void)
gtk_box_pack_start(GTK_BOX(hbox),tmpw,FALSE,TRUE,0);
gtk_widget_show(tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK(smnextclick), NULL);
G_CALLBACK(smnextclick), NULL);
gimp_help_set_help_data (tmpw, _("Select next smvector"), NULL);
add_button = tmpw = gtk_button_new_with_mnemonic( _("A_dd"));
gtk_box_pack_start(GTK_BOX(hbox),tmpw,FALSE,TRUE,0);
gtk_widget_show(tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK(smaddclick), NULL);
G_CALLBACK(smaddclick), NULL);
gimp_help_set_help_data (tmpw, _("Add new smvector"), NULL);
kill_button = tmpw = gtk_button_new_with_mnemonic( _("_Kill"));
gtk_box_pack_start(GTK_BOX(hbox),tmpw,FALSE,TRUE,0);
gtk_widget_show(tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK(smdeleteclick), NULL);
G_CALLBACK(smdeleteclick), NULL);
gimp_help_set_help_data (tmpw, _("Delete selected smvector"), NULL);
table2 = gtk_table_new(3, 4, FALSE);
@@ -505,36 +451,36 @@ void create_sizemap_dialog(void)
sizadjust =
gimp_scale_entry_new (GTK_TABLE(table2), 0, 0,
_("_Size:"),
150, 6, 50.0,
0.0, 100.0, 1.0, 10.0, 1,
TRUE, 0, 0,
_("Change the angle of the selected smvector"),
NULL);
_("_Size:"),
150, 6, 50.0,
0.0, 100.0, 1.0, 10.0, 1,
TRUE, 0, 0,
_("Change the angle of the selected smvector"),
NULL);
g_signal_connect (sizadjust, "value_changed", G_CALLBACK(angsmadjmove),
NULL);
NULL);
smstradjust =
gimp_scale_entry_new (GTK_TABLE(table2), 0, 1,
_("S_trength:"),
150, 6, 1.0,
0.1, 5.0, 0.1, 0.5, 1,
TRUE, 0, 0,
_("Change the strength of the selected smvector"),
NULL);
_("S_trength:"),
150, 6, 1.0,
0.1, 5.0, 0.1, 0.5, 1,
TRUE, 0, 0,
_("Change the strength of the selected smvector"),
NULL);
g_signal_connect (smstradjust, "value_changed", G_CALLBACK(strsmadjmove),
NULL);
NULL);
smstrexpadjust =
gimp_scale_entry_new (GTK_TABLE(table2), 0, 2,
_("St_rength exp.:"),
150, 6, 1.0,
0.1, 10.9, 0.1, 0.5, 1,
TRUE, 0, 0,
_("Change the exponent of the strength"),
NULL);
_("St_rength exp.:"),
150, 6, 1.0,
0.1, 10.9, 0.1, 0.5, 1,
TRUE, 0, 0,
_("Change the exponent of the strength"),
NULL);
g_signal_connect (smstrexpadjust, "value_changed",
G_CALLBACK(smstrexpsmadjmove), NULL);
G_CALLBACK(smstrexpsmadjmove), NULL);
sizevoronoi = tmpw = gtk_check_button_new_with_mnemonic( _("_Voronoi"));
gtk_table_attach_defaults(GTK_TABLE(table2), tmpw, 3, 4, 0, 1);
@@ -542,7 +488,7 @@ void create_sizemap_dialog(void)
gtk_widget_show (tmpw);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tmpw), pcvals.sizevoronoi);
g_signal_connect(tmpw, "clicked",
G_CALLBACK(smstrexpsmadjmove), NULL);
G_CALLBACK(smstrexpsmadjmove), NULL);
gimp_help_set_help_data (tmpw, _("Voronoi-mode makes only the smvector closest to the given point have any influence"), NULL);
gtk_widget_show(smwindow);

View File

@@ -0,0 +1,355 @@
/*
* utils.c - various utility routines that don't fit anywhere else. Usually
* these routines don't affect the state of the program.
* */
#include <math.h>
#include <string.h>
#include "gimpressionist.h"
#include "config.h"
#include "libgimp/stdplugins-intl.h"
/* Mathematical Utilities */
double degtorad(double d)
{
return d/180.0*G_PI;
}
double radtodeg(double d)
{
double v = d/G_PI*180.0;
if(v < 0.0) v += 360;
return v;
}
double dist(double x, double y, double end_x, double end_y)
{
double dx = end_x - x;
double dy = end_y - y;
return sqrt(dx * dx + dy * dy);
}
double getsiz_proto (double x, double y, int n, smvector_t *vec,
double smstrexp, int voronoi)
{
int i;
double sum, ssum, dst;
int first = 0, last;
if((x < 0.0) || (x > 1.0)) printf("HUH? x = %f\n",x);
#if 0
if (from == 0)
{
n = numsmvect;
vec = smvector;
smstrexp = GTK_ADJUSTMENT(smstrexpadjust)->value;
voronoi = GTK_TOGGLE_BUTTON(sizevoronoi)->active;
}
else
{
n = pcvals.numsizevector;
vec = pcvals.sizevector;
smstrexp = pcvals.sizestrexp;
voronoi = pcvals.sizevoronoi;
}
#endif
if (voronoi)
{
gdouble bestdist = -1.0;
for (i = 0; i < n; i++)
{
dst = dist(x, y, vec[i].x, vec[i].y);
if ((bestdist < 0.0) || (dst < bestdist))
{
bestdist = dst;
first = i;
}
}
last = first+1;
}
else
{
first = 0;
last = n;
}
sum = ssum = 0.0;
for (i = first; i < last; i++)
{
gdouble s = vec[i].str;
dst = dist(x,y,vec[i].x,vec[i].y);
dst = pow(dst, smstrexp);
if (dst < 0.0001)
dst = 0.0001;
s = s / dst;
sum += vec[i].siz * s;
ssum += 1.0/dst;
}
sum = sum / ssum / 100.0;
return CLAMP(sum, 0.0, 1.0);
}
/* String and Path Manipulation Routines */
void remove_trailing_whitespace(char *buffer)
{
char * ptr;
/*
* Note: there is some reliance on the ASCII character code
* characteristics here.
* */
ptr = buffer + strlen(buffer)-1;
while ((ptr > buffer) && ((*ptr) <= ' '))
*(ptr--) = '\0';
}
static GList *parsepath_cached_path = NULL;
/* This function is memoized. Once it finds the value it permanently
* caches it
* */
GList * parsepath (void)
{
gchar *gimpdatasubdir, *defaultpath, *tmps;
if (parsepath_cached_path)
return parsepath_cached_path;
gimpdatasubdir = g_build_filename (gimp_data_directory (),
"gimpressionist", NULL);
defaultpath = g_build_filename (gimp_directory (),
"gimpressionist", gimpdatasubdir, NULL);
tmps = gimp_gimprc_query ("gimpressionist-path");
if (!tmps)
{
if (!g_file_test (gimpdatasubdir, G_FILE_TEST_IS_DIR))
{
/* No gimpressionist-path parameter,
and the default doesn't exist */
gchar *path = g_strconcat ("${gimp_dir}",
G_DIR_SEPARATOR_S,
"gimpressionist",
G_SEARCHPATH_SEPARATOR_S,
"${gimp_data_dir}",
G_DIR_SEPARATOR_S,
"gimpressionist",
NULL);
/* don't translate the gimprc entry */
g_message (_("It is highly recommended to add\n"
" (gimpressionist-path \"%s\")\n"
"(or similar) to your gimprc file."), path);
g_free (path);
}
tmps = g_strdup (defaultpath);
}
parsepath_cached_path = gimp_path_parse (tmps, 16, FALSE, NULL);
g_free (tmps);
return parsepath_cached_path;
}
static void my_g_free (gpointer data, gpointer userdata)
{
g_free(data);
}
void free_parsepath_cache(void)
{
if (parsepath_cached_path != NULL)
return
g_list_foreach(parsepath_cached_path, my_g_free, NULL);
g_list_free(parsepath_cached_path);
parsepath_cached_path = NULL;
}
gchar *
findfile (const gchar *fn)
{
GList *rcpath;
GList *thispath;
gchar *filename;
g_return_val_if_fail (fn != NULL, NULL);
rcpath = parsepath ();
thispath = rcpath;
while (thispath)
{
filename = g_build_filename (thispath->data, fn, NULL);
if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
return filename;
g_free (filename);
thispath = thispath->next;
}
return NULL;
}
/* GUI Routines */
void
reselect (GtkWidget *view,
gchar *fname)
{
GtkTreeModel *model;
GtkTreeSelection *selection;
GtkTreeIter iter;
char *tmpfile;
tmpfile = strrchr(fname, '/');
if (tmpfile)
fname = ++tmpfile;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
if (gtk_tree_model_get_iter_first (model, &iter)) {
gboolean quit = FALSE;
do {
gchar *name;
gtk_tree_model_get (model, &iter, 0, &name, -1);
if (!strcmp(name, fname)) {
gtk_tree_selection_select_iter (selection, &iter);
quit = TRUE;
}
g_free (name);
} while ((!quit) && gtk_tree_model_iter_next (model, &iter));
}
}
static void readdirintolist_real(char *subdir, GtkWidget *view,
char *selected)
{
gchar *fpath;
const gchar *de;
GDir *dir;
GList *flist = NULL;
GtkTreeIter iter;
GtkListStore *store;
GtkTreeSelection *selection;
store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
if (selected) {
if (!selected[0])
selected = NULL;
else {
char *nsel;
nsel = strrchr(selected, '/');
if (nsel) selected = ++nsel;
}
}
dir = g_dir_open (subdir, 0, NULL);
if (!dir)
return;
for(;;)
{
gboolean file_exists;
de = g_dir_read_name (dir);
if (!de)
break;
fpath = g_build_filename (subdir, de, NULL);
file_exists = g_file_test (fpath, G_FILE_TEST_IS_REGULAR);
g_free (fpath);
if (!file_exists)
continue;
flist = g_list_insert_sorted(flist, g_strdup(de),
(GCompareFunc)g_ascii_strcasecmp);
}
g_dir_close(dir);
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
while (flist)
{
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter, 0, flist->data, -1);
if (selected)
{
if (!strcmp(flist->data, selected))
{
gtk_tree_selection_select_iter (selection, &iter);
}
}
g_free (flist->data);
flist = g_list_remove (flist, flist->data);
}
if (!selected)
{
if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
gtk_tree_selection_select_iter (selection, &iter);
}
}
void readdirintolist(char *subdir, GtkWidget *view, char *selected)
{
char *tmpdir;
GList *thispath = parsepath();
while (thispath)
{
tmpdir = g_build_filename ((gchar *) thispath->data, subdir, NULL);
readdirintolist_real (tmpdir, view, selected);
g_free (tmpdir);
thispath = thispath->next;
}
}
/*
* Creates a radio button.
* box - the containing box.
* orienttype - The orientation ID
* label, help_string - self-describing
* radio_group -
* A pointer to a radio group. The function assigns its value
* as the radio group of the radio button. Afterwards, it assigns it
* a new value of the new radio group of the button.
* This is useful to group buttons. Just reset the variable to NULL,
* to create a new group.
* */
GtkWidget *create_radio_button (GtkWidget *box, int orienttype,
void (*callback)(GtkWidget *wg, void *d),
gchar *label, gchar *help_string,
GSList **radio_group,
GtkWidget **buttons_array
)
{
GtkWidget *tmpw;
buttons_array[orienttype] = tmpw =
gtk_radio_button_new_with_label ((*radio_group), label);
gtk_box_pack_start (GTK_BOX (box), tmpw, FALSE, FALSE, 0);
gtk_widget_show (tmpw);
g_signal_connect (tmpw, "clicked",
G_CALLBACK (callback), GINT_TO_POINTER (orienttype));
gimp_help_set_help_data (tmpw, help_string, NULL);
*radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (tmpw));
return tmpw;
}