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:
committed by
Michael Natterer
parent
ccff34dc48
commit
9d19bf2a3e
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
||||
|
14
plug-ins/gimpressionist/color.h
Normal file
14
plug-ins/gimpressionist/color.h
Normal 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 */
|
||||
|
@@ -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);
|
||||
|
||||
|
7
plug-ins/gimpressionist/general.h
Normal file
7
plug-ins/gimpressionist/general.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef __GENERAL_H
|
||||
#define __GENERAL_H
|
||||
|
||||
void general_restore(void);
|
||||
void general_store(void);
|
||||
|
||||
#endif /* #ifndef __GENERAL_H */
|
@@ -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;
|
||||
|
||||
|
@@ -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),
|
||||
|
@@ -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 */
|
||||
|
||||
|
80
plug-ins/gimpressionist/globals.c
Normal file
80
plug-ins/gimpressionist/globals.c
Normal 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;
|
||||
}
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
13
plug-ins/gimpressionist/placement.h
Normal file
13
plug-ins/gimpressionist/placement.h
Normal 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
|
@@ -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;
|
||||
|
@@ -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 */
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
8
plug-ins/gimpressionist/preview.h
Normal file
8
plug-ins/gimpressionist/preview.h
Normal 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 */
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
20
plug-ins/gimpressionist/size.h
Normal file
20
plug-ins/gimpressionist/size.h
Normal 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 */
|
@@ -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);
|
||||
|
355
plug-ins/gimpressionist/utils.c
Normal file
355
plug-ins/gimpressionist/utils.c
Normal 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user