mirror of https://github.com/GNOME/gimp.git
776 lines
22 KiB
C
776 lines
22 KiB
C
/*
|
|
* This is a plugin for the GIMP.
|
|
*
|
|
* Copyright (C) 1997 Xavier Bouchoux
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* This plug-in produces sinus textures.
|
|
*
|
|
* Please send any patches or suggestions to me: Xavier.Bouchoux@ensimag.imag.fr.
|
|
*/
|
|
|
|
|
|
/* Version 0.99 */
|
|
|
|
#define USE_LOGO
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#include <gdk/gdk.h>
|
|
#include <gtk/gtk.h>
|
|
#include <libgimp/gimp.h>
|
|
#include "megawidget.h"
|
|
#ifdef USE_LOGO
|
|
#include "sinus_logo.h"
|
|
#endif
|
|
|
|
#ifdef __GNUC__
|
|
#define inline inline
|
|
#else
|
|
#define inline
|
|
#endif
|
|
|
|
#define ROUND_TO_INT(val) ((val) + 0.5)
|
|
|
|
typedef gdouble colRGBA[4];
|
|
|
|
/*
|
|
* This structure is used for persistent data.
|
|
*/
|
|
|
|
#define B_W 0 /* colors setting */
|
|
#define USE_FG_BG 1
|
|
#define USE_COLORS 2
|
|
|
|
#define LINEAR 0 /* colorization settings */
|
|
#define BILINEAR 1
|
|
#define SINUS 2
|
|
|
|
#define IDEAL 0 /* Perturbation settings */
|
|
#define PERTURBED 1
|
|
|
|
typedef struct {
|
|
gdouble scalex, scaley;
|
|
gdouble cmplx;
|
|
gdouble blend_power;
|
|
gint seed;
|
|
gint tiling;
|
|
gint perturbation;
|
|
gint colorization;
|
|
gint colors;
|
|
colRGBA col1,col2;
|
|
} SinusVals;
|
|
|
|
static SinusVals svals={15.0, 15.0, 1.0, 0.0, 42, TRUE, PERTURBED, LINEAR, USE_COLORS, {1,1,0,1}, {0,0,1,1}};
|
|
|
|
typedef struct {
|
|
gint height, width;
|
|
double c11,c12,c13, c21,c22,c23, c31,c32,c33;
|
|
double (*blend) (double );
|
|
guchar r,g,b,a;
|
|
int dr,dg,db,da;
|
|
} params;
|
|
|
|
|
|
static gint drawable_is_grayscale= FALSE;
|
|
static struct mwPreview *thePreview;
|
|
static GDrawable *drawable;
|
|
|
|
/* Declare functions */
|
|
|
|
static void query ();
|
|
static void run (gchar *name,
|
|
gint nparams,
|
|
GParam *param,
|
|
gint *nreturn_vals,
|
|
GParam **return_vals);
|
|
static void sinus();
|
|
|
|
double frac( double v );
|
|
double linear (double v);
|
|
double bilinear(double v);
|
|
double cosinus(double v);
|
|
int sinus_dialog(void);
|
|
void sinus_do_preview(GtkWidget *w);
|
|
|
|
void DrawPreviewImage(gint DoCompute);
|
|
inline void compute_block_4(guchar *dest_row, guint rowstride,gint x0,gint y0,gint h,gint w, params *p);
|
|
inline void compute_block_3(guchar *dest_row, guint rowstride,gint x0,gint y0,gint h,gint w, params *p) ;
|
|
inline void compute_block_2(guchar *dest_row, guint rowstride,gint x0,gint y0,gint h,gint w, params *p) ;
|
|
inline void compute_block_1(guchar *dest_row, guint rowstride,gint x0,gint y0,gint h,gint w, params *p) ;
|
|
|
|
GPlugInInfo PLUG_IN_INFO =
|
|
{
|
|
NULL, /* init_proc */
|
|
NULL, /* quit_proc */
|
|
query, /* query_proc */
|
|
run, /* run_proc */
|
|
};
|
|
|
|
|
|
MAIN ()
|
|
|
|
|
|
static void query ()
|
|
{
|
|
static GParamDef args[] =
|
|
{
|
|
{ PARAM_INT32, "run_mode", "Interactive, non-interactive" },
|
|
{ PARAM_IMAGE, "image", "Input image (unused)" },
|
|
{ PARAM_DRAWABLE, "drawable", "Input drawable" },
|
|
|
|
{ PARAM_FLOAT, "xscale", "Scale value for x axis" },
|
|
{ PARAM_FLOAT, "yscale", "Scale value dor y axis" },
|
|
{ PARAM_FLOAT, "complex", "Complexity factor" },
|
|
{ PARAM_INT32, "seed", "Seed value for random number generator" },
|
|
{ PARAM_INT32, "tiling", "If set, the pattern generated will tile" },
|
|
{ PARAM_INT32, "perturb", "If set, the pattern is a little more distorted..." },
|
|
|
|
{ PARAM_INT32, "colors", "where to take the colors (0= B&W, 1= fg/bg, 2= col1/col2)"},
|
|
/* { PARAM_COLOR, "col1", "fist color (sometimes unused)" },
|
|
{ PARAM_COLOR, "col2", "second color (sometimes unused)" },*/
|
|
{ PARAM_FLOAT, "alpha1", "alpha for the first color (used if the drawable has an alpha chanel)" },
|
|
{ PARAM_FLOAT, "alpha2", "alpha for the second color (used if the drawable has an alpha chanel)" },
|
|
|
|
{ PARAM_INT32, "blend", "0= linear, 1= bilinear, 2= sinusoidal" },
|
|
{ PARAM_FLOAT, "blend_power", "Power used to strech the blend" }
|
|
};
|
|
|
|
static GParamDef *return_vals = NULL;
|
|
static gint nargs = sizeof (args) / sizeof (args[0]);
|
|
static gint nreturn_vals = 0;
|
|
|
|
gimp_install_procedure ("plug_in_sinus",
|
|
"Generates a texture with sinus functions",
|
|
"FIX ME: sinus help",
|
|
"Xavier Bouchoux",
|
|
"Xavier Bouchoux",
|
|
"1997",
|
|
"<Image>/Filters/Textures/Sinus",
|
|
"RGB*, GRAY*",
|
|
PROC_PLUG_IN,
|
|
nargs, nreturn_vals,
|
|
args, return_vals);
|
|
}
|
|
|
|
static void run (gchar *name,
|
|
gint nparams,
|
|
GParam *param,
|
|
gint *nreturn_vals,
|
|
GParam **return_vals)
|
|
{
|
|
static GParam values[1];
|
|
GRunModeType run_mode;
|
|
GStatusType status = STATUS_SUCCESS;
|
|
|
|
run_mode = param[0].data.d_int32;
|
|
|
|
*nreturn_vals = 1;
|
|
*return_vals = values;
|
|
|
|
values[0].type = PARAM_STATUS;
|
|
values[0].data.d_status = status;
|
|
|
|
switch (run_mode)
|
|
{
|
|
case RUN_INTERACTIVE:
|
|
/* Possibly retrieve data */
|
|
gimp_get_data ("plug_in_sinus", &svals);
|
|
|
|
/* In order to prepare the dialog I need to know wether it's grayscale or not */
|
|
drawable = gimp_drawable_get (param[2].data.d_drawable);
|
|
thePreview = mw_preview_build_virgin(drawable);
|
|
if (gimp_drawable_gray (drawable->id))
|
|
drawable_is_grayscale= TRUE;
|
|
else
|
|
drawable_is_grayscale= FALSE;
|
|
|
|
if (!sinus_dialog())
|
|
return;
|
|
|
|
break;
|
|
|
|
case RUN_NONINTERACTIVE:
|
|
/* Make sure all the arguments are there! */
|
|
if (nparams != 16)
|
|
status = STATUS_CALLING_ERROR;
|
|
if (status == STATUS_SUCCESS)
|
|
{
|
|
svals.seed = param[6].data.d_int32;
|
|
svals.scalex = param[3].data.d_float;
|
|
svals.scaley = param[4].data.d_float;
|
|
svals.cmplx = param[5].data.d_float;
|
|
svals.blend_power = param[15].data.d_float;
|
|
svals.tiling = param[7].data.d_int32;
|
|
svals.perturbation = param[8].data.d_int32;
|
|
svals.colorization = param[14].data.d_int32;
|
|
svals.colors = param[9].data.d_int32;
|
|
svals.col1[3] = param[12].data.d_float;
|
|
svals.col2[3] = param[13].data.d_float;
|
|
svals.col1[0] = param[10].data.d_color.red/255.999;
|
|
svals.col1[1] = param[10].data.d_color.green/255.999;
|
|
svals.col1[2] = param[10].data.d_color.blue/255.999;
|
|
svals.col2[0] = param[11].data.d_color.red/255.999;
|
|
svals.col2[1] = param[11].data.d_color.green/255.999;
|
|
svals.col2[2] = param[11].data.d_color.blue/255.999;
|
|
}
|
|
break;
|
|
|
|
case RUN_WITH_LAST_VALS:
|
|
/* Possibly retrieve data */
|
|
gimp_get_data ("plug_in_sinus", &svals);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* Get the specified drawable */
|
|
drawable = gimp_drawable_get (param[2].data.d_drawable);
|
|
|
|
/* Make sure that the drawable is gray or RGB */
|
|
if (( status == STATUS_SUCCESS) && (gimp_drawable_color (drawable->id) || gimp_drawable_gray (drawable->id)))
|
|
{
|
|
gimp_progress_init("Calculating picture...");
|
|
gimp_tile_cache_ntiles( 1 );
|
|
sinus ();
|
|
|
|
if (run_mode != RUN_NONINTERACTIVE)
|
|
gimp_displays_flush ();
|
|
|
|
/* Store data */
|
|
if (run_mode == RUN_INTERACTIVE)
|
|
gimp_set_data ("plug_in_sinus", &svals, sizeof (SinusVals));
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_EXECUTION_ERROR;
|
|
}
|
|
|
|
values[0].data.d_status = status;
|
|
|
|
gimp_drawable_detach (drawable);
|
|
}
|
|
|
|
/*
|
|
* Main procedure
|
|
*/
|
|
|
|
void prepare_coef( params *p)
|
|
{
|
|
typedef struct { guchar r,g,b,a;} type_color;
|
|
type_color col1,col2;
|
|
double scalex=svals.scalex;
|
|
double scaley=svals.scaley;
|
|
|
|
srand(svals.seed);
|
|
switch (svals.colorization) {
|
|
case BILINEAR:
|
|
p->blend = bilinear;
|
|
break;
|
|
case SINUS:
|
|
p->blend = cosinus;
|
|
break;
|
|
case LINEAR:
|
|
default:
|
|
p->blend = linear;
|
|
}
|
|
|
|
if (svals.perturbation==IDEAL) {
|
|
p->c11= 0*rand();
|
|
p->c12= (2.0*rand()/(RAND_MAX+1.0)-1)*scaley; /*rand+rand is used to keep */
|
|
p->c13= (2*M_PI*rand())/RAND_MAX;
|
|
p->c21= 0*rand();
|
|
p->c22= (2.0*rand()/(RAND_MAX+1.0)-1)*scaley; /*correspondance beetween Ideal*/
|
|
p->c23= (2*M_PI*rand())/RAND_MAX;
|
|
p->c31= (2.0*rand()/(RAND_MAX+1.0)-1)*scalex; /*and perturbed coefs (I hope...)*/
|
|
p->c32= 0*rand();
|
|
p->c33= (2*M_PI*rand())/RAND_MAX;
|
|
} else {
|
|
p->c11= (2.0*rand()/(RAND_MAX+1.0)-1)*scalex;
|
|
p->c12= (2.0*rand()/(RAND_MAX+1.0)-1)*scaley;
|
|
p->c13= (2*M_PI*rand())/RAND_MAX;
|
|
p->c21= (2.0*rand()/(RAND_MAX+1.0)-1)*scalex;
|
|
p->c22= (2.0*rand()/(RAND_MAX+1.0)-1)*scaley;
|
|
p->c23= (2*M_PI*rand())/RAND_MAX;
|
|
p->c31= (2.0*rand()/(RAND_MAX+1.0)-1)*scalex;
|
|
p->c32= (2.0*rand()/(RAND_MAX+1.0)-1)*scaley;
|
|
p->c33= (2*M_PI*rand())/RAND_MAX;
|
|
}
|
|
|
|
if (svals.tiling) {
|
|
p->c11= ROUND_TO_INT(p->c11/(2*M_PI))*2*M_PI;
|
|
p->c12= ROUND_TO_INT(p->c12/(2*M_PI))*2*M_PI;
|
|
p->c21= ROUND_TO_INT(p->c21/(2*M_PI))*2*M_PI;
|
|
p->c22= ROUND_TO_INT(p->c22/(2*M_PI))*2*M_PI;
|
|
p->c31= ROUND_TO_INT(p->c31/(2*M_PI))*2*M_PI;
|
|
p->c32= ROUND_TO_INT(p->c32/(2*M_PI))*2*M_PI;
|
|
}
|
|
|
|
col2.a=255.999*svals.col2[3];
|
|
col1.a=255.999*svals.col1[3];
|
|
|
|
if (drawable_is_grayscale) {
|
|
col1.r=col1.g=col1.b=255;
|
|
col2.r=col2.g=col2.b=0;
|
|
} else {
|
|
switch (svals.colors) {
|
|
case USE_COLORS:
|
|
col1.r=255.999*svals.col1[0];
|
|
col1.g=255.999*svals.col1[1];
|
|
col1.b=255.999*svals.col1[2];
|
|
col2.r=255.999*svals.col2[0];
|
|
col2.g=255.999*svals.col2[1];
|
|
col2.b=255.999*svals.col2[2];
|
|
break;
|
|
case B_W:
|
|
col1.r=col1.g=col1.b=255;
|
|
col2.r=col2.g=col2.b=0;
|
|
break;
|
|
case USE_FG_BG:
|
|
gimp_palette_get_foreground(&col2.r, &col2.g, &col2.b);
|
|
gimp_palette_get_background(&col1.r, &col1.g, &col1.b);
|
|
break;
|
|
}
|
|
}
|
|
p->r = col1.r;
|
|
p->g = col1.g;
|
|
p->b = col1.b;
|
|
p->a = col1.a;
|
|
p->dr=(int)col2.r-col1.r;
|
|
p->dg=(int)col2.g-col1.g;
|
|
p->db=(int)col2.b-col1.b;
|
|
p->da=(int)col2.a-col1.a;
|
|
|
|
}
|
|
|
|
static void
|
|
sinus()
|
|
{
|
|
params p;
|
|
gint bytes;
|
|
GPixelRgn dest_rgn;
|
|
int ix1, iy1, ix2, iy2; /* Selected image size. */
|
|
gpointer pr;
|
|
gint progress, max_progress;
|
|
|
|
prepare_coef(&p);
|
|
|
|
gimp_drawable_mask_bounds(drawable->id, &ix1, &iy1, &ix2, &iy2);
|
|
|
|
p.width = drawable->width;
|
|
p.height = drawable->height;
|
|
bytes = drawable->bpp;
|
|
|
|
gimp_pixel_rgn_init(&dest_rgn, drawable, ix1, iy1, ix2-ix1, iy2-iy1, TRUE,TRUE);
|
|
progress = 0;
|
|
max_progress = (ix2-ix1)*(iy2-iy1);
|
|
|
|
for (pr= gimp_pixel_rgns_register(1, &dest_rgn); pr != NULL; pr = gimp_pixel_rgns_process(pr)) {
|
|
switch (bytes) {
|
|
case 4:
|
|
compute_block_4(dest_rgn.data, dest_rgn.rowstride, dest_rgn.x, dest_rgn.y, dest_rgn.w, dest_rgn.h, &p);
|
|
break;
|
|
case 3:
|
|
compute_block_3(dest_rgn.data, dest_rgn.rowstride, dest_rgn.x, dest_rgn.y, dest_rgn.w, dest_rgn.h, &p);
|
|
break;
|
|
case 2:
|
|
compute_block_2(dest_rgn.data, dest_rgn.rowstride, dest_rgn.x, dest_rgn.y, dest_rgn.w, dest_rgn.h, &p);
|
|
break;
|
|
case 1:
|
|
compute_block_1(dest_rgn.data, dest_rgn.rowstride, dest_rgn.x, dest_rgn.y, dest_rgn.w, dest_rgn.h, &p);
|
|
break;
|
|
}
|
|
progress+= dest_rgn.w * dest_rgn.h;
|
|
gimp_progress_update((double) progress/ (double) max_progress);
|
|
}
|
|
|
|
|
|
gimp_drawable_flush(drawable);
|
|
gimp_drawable_merge_shadow(drawable->id, TRUE);
|
|
gimp_drawable_update ( drawable->id, ix1, iy1, (ix2-ix1), (iy2-iy1));
|
|
}
|
|
|
|
double linear (double v)
|
|
{
|
|
register double a=v-(int)v;
|
|
return (a<0?1.0+a:a);
|
|
}
|
|
|
|
double bilinear(double v)
|
|
{
|
|
register double a=v-(int)v;
|
|
a=(a<0?1.0+a:a);
|
|
return (a>0.5?2-2*a:2*a);
|
|
}
|
|
|
|
double cosinus(double v)
|
|
{
|
|
return 0.5-0.5*sin((v+0.25)*M_PI*2);
|
|
}
|
|
|
|
|
|
inline void compute_block_4(guchar *dest_row, guint rowstride,gint x0,gint y0,gint w,gint h, params *p)
|
|
{
|
|
gint i,j;
|
|
double x,y, grey;
|
|
guchar *dest;
|
|
|
|
for (j=y0; j<(y0+h); j++) {
|
|
y=((double)j)/p->height;
|
|
dest = dest_row;
|
|
for (i= x0; i<(x0+w); i++) {
|
|
x=((double)i)/p->width;
|
|
|
|
grey = sin(p->c11*x + p->c12*y + p->c13) * (0.5+0.5*sin(p->c31*x + p->c32*y +p->c33)) \
|
|
+ sin(p->c21*x + p->c22*y + p->c23) * (0.5-0.5*sin(p->c31*x + p->c32*y +p->c33));
|
|
grey=pow(p->blend(svals.cmplx*(0.5+0.5*grey)),exp(svals.blend_power));
|
|
|
|
*dest++= p->r+(int)(grey*p->dr);
|
|
*dest++= p->g+(int)(grey*p->dg);
|
|
*dest++= p->b+(int)(grey*p->db);
|
|
*dest++= p->a+(int)(grey*p->da);
|
|
}
|
|
dest_row += rowstride;
|
|
}
|
|
}
|
|
|
|
inline void compute_block_3(guchar *dest_row, guint rowstride,gint x0,gint y0,gint w,gint h, params *p)
|
|
{
|
|
gint i,j;
|
|
double x,y, grey;
|
|
guchar *dest;
|
|
for (j=y0; j<(y0+h); j++) {
|
|
y=((double)j)/p->height;
|
|
dest = dest_row;
|
|
for (i= x0; i<(x0+w); i++) {
|
|
x=((double)i)/p->width;
|
|
|
|
grey = sin(p->c11*x + p->c12*y + p->c13) * (0.5+0.5*sin(p->c31*x + p->c32*y +p->c33)) \
|
|
+ sin(p->c21*x + p->c22*y + p->c23) * (0.5-0.5*sin(p->c31*x + p->c32*y +p->c33));
|
|
grey=pow(p->blend(svals.cmplx*(0.5+0.5*grey)),exp(svals.blend_power));
|
|
|
|
*dest++= p->r+(int)(grey*p->dr);
|
|
*dest++= p->g+(int)(grey*p->dg);
|
|
*dest++= p->b+(int)(grey*p->db);
|
|
}
|
|
dest_row += rowstride;
|
|
}
|
|
}
|
|
inline void compute_block_2(guchar *dest_row, guint rowstride,gint x0,gint y0,gint w,gint h, params *p)
|
|
{
|
|
gint i,j;
|
|
double x,y, grey;
|
|
guchar *dest;
|
|
|
|
for (j=y0; j<(y0+h); j++) {
|
|
y=((double)j)/p->height;
|
|
dest = dest_row;
|
|
for (i= x0; i<(x0+w); i++) {
|
|
x=((double)i)/p->width;
|
|
|
|
grey = sin(p->c11*x + p->c12*y + p->c13) * (0.5+0.5*sin(p->c31*x + p->c32*y +p->c33)) \
|
|
+ sin(p->c21*x + p->c22*y + p->c23) * (0.5-0.5*sin(p->c31*x + p->c32*y +p->c33));
|
|
grey=pow(p->blend(svals.cmplx*(0.5+0.5*grey)),exp(svals.blend_power));
|
|
|
|
*dest++= (guchar)(grey*255.0);
|
|
*dest++= p->a+(int)(grey*p->da);
|
|
}
|
|
dest_row += rowstride;
|
|
}
|
|
}
|
|
inline void compute_block_1(guchar *dest_row, guint rowstride,gint x0,gint y0,gint w,gint h, params *p)
|
|
{
|
|
gint i,j;
|
|
double x,y, grey;
|
|
guchar *dest;
|
|
|
|
for (j=y0; j<(y0+h); j++) {
|
|
y=((double)j)/p->height;
|
|
dest = dest_row;
|
|
for (i= x0; i<(x0+w); i++) {
|
|
x=((double)i)/p->width;
|
|
|
|
grey = sin(p->c11*x + p->c12*y + p->c13) * (0.5+0.5*sin(p->c31*x + p->c32*y +p->c33)) \
|
|
+ sin(p->c21*x + p->c22*y + p->c23) * (0.5-0.5*sin(p->c31*x + p->c32*y +p->c33));
|
|
grey=pow(p->blend(svals.cmplx*(0.5+0.5*grey)),exp(svals.blend_power));
|
|
|
|
*dest++= (guchar)(grey*255.0);
|
|
}
|
|
dest_row += rowstride;
|
|
}
|
|
}
|
|
|
|
|
|
/* ---------------------------------------------------------------*/
|
|
/* -------------------------- UI ------------------------------- */
|
|
/* -------------------------------------------------------------- */
|
|
|
|
/*****************************************/
|
|
/* The note book */
|
|
/*****************************************/
|
|
int sinus_dialog(void)
|
|
{
|
|
GtkWidget *dlg;
|
|
GtkWidget *preview;
|
|
gint runp;
|
|
GtkWidget *main_hbox, *notebook;
|
|
GtkWidget *page,*frame, *label, *vbox, *hbox, *table;
|
|
struct mwColorSel *push_col1, *push_col2;
|
|
#ifdef USE_LOGO
|
|
GtkWidget *logo;
|
|
gint x,y;
|
|
char buf[3*100];
|
|
guchar *data;
|
|
#endif
|
|
|
|
static struct mwValueRadioGroup coloriz_radio[] = {
|
|
{ "Linear", LINEAR },
|
|
{ "Bilinear", BILINEAR },
|
|
{ "Sinusoidal", SINUS },
|
|
{ NULL, 0 },
|
|
};
|
|
static struct mwValueRadioGroup colors_radio[] = {
|
|
{ "Black & White", B_W },
|
|
{ "Foreground & Background", USE_FG_BG },
|
|
{ "Choose here:", USE_COLORS},
|
|
{ NULL, 0 },
|
|
};
|
|
static struct mwValueRadioGroup coefs_radio[] = {
|
|
{ "Ideal", IDEAL },
|
|
{ "Distorted", PERTURBED },
|
|
{ NULL, 0 },
|
|
};
|
|
|
|
/* Create Main window with a vbox */
|
|
/* ============================== */
|
|
dlg = mw_app_new("plug_in_sinus", "Sinus", &runp);
|
|
main_hbox = gtk_hbox_new(FALSE, 5);
|
|
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), main_hbox, TRUE, TRUE, 0);
|
|
gtk_widget_show(main_hbox);
|
|
|
|
/* Create preview */
|
|
/* ============== */
|
|
vbox= gtk_vbox_new(TRUE,0);
|
|
gtk_box_pack_start(GTK_BOX(main_hbox), vbox, TRUE, FALSE, 0);
|
|
gtk_widget_show(vbox);
|
|
|
|
preview = mw_preview_new(vbox, thePreview, &sinus_do_preview);
|
|
sinus_do_preview(preview);
|
|
|
|
#ifdef USE_LOGO
|
|
logo = gtk_preview_new(GTK_PREVIEW_COLOR);
|
|
gtk_preview_size(GTK_PREVIEW(logo), 100, 100);
|
|
gtk_box_pack_start(GTK_BOX(vbox), logo, TRUE, FALSE, 0);
|
|
gtk_widget_show(logo);
|
|
|
|
data= logo_data;
|
|
for (y=0;y<100; y++) {
|
|
for (x=0; x<100; x++) {
|
|
HEADER_PIXEL(data,(&buf[3*x]));
|
|
}
|
|
gtk_preview_draw_row(GTK_PREVIEW(logo), buf, 0, y, 100);
|
|
}
|
|
#endif
|
|
|
|
/* Create the notebook */
|
|
/* =================== */
|
|
notebook = gtk_notebook_new();
|
|
gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
|
|
gtk_box_pack_start(GTK_BOX(main_hbox),notebook,FALSE,FALSE,5);
|
|
gtk_widget_show(notebook);
|
|
|
|
/* Create the drawing settings frame */
|
|
/* ================================= */
|
|
page = gtk_vbox_new(FALSE, 0);
|
|
gtk_container_border_width(GTK_CONTAINER(page), 4);
|
|
frame= gtk_frame_new("Drawing settings");
|
|
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
|
|
gtk_container_border_width(GTK_CONTAINER(frame), 10);
|
|
gtk_box_pack_start(GTK_BOX(page), frame, TRUE, TRUE, 0);
|
|
gtk_widget_show(frame);
|
|
table = gtk_table_new(4, 2, FALSE);
|
|
gtk_container_border_width(GTK_CONTAINER (table), 5);
|
|
gtk_container_add(GTK_CONTAINER(frame), table);
|
|
mw_fscale_entry_new(table, "X scale: ", 0.0001, 100.0, 0.001, 5, 0,
|
|
0, 1, 1, 2, &(svals.scalex));
|
|
mw_fscale_entry_new(table, "Y scale: ", 0.0001, 100.0, 0.001, 5, 0,
|
|
0, 1, 2, 3, &(svals.scaley));
|
|
mw_fscale_entry_new(table, "Complexity: ", 0, 15.0, 0.01, 5, 0,
|
|
0, 1, 3, 4, &(svals.cmplx));
|
|
gtk_widget_show(table);
|
|
|
|
frame= gtk_frame_new("Calculation settings");
|
|
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
|
|
gtk_container_border_width(GTK_CONTAINER(frame), 10);
|
|
gtk_box_pack_start(GTK_BOX(page), frame, TRUE, TRUE, 0);
|
|
gtk_widget_show(frame);
|
|
vbox= gtk_vbox_new(FALSE, 5);
|
|
gtk_container_add(GTK_CONTAINER(frame), vbox);
|
|
gtk_widget_show(vbox);
|
|
mw_ientry_new(vbox, NULL, "Random seed:", &svals.seed);
|
|
mw_toggle_button_new(vbox, NULL, "Force tiling?", &svals.tiling);
|
|
mw_value_radio_group_new(vbox, NULL , coefs_radio, &svals.perturbation);
|
|
|
|
label = gtk_label_new("Settings");
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
|
|
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label);
|
|
gtk_widget_show(page);
|
|
|
|
|
|
/* Color settings dialog: */
|
|
/* ====================== */
|
|
page = gtk_vbox_new(FALSE, 0);
|
|
gtk_container_border_width(GTK_CONTAINER(page), 4);
|
|
|
|
frame = gtk_frame_new("Colors");
|
|
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
|
|
gtk_container_border_width(GTK_CONTAINER(frame), 10);
|
|
gtk_box_pack_start(GTK_BOX(page), frame, TRUE, TRUE, 0);
|
|
gtk_widget_show(frame);
|
|
if (drawable_is_grayscale) {
|
|
/*if in grey scale, the colors are necessarily black and white */
|
|
label = gtk_label_new("The colors are white and black.");
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
|
|
gtk_container_add(GTK_CONTAINER(frame), label);
|
|
gtk_widget_show(label);
|
|
|
|
} else {
|
|
vbox= gtk_vbox_new(FALSE, 5);
|
|
gtk_container_add(GTK_CONTAINER(frame), vbox);
|
|
gtk_widget_show(vbox);
|
|
mw_value_radio_group_new(vbox, NULL, colors_radio, &svals.colors);
|
|
hbox= gtk_hbox_new(TRUE, 20);
|
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, FALSE, 0);
|
|
|
|
push_col1 = mw_color_select_button_create(hbox, "Fisrt Color", svals.col1, FALSE);
|
|
push_col2 = mw_color_select_button_create(hbox, "Second Color", svals.col2, FALSE);
|
|
gtk_widget_show(hbox);
|
|
|
|
}
|
|
|
|
|
|
frame = gtk_frame_new("Alpha Channels");
|
|
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
|
|
gtk_container_border_width(GTK_CONTAINER(frame), 10);
|
|
gtk_box_pack_start(GTK_BOX(page), frame, TRUE, TRUE, 0);
|
|
gtk_widget_show(frame);
|
|
table = gtk_table_new(3, 2, FALSE);
|
|
gtk_container_border_width(GTK_CONTAINER (table), 5);
|
|
gtk_container_add(GTK_CONTAINER(frame), table);
|
|
|
|
mw_fscale_entry_new(table, "first color ", 0, 1.0, 0.01, 5, 0,
|
|
0, 1, 1, 2, &(svals.col1[3]));
|
|
mw_fscale_entry_new(table, "last color ", 0, 1.0, 0.01, 5, 0,
|
|
0, 1, 2, 3, &(svals.col2[3]));
|
|
|
|
gtk_widget_show(table);
|
|
|
|
label = gtk_label_new("Colors");
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
|
|
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label);
|
|
gtk_widget_show(page);
|
|
|
|
|
|
/* blend settings dialog: */
|
|
/* ====================== */
|
|
label = gtk_label_new("Blend");
|
|
gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
|
|
page = gtk_vbox_new(FALSE, 0);
|
|
gtk_container_border_width(GTK_CONTAINER(page), 4);
|
|
|
|
frame = gtk_frame_new("Blend settings");
|
|
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN);
|
|
gtk_container_border_width(GTK_CONTAINER(frame), 10);
|
|
gtk_box_pack_start(GTK_BOX(page), frame, TRUE, TRUE, 0);
|
|
gtk_widget_show(frame);
|
|
|
|
vbox= gtk_vbox_new(FALSE, 5);
|
|
gtk_container_add(GTK_CONTAINER(frame), vbox);
|
|
gtk_widget_show(vbox);
|
|
mw_value_radio_group_new(vbox, "Gradient", coloriz_radio, &svals.colorization);
|
|
|
|
table = gtk_table_new(2, 2, FALSE);
|
|
gtk_container_border_width(GTK_CONTAINER (table), 5);
|
|
gtk_container_add(GTK_CONTAINER(vbox), table);
|
|
|
|
mw_fscale_entry_new(table, "Exponent ", -7.5, 7.5, 0.01, 5.0, 0.0,
|
|
0, 1, 0, 1, &svals.blend_power);
|
|
gtk_widget_show(table);
|
|
|
|
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page, label);
|
|
gtk_widget_show(page);
|
|
|
|
|
|
|
|
gtk_widget_show(dlg);
|
|
gtk_main();
|
|
gdk_flush();
|
|
|
|
/* argp->type = mw_radio_result(mode); */
|
|
return runp;
|
|
}
|
|
|
|
/******************************************************************/
|
|
/* Draw preview image. if DoCompute is TRUE then recompute image. */
|
|
/******************************************************************/
|
|
|
|
void sinus_do_preview(GtkWidget *w)
|
|
{
|
|
static GtkWidget *theWidget = NULL;
|
|
gint y,rowsize;
|
|
guchar *buf, *savbuf;
|
|
params p;
|
|
|
|
if(theWidget==NULL){
|
|
theWidget=w;
|
|
}
|
|
|
|
|
|
rowsize=thePreview->width*thePreview->bpp;
|
|
savbuf = buf = (guchar *)malloc(thePreview->width*thePreview->height*thePreview->bpp);
|
|
if (buf != NULL) {
|
|
p.height= thePreview->height;
|
|
p.width= thePreview->width;
|
|
prepare_coef(&p);
|
|
|
|
|
|
if (thePreview->bpp == 3)
|
|
compute_block_3(buf, rowsize,0,0,thePreview->width,thePreview->height, &p);
|
|
else if (thePreview->bpp == 1) {
|
|
compute_block_1(buf, rowsize,0,0,thePreview->width,thePreview->height, &p);
|
|
}
|
|
else
|
|
fprintf(stderr,"Uh Oh.... Little sinus preview-only problem...\n");
|
|
|
|
for (y=0;y<thePreview->height; y++) {
|
|
gtk_preview_draw_row(GTK_PREVIEW(theWidget),
|
|
buf, 0, y, thePreview->width);
|
|
buf+= rowsize;
|
|
}
|
|
free(savbuf);
|
|
gtk_widget_draw(theWidget, NULL);
|
|
gdk_flush();
|
|
} else {
|
|
fprintf(stderr,"Not enough mem for sinus Preview...\n");
|
|
}
|
|
}
|