diff --git a/ChangeLog b/ChangeLog index 00f5c0ebf9..f82e644b19 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2004-05-06 Maurits Rijk + + * plug-ins/fp/fp_gdk.c + * plug-ins/fp/fp_gtk.c + * plug-ins/fp/fp_misc.c + * plug-ins/fp/fp.h: removed + + * plug-ins/fp/Makefile.am: changed accordingly + + * plug-ins/fp/fp.c: merged into one single file to get rid of all + global variables and functions. Major clean-up. Still more to come. + 2004-05-06 Sven Neumann * app/gui/about-dialog.c: center the about dialog on the monitor, @@ -1898,7 +1910,7 @@ * app/core/gimppalette-import.[ch] * app/gui/palette-import-dialog.c: added palette import from RIFF - palette files based on a patch from ÉRDI Gergõ (bug #129788). + palette files based on a patch from ÉRDI GergÁ (bug #129788). 2004-04-15 Michael Natterer @@ -2095,7 +2107,7 @@ * app/pdb/*_cmds.c: regenerated. -2004-04-14 Raphaël Quinet +2004-04-14 RaphaÁl Quinet * plug-ins/script-fu/scripts/copy-visible.scm: New version of the script that works on a temporary copy of the image instead of @@ -2115,7 +2127,7 @@ * Made 2.0.1 release. -2004-04-13 Raphaël Quinet +2004-04-13 RaphaÁl Quinet * plug-ins/common/mng.c (query, run): Workaround for bug #139947: do not register the plug-in for INDEXED* modes and do not declare @@ -2294,11 +2306,11 @@ * configure.in (ALL_LINGUAS): revert addition of "is" until all .po files are there. -2004-04-07 Samúel Jón Gunnarsson +2004-04-07 SamÁel JÁn Gunnarsson * configure.in: Added "is" to ALL_LINGUAS -2004-04-06 Iñaki Larrañaga +2004-04-06 IÁaki LarraÁaga * configure.in: Added "eu" (Basque) to ALL_LINGUAS. diff --git a/plug-ins/common/fp.c b/plug-ins/common/fp.c index 514db79f79..f24d19786c 100644 --- a/plug-ins/common/fp.c +++ b/plug-ins/common/fp.c @@ -23,19 +23,248 @@ #include "config.h" -#include -#include - #include #include - -#include "fp.h" +#include #include "libgimp/stdplugins-intl.h" +#define MAX_PREVIEW_SIZE 125 +#define MAX_ROUGHNESS 128 +#define RANGE_HEIGHT 15 +#define PR_BX_BRDR 4 +#define ALL 255 +#define MARGIN 4 -FP_Params Current = +#define HELP_ID "plug-in-filter-pack" + +#define RANGE_ADJUST_MASK GDK_EXPOSURE_MASK | \ + GDK_ENTER_NOTIFY_MASK | \ + GDK_BUTTON_PRESS_MASK | \ + GDK_BUTTON_RELEASE_MASK | \ + GDK_BUTTON1_MOTION_MASK | \ + GDK_POINTER_MOTION_HINT_MASK + + +typedef struct { + gint run; +} fpInterface; + +typedef struct { + gint width; + gint height; + guchar *rgb; + gdouble *hsv; + guchar *mask; +} ReducedImage; + +typedef enum { + SHADOWS, + MIDTONES, + HIGHLIGHTS, + INTENSITIES +}FP_Intensity; + +enum { + NONEATALL =0, + CURRENT =1, + HUE =2, + SATURATION =4, + VALUE =8 +}; + +enum { + BY_HUE, + BY_SAT, + BY_VAL, + JUDGE_BY +}; + +enum { + RED, + GREEN, + BLUE, + CYAN, + YELLOW, + MAGENTA, + ALL_PRIMARY +}; + +enum { + DOWN = -1, + UP = 1 +}; + +typedef struct { + GtkWidget *window; + GtkWidget *shadowsEntry; + GtkWidget *midtonesEntry; + GtkWidget *rangePreview; + GtkWidget *aliasingPreview; + GtkObject *aliasingData; + GtkWidget *aliasingGraph; +} AdvancedWindow; + + +typedef struct { + int Color; + float Rough; + GtkWidget *roughnessScale; + float Alias; + GtkWidget *aliasingScale; + float PreviewSize; + GtkWidget *previewSizeScale; + FP_Intensity Range; + gint ValueBy; + gint SlctnOnly; + gint RealTime; + guchar Offset; + guchar VisibleFrames; + guchar Cutoffs[INTENSITIES]; + gint Touched[JUDGE_BY]; + gint redAdj[JUDGE_BY][256]; + gint blueAdj[JUDGE_BY][256]; + gint greenAdj[JUDGE_BY][256]; + gint satAdj[JUDGE_BY][256]; + GtkWidget *rangeLabels[12]; +} FP_Params; + +static void fp_show_hide_frame(GtkWidget *button, + GtkWidget *frame); + +static ReducedImage *Reduce_The_Image (GimpDrawable *, + GimpDrawable *, + gint, + gint); + +static void fp_render_preview (GtkWidget *, + gint, + gint); + +static void Update_Current_FP (gint, + gint); + +static void fp_Create_Nudge (gint*); + +static gint fp_dialog (void); +static void fp_advanced_dialog (void); + +static void selectionMade (GtkWidget *, + gpointer ); +static void fp_scale_update (GtkAdjustment *, + float* ); +static void resetFilterPacks (void); + +static void fp_create_smoothness_graph (GtkWidget* ); + +static void fp_range_preview_spill (GtkWidget*, + gint ); +static gint fp_fake_transparency (gint i, gint j); + +static void Adjust_Preview_Sizes (gint width, + gint height ); +static void fp_redraw_all_windows (void); +static void refreshPreviews (int); +static void initializeFilterPacks (void); + +static void As_You_Drag (GtkWidget *button); +static void preview_size_scale_update (GtkAdjustment *adjustment, + float *scale_val); + +static void fp (GimpDrawable *drawable); +static GtkWidget *fp_create_bna (void); +static GtkWidget *fp_create_rough (void); +static GtkWidget *fp_create_range (void); +static GtkWidget *fp_create_circle_palette(void); +static GtkWidget *fp_create_lnd (void); +static GtkWidget *fp_create_show (void); +static GtkWidget *fp_create_msnls (void); +static GtkWidget *fp_create_pixels_select_by(void); +static void update_range_labels (void); +static gboolean FP_Range_Change_Events (GtkWidget *widget, + GdkEvent *event, + FP_Params *current); + +static void Create_A_Preview (GtkWidget **, + GtkWidget **, + int, + int ); + +static void Create_A_Table_Entry (GtkWidget **, + GtkWidget *, + const gchar *); + +static void Check_Button_In_A_Box (GtkWidget *, + const gchar *label, + GtkSignalFunc func, + gpointer data, + int clicked); + +static void Frames_Check_Button_In_A_Box (GtkWidget *, + const gchar *label, + GtkSignalFunc func, + GtkWidget *frame, + int clicked); + + +#define RESPONSE_RESET 1 + +/* These values are translated for the GUI but also used internally + to figure out which button the user pushed, etc. + Not my design, please don't blame me -- njl */ + +static const gchar *hue_red = N_("Red:"); +static const gchar *hue_green = N_("Green:"); +static const gchar *hue_blue = N_("Blue:"); +static const gchar *hue_cyan = N_("Cyan:"); +static const gchar *hue_yellow = N_("Yellow:"); +static const gchar *hue_magenta = N_("Magenta:"); + +static const gchar *val_darker = N_("Darker:"); +static const gchar *val_lighter = N_("Lighter:"); + +static const gchar *sat_more = N_("More Sat:"); +static const gchar *sat_less = N_("Less Sat:"); + +static const gchar *current_val = N_("Current:"); + +static gint colorSign[3][ALL_PRIMARY]= +{{1,-1,-1,-1,1,1},{-1,1,-1,1,1,-1},{-1,-1,1,1,-1,1}}; + +static AdvancedWindow AW = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + +static gint nudgeArray[256]; + +static GtkWidget *origPreview, *curPreview; +static GtkWidget *rPreview, *gPreview, *bPreview; +static GtkWidget *cPreview, *yPreview, *mPreview; +static GtkWidget *centerPreview; +static GtkWidget *darkerPreview, *lighterPreview, *middlePreview; +static GtkWidget *dlg; +static GtkWidget *plusSatPreview, *SatPreview, *minusSatPreview; + +static struct +{ + GtkWidget *bna; + GtkWidget *palette; + GtkWidget *rough; + GtkWidget *range; + GtkWidget *show; + GtkWidget *lnd; + GtkWidget *pixelsBy; + GtkWidget *frameSelect; + GtkWidget *satur; +} fpFrames; + +static fpInterface FPint = +{ + FALSE /* run */ +}; + +static ReducedImage *reduced; + +static FP_Params Current = { 1, .25, /* Initial Roughness */ @@ -54,14 +283,15 @@ FP_Params Current = {0,0,0} }; -GimpDrawable *drawable, *mask; +static GimpDrawable *drawable, *mask; +static GimpRunMode run_mode; -void query (void); -void run (const gchar *name, - gint nparams, - const GimpParam *param, - gint *nreturn_vals, - GimpParam **return_vals); +static void query (void); +static void run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); GimpPlugInInfo PLUG_IN_INFO = { @@ -73,7 +303,7 @@ GimpPlugInInfo PLUG_IN_INFO = MAIN() -void +static void query (void) { GimpParamDef args[] = @@ -98,7 +328,7 @@ query (void) /********************************STANDARD RUN*************************/ -void +static void run (const gchar *name, gint nparams, const GimpParam *param, @@ -111,6 +341,8 @@ run (const gchar *name, *nreturn_vals = 1; *return_vals = values; + run_mode = param[0].data.d_int32; + INIT_I18N (); values[0].type = GIMP_PDB_STATUS; @@ -142,136 +374,1617 @@ run (const gchar *name, gimp_drawable_detach (drawable); } - -void -fp_row (const guchar *src_row, - guchar *dest_row, - gint row, - gint row_width, - gint bytes) +static void +fp_func (const guchar *src, + guchar *dest, + gint bpp, + gpointer data) { - gint col, bytenum, k; - gint JudgeBy, Intensity=0, P[3], backupP[3]; + gint bytenum, k; + gint JudgeBy, Intensity = 0, P[3]; GimpRGB rgb; GimpHSV hsv; gint M, m, middle; - for (col = 0; col < row_width ; col++) + P[0] = src[0]; + P[1] = src[1]; + P[2] = src[2]; + + gimp_rgb_set_uchar (&rgb, (guchar) P[0], (guchar) P[1], (guchar) P[2]); + gimp_rgb_to_hsv (&rgb, &hsv); + + for (JudgeBy = BY_HUE; JudgeBy < JUDGE_BY; JudgeBy++) { + if (!Current.Touched[JudgeBy]) + continue; + + switch (JudgeBy) + { + case BY_HUE: + Intensity = 255 * hsv.h; + break; - backupP[0] = P[0] = src_row[col * bytes + 0]; - backupP[0] = P[1] = src_row[col * bytes + 1]; - backupP[0] = P[2] = src_row[col * bytes + 2]; + case BY_SAT: + Intensity = 255 * hsv.s; + break; + + case BY_VAL: + Intensity = 255 * hsv.v; + break; + } + + + /* It's important to take care of Saturation first!!! */ + + m = MIN (MIN (P[0], P[1]), P[2]); + M = MAX (MAX (P[0], P[1]), P[2]); + middle = (M + m) / 2; + + for (k = 0; k < 3; k++) + if (P[k] != m && P[k] != M) + middle = P[k]; + + for (k = 0; k < 3; k++) + if (M != m) + { + if (P[k] == M) + P[k] = MAX (P[k] + Current.satAdj[JudgeBy][Intensity], middle); + else if (P[k] == m) + P[k] = MIN (P[k] - Current.satAdj[JudgeBy][Intensity], middle); + } + + P[0] += Current.redAdj[JudgeBy][Intensity]; + P[1] += Current.greenAdj[JudgeBy][Intensity]; + P[2] += Current.blueAdj[JudgeBy][Intensity]; + + P[0] = CLAMP0255(P[0]); + P[1] = CLAMP0255(P[1]); + P[2] = CLAMP0255(P[2]); + } + + dest[0] = P[0]; + dest[1] = P[1]; + dest[2] = P[2]; + + for (bytenum = 3; bytenum < bpp; bytenum++) + dest[bytenum] = src[bytenum]; +} - gimp_rgb_set_uchar (&rgb, (guchar) P[0], (guchar) P[1], (guchar) P[2]); - gimp_rgb_to_hsv (&rgb, &hsv); +static void +fp (GimpDrawable *drawable) +{ + gimp_rgn_iterate2 (drawable, run_mode, fp_func, NULL); +} - for (JudgeBy = BY_HUE; JudgeBy < JUDGE_BY; JudgeBy++) - { - if (! Current.Touched[JudgeBy]) - continue; +/***********************************************************/ +/************ Main Dialog Window ******************/ +/***********************************************************/ - switch (JudgeBy) - { - case BY_HUE: - Intensity = 255 * hsv.h; - break; +static GtkWidget * +fp_create_bna (void) +{ + GtkWidget *frame, *blabel, *alabel, *bframe, *aframe, *table; - case BY_SAT: - Intensity = 255 * hsv.s; - break; + Create_A_Preview (&origPreview, &bframe, reduced->width, reduced->height); + Create_A_Preview (&curPreview, &aframe, reduced->width, reduced->height); - case BY_VAL: - Intensity = 255 * hsv.v; - break; - } + frame = gtk_frame_new (_("Before and After")); + /* All the previews */ + alabel = gtk_label_new (_("Current:")); + gtk_widget_show (alabel); + gtk_misc_set_alignment (GTK_MISC (alabel), 0.0, 0.5); - /* It's important to take care of Saturation first!!! */ + blabel = gtk_label_new (_("Original:")); + gtk_widget_show (blabel); + gtk_misc_set_alignment (GTK_MISC (blabel), 0.0, 0.5); - m = MIN (MIN (P[0], P[1]), P[2]); - M = MAX (MAX (P[0], P[1]), P[2]); - middle = (M + m) / 2; + table = gtk_table_new (2, 2, FALSE); + gtk_container_set_border_width (GTK_CONTAINER (table), 4); + gtk_table_set_row_spacings (GTK_TABLE (table), 2); + gtk_table_set_col_spacings (GTK_TABLE (table), 4); - for (k = 0; k < 3; k++) - if (P[k] != m && P[k] != M) - middle = P[k]; + gtk_container_add (GTK_CONTAINER (frame), table); - for (k = 0; k < 3; k++) - if (M != m) - { - if (P[k] == M) - P[k] = MAX (P[k] + Current.satAdj[JudgeBy][Intensity], middle); - else if (P[k] == m) - P[k] = MIN (P[k] - Current.satAdj[JudgeBy][Intensity], middle); - } + gtk_table_attach (GTK_TABLE (table), blabel, 0, 1, 0, 1, + 0, GTK_EXPAND | GTK_FILL, 0, 0); - P[0] += Current.redAdj[JudgeBy][Intensity]; - P[1] += Current.greenAdj[JudgeBy][Intensity]; - P[2] += Current.blueAdj[JudgeBy][Intensity]; + gtk_table_attach (GTK_TABLE (table), alabel, 1, 2, 0, 1, + 0, GTK_EXPAND | GTK_FILL, 0, 0); - P[0] = MAX (0, MIN (255, P[0])); - P[1] = MAX (0, MIN (255, P[1])); - P[2] = MAX (0, MIN (255, P[2])); - } + gtk_table_attach (GTK_TABLE (table), bframe, 0, 1, 1, 2, + GTK_EXPAND, GTK_EXPAND, 0, 0); - dest_row[col * bytes + 0] = P[0]; - dest_row[col * bytes + 1] = P[1]; - dest_row[col * bytes + 2] = P[2]; + gtk_table_attach (GTK_TABLE (table), aframe, 1, 2, 1, 2, + GTK_EXPAND, GTK_EXPAND, 0, 0); - if (bytes > 3) - for (bytenum = 3; bytenum < bytes; bytenum++) - dest_row[col * bytes + bytenum] = src_row[col * bytes + bytenum]; + gtk_widget_show (table); + gtk_widget_show (frame); + + return frame; +} + +/* close a sub dialog (from window manager) by simulating toggle click */ +static gboolean +sub_dialog_destroy (GtkWidget *dialog, + GdkEvent *ev, + gpointer dummy) +{ + GtkWidget *button = + GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), "ctrlButton")); + + gtk_button_clicked (GTK_BUTTON (button)); + + return TRUE; +} + +static GtkWidget * +fp_create_circle_palette (void) +{ + GtkWidget *frame, *table; + GtkWidget *rVbox, *rFrame; + GtkWidget *gVbox, *gFrame; + GtkWidget *bVbox, *bFrame; + GtkWidget *cVbox, *cFrame; + GtkWidget *yVbox, *yFrame; + GtkWidget *mVbox, *mFrame; + GtkWidget *centerVbox, *centerFrame; + + GtkWidget *win; + + frame = gtk_frame_new (NULL); + gtk_container_set_border_width (GTK_CONTAINER (frame), 4); + gtk_widget_show (frame); + + table = gtk_table_new (11, 11, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_widget_show (table); + + gtk_container_add (GTK_CONTAINER (frame), table); + + Create_A_Preview (&rPreview, &rFrame, reduced->width, reduced->height); + Create_A_Preview (&gPreview, &gFrame, reduced->width, reduced->height); + Create_A_Preview (&bPreview, &bFrame, reduced->width, reduced->height); + Create_A_Preview (&cPreview, &cFrame, reduced->width, reduced->height); + Create_A_Preview (&yPreview, &yFrame, reduced->width, reduced->height); + Create_A_Preview (&mPreview, &mFrame, reduced->width, reduced->height); + Create_A_Preview (¢erPreview, ¢erFrame, + reduced->width, reduced->height); + + Create_A_Table_Entry (&rVbox, rFrame, hue_red); + Create_A_Table_Entry (&gVbox, gFrame, hue_green); + Create_A_Table_Entry (&bVbox, bFrame, hue_blue); + Create_A_Table_Entry (&cVbox, cFrame, hue_cyan); + Create_A_Table_Entry (&yVbox, yFrame, hue_yellow); + Create_A_Table_Entry (&mVbox, mFrame, hue_magenta); + Create_A_Table_Entry (¢erVbox, centerFrame, current_val); + + gtk_table_attach (GTK_TABLE (table), rVbox, 8, 11 ,4 , 7, + GTK_EXPAND , GTK_EXPAND, 0 ,0); + gtk_table_attach (GTK_TABLE (table), gVbox, 2, 5, 0, 3, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), bVbox, 2, 5, 8, 11, + GTK_EXPAND, GTK_EXPAND,0,0); + gtk_table_attach (GTK_TABLE (table), cVbox, 0, 3, 4, 7, + GTK_EXPAND, GTK_EXPAND, 0 ,0); + gtk_table_attach (GTK_TABLE (table), yVbox, 6, 9, 0, 3, + GTK_EXPAND, GTK_EXPAND, 0 ,0); + gtk_table_attach (GTK_TABLE (table), mVbox, 6, 9, 8, 11, + GTK_EXPAND, GTK_EXPAND, 0 ,0); + gtk_table_attach (GTK_TABLE (table), centerVbox, 4, 7, 4, 7, + GTK_EXPAND, GTK_EXPAND, 0 ,0); + + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); + + gtk_window_set_title (GTK_WINDOW (win), _("Hue Variations")); + gtk_container_add (GTK_CONTAINER (win), frame); + + g_signal_connect (win, "delete_event", + G_CALLBACK (sub_dialog_destroy), + NULL); + + return win; +} + +static GtkWidget * +fp_create_rough (void) +{ + GtkWidget *frame, *scale, *vbox; + GtkObject *data; + + frame = gtk_frame_new (_("Roughness")); + gtk_widget_show (frame); + + data = gtk_adjustment_new (Current.Rough, 0, 1.0, 0.05, 0.01, 0.0); + Current.roughnessScale = scale = gtk_hscale_new (GTK_ADJUSTMENT (data)); + + gtk_widget_set_size_request (scale, 60, -1); + gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); + gtk_scale_set_digits (GTK_SCALE (scale), 2); + gtk_widget_show (scale); + + g_signal_connect (data, "value_changed", + G_CALLBACK (fp_scale_update), + &Current.Rough); + + vbox = gtk_vbox_new (FALSE, 2); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_widget_show (vbox); + gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0); + gtk_container_add (GTK_CONTAINER( frame), vbox); + + return frame; +} + +static void +fp_change_current_range (GtkWidget *widget, + gpointer data) +{ + gimp_radio_button_update (widget, data); + + if (GTK_TOGGLE_BUTTON (widget)->active) + { + refreshPreviews (Current.VisibleFrames); + if (AW.window && GTK_WIDGET_VISIBLE (AW.window)) + fp_create_smoothness_graph (AW.aliasingPreview); } } - -void fp (GimpDrawable *drawable) +static GtkWidget * +fp_create_range (void) { - GimpPixelRgn srcPR, destPR; - gint width, height; - gint bytes; - guchar *src_row, *dest_row; - gint row; - gint x1, y1, x2, y2; + GtkWidget *frame; + + frame = gimp_int_radio_group_new (TRUE, _("Affected Range"), + G_CALLBACK (fp_change_current_range), + &Current.Range, Current.Range, + + _("Sha_dows"), SHADOWS, NULL, + _("_Midtones"), MIDTONES, NULL, + _("H_ighlights"), HIGHLIGHTS, NULL, + + NULL); + + gtk_widget_show (frame); + + return frame; +} + +static GtkWidget * +fp_create_control (void) +{ + GtkWidget *frame, *box; + + frame = gtk_frame_new (_("Windows")); + + gtk_widget_show (frame); + + box = gtk_vbox_new (FALSE, 2); + gtk_container_add (GTK_CONTAINER (frame), box); + gtk_container_set_border_width (GTK_CONTAINER (box), 4); + gtk_widget_show (box); + + Frames_Check_Button_In_A_Box (box, _("_Hue"), + GTK_SIGNAL_FUNC (fp_show_hide_frame), + fpFrames.palette, + Current.VisibleFrames & HUE); + Frames_Check_Button_In_A_Box (box, _("_Saturation"), + GTK_SIGNAL_FUNC (fp_show_hide_frame), + fpFrames.satur, + Current.VisibleFrames & SATURATION); + Frames_Check_Button_In_A_Box (box, _("_Value"), + GTK_SIGNAL_FUNC (fp_show_hide_frame), + fpFrames.lnd, + Current.VisibleFrames & VALUE); + Frames_Check_Button_In_A_Box (box, _("A_dvanced"), + GTK_SIGNAL_FUNC (fp_show_hide_frame), + AW.window, + FALSE); + + return frame; +} + +static GtkWidget * +fp_create_lnd (void) +{ + GtkWidget *frame, *table, *lighterFrame, *middleFrame, *darkerFrame; + GtkWidget *lighterVbox, *middleVbox, *darkerVbox; + GtkWidget *win; + + Create_A_Preview (&lighterPreview, &lighterFrame, + reduced->width, reduced->height); + Create_A_Preview (&middlePreview, &middleFrame, + reduced->width, reduced->height); + Create_A_Preview (&darkerPreview, &darkerFrame, + reduced->width, reduced->height); + + Create_A_Table_Entry (&lighterVbox, lighterFrame, val_lighter); + Create_A_Table_Entry (&middleVbox, middleFrame, current_val); + Create_A_Table_Entry (&darkerVbox, darkerFrame, val_darker); + + frame = gtk_frame_new (NULL); + gtk_container_set_border_width (GTK_CONTAINER (frame), 6); + gtk_widget_show (frame); + + table = gtk_table_new (1, 11, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_widget_show (table); + + gtk_table_attach (GTK_TABLE (table), lighterVbox, 0, 3, 0, 1, + GTK_EXPAND , GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), middleVbox, 4, 7, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), darkerVbox, 8, 11, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_container_add (GTK_CONTAINER (frame), table); + + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); + + gtk_window_set_title (GTK_WINDOW (win), _("Value Variations")); + gtk_container_add (GTK_CONTAINER (win), frame); + + g_signal_connect (win, "delete_event", + G_CALLBACK (sub_dialog_destroy), + NULL); + + return win; +} + +static GtkWidget * +fp_create_msnls (void) +{ + GtkWidget *frame, *table, *lessFrame, *middleFrame, *moreFrame; + GtkWidget *lessVbox, *middleVbox, *moreVbox; + GtkWidget *win; + + Create_A_Preview (&minusSatPreview, &lessFrame, + reduced->width, reduced->height); + Create_A_Preview (&SatPreview, &middleFrame, + reduced->width, reduced->height); + Create_A_Preview (&plusSatPreview, &moreFrame, + reduced->width, reduced->height); + + Create_A_Table_Entry (&moreVbox, moreFrame, sat_more); + Create_A_Table_Entry (&middleVbox, middleFrame, current_val); + Create_A_Table_Entry (&lessVbox, lessFrame, sat_less); + + frame = gtk_frame_new (NULL); + gtk_container_set_border_width (GTK_CONTAINER (frame), 4); + gtk_widget_show (frame); + + table = gtk_table_new (1, 11, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_widget_show (table); + + gtk_table_attach (GTK_TABLE (table), moreVbox, 0, 3, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), middleVbox, 4, 7, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), lessVbox, 8, 11, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_container_add (GTK_CONTAINER (frame), table); + + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); + + gtk_window_set_title (GTK_WINDOW (win), _("Saturation Variations")); + gtk_container_add (GTK_CONTAINER (win), frame); + + g_signal_connect (win, "delete_event", + G_CALLBACK (sub_dialog_destroy), + NULL); + + return win; +} + +static void +fp_change_current_pixels_by (GtkWidget *widget, + gpointer data) +{ + gimp_radio_button_update (widget, data); + + if (GTK_TOGGLE_BUTTON (widget)->active) + { + refreshPreviews (Current.VisibleFrames); + if (AW.window && GTK_WIDGET_VISIBLE (AW.window) && AW.rangePreview) + fp_range_preview_spill (AW.rangePreview,Current.ValueBy); + } +} + +static GtkWidget * +fp_create_pixels_select_by (void) +{ + GtkWidget *frame; + + frame = gimp_int_radio_group_new (TRUE, _("Select Pixels by"), + G_CALLBACK (fp_change_current_pixels_by), + &Current.ValueBy, + Current.ValueBy, + + _("H_ue"), 0, NULL, + _("Satu_ration"), 1, NULL, + _("V_alue"), 2, NULL, + + NULL); + + gtk_widget_show (frame); + + return frame; +} + +static void +fp_change_selection (GtkWidget *widget, + gpointer data) +{ + gimp_radio_button_update (widget, data); + + if (GTK_TOGGLE_BUTTON (widget)->active) + { + fp_redraw_all_windows (); + } +} + +static GtkWidget * +fp_create_show (void) +{ + GtkWidget *frame; + + frame = gimp_int_radio_group_new (TRUE, _("Show"), + G_CALLBACK (fp_change_selection), + &Current.SlctnOnly, + Current.SlctnOnly, + + _("_Entire Image"), 0, NULL, + _("Se_lection Only"), 1, NULL, + _("Selec_tion In Context"), 2, NULL, + + NULL); + + gtk_widget_show (frame); + + return frame; +} + +static void +Create_A_Preview (GtkWidget **preview, + GtkWidget **frame, + gint previewWidth, + gint previewHeight) +{ + *frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (*frame), GTK_SHADOW_IN); + gtk_widget_show (*frame); + + *preview = gtk_preview_new (Current.Color ? + GTK_PREVIEW_COLOR : GTK_PREVIEW_GRAYSCALE); + gtk_preview_size (GTK_PREVIEW (*preview), previewWidth, previewHeight); + gtk_widget_show (*preview); + gtk_container_add (GTK_CONTAINER (*frame), *preview); +} + +static void +Check_Button_In_A_Box (GtkWidget *vbox, + const gchar *label, + GtkSignalFunc function, + gpointer data, + gboolean clicked) +{ + GtkWidget *button; + + button = gtk_check_button_new_with_mnemonic (label); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect (button, "clicked", + G_CALLBACK (function), + data); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clicked); +} + +static void +Frames_Check_Button_In_A_Box (GtkWidget *vbox, + const gchar *label, + GtkSignalFunc function, + GtkWidget *frame, + gboolean clicked) +{ + GtkWidget *button; + + button = gtk_check_button_new_with_mnemonic (label); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (frame), "ctrlButton", (gpointer) button); + gtk_widget_show (button); + + g_signal_connect (button, "clicked", + G_CALLBACK (function), + frame); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clicked); +} + +static void +Create_A_Table_Entry (GtkWidget **box, + GtkWidget *SmallerFrame, + const gchar *description) +{ + GtkWidget *label, *button, *table; + + *box = gtk_vbox_new (FALSE, 1); + gtk_container_set_border_width (GTK_CONTAINER (*box), PR_BX_BRDR); + gtk_widget_show (*box); + + /* Delayed translation applied here */ + label = gtk_label_new (gettext (description)); + + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + + table = gtk_table_new (2, 1, FALSE); + gtk_widget_show (table); + + gtk_box_pack_start (GTK_BOX (*box), table, TRUE, TRUE, 0); + + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, + 0, 0, 0, 0); + + if (description != current_val) + { + button = gtk_button_new (); + gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2, + 0, 0, 0, 4); + gtk_widget_show (button); + + gtk_container_add (GTK_CONTAINER (button), SmallerFrame); + + g_signal_connect (button, "clicked", + G_CALLBACK (selectionMade), + (gchar *) description); + } + else + { + gtk_table_attach (GTK_TABLE (table), SmallerFrame, 0, 1, 1, 2, + 0, 0, 0, 4); + } +} + +static void +fp_redraw_all_windows (void) +{ + reduced = Reduce_The_Image (drawable,mask, + Current.PreviewSize, + Current.SlctnOnly); + Adjust_Preview_Sizes (reduced->width, reduced->height); + + gtk_widget_queue_draw (fpFrames.palette); + gtk_widget_queue_draw (fpFrames.satur); + gtk_widget_queue_draw (fpFrames.lnd); + gtk_widget_queue_draw (dlg); + + refreshPreviews (Current.VisibleFrames); +} + +static void +fp_show_hide_frame (GtkWidget *button, + GtkWidget *frame) +{ + gint prev = Current.VisibleFrames; + + if (frame == NULL) + return; + + if (GTK_TOGGLE_BUTTON (button)->active) + { + if (!GTK_WIDGET_VISIBLE (frame)) + { + gtk_widget_show (frame); + + if (frame==fpFrames.palette) + Current.VisibleFrames |= HUE; + else if (frame==fpFrames.satur) + Current.VisibleFrames |= SATURATION; + else if (frame==fpFrames.lnd) + Current.VisibleFrames |= VALUE; + + refreshPreviews (Current.VisibleFrames & ~prev); + } + } + else + { + if (GTK_WIDGET_VISIBLE (frame)) + { + gtk_widget_hide (frame); + + if (frame==fpFrames.palette) + Current.VisibleFrames &= ~HUE; + else if (frame==fpFrames.satur) + Current.VisibleFrames &= ~SATURATION; + else if (frame==fpFrames.lnd) + Current.VisibleFrames &= ~VALUE; + } + } +} + +static void +Adjust_Preview_Sizes (gint width, + gint height) +{ + gtk_preview_size (GTK_PREVIEW (origPreview), width, height); + gtk_preview_size (GTK_PREVIEW (curPreview), width, height); + gtk_preview_size (GTK_PREVIEW (rPreview), width, height); + gtk_preview_size (GTK_PREVIEW (gPreview), width, height); + gtk_preview_size (GTK_PREVIEW (bPreview), width, height); + gtk_preview_size (GTK_PREVIEW (cPreview), width, height); + gtk_preview_size (GTK_PREVIEW (yPreview), width, height); + gtk_preview_size (GTK_PREVIEW (mPreview), width, height); + gtk_preview_size (GTK_PREVIEW (centerPreview), width, height); + gtk_preview_size (GTK_PREVIEW (lighterPreview), width, height); + gtk_preview_size (GTK_PREVIEW (darkerPreview), width, height); + gtk_preview_size (GTK_PREVIEW (middlePreview), width, height); + gtk_preview_size (GTK_PREVIEW (minusSatPreview), width, height); + gtk_preview_size (GTK_PREVIEW (SatPreview), width, height); + gtk_preview_size (GTK_PREVIEW (plusSatPreview), width, height); +} + +static void +selectionMade (GtkWidget *widget, + gpointer data) +{ + Current.Touched[Current.ValueBy] = 1; + + if (data == (gpointer) hue_red) { + Update_Current_FP (HUE, RED); + } else if (data == (gpointer) hue_green) { + Update_Current_FP (HUE, GREEN); + } else if (data == (gpointer) hue_blue) { + Update_Current_FP (HUE, BLUE); + } else if (data == (gpointer) hue_cyan) { + Update_Current_FP (HUE, CYAN); + } else if (data == (gpointer) hue_yellow) { + Update_Current_FP (HUE, YELLOW); + } else if (data == (gpointer) hue_magenta) { + Update_Current_FP (HUE, MAGENTA); + } else if (data == (gpointer) val_darker) { + Update_Current_FP (VALUE, DOWN); + } else if (data == (gpointer) val_lighter) { + Update_Current_FP (VALUE, UP); + } else if (data == (gpointer) sat_more) { + Update_Current_FP (SATURATION, UP); + } else if (data == (gpointer) sat_less) { + Update_Current_FP (SATURATION, DOWN); + } + + refreshPreviews (Current.VisibleFrames); +} + +static void +refreshPreviews (gint which) +{ + fp_Create_Nudge (nudgeArray); + fp_render_preview (origPreview, NONEATALL, 0); + fp_render_preview (curPreview, CURRENT, 0); + if (which & HUE) + { + fp_render_preview (rPreview, HUE, RED); + fp_render_preview (gPreview, HUE, GREEN); + fp_render_preview (bPreview, HUE, BLUE); + fp_render_preview (cPreview, HUE, CYAN); + fp_render_preview (yPreview, HUE, YELLOW); + fp_render_preview (mPreview, HUE, MAGENTA); + fp_render_preview (centerPreview, CURRENT, 0); + } + if (which & VALUE) + { + fp_render_preview (lighterPreview, VALUE, UP); + fp_render_preview (middlePreview, CURRENT, 0); + fp_render_preview (darkerPreview, VALUE, DOWN); + } + if (which & SATURATION) + { + fp_render_preview (plusSatPreview, SATURATION, UP); + fp_render_preview (SatPreview, CURRENT, 0); + fp_render_preview (minusSatPreview, SATURATION, DOWN); + } +} + +static void +fp_response (GtkWidget *widget, + gint response_id, + gpointer data) +{ + switch (response_id) + { + case RESPONSE_RESET: + resetFilterPacks (); + break; + + case GTK_RESPONSE_OK: + FPint.run = TRUE; + gtk_widget_destroy (widget); + break; + + default: + gtk_widget_destroy (widget); + break; + } +} + +static void +fp_scale_update (GtkAdjustment *adjustment, + float *scale_val) +{ + static gfloat prevValue = 0.25; + + *scale_val = adjustment->value; + + if (prevValue != adjustment->value) + { + fp_Create_Nudge (nudgeArray); + refreshPreviews (Current.VisibleFrames); + if (AW.window != NULL && GTK_WIDGET_VISIBLE (AW.window)) + fp_create_smoothness_graph (AW.aliasingPreview); + prevValue = adjustment->value; + } +} + +static gint +fp_dialog (void) +{ + GtkWidget *bna; + GtkWidget *palette; + GtkWidget *lnd; + GtkWidget *show; + GtkWidget *rough; + GtkWidget *range; + GtkWidget *pixelsBy; + GtkWidget *satur; + GtkWidget *control; + GtkWidget *table; + + reduced = Reduce_The_Image (drawable,mask, + Current.PreviewSize, + Current.SlctnOnly); + + gimp_ui_init ("fp", TRUE); + + dlg = gimp_dialog_new (_("Filter Pack Simulation"), "fp", + NULL, 0, + gimp_standard_help_func, HELP_ID, + + GIMP_STOCK_RESET, RESPONSE_RESET, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + + NULL); + + g_signal_connect (dlg, "response", + G_CALLBACK (fp_response), + dlg); + + g_signal_connect (dlg, "destroy", + G_CALLBACK (gtk_main_quit), + NULL); + + fp_advanced_dialog (); + + fpFrames.bna = bna = fp_create_bna(); + fpFrames.rough = rough = fp_create_rough(); + fpFrames.range = range = fp_create_range(); + fpFrames.palette = palette = fp_create_circle_palette(); + fpFrames.lnd = lnd = fp_create_lnd(); + fpFrames.show = show = fp_create_show(); + fpFrames.satur = satur = fp_create_msnls(); + fpFrames.pixelsBy = pixelsBy = fp_create_pixels_select_by(); + control = fp_create_control(); + /********************************************************************/ + /******************** PUT EVERYTHING TOGETHER ******************/ + + table = gtk_table_new (4, 2, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 4); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_container_set_border_width (GTK_CONTAINER (table), 6); + + gtk_table_attach (GTK_TABLE (table), bna, 0, 2, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), control, 1, 2, 1, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), rough, 1, 2, 3, 4, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), show, 0, 1, 1, 2, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), range, 0, 1, 2, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), pixelsBy, 0, 1, 3, 4, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), table, TRUE, TRUE, 0); + gtk_widget_show (table); + gtk_widget_show (dlg); + + refreshPreviews (Current.VisibleFrames); + + gtk_main (); + gdk_flush (); + + return FPint.run; +} + +/***********************************************************/ +/************ Advanced Options Window ******************/ +/***********************************************************/ + +static void +As_You_Drag (GtkWidget *button) +{ + static gboolean notFirstTime = FALSE; + + if (! notFirstTime) + return; + + notFirstTime = TRUE; + + if (GTK_TOGGLE_BUTTON (button)->active) + { + Current.RealTime=TRUE; + gtk_range_set_update_policy (GTK_RANGE (Current.roughnessScale),0); + gtk_range_set_update_policy (GTK_RANGE (Current.aliasingScale),0); + gtk_range_set_update_policy (GTK_RANGE (Current.previewSizeScale),0); + } + else + { + Current.RealTime=FALSE; + gtk_range_set_update_policy (GTK_RANGE (Current.roughnessScale), + GTK_UPDATE_DELAYED); + gtk_range_set_update_policy (GTK_RANGE (Current.aliasingScale), + GTK_UPDATE_DELAYED); + gtk_range_set_update_policy (GTK_RANGE (Current.previewSizeScale), + GTK_UPDATE_DELAYED); + } +} + +static void +preview_size_scale_update (GtkAdjustment *adjustment, + float *scale_val) +{ + Current.PreviewSize = adjustment->value; + fp_redraw_all_windows(); +} + +static void +fp_advanced_dialog (void) +{ + gchar *rangeNames[] = { N_("Shadows:"), + N_("Midtones:"), + N_("Highlights:") }; + GtkWidget *frame, *mainvbox; + GtkObject *smoothnessData; + GtkWidget *graphFrame, *table, *scale; + GtkWidget *vbox, *label, *labelTable; + GtkWidget *optionsFrame; + gint i; + + AW.window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gimp_help_connect (AW.window, gimp_standard_help_func, HELP_ID, NULL); + + gtk_window_set_title (GTK_WINDOW (AW.window), + _("Advanced Filter Pack Options")); + + g_signal_connect (AW.window, "delete_event", + G_CALLBACK (sub_dialog_destroy), + NULL); + + mainvbox = gtk_hbox_new (FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (mainvbox), 6); + gtk_container_add (GTK_CONTAINER (AW.window), mainvbox); + gtk_widget_show (mainvbox); + + frame = gtk_frame_new (_("Smoothness of Aliasing")); + gtk_box_pack_start (GTK_BOX (mainvbox), frame, TRUE, TRUE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (3, 1, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_container_set_border_width (GTK_CONTAINER (table), 4); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + graphFrame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (graphFrame), GTK_SHADOW_IN); + gtk_container_set_border_width (GTK_CONTAINER (graphFrame),0); + gtk_widget_show (graphFrame); + gtk_table_attach (GTK_TABLE (table), graphFrame, 0, 1, 0, 1, + GTK_EXPAND, 0, 0, 0); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (graphFrame), vbox); + gtk_widget_show (vbox); + + AW.aliasingPreview = gtk_preview_new (GTK_PREVIEW_COLOR); + gtk_preview_size (GTK_PREVIEW (AW.aliasingPreview), 256, MAX_ROUGHNESS); + gtk_box_pack_start (GTK_BOX (vbox),AW.aliasingPreview, TRUE, TRUE, 0); + gtk_widget_show (AW.aliasingPreview); + + fp_create_smoothness_graph (AW.aliasingPreview); + + AW.rangePreview = gtk_preview_new (GTK_PREVIEW_COLOR); + gtk_preview_size (GTK_PREVIEW (AW.rangePreview), 256, RANGE_HEIGHT); + gtk_box_pack_start(GTK_BOX(vbox),AW.rangePreview, TRUE, TRUE, 0); + gtk_widget_show (AW.rangePreview); + + fp_range_preview_spill (AW.rangePreview, Current.ValueBy); + + labelTable = gtk_table_new (3, 4, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (labelTable), 4); + gtk_table_set_row_spacings (GTK_TABLE (labelTable), 2); + gtk_widget_show (labelTable); + gtk_table_attach (GTK_TABLE (table), labelTable, 0, 1, 1, 2, + GTK_EXPAND, 0, 0, 0); + + for (i = 0; i < 12; i++) + { + label = Current.rangeLabels[i] = gtk_label_new ("-"); + if (!(i % 4)) + { + gtk_label_set_text (GTK_LABEL(label), gettext (rangeNames[i/4])); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); + } + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (labelTable), label, i%4, i%4+1, i/4, i/4+1, + GTK_EXPAND | GTK_FILL, 0, 0, 0); + } + + /************************************************************/ + + AW.aliasingGraph = gtk_drawing_area_new (); + gtk_widget_set_size_request (AW.aliasingGraph, + 2 * MARGIN + 256, + RANGE_HEIGHT); + gtk_box_pack_start (GTK_BOX (vbox), AW.aliasingGraph, TRUE, TRUE, 0); + gtk_widget_show (AW.aliasingGraph); + gtk_widget_set_events (AW.aliasingGraph, RANGE_ADJUST_MASK); + + g_signal_connect (AW.aliasingGraph, "event", + G_CALLBACK (FP_Range_Change_Events), + &Current); + + /************************************************************/ + + smoothnessData = gtk_adjustment_new (Current.Alias, 0, 1.0, 0.05, 0.01, 0.0); + + Current.aliasingScale = scale = + gtk_hscale_new (GTK_ADJUSTMENT (smoothnessData)); + gtk_widget_set_size_request (scale, 200, -1); + gtk_scale_set_digits (GTK_SCALE (scale), 2); + gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); + gtk_range_set_update_policy (GTK_RANGE (scale), 0); + gtk_table_attach (GTK_TABLE (table), scale, 0, 1, 2, 3, + 0, 0, 0, 0); + gtk_widget_show (scale); + + g_signal_connect (smoothnessData, "value_changed", + G_CALLBACK (fp_scale_update), + &Current.Alias); + + /******************* MISC OPTIONS ***************************/ + + optionsFrame = gtk_frame_new (_("Miscellaneous Options")); + gtk_widget_show (optionsFrame); + + gtk_box_pack_start (GTK_BOX (mainvbox), optionsFrame, TRUE, TRUE, 0); + + + vbox = gtk_vbox_new (FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_container_add (GTK_CONTAINER (optionsFrame), vbox); + gtk_widget_show (vbox); + + Check_Button_In_A_Box (vbox, _("Preview as You Drag"), + GTK_SIGNAL_FUNC (As_You_Drag), + NULL, TRUE); + + frame = gtk_frame_new (_("Preview Size")); + gtk_widget_show (frame); + + smoothnessData = gtk_adjustment_new (Current.PreviewSize, + 50, MAX_PREVIEW_SIZE, + 5, 5, 0.0); + + Current.previewSizeScale = scale = + gtk_hscale_new (GTK_ADJUSTMENT (smoothnessData)); + gtk_container_add (GTK_CONTAINER (frame),scale); + gtk_widget_set_size_request (scale, 100, -1); + gtk_scale_set_digits (GTK_SCALE (scale), 0); + gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); + gtk_range_set_update_policy (GTK_RANGE (scale), 0); + gtk_widget_show (scale); + + g_signal_connect (smoothnessData, "value_changed", + G_CALLBACK (preview_size_scale_update), + &Current.PreviewSize); + + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); +} + +static void +slider_erase (GdkWindow *window, + int xpos) +{ + gdk_window_clear_area (window, MARGIN + xpos - (RANGE_HEIGHT - 1) / 2, 0, + RANGE_HEIGHT, RANGE_HEIGHT); +} + +static void +draw_slider (GdkWindow *window, + GdkGC *border_gc, + GdkGC *fill_gc, + gint xpos) +{ + gint i; + + for (i = 0; i < RANGE_HEIGHT; i++) + gdk_draw_line (window, fill_gc, MARGIN + xpos-i/2, i, MARGIN + xpos+i/2,i); + + gdk_draw_line (window, border_gc, MARGIN + xpos, 0, + MARGIN + xpos - (RANGE_HEIGHT - 1) / 2, RANGE_HEIGHT - 1); + + gdk_draw_line (window, border_gc, MARGIN + xpos, 0, + MARGIN + xpos + (RANGE_HEIGHT - 1) / 2, RANGE_HEIGHT - 1); + + gdk_draw_line (window, border_gc, MARGIN + xpos- (RANGE_HEIGHT - 1)/2, + RANGE_HEIGHT-1, MARGIN + xpos + (RANGE_HEIGHT-1)/2, + RANGE_HEIGHT - 1); +} + +static void +draw_it (GtkWidget *widget) +{ + draw_slider (AW.aliasingGraph->window, + AW.aliasingGraph->style->black_gc, + AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL], + Current.Cutoffs[SHADOWS]); + + draw_slider (AW.aliasingGraph->window, + AW.aliasingGraph->style->black_gc, + AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL], + Current.Cutoffs[MIDTONES]); + + draw_slider (AW.aliasingGraph->window, + AW.aliasingGraph->style->black_gc, + AW.aliasingGraph->style->dark_gc[GTK_STATE_SELECTED], + Current.Offset); +} + +static gboolean +FP_Range_Change_Events (GtkWidget *widget, + GdkEvent *event, + FP_Params *current) +{ + GdkEventButton *bevent; + GdkEventMotion *mevent; + gint shad, mid, offset, min; + static guchar *new; + gint x; + + switch (event->type) + { + case GDK_EXPOSE: + draw_it (NULL); + break; + + case GDK_BUTTON_PRESS: + bevent= (GdkEventButton *) event; + + shad = abs (bevent->x - Current.Cutoffs[SHADOWS]); + mid = abs (bevent->x - Current.Cutoffs[MIDTONES]); + offset = abs (bevent->x - Current.Offset); + + min = MIN (MIN (shad, mid), offset); + + if (bevent->x >0 && bevent->x<256) + { + if (min == shad) + new = &Current.Cutoffs[SHADOWS]; + else if (min == mid) + new = &Current.Cutoffs[MIDTONES]; + else + new = &Current.Offset; + + slider_erase (AW.aliasingGraph->window, *new); + *new = bevent->x; + } + + draw_it (NULL); + + if (Current.RealTime) + { + fp_range_preview_spill (AW.rangePreview, Current.ValueBy); + update_range_labels (); + fp_create_smoothness_graph (AW.aliasingPreview); + refreshPreviews (Current.VisibleFrames); + } + break; + + case GDK_BUTTON_RELEASE: + if (!Current.RealTime) + { + fp_range_preview_spill (AW.rangePreview, Current.ValueBy); + update_range_labels (); + fp_create_smoothness_graph (AW.aliasingPreview); + refreshPreviews (Current.VisibleFrames); + } + break; + + case GDK_MOTION_NOTIFY: + mevent = (GdkEventMotion *) event; + gdk_window_get_pointer (widget->window, &x, NULL, NULL); + + if (x >= 0 && x < 256) + { + slider_erase (AW.aliasingGraph->window, *new); + *new = x; + draw_it (NULL); + if (Current.RealTime) + { + fp_range_preview_spill (AW.rangePreview, Current.ValueBy); + update_range_labels (); + fp_create_smoothness_graph (AW.aliasingPreview); + refreshPreviews (Current.VisibleFrames); + } + } + break; + + default: + break; + } + + return FALSE; +} + +static void +update_range_labels (void) +{ + gchar buffer[3]; + + gtk_label_set_text (GTK_LABEL(Current.rangeLabels[1]),"0"); + + g_snprintf (buffer, sizeof (buffer), "%d", Current.Cutoffs[SHADOWS]); + gtk_label_set_text (GTK_LABEL (Current.rangeLabels[3]), buffer); + gtk_label_set_text (GTK_LABEL (Current.rangeLabels[5]), buffer); + + g_snprintf (buffer, sizeof (buffer), "%d", Current.Cutoffs[MIDTONES]); + gtk_label_set_text (GTK_LABEL (Current.rangeLabels[7]), buffer); + gtk_label_set_text (GTK_LABEL (Current.rangeLabels[9]), buffer); + + gtk_label_set_text (GTK_LABEL(Current.rangeLabels[11]), "255"); +} + +static void +initializeFilterPacks (void) +{ + gint i, j; + for (i = 0; i < 256; i++) + for (j = BY_HUE; j < JUDGE_BY; j++) + { + Current.redAdj [j][i] = 0; + Current.greenAdj [j][i] = 0; + Current.blueAdj [j][i] = 0; + Current.satAdj [j][i] = 0; + } +} + +static void +resetFilterPacks (void) +{ + initializeFilterPacks (); + refreshPreviews (Current.VisibleFrames); +} + +static ReducedImage * +Reduce_The_Image (GimpDrawable *drawable, + GimpDrawable *mask, + gint LongerSize, + gint Slctn) +{ + gint RH, RW, width, height, bytes=drawable->bpp; + ReducedImage *temp = (ReducedImage *) malloc (sizeof (ReducedImage)); + guchar *tempRGB, *src_row, *tempmask, *src_mask_row, R, G, B; + gint i, j, whichcol, whichrow, x1, x2, y1, y2; + GimpPixelRgn srcPR, srcMask; + gboolean NoSelectionMade = TRUE; + gdouble *tempHSV; + GimpRGB rgb; + GimpHSV hsv; gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); + width = x2 - x1; + height = y2 - y1; - width = drawable->width; - height = drawable->height; - bytes = drawable->bpp; + if (width != drawable->width && height != drawable->height) + NoSelectionMade = FALSE; - src_row = (guchar *) malloc ((x2 - x1) * bytes); - dest_row = (guchar *) malloc ((x2 - x1) * bytes); - - gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE); - gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE); - - for (row = y1; row < y2; row++) + if (Slctn == 0) { - gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, (x2 - x1)); - - fp_row (src_row, - dest_row, - row, - (x2 - x1), - bytes - ); - - gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, (x2 - x1)); - - if ((row % 10) == 0) - gimp_progress_update ((double) row / (double) (y2 - y1)); + x1 = 0; + x2 = drawable->width; + y1 = 0; + y2 = drawable->height; + } + else if (Slctn == 2) + { + x1 = MAX (0, x1 - width / 2.0); + x2 = MIN (drawable->width, x2 + width / 2.0); + y1 = MAX (0, y1 - height / 2.0); + y2 = MIN (drawable->height, y2 + height / 2.0); } + width = x2 - x1; + height = y2 - y1; - /* update the processed region */ + if (width > height) + { + RW = LongerSize; + RH = (gfloat) height * (gfloat) LongerSize / (gfloat) width; + } + else + { + RH = LongerSize; + RW = (gfloat) width * (gfloat) LongerSize / (gfloat) height; + } + + tempRGB = (guchar *) malloc (RW * RH * bytes); + tempHSV = (gdouble *) malloc (RW * RH * bytes * sizeof (gdouble)); + tempmask = (guchar *) malloc (RW * RH); - gimp_drawable_flush (drawable); - gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); - gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); + gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, FALSE, FALSE); + gimp_pixel_rgn_init (&srcMask, mask, x1, y1, width, height, FALSE, FALSE); - free (src_row); - free (dest_row); + src_row = (guchar *) malloc (width * bytes); + src_mask_row = (guchar *) malloc (width * bytes); + for (i = 0; i < RH; i++) + { + whichrow = (gfloat) i * (gfloat) height / (gfloat) RH; + + gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y1 + whichrow, width); + gimp_pixel_rgn_get_row (&srcMask, src_mask_row, x1, y1 + whichrow, width); + + for (j = 0; j < RW; j++) + { + whichcol = (gfloat) j * (gfloat) width / (gfloat) RW; + + if (NoSelectionMade) + tempmask[i * RW + j] = 255; + else + tempmask[i * RW + j] = src_mask_row[whichcol]; + + R = src_row[whichcol * bytes + 0]; + G = src_row[whichcol * bytes + 1]; + B = src_row[whichcol * bytes + 2]; + + gimp_rgb_set_uchar (&rgb, R, G, B); + gimp_rgb_to_hsv (&rgb, &hsv); + + tempRGB[i * RW * bytes + j * bytes + 0] = R; + tempRGB[i * RW * bytes + j * bytes + 1] = G; + tempRGB[i * RW * bytes + j * bytes + 2] = B; + + tempHSV[i * RW * bytes + j * bytes + 0] = hsv.h; + tempHSV[i * RW * bytes + j * bytes + 1] = hsv.s; + tempHSV[i * RW * bytes + j * bytes + 2] = hsv.v; + + if (bytes == 4) + tempRGB[i * RW * bytes + j * bytes + 3] = + src_row[whichcol * bytes + 3]; + } + } + + temp->width = RW; + temp->height = RH; + temp->rgb = tempRGB; + temp->hsv = tempHSV; + temp->mask = tempmask; + + return temp; +} + +static void +fp_render_preview(GtkWidget *preview, + gint changewhat, + gint changewhich) +{ + guchar *a; + gint Inten, bytes = drawable->bpp; + gint i, j, k, nudge, M, m, middle,JudgeBy; + float partial; + gint RW = reduced->width; + gint RH = reduced->height; + gint backupP[3], P[3], tempSat[JUDGE_BY][256]; + + a =(guchar *) malloc(bytes*RW); + + if (changewhat==SATURATION) + for (k=0; k<256; k++) { + for (JudgeBy=BY_HUE; JudgeByrgb[i*RW*bytes + j*bytes + 0]; + backupP[1] = P[1] = (int) reduced->rgb[i*RW*bytes + j*bytes + 1]; + backupP[2] = P[2] = (int) reduced->rgb[i*RW*bytes + j*bytes + 2]; + + m = MIN(MIN(P[0],P[1]),P[2]); + M = MAX(MAX(P[0],P[1]),P[2]); + middle=(M+m)/2; + for (k=0; k<3; k++) + if (P[k]!=m && P[k]!=M) middle=P[k]; + + partial = reduced->mask[i*RW+j]/255.0; + + for (JudgeBy=BY_HUE; JudgeByhsv[i*RW*bytes + j*bytes + JudgeBy]*255.0; + + /*DO SATURATION FIRST*/ + if (changewhat != NONEATALL) { + if (M!=m) { + for (k=0; k<3; k++) + if (backupP[k] == M) + P[k] = MAX(P[k]+partial*Current.satAdj[JudgeBy][Inten],middle); + else if (backupP[k] == m) + P[k] = MIN(P[k]-partial*Current.satAdj[JudgeBy][Inten],middle); + } + P[0] += partial*Current.redAdj[JudgeBy][Inten]; + P[1] += partial*Current.greenAdj[JudgeBy][Inten]; + P[2] += partial*Current.blueAdj[JudgeBy][Inten]; + } + } + + Inten = reduced->hsv[i*RW*bytes + j*bytes + Current.ValueBy]*255.0; + nudge = partial*nudgeArray[(Inten+Current.Offset)%256]; + + switch (changewhat) { + case HUE: + P[0] += colorSign[RED][changewhich] * nudge; + P[1] += colorSign[GREEN][changewhich] * nudge; + P[2] += colorSign[BLUE][changewhich] * nudge; + break; + + case SATURATION: + for (JudgeBy=BY_HUE; JudgeByrgb[i*RW*bytes+j*bytes+3]/255.0; + a[3*j+k]=transp*a[3*j+k]+(1-transp)*fp_fake_transparency(i,j); + } + } + gtk_preview_draw_row (GTK_PREVIEW (preview), a, 0, i, RW); + } + + free (a); + gtk_widget_queue_draw (preview); +} + +static void +Update_Current_FP (gint changewhat, + gint changewhich) +{ + gint i; + + for (i = 0; i < 256; i++) + { + gint nudge; + + fp_Create_Nudge (nudgeArray); + nudge = nudgeArray[(i + Current.Offset) % 256]; + + switch (changewhat) { + case HUE: + Current.redAdj[Current.ValueBy][i] += + colorSign[RED][changewhich] * nudge; + + Current.greenAdj[Current.ValueBy][i] += + colorSign[GREEN][changewhich] * nudge; + + Current.blueAdj[Current.ValueBy][i] += + colorSign[BLUE][changewhich] * nudge; + break; + + case SATURATION: + Current.satAdj[Current.ValueBy][i] += changewhich * nudge; + break; + + case VALUE: + Current.redAdj[Current.ValueBy][i] += changewhich * nudge; + Current.greenAdj[Current.ValueBy][i] += changewhich * nudge; + Current.blueAdj[Current.ValueBy][i] += changewhich * nudge; + break; + + default: + break; + } + } +} + +static void +fp_create_smoothness_graph (GtkWidget *preview) +{ + guchar data[256 * 3]; + gint nArray[256]; + gint i, j; + gboolean toBeBlack; + + fp_Create_Nudge(nArray); + + for (i = 0; i < MAX_ROUGHNESS; i++) + { + gint coor = MAX_ROUGHNESS - i; + for (j = 0; j < 256; j++) { + data[3 * j + 0] = 255; + data[3 * j + 1] = 255; + data[3 * j + 2] = 255; + if (!(i % (MAX_ROUGHNESS / 4))) { + data[3 * j + 0] = 255; + data[3 * j + 1] = 128; + data[3 * j + 2] = 128; + } + if (!((j + 1) % 32)) { + data[3 * j + 0] = 255; + data[3 * j + 1] = 128; + data[3 * j + 2] = 128; + } + toBeBlack = FALSE; + if (nArray[j] == coor) + toBeBlack = TRUE; + + if (j < 255) { + gint jump = abs (nArray[j] - nArray[j+1]); + if (abs (coor - nArray[j]) < jump && + abs (coor - nArray[j + 1]) < jump) + toBeBlack = TRUE; + } + if (toBeBlack) { + data[3 * j + 0] = 0; + data[3 * j + 1] = 0; + data[3 * j + 2] = 0; + } + } + gtk_preview_draw_row (GTK_PREVIEW (preview), data, 0, i, 256); + } + gtk_widget_queue_draw (preview); +} + +static void +fp_range_preview_spill (GtkWidget *preview, + gint type) +{ + gint i; + + for (i = 0; i < RANGE_HEIGHT; i++) + { + gint j; + + for (j = 0; j < 256; j++) + { + guchar data[256 * 3]; + GimpRGB rgb; + GimpHSV hsv; + + if (! ((j + 1) % 32)) + { + data[3 * j + 0] = 255; + data[3 * j + 1] = 128; + data[3 * j + 2] = 128; + } + else + { + switch (type) + { + case BY_VAL: + data[3 * j + 0] = j - Current.Offset; + data[3 * j + 1] = j - Current.Offset; + data[3 * j + 2] = j - Current.Offset; + break; + + case BY_HUE: + gimp_hsv_set (&hsv, + ((j - Current.Offset + 256) % 256) / 255.0, + 1.0, + 0.5); + gimp_hsv_to_rgb (&hsv, &rgb); + gimp_rgb_get_uchar (&rgb, + &data[3 * j + 0], + &data[3 * j + 1], + &data[3 * j + 2]); + break; + + case BY_SAT: + gimp_hsv_set (&hsv, + 0.5, + ((j-(gint)Current.Offset+256)%256) / 255.0, + 0.5); + gimp_hsv_to_rgb (&hsv, &rgb); + gimp_rgb_get_uchar (&rgb, + &data[3 * j + 0], + &data[3 * j + 1], + &data[3 * j + 2]); + break; + } + + gtk_preview_draw_row (GTK_PREVIEW (preview), data, 0, i, 256); + } + } + } + gtk_widget_queue_draw (preview); +} + +static void +fp_Create_Nudge(gint *adjArray) +{ + gint left, right, middle,i; + /* The following function was determined by trial and error */ + gdouble Steepness = pow (1 - Current.Alias, 4) * .8; + + left = (Current.Range == SHADOWS) ? 0 : Current.Cutoffs[Current.Range - 1]; + right = Current.Cutoffs[Current.Range]; + middle = (left + right)/2; + + if (Current.Alias) + for (i = 0; i < 256; i++) + if (i <= middle) + adjArray[i] = MAX_ROUGHNESS * + Current.Rough * (1 + tanh (Steepness * (i - left))) / 2; + else + adjArray[i] = MAX_ROUGHNESS * + Current.Rough * (1 + tanh (Steepness * (right - i))) / 2; + else + for (i = 0; i < 256; i++) + adjArray[i] = (left <= i && i <= right) + ? MAX_ROUGHNESS * Current.Rough : 0; +} + +static gint +fp_fake_transparency (gint i, gint j) +{ + return (((i % 20) - 10) * ((j % 20) - 10) > 0) ? 64 : 196; } diff --git a/plug-ins/fp/Makefile.am b/plug-ins/fp/Makefile.am index 40d2635ace..24efee1ae6 100644 --- a/plug-ins/fp/Makefile.am +++ b/plug-ins/fp/Makefile.am @@ -17,11 +17,7 @@ libexecdir = $(gimpplugindir)/plug-ins libexec_PROGRAMS = fp fp_SOURCES = \ - fp.c \ - fp.h \ - fp_gdk.c \ - fp_gtk.c \ - fp_misc.c + fp.c INCLUDES = \ -I$(top_srcdir) \ diff --git a/plug-ins/fp/fp.c b/plug-ins/fp/fp.c index 514db79f79..f24d19786c 100644 --- a/plug-ins/fp/fp.c +++ b/plug-ins/fp/fp.c @@ -23,19 +23,248 @@ #include "config.h" -#include -#include - #include #include - -#include "fp.h" +#include #include "libgimp/stdplugins-intl.h" +#define MAX_PREVIEW_SIZE 125 +#define MAX_ROUGHNESS 128 +#define RANGE_HEIGHT 15 +#define PR_BX_BRDR 4 +#define ALL 255 +#define MARGIN 4 -FP_Params Current = +#define HELP_ID "plug-in-filter-pack" + +#define RANGE_ADJUST_MASK GDK_EXPOSURE_MASK | \ + GDK_ENTER_NOTIFY_MASK | \ + GDK_BUTTON_PRESS_MASK | \ + GDK_BUTTON_RELEASE_MASK | \ + GDK_BUTTON1_MOTION_MASK | \ + GDK_POINTER_MOTION_HINT_MASK + + +typedef struct { + gint run; +} fpInterface; + +typedef struct { + gint width; + gint height; + guchar *rgb; + gdouble *hsv; + guchar *mask; +} ReducedImage; + +typedef enum { + SHADOWS, + MIDTONES, + HIGHLIGHTS, + INTENSITIES +}FP_Intensity; + +enum { + NONEATALL =0, + CURRENT =1, + HUE =2, + SATURATION =4, + VALUE =8 +}; + +enum { + BY_HUE, + BY_SAT, + BY_VAL, + JUDGE_BY +}; + +enum { + RED, + GREEN, + BLUE, + CYAN, + YELLOW, + MAGENTA, + ALL_PRIMARY +}; + +enum { + DOWN = -1, + UP = 1 +}; + +typedef struct { + GtkWidget *window; + GtkWidget *shadowsEntry; + GtkWidget *midtonesEntry; + GtkWidget *rangePreview; + GtkWidget *aliasingPreview; + GtkObject *aliasingData; + GtkWidget *aliasingGraph; +} AdvancedWindow; + + +typedef struct { + int Color; + float Rough; + GtkWidget *roughnessScale; + float Alias; + GtkWidget *aliasingScale; + float PreviewSize; + GtkWidget *previewSizeScale; + FP_Intensity Range; + gint ValueBy; + gint SlctnOnly; + gint RealTime; + guchar Offset; + guchar VisibleFrames; + guchar Cutoffs[INTENSITIES]; + gint Touched[JUDGE_BY]; + gint redAdj[JUDGE_BY][256]; + gint blueAdj[JUDGE_BY][256]; + gint greenAdj[JUDGE_BY][256]; + gint satAdj[JUDGE_BY][256]; + GtkWidget *rangeLabels[12]; +} FP_Params; + +static void fp_show_hide_frame(GtkWidget *button, + GtkWidget *frame); + +static ReducedImage *Reduce_The_Image (GimpDrawable *, + GimpDrawable *, + gint, + gint); + +static void fp_render_preview (GtkWidget *, + gint, + gint); + +static void Update_Current_FP (gint, + gint); + +static void fp_Create_Nudge (gint*); + +static gint fp_dialog (void); +static void fp_advanced_dialog (void); + +static void selectionMade (GtkWidget *, + gpointer ); +static void fp_scale_update (GtkAdjustment *, + float* ); +static void resetFilterPacks (void); + +static void fp_create_smoothness_graph (GtkWidget* ); + +static void fp_range_preview_spill (GtkWidget*, + gint ); +static gint fp_fake_transparency (gint i, gint j); + +static void Adjust_Preview_Sizes (gint width, + gint height ); +static void fp_redraw_all_windows (void); +static void refreshPreviews (int); +static void initializeFilterPacks (void); + +static void As_You_Drag (GtkWidget *button); +static void preview_size_scale_update (GtkAdjustment *adjustment, + float *scale_val); + +static void fp (GimpDrawable *drawable); +static GtkWidget *fp_create_bna (void); +static GtkWidget *fp_create_rough (void); +static GtkWidget *fp_create_range (void); +static GtkWidget *fp_create_circle_palette(void); +static GtkWidget *fp_create_lnd (void); +static GtkWidget *fp_create_show (void); +static GtkWidget *fp_create_msnls (void); +static GtkWidget *fp_create_pixels_select_by(void); +static void update_range_labels (void); +static gboolean FP_Range_Change_Events (GtkWidget *widget, + GdkEvent *event, + FP_Params *current); + +static void Create_A_Preview (GtkWidget **, + GtkWidget **, + int, + int ); + +static void Create_A_Table_Entry (GtkWidget **, + GtkWidget *, + const gchar *); + +static void Check_Button_In_A_Box (GtkWidget *, + const gchar *label, + GtkSignalFunc func, + gpointer data, + int clicked); + +static void Frames_Check_Button_In_A_Box (GtkWidget *, + const gchar *label, + GtkSignalFunc func, + GtkWidget *frame, + int clicked); + + +#define RESPONSE_RESET 1 + +/* These values are translated for the GUI but also used internally + to figure out which button the user pushed, etc. + Not my design, please don't blame me -- njl */ + +static const gchar *hue_red = N_("Red:"); +static const gchar *hue_green = N_("Green:"); +static const gchar *hue_blue = N_("Blue:"); +static const gchar *hue_cyan = N_("Cyan:"); +static const gchar *hue_yellow = N_("Yellow:"); +static const gchar *hue_magenta = N_("Magenta:"); + +static const gchar *val_darker = N_("Darker:"); +static const gchar *val_lighter = N_("Lighter:"); + +static const gchar *sat_more = N_("More Sat:"); +static const gchar *sat_less = N_("Less Sat:"); + +static const gchar *current_val = N_("Current:"); + +static gint colorSign[3][ALL_PRIMARY]= +{{1,-1,-1,-1,1,1},{-1,1,-1,1,1,-1},{-1,-1,1,1,-1,1}}; + +static AdvancedWindow AW = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; + +static gint nudgeArray[256]; + +static GtkWidget *origPreview, *curPreview; +static GtkWidget *rPreview, *gPreview, *bPreview; +static GtkWidget *cPreview, *yPreview, *mPreview; +static GtkWidget *centerPreview; +static GtkWidget *darkerPreview, *lighterPreview, *middlePreview; +static GtkWidget *dlg; +static GtkWidget *plusSatPreview, *SatPreview, *minusSatPreview; + +static struct +{ + GtkWidget *bna; + GtkWidget *palette; + GtkWidget *rough; + GtkWidget *range; + GtkWidget *show; + GtkWidget *lnd; + GtkWidget *pixelsBy; + GtkWidget *frameSelect; + GtkWidget *satur; +} fpFrames; + +static fpInterface FPint = +{ + FALSE /* run */ +}; + +static ReducedImage *reduced; + +static FP_Params Current = { 1, .25, /* Initial Roughness */ @@ -54,14 +283,15 @@ FP_Params Current = {0,0,0} }; -GimpDrawable *drawable, *mask; +static GimpDrawable *drawable, *mask; +static GimpRunMode run_mode; -void query (void); -void run (const gchar *name, - gint nparams, - const GimpParam *param, - gint *nreturn_vals, - GimpParam **return_vals); +static void query (void); +static void run (const gchar *name, + gint nparams, + const GimpParam *param, + gint *nreturn_vals, + GimpParam **return_vals); GimpPlugInInfo PLUG_IN_INFO = { @@ -73,7 +303,7 @@ GimpPlugInInfo PLUG_IN_INFO = MAIN() -void +static void query (void) { GimpParamDef args[] = @@ -98,7 +328,7 @@ query (void) /********************************STANDARD RUN*************************/ -void +static void run (const gchar *name, gint nparams, const GimpParam *param, @@ -111,6 +341,8 @@ run (const gchar *name, *nreturn_vals = 1; *return_vals = values; + run_mode = param[0].data.d_int32; + INIT_I18N (); values[0].type = GIMP_PDB_STATUS; @@ -142,136 +374,1617 @@ run (const gchar *name, gimp_drawable_detach (drawable); } - -void -fp_row (const guchar *src_row, - guchar *dest_row, - gint row, - gint row_width, - gint bytes) +static void +fp_func (const guchar *src, + guchar *dest, + gint bpp, + gpointer data) { - gint col, bytenum, k; - gint JudgeBy, Intensity=0, P[3], backupP[3]; + gint bytenum, k; + gint JudgeBy, Intensity = 0, P[3]; GimpRGB rgb; GimpHSV hsv; gint M, m, middle; - for (col = 0; col < row_width ; col++) + P[0] = src[0]; + P[1] = src[1]; + P[2] = src[2]; + + gimp_rgb_set_uchar (&rgb, (guchar) P[0], (guchar) P[1], (guchar) P[2]); + gimp_rgb_to_hsv (&rgb, &hsv); + + for (JudgeBy = BY_HUE; JudgeBy < JUDGE_BY; JudgeBy++) { + if (!Current.Touched[JudgeBy]) + continue; + + switch (JudgeBy) + { + case BY_HUE: + Intensity = 255 * hsv.h; + break; - backupP[0] = P[0] = src_row[col * bytes + 0]; - backupP[0] = P[1] = src_row[col * bytes + 1]; - backupP[0] = P[2] = src_row[col * bytes + 2]; + case BY_SAT: + Intensity = 255 * hsv.s; + break; + + case BY_VAL: + Intensity = 255 * hsv.v; + break; + } + + + /* It's important to take care of Saturation first!!! */ + + m = MIN (MIN (P[0], P[1]), P[2]); + M = MAX (MAX (P[0], P[1]), P[2]); + middle = (M + m) / 2; + + for (k = 0; k < 3; k++) + if (P[k] != m && P[k] != M) + middle = P[k]; + + for (k = 0; k < 3; k++) + if (M != m) + { + if (P[k] == M) + P[k] = MAX (P[k] + Current.satAdj[JudgeBy][Intensity], middle); + else if (P[k] == m) + P[k] = MIN (P[k] - Current.satAdj[JudgeBy][Intensity], middle); + } + + P[0] += Current.redAdj[JudgeBy][Intensity]; + P[1] += Current.greenAdj[JudgeBy][Intensity]; + P[2] += Current.blueAdj[JudgeBy][Intensity]; + + P[0] = CLAMP0255(P[0]); + P[1] = CLAMP0255(P[1]); + P[2] = CLAMP0255(P[2]); + } + + dest[0] = P[0]; + dest[1] = P[1]; + dest[2] = P[2]; + + for (bytenum = 3; bytenum < bpp; bytenum++) + dest[bytenum] = src[bytenum]; +} - gimp_rgb_set_uchar (&rgb, (guchar) P[0], (guchar) P[1], (guchar) P[2]); - gimp_rgb_to_hsv (&rgb, &hsv); +static void +fp (GimpDrawable *drawable) +{ + gimp_rgn_iterate2 (drawable, run_mode, fp_func, NULL); +} - for (JudgeBy = BY_HUE; JudgeBy < JUDGE_BY; JudgeBy++) - { - if (! Current.Touched[JudgeBy]) - continue; +/***********************************************************/ +/************ Main Dialog Window ******************/ +/***********************************************************/ - switch (JudgeBy) - { - case BY_HUE: - Intensity = 255 * hsv.h; - break; +static GtkWidget * +fp_create_bna (void) +{ + GtkWidget *frame, *blabel, *alabel, *bframe, *aframe, *table; - case BY_SAT: - Intensity = 255 * hsv.s; - break; + Create_A_Preview (&origPreview, &bframe, reduced->width, reduced->height); + Create_A_Preview (&curPreview, &aframe, reduced->width, reduced->height); - case BY_VAL: - Intensity = 255 * hsv.v; - break; - } + frame = gtk_frame_new (_("Before and After")); + /* All the previews */ + alabel = gtk_label_new (_("Current:")); + gtk_widget_show (alabel); + gtk_misc_set_alignment (GTK_MISC (alabel), 0.0, 0.5); - /* It's important to take care of Saturation first!!! */ + blabel = gtk_label_new (_("Original:")); + gtk_widget_show (blabel); + gtk_misc_set_alignment (GTK_MISC (blabel), 0.0, 0.5); - m = MIN (MIN (P[0], P[1]), P[2]); - M = MAX (MAX (P[0], P[1]), P[2]); - middle = (M + m) / 2; + table = gtk_table_new (2, 2, FALSE); + gtk_container_set_border_width (GTK_CONTAINER (table), 4); + gtk_table_set_row_spacings (GTK_TABLE (table), 2); + gtk_table_set_col_spacings (GTK_TABLE (table), 4); - for (k = 0; k < 3; k++) - if (P[k] != m && P[k] != M) - middle = P[k]; + gtk_container_add (GTK_CONTAINER (frame), table); - for (k = 0; k < 3; k++) - if (M != m) - { - if (P[k] == M) - P[k] = MAX (P[k] + Current.satAdj[JudgeBy][Intensity], middle); - else if (P[k] == m) - P[k] = MIN (P[k] - Current.satAdj[JudgeBy][Intensity], middle); - } + gtk_table_attach (GTK_TABLE (table), blabel, 0, 1, 0, 1, + 0, GTK_EXPAND | GTK_FILL, 0, 0); - P[0] += Current.redAdj[JudgeBy][Intensity]; - P[1] += Current.greenAdj[JudgeBy][Intensity]; - P[2] += Current.blueAdj[JudgeBy][Intensity]; + gtk_table_attach (GTK_TABLE (table), alabel, 1, 2, 0, 1, + 0, GTK_EXPAND | GTK_FILL, 0, 0); - P[0] = MAX (0, MIN (255, P[0])); - P[1] = MAX (0, MIN (255, P[1])); - P[2] = MAX (0, MIN (255, P[2])); - } + gtk_table_attach (GTK_TABLE (table), bframe, 0, 1, 1, 2, + GTK_EXPAND, GTK_EXPAND, 0, 0); - dest_row[col * bytes + 0] = P[0]; - dest_row[col * bytes + 1] = P[1]; - dest_row[col * bytes + 2] = P[2]; + gtk_table_attach (GTK_TABLE (table), aframe, 1, 2, 1, 2, + GTK_EXPAND, GTK_EXPAND, 0, 0); - if (bytes > 3) - for (bytenum = 3; bytenum < bytes; bytenum++) - dest_row[col * bytes + bytenum] = src_row[col * bytes + bytenum]; + gtk_widget_show (table); + gtk_widget_show (frame); + + return frame; +} + +/* close a sub dialog (from window manager) by simulating toggle click */ +static gboolean +sub_dialog_destroy (GtkWidget *dialog, + GdkEvent *ev, + gpointer dummy) +{ + GtkWidget *button = + GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), "ctrlButton")); + + gtk_button_clicked (GTK_BUTTON (button)); + + return TRUE; +} + +static GtkWidget * +fp_create_circle_palette (void) +{ + GtkWidget *frame, *table; + GtkWidget *rVbox, *rFrame; + GtkWidget *gVbox, *gFrame; + GtkWidget *bVbox, *bFrame; + GtkWidget *cVbox, *cFrame; + GtkWidget *yVbox, *yFrame; + GtkWidget *mVbox, *mFrame; + GtkWidget *centerVbox, *centerFrame; + + GtkWidget *win; + + frame = gtk_frame_new (NULL); + gtk_container_set_border_width (GTK_CONTAINER (frame), 4); + gtk_widget_show (frame); + + table = gtk_table_new (11, 11, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_widget_show (table); + + gtk_container_add (GTK_CONTAINER (frame), table); + + Create_A_Preview (&rPreview, &rFrame, reduced->width, reduced->height); + Create_A_Preview (&gPreview, &gFrame, reduced->width, reduced->height); + Create_A_Preview (&bPreview, &bFrame, reduced->width, reduced->height); + Create_A_Preview (&cPreview, &cFrame, reduced->width, reduced->height); + Create_A_Preview (&yPreview, &yFrame, reduced->width, reduced->height); + Create_A_Preview (&mPreview, &mFrame, reduced->width, reduced->height); + Create_A_Preview (¢erPreview, ¢erFrame, + reduced->width, reduced->height); + + Create_A_Table_Entry (&rVbox, rFrame, hue_red); + Create_A_Table_Entry (&gVbox, gFrame, hue_green); + Create_A_Table_Entry (&bVbox, bFrame, hue_blue); + Create_A_Table_Entry (&cVbox, cFrame, hue_cyan); + Create_A_Table_Entry (&yVbox, yFrame, hue_yellow); + Create_A_Table_Entry (&mVbox, mFrame, hue_magenta); + Create_A_Table_Entry (¢erVbox, centerFrame, current_val); + + gtk_table_attach (GTK_TABLE (table), rVbox, 8, 11 ,4 , 7, + GTK_EXPAND , GTK_EXPAND, 0 ,0); + gtk_table_attach (GTK_TABLE (table), gVbox, 2, 5, 0, 3, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), bVbox, 2, 5, 8, 11, + GTK_EXPAND, GTK_EXPAND,0,0); + gtk_table_attach (GTK_TABLE (table), cVbox, 0, 3, 4, 7, + GTK_EXPAND, GTK_EXPAND, 0 ,0); + gtk_table_attach (GTK_TABLE (table), yVbox, 6, 9, 0, 3, + GTK_EXPAND, GTK_EXPAND, 0 ,0); + gtk_table_attach (GTK_TABLE (table), mVbox, 6, 9, 8, 11, + GTK_EXPAND, GTK_EXPAND, 0 ,0); + gtk_table_attach (GTK_TABLE (table), centerVbox, 4, 7, 4, 7, + GTK_EXPAND, GTK_EXPAND, 0 ,0); + + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); + + gtk_window_set_title (GTK_WINDOW (win), _("Hue Variations")); + gtk_container_add (GTK_CONTAINER (win), frame); + + g_signal_connect (win, "delete_event", + G_CALLBACK (sub_dialog_destroy), + NULL); + + return win; +} + +static GtkWidget * +fp_create_rough (void) +{ + GtkWidget *frame, *scale, *vbox; + GtkObject *data; + + frame = gtk_frame_new (_("Roughness")); + gtk_widget_show (frame); + + data = gtk_adjustment_new (Current.Rough, 0, 1.0, 0.05, 0.01, 0.0); + Current.roughnessScale = scale = gtk_hscale_new (GTK_ADJUSTMENT (data)); + + gtk_widget_set_size_request (scale, 60, -1); + gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); + gtk_scale_set_digits (GTK_SCALE (scale), 2); + gtk_widget_show (scale); + + g_signal_connect (data, "value_changed", + G_CALLBACK (fp_scale_update), + &Current.Rough); + + vbox = gtk_vbox_new (FALSE, 2); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_widget_show (vbox); + gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0); + gtk_container_add (GTK_CONTAINER( frame), vbox); + + return frame; +} + +static void +fp_change_current_range (GtkWidget *widget, + gpointer data) +{ + gimp_radio_button_update (widget, data); + + if (GTK_TOGGLE_BUTTON (widget)->active) + { + refreshPreviews (Current.VisibleFrames); + if (AW.window && GTK_WIDGET_VISIBLE (AW.window)) + fp_create_smoothness_graph (AW.aliasingPreview); } } - -void fp (GimpDrawable *drawable) +static GtkWidget * +fp_create_range (void) { - GimpPixelRgn srcPR, destPR; - gint width, height; - gint bytes; - guchar *src_row, *dest_row; - gint row; - gint x1, y1, x2, y2; + GtkWidget *frame; + + frame = gimp_int_radio_group_new (TRUE, _("Affected Range"), + G_CALLBACK (fp_change_current_range), + &Current.Range, Current.Range, + + _("Sha_dows"), SHADOWS, NULL, + _("_Midtones"), MIDTONES, NULL, + _("H_ighlights"), HIGHLIGHTS, NULL, + + NULL); + + gtk_widget_show (frame); + + return frame; +} + +static GtkWidget * +fp_create_control (void) +{ + GtkWidget *frame, *box; + + frame = gtk_frame_new (_("Windows")); + + gtk_widget_show (frame); + + box = gtk_vbox_new (FALSE, 2); + gtk_container_add (GTK_CONTAINER (frame), box); + gtk_container_set_border_width (GTK_CONTAINER (box), 4); + gtk_widget_show (box); + + Frames_Check_Button_In_A_Box (box, _("_Hue"), + GTK_SIGNAL_FUNC (fp_show_hide_frame), + fpFrames.palette, + Current.VisibleFrames & HUE); + Frames_Check_Button_In_A_Box (box, _("_Saturation"), + GTK_SIGNAL_FUNC (fp_show_hide_frame), + fpFrames.satur, + Current.VisibleFrames & SATURATION); + Frames_Check_Button_In_A_Box (box, _("_Value"), + GTK_SIGNAL_FUNC (fp_show_hide_frame), + fpFrames.lnd, + Current.VisibleFrames & VALUE); + Frames_Check_Button_In_A_Box (box, _("A_dvanced"), + GTK_SIGNAL_FUNC (fp_show_hide_frame), + AW.window, + FALSE); + + return frame; +} + +static GtkWidget * +fp_create_lnd (void) +{ + GtkWidget *frame, *table, *lighterFrame, *middleFrame, *darkerFrame; + GtkWidget *lighterVbox, *middleVbox, *darkerVbox; + GtkWidget *win; + + Create_A_Preview (&lighterPreview, &lighterFrame, + reduced->width, reduced->height); + Create_A_Preview (&middlePreview, &middleFrame, + reduced->width, reduced->height); + Create_A_Preview (&darkerPreview, &darkerFrame, + reduced->width, reduced->height); + + Create_A_Table_Entry (&lighterVbox, lighterFrame, val_lighter); + Create_A_Table_Entry (&middleVbox, middleFrame, current_val); + Create_A_Table_Entry (&darkerVbox, darkerFrame, val_darker); + + frame = gtk_frame_new (NULL); + gtk_container_set_border_width (GTK_CONTAINER (frame), 6); + gtk_widget_show (frame); + + table = gtk_table_new (1, 11, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_widget_show (table); + + gtk_table_attach (GTK_TABLE (table), lighterVbox, 0, 3, 0, 1, + GTK_EXPAND , GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), middleVbox, 4, 7, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), darkerVbox, 8, 11, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_container_add (GTK_CONTAINER (frame), table); + + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); + + gtk_window_set_title (GTK_WINDOW (win), _("Value Variations")); + gtk_container_add (GTK_CONTAINER (win), frame); + + g_signal_connect (win, "delete_event", + G_CALLBACK (sub_dialog_destroy), + NULL); + + return win; +} + +static GtkWidget * +fp_create_msnls (void) +{ + GtkWidget *frame, *table, *lessFrame, *middleFrame, *moreFrame; + GtkWidget *lessVbox, *middleVbox, *moreVbox; + GtkWidget *win; + + Create_A_Preview (&minusSatPreview, &lessFrame, + reduced->width, reduced->height); + Create_A_Preview (&SatPreview, &middleFrame, + reduced->width, reduced->height); + Create_A_Preview (&plusSatPreview, &moreFrame, + reduced->width, reduced->height); + + Create_A_Table_Entry (&moreVbox, moreFrame, sat_more); + Create_A_Table_Entry (&middleVbox, middleFrame, current_val); + Create_A_Table_Entry (&lessVbox, lessFrame, sat_less); + + frame = gtk_frame_new (NULL); + gtk_container_set_border_width (GTK_CONTAINER (frame), 4); + gtk_widget_show (frame); + + table = gtk_table_new (1, 11, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_widget_show (table); + + gtk_table_attach (GTK_TABLE (table), moreVbox, 0, 3, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), middleVbox, 4, 7, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_table_attach (GTK_TABLE (table), lessVbox, 8, 11, 0, 1, + GTK_EXPAND, GTK_EXPAND, 0, 0); + gtk_container_add (GTK_CONTAINER (frame), table); + + win = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); + + gtk_window_set_title (GTK_WINDOW (win), _("Saturation Variations")); + gtk_container_add (GTK_CONTAINER (win), frame); + + g_signal_connect (win, "delete_event", + G_CALLBACK (sub_dialog_destroy), + NULL); + + return win; +} + +static void +fp_change_current_pixels_by (GtkWidget *widget, + gpointer data) +{ + gimp_radio_button_update (widget, data); + + if (GTK_TOGGLE_BUTTON (widget)->active) + { + refreshPreviews (Current.VisibleFrames); + if (AW.window && GTK_WIDGET_VISIBLE (AW.window) && AW.rangePreview) + fp_range_preview_spill (AW.rangePreview,Current.ValueBy); + } +} + +static GtkWidget * +fp_create_pixels_select_by (void) +{ + GtkWidget *frame; + + frame = gimp_int_radio_group_new (TRUE, _("Select Pixels by"), + G_CALLBACK (fp_change_current_pixels_by), + &Current.ValueBy, + Current.ValueBy, + + _("H_ue"), 0, NULL, + _("Satu_ration"), 1, NULL, + _("V_alue"), 2, NULL, + + NULL); + + gtk_widget_show (frame); + + return frame; +} + +static void +fp_change_selection (GtkWidget *widget, + gpointer data) +{ + gimp_radio_button_update (widget, data); + + if (GTK_TOGGLE_BUTTON (widget)->active) + { + fp_redraw_all_windows (); + } +} + +static GtkWidget * +fp_create_show (void) +{ + GtkWidget *frame; + + frame = gimp_int_radio_group_new (TRUE, _("Show"), + G_CALLBACK (fp_change_selection), + &Current.SlctnOnly, + Current.SlctnOnly, + + _("_Entire Image"), 0, NULL, + _("Se_lection Only"), 1, NULL, + _("Selec_tion In Context"), 2, NULL, + + NULL); + + gtk_widget_show (frame); + + return frame; +} + +static void +Create_A_Preview (GtkWidget **preview, + GtkWidget **frame, + gint previewWidth, + gint previewHeight) +{ + *frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (*frame), GTK_SHADOW_IN); + gtk_widget_show (*frame); + + *preview = gtk_preview_new (Current.Color ? + GTK_PREVIEW_COLOR : GTK_PREVIEW_GRAYSCALE); + gtk_preview_size (GTK_PREVIEW (*preview), previewWidth, previewHeight); + gtk_widget_show (*preview); + gtk_container_add (GTK_CONTAINER (*frame), *preview); +} + +static void +Check_Button_In_A_Box (GtkWidget *vbox, + const gchar *label, + GtkSignalFunc function, + gpointer data, + gboolean clicked) +{ + GtkWidget *button; + + button = gtk_check_button_new_with_mnemonic (label); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect (button, "clicked", + G_CALLBACK (function), + data); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clicked); +} + +static void +Frames_Check_Button_In_A_Box (GtkWidget *vbox, + const gchar *label, + GtkSignalFunc function, + GtkWidget *frame, + gboolean clicked) +{ + GtkWidget *button; + + button = gtk_check_button_new_with_mnemonic (label); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (frame), "ctrlButton", (gpointer) button); + gtk_widget_show (button); + + g_signal_connect (button, "clicked", + G_CALLBACK (function), + frame); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clicked); +} + +static void +Create_A_Table_Entry (GtkWidget **box, + GtkWidget *SmallerFrame, + const gchar *description) +{ + GtkWidget *label, *button, *table; + + *box = gtk_vbox_new (FALSE, 1); + gtk_container_set_border_width (GTK_CONTAINER (*box), PR_BX_BRDR); + gtk_widget_show (*box); + + /* Delayed translation applied here */ + label = gtk_label_new (gettext (description)); + + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + + table = gtk_table_new (2, 1, FALSE); + gtk_widget_show (table); + + gtk_box_pack_start (GTK_BOX (*box), table, TRUE, TRUE, 0); + + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, + 0, 0, 0, 0); + + if (description != current_val) + { + button = gtk_button_new (); + gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2, + 0, 0, 0, 4); + gtk_widget_show (button); + + gtk_container_add (GTK_CONTAINER (button), SmallerFrame); + + g_signal_connect (button, "clicked", + G_CALLBACK (selectionMade), + (gchar *) description); + } + else + { + gtk_table_attach (GTK_TABLE (table), SmallerFrame, 0, 1, 1, 2, + 0, 0, 0, 4); + } +} + +static void +fp_redraw_all_windows (void) +{ + reduced = Reduce_The_Image (drawable,mask, + Current.PreviewSize, + Current.SlctnOnly); + Adjust_Preview_Sizes (reduced->width, reduced->height); + + gtk_widget_queue_draw (fpFrames.palette); + gtk_widget_queue_draw (fpFrames.satur); + gtk_widget_queue_draw (fpFrames.lnd); + gtk_widget_queue_draw (dlg); + + refreshPreviews (Current.VisibleFrames); +} + +static void +fp_show_hide_frame (GtkWidget *button, + GtkWidget *frame) +{ + gint prev = Current.VisibleFrames; + + if (frame == NULL) + return; + + if (GTK_TOGGLE_BUTTON (button)->active) + { + if (!GTK_WIDGET_VISIBLE (frame)) + { + gtk_widget_show (frame); + + if (frame==fpFrames.palette) + Current.VisibleFrames |= HUE; + else if (frame==fpFrames.satur) + Current.VisibleFrames |= SATURATION; + else if (frame==fpFrames.lnd) + Current.VisibleFrames |= VALUE; + + refreshPreviews (Current.VisibleFrames & ~prev); + } + } + else + { + if (GTK_WIDGET_VISIBLE (frame)) + { + gtk_widget_hide (frame); + + if (frame==fpFrames.palette) + Current.VisibleFrames &= ~HUE; + else if (frame==fpFrames.satur) + Current.VisibleFrames &= ~SATURATION; + else if (frame==fpFrames.lnd) + Current.VisibleFrames &= ~VALUE; + } + } +} + +static void +Adjust_Preview_Sizes (gint width, + gint height) +{ + gtk_preview_size (GTK_PREVIEW (origPreview), width, height); + gtk_preview_size (GTK_PREVIEW (curPreview), width, height); + gtk_preview_size (GTK_PREVIEW (rPreview), width, height); + gtk_preview_size (GTK_PREVIEW (gPreview), width, height); + gtk_preview_size (GTK_PREVIEW (bPreview), width, height); + gtk_preview_size (GTK_PREVIEW (cPreview), width, height); + gtk_preview_size (GTK_PREVIEW (yPreview), width, height); + gtk_preview_size (GTK_PREVIEW (mPreview), width, height); + gtk_preview_size (GTK_PREVIEW (centerPreview), width, height); + gtk_preview_size (GTK_PREVIEW (lighterPreview), width, height); + gtk_preview_size (GTK_PREVIEW (darkerPreview), width, height); + gtk_preview_size (GTK_PREVIEW (middlePreview), width, height); + gtk_preview_size (GTK_PREVIEW (minusSatPreview), width, height); + gtk_preview_size (GTK_PREVIEW (SatPreview), width, height); + gtk_preview_size (GTK_PREVIEW (plusSatPreview), width, height); +} + +static void +selectionMade (GtkWidget *widget, + gpointer data) +{ + Current.Touched[Current.ValueBy] = 1; + + if (data == (gpointer) hue_red) { + Update_Current_FP (HUE, RED); + } else if (data == (gpointer) hue_green) { + Update_Current_FP (HUE, GREEN); + } else if (data == (gpointer) hue_blue) { + Update_Current_FP (HUE, BLUE); + } else if (data == (gpointer) hue_cyan) { + Update_Current_FP (HUE, CYAN); + } else if (data == (gpointer) hue_yellow) { + Update_Current_FP (HUE, YELLOW); + } else if (data == (gpointer) hue_magenta) { + Update_Current_FP (HUE, MAGENTA); + } else if (data == (gpointer) val_darker) { + Update_Current_FP (VALUE, DOWN); + } else if (data == (gpointer) val_lighter) { + Update_Current_FP (VALUE, UP); + } else if (data == (gpointer) sat_more) { + Update_Current_FP (SATURATION, UP); + } else if (data == (gpointer) sat_less) { + Update_Current_FP (SATURATION, DOWN); + } + + refreshPreviews (Current.VisibleFrames); +} + +static void +refreshPreviews (gint which) +{ + fp_Create_Nudge (nudgeArray); + fp_render_preview (origPreview, NONEATALL, 0); + fp_render_preview (curPreview, CURRENT, 0); + if (which & HUE) + { + fp_render_preview (rPreview, HUE, RED); + fp_render_preview (gPreview, HUE, GREEN); + fp_render_preview (bPreview, HUE, BLUE); + fp_render_preview (cPreview, HUE, CYAN); + fp_render_preview (yPreview, HUE, YELLOW); + fp_render_preview (mPreview, HUE, MAGENTA); + fp_render_preview (centerPreview, CURRENT, 0); + } + if (which & VALUE) + { + fp_render_preview (lighterPreview, VALUE, UP); + fp_render_preview (middlePreview, CURRENT, 0); + fp_render_preview (darkerPreview, VALUE, DOWN); + } + if (which & SATURATION) + { + fp_render_preview (plusSatPreview, SATURATION, UP); + fp_render_preview (SatPreview, CURRENT, 0); + fp_render_preview (minusSatPreview, SATURATION, DOWN); + } +} + +static void +fp_response (GtkWidget *widget, + gint response_id, + gpointer data) +{ + switch (response_id) + { + case RESPONSE_RESET: + resetFilterPacks (); + break; + + case GTK_RESPONSE_OK: + FPint.run = TRUE; + gtk_widget_destroy (widget); + break; + + default: + gtk_widget_destroy (widget); + break; + } +} + +static void +fp_scale_update (GtkAdjustment *adjustment, + float *scale_val) +{ + static gfloat prevValue = 0.25; + + *scale_val = adjustment->value; + + if (prevValue != adjustment->value) + { + fp_Create_Nudge (nudgeArray); + refreshPreviews (Current.VisibleFrames); + if (AW.window != NULL && GTK_WIDGET_VISIBLE (AW.window)) + fp_create_smoothness_graph (AW.aliasingPreview); + prevValue = adjustment->value; + } +} + +static gint +fp_dialog (void) +{ + GtkWidget *bna; + GtkWidget *palette; + GtkWidget *lnd; + GtkWidget *show; + GtkWidget *rough; + GtkWidget *range; + GtkWidget *pixelsBy; + GtkWidget *satur; + GtkWidget *control; + GtkWidget *table; + + reduced = Reduce_The_Image (drawable,mask, + Current.PreviewSize, + Current.SlctnOnly); + + gimp_ui_init ("fp", TRUE); + + dlg = gimp_dialog_new (_("Filter Pack Simulation"), "fp", + NULL, 0, + gimp_standard_help_func, HELP_ID, + + GIMP_STOCK_RESET, RESPONSE_RESET, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + + NULL); + + g_signal_connect (dlg, "response", + G_CALLBACK (fp_response), + dlg); + + g_signal_connect (dlg, "destroy", + G_CALLBACK (gtk_main_quit), + NULL); + + fp_advanced_dialog (); + + fpFrames.bna = bna = fp_create_bna(); + fpFrames.rough = rough = fp_create_rough(); + fpFrames.range = range = fp_create_range(); + fpFrames.palette = palette = fp_create_circle_palette(); + fpFrames.lnd = lnd = fp_create_lnd(); + fpFrames.show = show = fp_create_show(); + fpFrames.satur = satur = fp_create_msnls(); + fpFrames.pixelsBy = pixelsBy = fp_create_pixels_select_by(); + control = fp_create_control(); + /********************************************************************/ + /******************** PUT EVERYTHING TOGETHER ******************/ + + table = gtk_table_new (4, 2, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 4); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_container_set_border_width (GTK_CONTAINER (table), 6); + + gtk_table_attach (GTK_TABLE (table), bna, 0, 2, 0, 1, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), control, 1, 2, 1, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), rough, 1, 2, 3, 4, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), show, 0, 1, 1, 2, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), range, 0, 1, 2, 3, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_table_attach (GTK_TABLE (table), pixelsBy, 0, 1, 3, 4, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), table, TRUE, TRUE, 0); + gtk_widget_show (table); + gtk_widget_show (dlg); + + refreshPreviews (Current.VisibleFrames); + + gtk_main (); + gdk_flush (); + + return FPint.run; +} + +/***********************************************************/ +/************ Advanced Options Window ******************/ +/***********************************************************/ + +static void +As_You_Drag (GtkWidget *button) +{ + static gboolean notFirstTime = FALSE; + + if (! notFirstTime) + return; + + notFirstTime = TRUE; + + if (GTK_TOGGLE_BUTTON (button)->active) + { + Current.RealTime=TRUE; + gtk_range_set_update_policy (GTK_RANGE (Current.roughnessScale),0); + gtk_range_set_update_policy (GTK_RANGE (Current.aliasingScale),0); + gtk_range_set_update_policy (GTK_RANGE (Current.previewSizeScale),0); + } + else + { + Current.RealTime=FALSE; + gtk_range_set_update_policy (GTK_RANGE (Current.roughnessScale), + GTK_UPDATE_DELAYED); + gtk_range_set_update_policy (GTK_RANGE (Current.aliasingScale), + GTK_UPDATE_DELAYED); + gtk_range_set_update_policy (GTK_RANGE (Current.previewSizeScale), + GTK_UPDATE_DELAYED); + } +} + +static void +preview_size_scale_update (GtkAdjustment *adjustment, + float *scale_val) +{ + Current.PreviewSize = adjustment->value; + fp_redraw_all_windows(); +} + +static void +fp_advanced_dialog (void) +{ + gchar *rangeNames[] = { N_("Shadows:"), + N_("Midtones:"), + N_("Highlights:") }; + GtkWidget *frame, *mainvbox; + GtkObject *smoothnessData; + GtkWidget *graphFrame, *table, *scale; + GtkWidget *vbox, *label, *labelTable; + GtkWidget *optionsFrame; + gint i; + + AW.window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + gimp_help_connect (AW.window, gimp_standard_help_func, HELP_ID, NULL); + + gtk_window_set_title (GTK_WINDOW (AW.window), + _("Advanced Filter Pack Options")); + + g_signal_connect (AW.window, "delete_event", + G_CALLBACK (sub_dialog_destroy), + NULL); + + mainvbox = gtk_hbox_new (FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (mainvbox), 6); + gtk_container_add (GTK_CONTAINER (AW.window), mainvbox); + gtk_widget_show (mainvbox); + + frame = gtk_frame_new (_("Smoothness of Aliasing")); + gtk_box_pack_start (GTK_BOX (mainvbox), frame, TRUE, TRUE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (3, 1, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_container_set_border_width (GTK_CONTAINER (table), 4); + gtk_container_add (GTK_CONTAINER (frame), table); + gtk_widget_show (table); + + graphFrame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (graphFrame), GTK_SHADOW_IN); + gtk_container_set_border_width (GTK_CONTAINER (graphFrame),0); + gtk_widget_show (graphFrame); + gtk_table_attach (GTK_TABLE (table), graphFrame, 0, 1, 0, 1, + GTK_EXPAND, 0, 0, 0); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (graphFrame), vbox); + gtk_widget_show (vbox); + + AW.aliasingPreview = gtk_preview_new (GTK_PREVIEW_COLOR); + gtk_preview_size (GTK_PREVIEW (AW.aliasingPreview), 256, MAX_ROUGHNESS); + gtk_box_pack_start (GTK_BOX (vbox),AW.aliasingPreview, TRUE, TRUE, 0); + gtk_widget_show (AW.aliasingPreview); + + fp_create_smoothness_graph (AW.aliasingPreview); + + AW.rangePreview = gtk_preview_new (GTK_PREVIEW_COLOR); + gtk_preview_size (GTK_PREVIEW (AW.rangePreview), 256, RANGE_HEIGHT); + gtk_box_pack_start(GTK_BOX(vbox),AW.rangePreview, TRUE, TRUE, 0); + gtk_widget_show (AW.rangePreview); + + fp_range_preview_spill (AW.rangePreview, Current.ValueBy); + + labelTable = gtk_table_new (3, 4, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (labelTable), 4); + gtk_table_set_row_spacings (GTK_TABLE (labelTable), 2); + gtk_widget_show (labelTable); + gtk_table_attach (GTK_TABLE (table), labelTable, 0, 1, 1, 2, + GTK_EXPAND, 0, 0, 0); + + for (i = 0; i < 12; i++) + { + label = Current.rangeLabels[i] = gtk_label_new ("-"); + if (!(i % 4)) + { + gtk_label_set_text (GTK_LABEL(label), gettext (rangeNames[i/4])); + gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); + } + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (labelTable), label, i%4, i%4+1, i/4, i/4+1, + GTK_EXPAND | GTK_FILL, 0, 0, 0); + } + + /************************************************************/ + + AW.aliasingGraph = gtk_drawing_area_new (); + gtk_widget_set_size_request (AW.aliasingGraph, + 2 * MARGIN + 256, + RANGE_HEIGHT); + gtk_box_pack_start (GTK_BOX (vbox), AW.aliasingGraph, TRUE, TRUE, 0); + gtk_widget_show (AW.aliasingGraph); + gtk_widget_set_events (AW.aliasingGraph, RANGE_ADJUST_MASK); + + g_signal_connect (AW.aliasingGraph, "event", + G_CALLBACK (FP_Range_Change_Events), + &Current); + + /************************************************************/ + + smoothnessData = gtk_adjustment_new (Current.Alias, 0, 1.0, 0.05, 0.01, 0.0); + + Current.aliasingScale = scale = + gtk_hscale_new (GTK_ADJUSTMENT (smoothnessData)); + gtk_widget_set_size_request (scale, 200, -1); + gtk_scale_set_digits (GTK_SCALE (scale), 2); + gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); + gtk_range_set_update_policy (GTK_RANGE (scale), 0); + gtk_table_attach (GTK_TABLE (table), scale, 0, 1, 2, 3, + 0, 0, 0, 0); + gtk_widget_show (scale); + + g_signal_connect (smoothnessData, "value_changed", + G_CALLBACK (fp_scale_update), + &Current.Alias); + + /******************* MISC OPTIONS ***************************/ + + optionsFrame = gtk_frame_new (_("Miscellaneous Options")); + gtk_widget_show (optionsFrame); + + gtk_box_pack_start (GTK_BOX (mainvbox), optionsFrame, TRUE, TRUE, 0); + + + vbox = gtk_vbox_new (FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_container_add (GTK_CONTAINER (optionsFrame), vbox); + gtk_widget_show (vbox); + + Check_Button_In_A_Box (vbox, _("Preview as You Drag"), + GTK_SIGNAL_FUNC (As_You_Drag), + NULL, TRUE); + + frame = gtk_frame_new (_("Preview Size")); + gtk_widget_show (frame); + + smoothnessData = gtk_adjustment_new (Current.PreviewSize, + 50, MAX_PREVIEW_SIZE, + 5, 5, 0.0); + + Current.previewSizeScale = scale = + gtk_hscale_new (GTK_ADJUSTMENT (smoothnessData)); + gtk_container_add (GTK_CONTAINER (frame),scale); + gtk_widget_set_size_request (scale, 100, -1); + gtk_scale_set_digits (GTK_SCALE (scale), 0); + gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); + gtk_range_set_update_policy (GTK_RANGE (scale), 0); + gtk_widget_show (scale); + + g_signal_connect (smoothnessData, "value_changed", + G_CALLBACK (preview_size_scale_update), + &Current.PreviewSize); + + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); +} + +static void +slider_erase (GdkWindow *window, + int xpos) +{ + gdk_window_clear_area (window, MARGIN + xpos - (RANGE_HEIGHT - 1) / 2, 0, + RANGE_HEIGHT, RANGE_HEIGHT); +} + +static void +draw_slider (GdkWindow *window, + GdkGC *border_gc, + GdkGC *fill_gc, + gint xpos) +{ + gint i; + + for (i = 0; i < RANGE_HEIGHT; i++) + gdk_draw_line (window, fill_gc, MARGIN + xpos-i/2, i, MARGIN + xpos+i/2,i); + + gdk_draw_line (window, border_gc, MARGIN + xpos, 0, + MARGIN + xpos - (RANGE_HEIGHT - 1) / 2, RANGE_HEIGHT - 1); + + gdk_draw_line (window, border_gc, MARGIN + xpos, 0, + MARGIN + xpos + (RANGE_HEIGHT - 1) / 2, RANGE_HEIGHT - 1); + + gdk_draw_line (window, border_gc, MARGIN + xpos- (RANGE_HEIGHT - 1)/2, + RANGE_HEIGHT-1, MARGIN + xpos + (RANGE_HEIGHT-1)/2, + RANGE_HEIGHT - 1); +} + +static void +draw_it (GtkWidget *widget) +{ + draw_slider (AW.aliasingGraph->window, + AW.aliasingGraph->style->black_gc, + AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL], + Current.Cutoffs[SHADOWS]); + + draw_slider (AW.aliasingGraph->window, + AW.aliasingGraph->style->black_gc, + AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL], + Current.Cutoffs[MIDTONES]); + + draw_slider (AW.aliasingGraph->window, + AW.aliasingGraph->style->black_gc, + AW.aliasingGraph->style->dark_gc[GTK_STATE_SELECTED], + Current.Offset); +} + +static gboolean +FP_Range_Change_Events (GtkWidget *widget, + GdkEvent *event, + FP_Params *current) +{ + GdkEventButton *bevent; + GdkEventMotion *mevent; + gint shad, mid, offset, min; + static guchar *new; + gint x; + + switch (event->type) + { + case GDK_EXPOSE: + draw_it (NULL); + break; + + case GDK_BUTTON_PRESS: + bevent= (GdkEventButton *) event; + + shad = abs (bevent->x - Current.Cutoffs[SHADOWS]); + mid = abs (bevent->x - Current.Cutoffs[MIDTONES]); + offset = abs (bevent->x - Current.Offset); + + min = MIN (MIN (shad, mid), offset); + + if (bevent->x >0 && bevent->x<256) + { + if (min == shad) + new = &Current.Cutoffs[SHADOWS]; + else if (min == mid) + new = &Current.Cutoffs[MIDTONES]; + else + new = &Current.Offset; + + slider_erase (AW.aliasingGraph->window, *new); + *new = bevent->x; + } + + draw_it (NULL); + + if (Current.RealTime) + { + fp_range_preview_spill (AW.rangePreview, Current.ValueBy); + update_range_labels (); + fp_create_smoothness_graph (AW.aliasingPreview); + refreshPreviews (Current.VisibleFrames); + } + break; + + case GDK_BUTTON_RELEASE: + if (!Current.RealTime) + { + fp_range_preview_spill (AW.rangePreview, Current.ValueBy); + update_range_labels (); + fp_create_smoothness_graph (AW.aliasingPreview); + refreshPreviews (Current.VisibleFrames); + } + break; + + case GDK_MOTION_NOTIFY: + mevent = (GdkEventMotion *) event; + gdk_window_get_pointer (widget->window, &x, NULL, NULL); + + if (x >= 0 && x < 256) + { + slider_erase (AW.aliasingGraph->window, *new); + *new = x; + draw_it (NULL); + if (Current.RealTime) + { + fp_range_preview_spill (AW.rangePreview, Current.ValueBy); + update_range_labels (); + fp_create_smoothness_graph (AW.aliasingPreview); + refreshPreviews (Current.VisibleFrames); + } + } + break; + + default: + break; + } + + return FALSE; +} + +static void +update_range_labels (void) +{ + gchar buffer[3]; + + gtk_label_set_text (GTK_LABEL(Current.rangeLabels[1]),"0"); + + g_snprintf (buffer, sizeof (buffer), "%d", Current.Cutoffs[SHADOWS]); + gtk_label_set_text (GTK_LABEL (Current.rangeLabels[3]), buffer); + gtk_label_set_text (GTK_LABEL (Current.rangeLabels[5]), buffer); + + g_snprintf (buffer, sizeof (buffer), "%d", Current.Cutoffs[MIDTONES]); + gtk_label_set_text (GTK_LABEL (Current.rangeLabels[7]), buffer); + gtk_label_set_text (GTK_LABEL (Current.rangeLabels[9]), buffer); + + gtk_label_set_text (GTK_LABEL(Current.rangeLabels[11]), "255"); +} + +static void +initializeFilterPacks (void) +{ + gint i, j; + for (i = 0; i < 256; i++) + for (j = BY_HUE; j < JUDGE_BY; j++) + { + Current.redAdj [j][i] = 0; + Current.greenAdj [j][i] = 0; + Current.blueAdj [j][i] = 0; + Current.satAdj [j][i] = 0; + } +} + +static void +resetFilterPacks (void) +{ + initializeFilterPacks (); + refreshPreviews (Current.VisibleFrames); +} + +static ReducedImage * +Reduce_The_Image (GimpDrawable *drawable, + GimpDrawable *mask, + gint LongerSize, + gint Slctn) +{ + gint RH, RW, width, height, bytes=drawable->bpp; + ReducedImage *temp = (ReducedImage *) malloc (sizeof (ReducedImage)); + guchar *tempRGB, *src_row, *tempmask, *src_mask_row, R, G, B; + gint i, j, whichcol, whichrow, x1, x2, y1, y2; + GimpPixelRgn srcPR, srcMask; + gboolean NoSelectionMade = TRUE; + gdouble *tempHSV; + GimpRGB rgb; + GimpHSV hsv; gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); + width = x2 - x1; + height = y2 - y1; - width = drawable->width; - height = drawable->height; - bytes = drawable->bpp; + if (width != drawable->width && height != drawable->height) + NoSelectionMade = FALSE; - src_row = (guchar *) malloc ((x2 - x1) * bytes); - dest_row = (guchar *) malloc ((x2 - x1) * bytes); - - gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, width, height, FALSE, FALSE); - gimp_pixel_rgn_init (&destPR, drawable, 0, 0, width, height, TRUE, TRUE); - - for (row = y1; row < y2; row++) + if (Slctn == 0) { - gimp_pixel_rgn_get_row (&srcPR, src_row, x1, row, (x2 - x1)); - - fp_row (src_row, - dest_row, - row, - (x2 - x1), - bytes - ); - - gimp_pixel_rgn_set_row (&destPR, dest_row, x1, row, (x2 - x1)); - - if ((row % 10) == 0) - gimp_progress_update ((double) row / (double) (y2 - y1)); + x1 = 0; + x2 = drawable->width; + y1 = 0; + y2 = drawable->height; + } + else if (Slctn == 2) + { + x1 = MAX (0, x1 - width / 2.0); + x2 = MIN (drawable->width, x2 + width / 2.0); + y1 = MAX (0, y1 - height / 2.0); + y2 = MIN (drawable->height, y2 + height / 2.0); } + width = x2 - x1; + height = y2 - y1; - /* update the processed region */ + if (width > height) + { + RW = LongerSize; + RH = (gfloat) height * (gfloat) LongerSize / (gfloat) width; + } + else + { + RH = LongerSize; + RW = (gfloat) width * (gfloat) LongerSize / (gfloat) height; + } + + tempRGB = (guchar *) malloc (RW * RH * bytes); + tempHSV = (gdouble *) malloc (RW * RH * bytes * sizeof (gdouble)); + tempmask = (guchar *) malloc (RW * RH); - gimp_drawable_flush (drawable); - gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); - gimp_drawable_update (drawable->drawable_id, x1, y1, (x2 - x1), (y2 - y1)); + gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, FALSE, FALSE); + gimp_pixel_rgn_init (&srcMask, mask, x1, y1, width, height, FALSE, FALSE); - free (src_row); - free (dest_row); + src_row = (guchar *) malloc (width * bytes); + src_mask_row = (guchar *) malloc (width * bytes); + for (i = 0; i < RH; i++) + { + whichrow = (gfloat) i * (gfloat) height / (gfloat) RH; + + gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y1 + whichrow, width); + gimp_pixel_rgn_get_row (&srcMask, src_mask_row, x1, y1 + whichrow, width); + + for (j = 0; j < RW; j++) + { + whichcol = (gfloat) j * (gfloat) width / (gfloat) RW; + + if (NoSelectionMade) + tempmask[i * RW + j] = 255; + else + tempmask[i * RW + j] = src_mask_row[whichcol]; + + R = src_row[whichcol * bytes + 0]; + G = src_row[whichcol * bytes + 1]; + B = src_row[whichcol * bytes + 2]; + + gimp_rgb_set_uchar (&rgb, R, G, B); + gimp_rgb_to_hsv (&rgb, &hsv); + + tempRGB[i * RW * bytes + j * bytes + 0] = R; + tempRGB[i * RW * bytes + j * bytes + 1] = G; + tempRGB[i * RW * bytes + j * bytes + 2] = B; + + tempHSV[i * RW * bytes + j * bytes + 0] = hsv.h; + tempHSV[i * RW * bytes + j * bytes + 1] = hsv.s; + tempHSV[i * RW * bytes + j * bytes + 2] = hsv.v; + + if (bytes == 4) + tempRGB[i * RW * bytes + j * bytes + 3] = + src_row[whichcol * bytes + 3]; + } + } + + temp->width = RW; + temp->height = RH; + temp->rgb = tempRGB; + temp->hsv = tempHSV; + temp->mask = tempmask; + + return temp; +} + +static void +fp_render_preview(GtkWidget *preview, + gint changewhat, + gint changewhich) +{ + guchar *a; + gint Inten, bytes = drawable->bpp; + gint i, j, k, nudge, M, m, middle,JudgeBy; + float partial; + gint RW = reduced->width; + gint RH = reduced->height; + gint backupP[3], P[3], tempSat[JUDGE_BY][256]; + + a =(guchar *) malloc(bytes*RW); + + if (changewhat==SATURATION) + for (k=0; k<256; k++) { + for (JudgeBy=BY_HUE; JudgeByrgb[i*RW*bytes + j*bytes + 0]; + backupP[1] = P[1] = (int) reduced->rgb[i*RW*bytes + j*bytes + 1]; + backupP[2] = P[2] = (int) reduced->rgb[i*RW*bytes + j*bytes + 2]; + + m = MIN(MIN(P[0],P[1]),P[2]); + M = MAX(MAX(P[0],P[1]),P[2]); + middle=(M+m)/2; + for (k=0; k<3; k++) + if (P[k]!=m && P[k]!=M) middle=P[k]; + + partial = reduced->mask[i*RW+j]/255.0; + + for (JudgeBy=BY_HUE; JudgeByhsv[i*RW*bytes + j*bytes + JudgeBy]*255.0; + + /*DO SATURATION FIRST*/ + if (changewhat != NONEATALL) { + if (M!=m) { + for (k=0; k<3; k++) + if (backupP[k] == M) + P[k] = MAX(P[k]+partial*Current.satAdj[JudgeBy][Inten],middle); + else if (backupP[k] == m) + P[k] = MIN(P[k]-partial*Current.satAdj[JudgeBy][Inten],middle); + } + P[0] += partial*Current.redAdj[JudgeBy][Inten]; + P[1] += partial*Current.greenAdj[JudgeBy][Inten]; + P[2] += partial*Current.blueAdj[JudgeBy][Inten]; + } + } + + Inten = reduced->hsv[i*RW*bytes + j*bytes + Current.ValueBy]*255.0; + nudge = partial*nudgeArray[(Inten+Current.Offset)%256]; + + switch (changewhat) { + case HUE: + P[0] += colorSign[RED][changewhich] * nudge; + P[1] += colorSign[GREEN][changewhich] * nudge; + P[2] += colorSign[BLUE][changewhich] * nudge; + break; + + case SATURATION: + for (JudgeBy=BY_HUE; JudgeByrgb[i*RW*bytes+j*bytes+3]/255.0; + a[3*j+k]=transp*a[3*j+k]+(1-transp)*fp_fake_transparency(i,j); + } + } + gtk_preview_draw_row (GTK_PREVIEW (preview), a, 0, i, RW); + } + + free (a); + gtk_widget_queue_draw (preview); +} + +static void +Update_Current_FP (gint changewhat, + gint changewhich) +{ + gint i; + + for (i = 0; i < 256; i++) + { + gint nudge; + + fp_Create_Nudge (nudgeArray); + nudge = nudgeArray[(i + Current.Offset) % 256]; + + switch (changewhat) { + case HUE: + Current.redAdj[Current.ValueBy][i] += + colorSign[RED][changewhich] * nudge; + + Current.greenAdj[Current.ValueBy][i] += + colorSign[GREEN][changewhich] * nudge; + + Current.blueAdj[Current.ValueBy][i] += + colorSign[BLUE][changewhich] * nudge; + break; + + case SATURATION: + Current.satAdj[Current.ValueBy][i] += changewhich * nudge; + break; + + case VALUE: + Current.redAdj[Current.ValueBy][i] += changewhich * nudge; + Current.greenAdj[Current.ValueBy][i] += changewhich * nudge; + Current.blueAdj[Current.ValueBy][i] += changewhich * nudge; + break; + + default: + break; + } + } +} + +static void +fp_create_smoothness_graph (GtkWidget *preview) +{ + guchar data[256 * 3]; + gint nArray[256]; + gint i, j; + gboolean toBeBlack; + + fp_Create_Nudge(nArray); + + for (i = 0; i < MAX_ROUGHNESS; i++) + { + gint coor = MAX_ROUGHNESS - i; + for (j = 0; j < 256; j++) { + data[3 * j + 0] = 255; + data[3 * j + 1] = 255; + data[3 * j + 2] = 255; + if (!(i % (MAX_ROUGHNESS / 4))) { + data[3 * j + 0] = 255; + data[3 * j + 1] = 128; + data[3 * j + 2] = 128; + } + if (!((j + 1) % 32)) { + data[3 * j + 0] = 255; + data[3 * j + 1] = 128; + data[3 * j + 2] = 128; + } + toBeBlack = FALSE; + if (nArray[j] == coor) + toBeBlack = TRUE; + + if (j < 255) { + gint jump = abs (nArray[j] - nArray[j+1]); + if (abs (coor - nArray[j]) < jump && + abs (coor - nArray[j + 1]) < jump) + toBeBlack = TRUE; + } + if (toBeBlack) { + data[3 * j + 0] = 0; + data[3 * j + 1] = 0; + data[3 * j + 2] = 0; + } + } + gtk_preview_draw_row (GTK_PREVIEW (preview), data, 0, i, 256); + } + gtk_widget_queue_draw (preview); +} + +static void +fp_range_preview_spill (GtkWidget *preview, + gint type) +{ + gint i; + + for (i = 0; i < RANGE_HEIGHT; i++) + { + gint j; + + for (j = 0; j < 256; j++) + { + guchar data[256 * 3]; + GimpRGB rgb; + GimpHSV hsv; + + if (! ((j + 1) % 32)) + { + data[3 * j + 0] = 255; + data[3 * j + 1] = 128; + data[3 * j + 2] = 128; + } + else + { + switch (type) + { + case BY_VAL: + data[3 * j + 0] = j - Current.Offset; + data[3 * j + 1] = j - Current.Offset; + data[3 * j + 2] = j - Current.Offset; + break; + + case BY_HUE: + gimp_hsv_set (&hsv, + ((j - Current.Offset + 256) % 256) / 255.0, + 1.0, + 0.5); + gimp_hsv_to_rgb (&hsv, &rgb); + gimp_rgb_get_uchar (&rgb, + &data[3 * j + 0], + &data[3 * j + 1], + &data[3 * j + 2]); + break; + + case BY_SAT: + gimp_hsv_set (&hsv, + 0.5, + ((j-(gint)Current.Offset+256)%256) / 255.0, + 0.5); + gimp_hsv_to_rgb (&hsv, &rgb); + gimp_rgb_get_uchar (&rgb, + &data[3 * j + 0], + &data[3 * j + 1], + &data[3 * j + 2]); + break; + } + + gtk_preview_draw_row (GTK_PREVIEW (preview), data, 0, i, 256); + } + } + } + gtk_widget_queue_draw (preview); +} + +static void +fp_Create_Nudge(gint *adjArray) +{ + gint left, right, middle,i; + /* The following function was determined by trial and error */ + gdouble Steepness = pow (1 - Current.Alias, 4) * .8; + + left = (Current.Range == SHADOWS) ? 0 : Current.Cutoffs[Current.Range - 1]; + right = Current.Cutoffs[Current.Range]; + middle = (left + right)/2; + + if (Current.Alias) + for (i = 0; i < 256; i++) + if (i <= middle) + adjArray[i] = MAX_ROUGHNESS * + Current.Rough * (1 + tanh (Steepness * (i - left))) / 2; + else + adjArray[i] = MAX_ROUGHNESS * + Current.Rough * (1 + tanh (Steepness * (right - i))) / 2; + else + for (i = 0; i < 256; i++) + adjArray[i] = (left <= i && i <= right) + ? MAX_ROUGHNESS * Current.Rough : 0; +} + +static gint +fp_fake_transparency (gint i, gint j) +{ + return (((i % 20) - 10) * ((j % 20) - 10) > 0) ? 64 : 196; } diff --git a/plug-ins/fp/fp.h b/plug-ins/fp/fp.h deleted file mode 100644 index 5f15e104c0..0000000000 --- a/plug-ins/fp/fp.h +++ /dev/null @@ -1,218 +0,0 @@ -#define MAX_PREVIEW_SIZE 125 -#define MAX_ROUGHNESS 128 -#define RANGE_HEIGHT 15 -#define PR_BX_BRDR 4 -#define ALL 255 -#define MARGIN 4 - -#define HELP_ID "plug-in-filter-pack" - -#define RANGE_ADJUST_MASK GDK_EXPOSURE_MASK | \ - GDK_ENTER_NOTIFY_MASK | \ - GDK_BUTTON_PRESS_MASK | \ - GDK_BUTTON_RELEASE_MASK | \ - GDK_BUTTON1_MOTION_MASK | \ - GDK_POINTER_MOTION_HINT_MASK - - -typedef struct { - gint run; -} fpInterface; - -typedef struct { - gint width; - gint height; - guchar *rgb; - gdouble *hsv; - guchar *mask; -} ReducedImage; - -typedef enum { - SHADOWS, - MIDTONES, - HIGHLIGHTS, - INTENSITIES -}FP_Intensity; - -enum { - NONEATALL =0, - CURRENT =1, - HUE =2, - SATURATION =4, - VALUE =8 -}; - - -enum { - RED, - GREEN, - BLUE, - CYAN, - YELLOW, - MAGENTA, - ALL_PRIMARY -}; - -enum { - DOWN = -1, - UP = 1 -}; - -enum { - BY_HUE, - BY_SAT, - BY_VAL, - JUDGE_BY -}; - - -typedef struct { - GtkWidget *window; - GtkWidget *shadowsEntry; - GtkWidget *midtonesEntry; - GtkWidget *rangePreview; - GtkWidget *aliasingPreview; - GtkObject *aliasingData; - GtkWidget *aliasingGraph; -} AdvancedWindow; - - -typedef struct { - int Color; - float Rough; - GtkWidget *roughnessScale; - float Alias; - GtkWidget *aliasingScale; - float PreviewSize; - GtkWidget *previewSizeScale; - FP_Intensity Range; - gint ValueBy; - gint SlctnOnly; - gint RealTime; - guchar Offset; - guchar VisibleFrames; - guchar Cutoffs[INTENSITIES]; - gint Touched[JUDGE_BY]; - gint redAdj[JUDGE_BY][256]; - gint blueAdj[JUDGE_BY][256]; - gint greenAdj[JUDGE_BY][256]; - gint satAdj[JUDGE_BY][256]; - GtkWidget *rangeLabels[12]; -}FP_Params; - -GtkWidget *fp_create_bna(void); -GtkWidget *fp_create_rough(void); -GtkWidget *fp_create_range(void); -GtkWidget *fp_create_circle_palette(void); -GtkWidget *fp_create_lnd(void); -GtkWidget *fp_create_show(void); -GtkWidget *fp_create_msnls(); -GtkWidget *fp_create_frame_select(); -GtkWidget *fp_create_pixels_select_by(); - -void fp_show_hide_frame(GtkWidget *button, - GtkWidget *frame); - -ReducedImage *Reduce_The_Image (GimpDrawable *, - GimpDrawable *, - gint, - gint); - -void fp_render_preview (GtkWidget *, - gint, - gint ); - -void Update_Current_FP (gint, - gint ); - -void fp_Create_Nudge (gint* ); - -gint fp_dialog (void); -void fp_advanced_dialog (void); - -void fp_advanced_call (void); - -void fp_entire_image (GtkWidget *, - gpointer ); -void fp_selection_only (GtkWidget *, - gpointer ); - -void fp_selection_in_context (GtkWidget *, - gpointer ); - -void selectionMade (GtkWidget *, - gpointer ); -void fp_close_callback (GtkWidget *, - gpointer ); -void fp_ok_callback (GtkWidget *, - gpointer ); -void fp_scale_update (GtkAdjustment *, - float* ); -void fp_change_current_range (GtkAdjustment*, - gint* ); -void fp_change_current_pixels_by (GtkWidget *, - gint *); -void resetFilterPacks (void); - -void update_range_labels (void); - -void fp_create_smoothness_graph (GtkWidget* ); - -void fp_range_preview_spill (GtkWidget*, - gint ); - -void Create_A_Preview (GtkWidget **, - GtkWidget **, - int, - int ); - -void Create_A_Table_Entry (GtkWidget **, - GtkWidget *, - const gchar *); - -GSList* Button_In_A_Box (GtkWidget *, - GSList *, - const gchar *, - GtkSignalFunc, - gpointer, - int ); - -void Check_Button_In_A_Box (GtkWidget *, - const gchar *label, - GtkSignalFunc func, - gpointer data, - int clicked); - -void Frames_Check_Button_In_A_Box (GtkWidget *, - const gchar *label, - GtkSignalFunc func, - GtkWidget *frame, - int clicked); - -void Adjust_Preview_Sizes (int width, - int height ); -void refreshPreviews (int); -void initializeFilterPacks (void); - -void fp (GimpDrawable *drawable); -void fp_row (const guchar *src_row, - guchar *dest_row, - gint row, - gint row_width, - gint bytes); - -void draw_slider (GdkWindow *window, - GdkGC *border_gc, - GdkGC *fill_gc, - int xpos); -gint FP_Range_Change_Events (GtkWidget *, - GdkEvent *, - FP_Params *); - -void As_You_Drag (GtkWidget *button); -void preview_size_scale_update (GtkAdjustment *adjustment, - float *scale_val); - - -void fp_advanced_ok(); -gint fp_fake_transparency(gint i, gint j); diff --git a/plug-ins/fp/fp_gdk.c b/plug-ins/fp/fp_gdk.c deleted file mode 100644 index 178baf3255..0000000000 --- a/plug-ins/fp/fp_gdk.c +++ /dev/null @@ -1,171 +0,0 @@ - -#include "config.h" - -#include -#include - -#include - -#include "libgimp/gimp.h" - -#include "fp.h" - -extern AdvancedWindow AW; -extern FP_Params Current; - - -extern gint nudgeArray[256]; - - -void -slider_erase (GdkWindow *window, - int xpos) -{ - gdk_window_clear_area (window, MARGIN + xpos - (RANGE_HEIGHT - 1) / 2, 0, - RANGE_HEIGHT, RANGE_HEIGHT); -} - -void -draw_slider(GdkWindow *window, - GdkGC *border_gc, - GdkGC *fill_gc, - int xpos) -{ - gint i; - - for (i = 0; i < RANGE_HEIGHT; i++) - gdk_draw_line (window, fill_gc, MARGIN + xpos-i/2, i, MARGIN + xpos+i/2,i); - - gdk_draw_line (window, border_gc, MARGIN + xpos, 0, - MARGIN + xpos - (RANGE_HEIGHT - 1) / 2, RANGE_HEIGHT - 1); - - gdk_draw_line (window, border_gc, MARGIN + xpos, 0, - MARGIN + xpos + (RANGE_HEIGHT - 1) / 2, RANGE_HEIGHT - 1); - - gdk_draw_line (window, border_gc, MARGIN + xpos-(RANGE_HEIGHT-1)/2,RANGE_HEIGHT-1, - MARGIN + xpos + (RANGE_HEIGHT-1)/2, RANGE_HEIGHT-1); -} - - -void -draw_it (GtkWidget *widget) -{ - draw_slider (AW.aliasingGraph->window, - AW.aliasingGraph->style->black_gc, - AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL], - Current.Cutoffs[SHADOWS]); - - draw_slider (AW.aliasingGraph->window, - AW.aliasingGraph->style->black_gc, - AW.aliasingGraph->style->dark_gc[GTK_STATE_NORMAL], - Current.Cutoffs[MIDTONES]); - - draw_slider (AW.aliasingGraph->window, - AW.aliasingGraph->style->black_gc, - AW.aliasingGraph->style->dark_gc[GTK_STATE_SELECTED], - Current.Offset); -} - -gint -FP_Range_Change_Events (GtkWidget *widget, - GdkEvent *event, - FP_Params *current) -{ - GdkEventButton *bevent; - GdkEventMotion *mevent; - gint shad, mid, offset, min; - static guchar *new; - gint x; - - switch (event->type) - { - case GDK_EXPOSE: - draw_it (NULL); - break; - - case GDK_BUTTON_PRESS: - bevent= (GdkEventButton *) event; - - shad = abs (bevent->x - Current.Cutoffs[SHADOWS]); - mid = abs (bevent->x - Current.Cutoffs[MIDTONES]); - offset = abs (bevent->x - Current.Offset); - - min = MIN (MIN (shad, mid), offset); - - if (bevent->x >0 && bevent->x<256) - { - if (min == shad) - new = &Current.Cutoffs[SHADOWS]; - else if (min == mid) - new = &Current.Cutoffs[MIDTONES]; - else - new = &Current.Offset; - - slider_erase (AW.aliasingGraph->window, *new); - *new=bevent->x; - } - - draw_it (NULL); - - if (Current.RealTime) - { - fp_range_preview_spill (AW.rangePreview, Current.ValueBy); - update_range_labels (); - fp_create_smoothness_graph (AW.aliasingPreview); - refreshPreviews (Current.VisibleFrames); - } - break; - - case GDK_BUTTON_RELEASE: - if (!Current.RealTime) - { - fp_range_preview_spill (AW.rangePreview, Current.ValueBy); - update_range_labels (); - fp_create_smoothness_graph (AW.aliasingPreview); - refreshPreviews (Current.VisibleFrames); - } - break; - - case GDK_MOTION_NOTIFY: - mevent = (GdkEventMotion *) event; - gdk_window_get_pointer (widget->window, &x, NULL, NULL); - - if (x >= 0 && x < 256) - { - slider_erase (AW.aliasingGraph->window, *new); - *new = x; - draw_it (NULL); - if (Current.RealTime) - { - fp_range_preview_spill (AW.rangePreview, Current.ValueBy); - update_range_labels (); - fp_create_smoothness_graph (AW.aliasingPreview); - refreshPreviews (Current.VisibleFrames); - } - } - break; - - default: - break; - } - - return FALSE; -} - -void -update_range_labels (void) -{ - gchar buffer[3]; - - gtk_label_set_text (GTK_LABEL(Current.rangeLabels[1]),"0"); - - g_snprintf (buffer, sizeof (buffer), "%d", Current.Cutoffs[SHADOWS]); - gtk_label_set_text (GTK_LABEL (Current.rangeLabels[3]), buffer); - gtk_label_set_text (GTK_LABEL (Current.rangeLabels[5]), buffer); - - g_snprintf (buffer, sizeof (buffer), "%d", Current.Cutoffs[MIDTONES]); - gtk_label_set_text (GTK_LABEL (Current.rangeLabels[7]), buffer); - gtk_label_set_text (GTK_LABEL (Current.rangeLabels[9]), buffer); - - gtk_label_set_text (GTK_LABEL(Current.rangeLabels[11]), "255"); -} diff --git a/plug-ins/fp/fp_gtk.c b/plug-ins/fp/fp_gtk.c deleted file mode 100644 index 773f5964f1..0000000000 --- a/plug-ins/fp/fp_gtk.c +++ /dev/null @@ -1,1193 +0,0 @@ -#include "config.h" - -#include -#include -#include - -#ifdef __GNUC__ -#warning GTK_DISABLE_DEPRECATED -#endif -#undef GTK_DISABLE_DEPRECATED - -#include - -#include -#include - -#include "libgimp/stdplugins-intl.h" - -#include "fp.h" - - -#define RESPONSE_RESET 1 - -/* These values are translated for the GUI but also used internally - to figure out which button the user pushed, etc. - Not my design, please don't blame me -- njl */ - -static const gchar *hue_red = N_("Red:"); -static const gchar *hue_green = N_("Green:"); -static const gchar *hue_blue = N_("Blue:"); -static const gchar *hue_cyan = N_("Cyan:"); -static const gchar *hue_yellow = N_("Yellow:"); -static const gchar *hue_magenta = N_("Magenta:"); - -static const gchar *val_darker = N_("Darker:"); -static const gchar *val_lighter = N_("Lighter:"); - -static const gchar *sat_more = N_("More Sat:"); -static const gchar *sat_less = N_("Less Sat:"); - -static const gchar *current_val = N_("Current:"); - -AdvancedWindow AW = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - -extern FP_Params Current; - -extern GimpDrawable *drawable; -extern GimpDrawable *mask; - -FP_Intensity ShMidHi[] = { SHADOWS, MIDTONES, HIGHLIGHTS }; -gint HueSatVal[] = { BY_HUE, BY_SAT, BY_VAL }; - -gint nudgeArray[256]; - -static GtkWidget *origPreview, *curPreview; -static GtkWidget *rPreview, *gPreview, *bPreview; -static GtkWidget *cPreview, *yPreview, *mPreview; -static GtkWidget *centerPreview; -static GtkWidget *darkerPreview, *lighterPreview, *middlePreview; -static GtkWidget *dlg; -static GtkWidget *plusSatPreview, *SatPreview, *minusSatPreview; - -struct -{ - GtkWidget *bna; - GtkWidget *palette; - GtkWidget *rough; - GtkWidget *range; - GtkWidget *show; - GtkWidget *lnd; - GtkWidget *pixelsBy; - GtkWidget *frameSelect; - GtkWidget *satur; -} fpFrames; - -fpInterface FPint = -{ - FALSE /* run */ -}; - -ReducedImage *reduced; - -/***********************************************************/ -/************ Main Dialog Window ******************/ -/***********************************************************/ - -GtkWidget * -fp_create_bna (void) -{ - GtkWidget *frame, *blabel, *alabel, *bframe, *aframe, *table; - - Create_A_Preview (&origPreview, &bframe, reduced->width, reduced->height); - Create_A_Preview (&curPreview, &aframe, reduced->width, reduced->height); - - frame = gtk_frame_new (_("Before and After")); - - /* All the previews */ - alabel = gtk_label_new (_("Current:")); - gtk_widget_show (alabel); - gtk_misc_set_alignment (GTK_MISC (alabel), 0.0, 0.5); - - blabel = gtk_label_new (_("Original:")); - gtk_widget_show (blabel); - gtk_misc_set_alignment (GTK_MISC (blabel), 0.0, 0.5); - - table = gtk_table_new (2, 2, FALSE); - gtk_container_set_border_width (GTK_CONTAINER (table), 4); - gtk_table_set_row_spacings (GTK_TABLE (table), 2); - gtk_table_set_col_spacings (GTK_TABLE (table), 4); - - gtk_container_add (GTK_CONTAINER (frame), table); - - gtk_table_attach (GTK_TABLE (table), blabel, 0, 1, 0, 1, - 0, GTK_EXPAND | GTK_FILL, 0, 0); - - gtk_table_attach (GTK_TABLE (table), alabel, 1, 2, 0, 1, - 0, GTK_EXPAND | GTK_FILL, 0, 0); - - gtk_table_attach (GTK_TABLE (table), bframe, 0, 1, 1, 2, - GTK_EXPAND, GTK_EXPAND, 0, 0); - - gtk_table_attach (GTK_TABLE (table), aframe, 1, 2, 1, 2, - GTK_EXPAND, GTK_EXPAND, 0, 0); - - gtk_widget_show (table); - gtk_widget_show (frame); - - return frame; -} - -/* close a sub dialog (from window manager) by simulating toggle click */ -gboolean -sub_dialog_destroy (GtkWidget *dialog, - GdkEvent *ev, - gpointer dummy) -{ - GtkWidget *button = - GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), "ctrlButton")); - - gtk_button_clicked (GTK_BUTTON (button)); - - return TRUE; -} - -GtkWidget * -fp_create_circle_palette (void) -{ - GtkWidget *frame, *table; - GtkWidget *rVbox, *rFrame; - GtkWidget *gVbox, *gFrame; - GtkWidget *bVbox, *bFrame; - GtkWidget *cVbox, *cFrame; - GtkWidget *yVbox, *yFrame; - GtkWidget *mVbox, *mFrame; - GtkWidget *centerVbox, *centerFrame; - - GtkWidget *win; - - frame = gtk_frame_new (NULL); - gtk_container_set_border_width (GTK_CONTAINER (frame), 4); - gtk_widget_show (frame); - - table = gtk_table_new (11, 11, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (table), 2); - gtk_widget_show (table); - - gtk_container_add (GTK_CONTAINER (frame), table); - - Create_A_Preview (&rPreview, &rFrame, reduced->width, reduced->height); - Create_A_Preview (&gPreview, &gFrame, reduced->width, reduced->height); - Create_A_Preview (&bPreview, &bFrame, reduced->width, reduced->height); - Create_A_Preview (&cPreview, &cFrame, reduced->width, reduced->height); - Create_A_Preview (&yPreview, &yFrame, reduced->width, reduced->height); - Create_A_Preview (&mPreview, &mFrame, reduced->width, reduced->height); - Create_A_Preview (¢erPreview, ¢erFrame, - reduced->width, reduced->height); - - Create_A_Table_Entry (&rVbox, rFrame, hue_red); - Create_A_Table_Entry (&gVbox, gFrame, hue_green); - Create_A_Table_Entry (&bVbox, bFrame, hue_blue); - Create_A_Table_Entry (&cVbox, cFrame, hue_cyan); - Create_A_Table_Entry (&yVbox, yFrame, hue_yellow); - Create_A_Table_Entry (&mVbox, mFrame, hue_magenta); - Create_A_Table_Entry (¢erVbox, centerFrame, current_val); - - gtk_table_attach (GTK_TABLE (table), rVbox, 8, 11 ,4 , 7, - GTK_EXPAND , GTK_EXPAND, 0 ,0); - gtk_table_attach (GTK_TABLE (table), gVbox, 2, 5, 0, 3, - GTK_EXPAND, GTK_EXPAND, 0, 0); - gtk_table_attach (GTK_TABLE (table), bVbox, 2, 5, 8, 11, - GTK_EXPAND, GTK_EXPAND,0,0); - gtk_table_attach (GTK_TABLE (table), cVbox, 0, 3, 4, 7, - GTK_EXPAND, GTK_EXPAND, 0 ,0); - gtk_table_attach (GTK_TABLE (table), yVbox, 6, 9, 0, 3, - GTK_EXPAND, GTK_EXPAND, 0 ,0); - gtk_table_attach (GTK_TABLE (table), mVbox, 6, 9, 8, 11, - GTK_EXPAND, GTK_EXPAND, 0 ,0); - gtk_table_attach (GTK_TABLE (table), centerVbox, 4, 7, 4, 7, - GTK_EXPAND, GTK_EXPAND, 0 ,0); - - win = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); - - gtk_window_set_title (GTK_WINDOW (win), _("Hue Variations")); - gtk_container_add (GTK_CONTAINER (win), frame); - - g_signal_connect (win, "delete_event", - G_CALLBACK (sub_dialog_destroy), - NULL); - - return win; -} - -GtkWidget * -fp_create_rough (void) -{ - GtkWidget *frame, *scale, *vbox; - GtkObject *data; - - frame = gtk_frame_new (_("Roughness")); - gtk_widget_show (frame); - - data = gtk_adjustment_new (Current.Rough, 0, 1.0, 0.05, 0.01, 0.0); - Current.roughnessScale = scale = gtk_hscale_new (GTK_ADJUSTMENT (data)); - - gtk_widget_set_size_request (scale, 60, -1); - gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); - gtk_scale_set_digits (GTK_SCALE (scale), 2); - gtk_widget_show (scale); - - g_signal_connect (data, "value_changed", - G_CALLBACK (fp_scale_update), - &Current.Rough); - - vbox = gtk_vbox_new (FALSE, 2); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); - gtk_widget_show (vbox); - gtk_box_pack_start (GTK_BOX (vbox), scale, FALSE, FALSE, 0); - gtk_container_add (GTK_CONTAINER( frame), vbox); - - return frame; -} - -GtkWidget * -fp_create_range (void) -{ - GtkWidget *frame, *vbox; - GSList *group=NULL; - - frame = gtk_frame_new (_("Affected Range")); - - gtk_widget_show (frame); - - vbox = gtk_vbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); - gtk_widget_show (vbox); - - group = Button_In_A_Box (vbox, group, _("Sha_dows"), - GTK_SIGNAL_FUNC (fp_change_current_range), - ShMidHi + SHADOWS, - Current.Range == SHADOWS); - group = Button_In_A_Box (vbox, group, _("_Midtones"), - GTK_SIGNAL_FUNC (fp_change_current_range), - ShMidHi + MIDTONES, - Current.Range == MIDTONES); - group = Button_In_A_Box (vbox, group, _("H_ighlights"), - GTK_SIGNAL_FUNC (fp_change_current_range), - ShMidHi + HIGHLIGHTS, - Current.Range == HIGHLIGHTS); - - return frame; -} - -GtkWidget * -fp_create_control (void) -{ - GtkWidget *frame, *box; - - frame = gtk_frame_new (_("Windows")); - - gtk_widget_show (frame); - - box = gtk_vbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (frame), box); - gtk_container_set_border_width (GTK_CONTAINER (box), 4); - gtk_widget_show (box); - - Frames_Check_Button_In_A_Box (box, _("_Hue"), - GTK_SIGNAL_FUNC (fp_show_hide_frame), - fpFrames.palette, - Current.VisibleFrames & HUE); - Frames_Check_Button_In_A_Box (box, _("_Saturation"), - GTK_SIGNAL_FUNC (fp_show_hide_frame), - fpFrames.satur, - Current.VisibleFrames & SATURATION); - Frames_Check_Button_In_A_Box (box, _("_Value"), - GTK_SIGNAL_FUNC (fp_show_hide_frame), - fpFrames.lnd, - Current.VisibleFrames & VALUE); - Frames_Check_Button_In_A_Box (box, _("A_dvanced"), - GTK_SIGNAL_FUNC (fp_show_hide_frame), - AW.window, - FALSE); - - return frame; -} - -GtkWidget * -fp_create_lnd (void) -{ - GtkWidget *frame, *table, *lighterFrame, *middleFrame, *darkerFrame; - GtkWidget *lighterVbox, *middleVbox, *darkerVbox; - GtkWidget *win; - - Create_A_Preview (&lighterPreview, &lighterFrame, - reduced->width, reduced->height); - Create_A_Preview (&middlePreview, &middleFrame, - reduced->width, reduced->height); - Create_A_Preview (&darkerPreview, &darkerFrame, - reduced->width, reduced->height); - - Create_A_Table_Entry (&lighterVbox, lighterFrame, val_lighter); - Create_A_Table_Entry (&middleVbox, middleFrame, current_val); - Create_A_Table_Entry (&darkerVbox, darkerFrame, val_darker); - - frame = gtk_frame_new (NULL); - gtk_container_set_border_width (GTK_CONTAINER (frame), 6); - gtk_widget_show (frame); - - table = gtk_table_new (1, 11, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (table), 2); - gtk_widget_show (table); - - - gtk_table_attach (GTK_TABLE (table), lighterVbox, 0, 3, 0, 1, - GTK_EXPAND , GTK_EXPAND, 0, 0); - gtk_table_attach (GTK_TABLE (table), middleVbox, 4, 7, 0, 1, - GTK_EXPAND, GTK_EXPAND, 0, 0); - gtk_table_attach (GTK_TABLE (table), darkerVbox, 8, 11, 0, 1, - GTK_EXPAND, GTK_EXPAND, 0, 0); - gtk_container_add (GTK_CONTAINER (frame), table); - - win = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); - - gtk_window_set_title (GTK_WINDOW (win), _("Value Variations")); - gtk_container_add (GTK_CONTAINER (win), frame); - - g_signal_connect (win, "delete_event", - G_CALLBACK (sub_dialog_destroy), - NULL); - - return win; -} - -GtkWidget * -fp_create_msnls (void) -{ - GtkWidget *frame, *table, *lessFrame, *middleFrame, *moreFrame; - GtkWidget *lessVbox, *middleVbox, *moreVbox; - GtkWidget *win; - - Create_A_Preview (&minusSatPreview, &lessFrame, - reduced->width, reduced->height); - Create_A_Preview (&SatPreview, &middleFrame, - reduced->width, reduced->height); - Create_A_Preview (&plusSatPreview, &moreFrame, - reduced->width, reduced->height); - - Create_A_Table_Entry (&moreVbox, moreFrame, sat_more); - Create_A_Table_Entry (&middleVbox, middleFrame, current_val); - Create_A_Table_Entry (&lessVbox, lessFrame, sat_less); - - frame = gtk_frame_new (NULL); - gtk_container_set_border_width (GTK_CONTAINER (frame), 4); - gtk_widget_show (frame); - - table = gtk_table_new (1, 11, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (table), 2); - gtk_widget_show (table); - - gtk_table_attach (GTK_TABLE (table), moreVbox, 0, 3, 0, 1, - GTK_EXPAND, GTK_EXPAND, 0, 0); - gtk_table_attach (GTK_TABLE (table), middleVbox, 4, 7, 0, 1, - GTK_EXPAND, GTK_EXPAND, 0, 0); - gtk_table_attach (GTK_TABLE (table), lessVbox, 8, 11, 0, 1, - GTK_EXPAND, GTK_EXPAND, 0, 0); - gtk_container_add (GTK_CONTAINER (frame), table); - - win = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - gimp_help_connect (win, gimp_standard_help_func, HELP_ID, NULL); - - gtk_window_set_title (GTK_WINDOW (win), _("Saturation Variations")); - gtk_container_add (GTK_CONTAINER (win), frame); - - g_signal_connect (win, "delete_event", - G_CALLBACK (sub_dialog_destroy), - NULL); - - return win; -} - -GtkWidget * -fp_create_pixels_select_by (void) -{ - GtkWidget *frame, *vbox; - GSList *group=NULL; - - frame = gtk_frame_new (_("Select Pixels by")); - gtk_widget_show (frame); - - vbox = gtk_vbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); - gtk_widget_show (vbox); - - group = Button_In_A_Box (vbox, group, _("H_ue"), - GTK_SIGNAL_FUNC (fp_change_current_pixels_by), - HueSatVal + 0, - Current.ValueBy == BY_HUE); - group = Button_In_A_Box (vbox,group, _("Satu_ration"), - GTK_SIGNAL_FUNC (fp_change_current_pixels_by), - HueSatVal + 1, - Current.ValueBy == BY_SAT); - group = Button_In_A_Box (vbox,group, _("V_alue"), - GTK_SIGNAL_FUNC (fp_change_current_pixels_by), - HueSatVal + 2, - Current.ValueBy == BY_VAL); - return frame; -} - -GtkWidget * -fp_create_show (void) -{ - GtkWidget *frame, *vbox; - GSList *group = NULL; - - frame = gtk_frame_new(_("Show")); - gtk_widget_show (frame); - - vbox = gtk_vbox_new (FALSE, 2); - gtk_container_add (GTK_CONTAINER (frame), vbox); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); - gtk_widget_show (vbox); - - group = Button_In_A_Box (vbox, group, _("_Entire Image"), - GTK_SIGNAL_FUNC (fp_entire_image), - &Current.SlctnOnly, - FALSE); - - group = Button_In_A_Box (vbox, group, _("Se_lection Only"), - GTK_SIGNAL_FUNC (fp_selection_only), - &Current.SlctnOnly, - TRUE); - - group = Button_In_A_Box (vbox, group, _("Selec_tion In Context"), - GTK_SIGNAL_FUNC (fp_selection_in_context), - &Current.SlctnOnly, - FALSE); - - return frame; -} - -#ifdef __FP_UNUSED_STUFF__ -GtkWidget * -fp_create_frame_select (void) -{ - GtkWidget *frame, *box; - - frame = gtk_frame_new (_("Display")); - gtk_container_set_border_width (GTK_CONTAINER (frame), 4); - gtk_widget_show (frame); - - box = gtk_hbox_new (FALSE, 8); - gtk_container_add (GTK_CONTAINER (frame), box); - gtk_container_set_border_width (GTK_CONTAINER (box),4); - gtk_widget_show (box); - - Check_Button_In_A_Box (box, _("CirclePalette"), - GTK_SIGNAL_FUNC (fp_show_hide_frame), - fpFrames.palette,TRUE); - Check_Button_In_A_Box (box, _("Lighter And Darker"), - GTK_SIGNAL_FUNC (fp_show_hide_frame), - fpFrames.lnd,TRUE); - Check_Button_In_A_Box (box, _("Saturation"), - GTK_SIGNAL_FUNC (fp_show_hide_frame), - fpFrames.satur,FALSE); - - return frame; -} -#endif - -void Create_A_Preview (GtkWidget **preview, - GtkWidget **frame, - gint previewWidth, - gint previewHeight) -{ - *frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (*frame), GTK_SHADOW_IN); - gtk_widget_show (*frame); - - *preview = gtk_preview_new (Current.Color ? - GTK_PREVIEW_COLOR : GTK_PREVIEW_GRAYSCALE); - gtk_preview_size (GTK_PREVIEW (*preview), previewWidth, previewHeight); - gtk_widget_show (*preview); - gtk_container_add (GTK_CONTAINER (*frame), *preview); -} - -GSList * -Button_In_A_Box (GtkWidget *vbox, - GSList *group, - const gchar *label, - GtkSignalFunc function, - gpointer data, - gboolean clicked) -{ - GtkWidget *button; - - button = gtk_radio_button_new_with_mnemonic (group, label); - gtk_widget_show (button); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - - g_signal_connect (button, "clicked", - G_CALLBACK (function), - data); - - if (clicked) - gtk_button_clicked (GTK_BUTTON (button)); - - return gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)); -} - -void -Check_Button_In_A_Box (GtkWidget *vbox, - const gchar *label, - GtkSignalFunc function, - gpointer data, - gboolean clicked) -{ - GtkWidget *button; - - button = gtk_check_button_new_with_mnemonic (label); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - gtk_widget_show (button); - - g_signal_connect (button, "clicked", - G_CALLBACK (function), - data); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clicked); -} - -void -Frames_Check_Button_In_A_Box (GtkWidget *vbox, - const gchar *label, - GtkSignalFunc function, - GtkWidget *frame, - gboolean clicked) -{ - GtkWidget *button; - - button = gtk_check_button_new_with_mnemonic (label); - gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); - g_object_set_data (G_OBJECT (frame), "ctrlButton", (gpointer) button); - gtk_widget_show (button); - - g_signal_connect (button, "clicked", - G_CALLBACK (function), - frame); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clicked); -} - -void -Create_A_Table_Entry (GtkWidget **box, - GtkWidget *SmallerFrame, - const gchar *description) -{ - GtkWidget *label, *button, *table; - - *box = gtk_vbox_new (FALSE, 1); - gtk_container_set_border_width (GTK_CONTAINER (*box), PR_BX_BRDR); - gtk_widget_show (*box); - - /* Delayed translation applied here */ - label = gtk_label_new (gettext (description)); - - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - - table = gtk_table_new (2, 1, FALSE); - gtk_widget_show (table); - - gtk_box_pack_start (GTK_BOX (*box), table, TRUE, TRUE, 0); - - gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, - 0, 0, 0, 0); - - if (description != current_val) - { - button = gtk_button_new (); - gtk_table_attach (GTK_TABLE (table), button, 0, 1, 1, 2, - 0, 0, 0, 4); - gtk_widget_show (button); - - gtk_container_add (GTK_CONTAINER (button), SmallerFrame); - - g_signal_connect (button, "clicked", - G_CALLBACK (selectionMade), - (gchar *) description); - } - else - { - gtk_table_attach (GTK_TABLE (table), SmallerFrame, 0, 1, 1, 2, - 0, 0, 0, 4); - } -} - -void -fp_redraw_all_windows (void) -{ - reduced = Reduce_The_Image (drawable,mask, - Current.PreviewSize, - Current.SlctnOnly); - Adjust_Preview_Sizes (reduced->width, reduced->height); - - /*gtk_container_check_resize(GTK_CONTAINER(fpFrames.palette), NULL);*/ - gtk_widget_queue_draw (fpFrames.palette); - - /*gtk_container_check_resize(GTK_CONTAINER(fpFrames.satur), NULL);*/ - gtk_widget_queue_draw (fpFrames.satur); - - /*gtk_container_check_resize(GTK_CONTAINER(fpFrames.lnd), NULL);*/ - gtk_widget_queue_draw (fpFrames.lnd); - - /*gtk_container_check_resize(GTK_CONTAINER(dlg), NULL);*/ - gtk_widget_queue_draw (dlg); - - refreshPreviews (Current.VisibleFrames); -} - -void -fp_entire_image (GtkWidget *button, - gpointer data) -{ - if (!GTK_TOGGLE_BUTTON (button)->active) - return; - Current.SlctnOnly = 0; - fp_redraw_all_windows (); -} - -void -fp_selection_only (GtkWidget *button, - gpointer data) -{ - static gint notFirstTime = 0; - - if (!(notFirstTime++)) - return; - - if (!GTK_TOGGLE_BUTTON (button)->active) - return; - Current.SlctnOnly = 1; - fp_redraw_all_windows (); -} - -void -fp_selection_in_context (GtkWidget *button, - gpointer data) -{ - if (!GTK_TOGGLE_BUTTON (button)->active) - return; - - Current.SlctnOnly = 2; - fp_redraw_all_windows (); -} - -void -fp_show_hide_frame (GtkWidget *button, - GtkWidget *frame) -{ - gint prev = Current.VisibleFrames; - - if (frame == NULL) - return; - - if (GTK_TOGGLE_BUTTON (button)->active) - { - if (!GTK_WIDGET_VISIBLE (frame)) - { - gtk_widget_show (frame); - - if (frame==fpFrames.palette) - Current.VisibleFrames |= HUE; - else if (frame==fpFrames.satur) - Current.VisibleFrames |= SATURATION; - else if (frame==fpFrames.lnd) - Current.VisibleFrames |= VALUE; - - refreshPreviews (Current.VisibleFrames & ~prev); - } - } - else - { - if (GTK_WIDGET_VISIBLE (frame)) - { - gtk_widget_hide (frame); - - if (frame==fpFrames.palette) - Current.VisibleFrames &= ~HUE; - else if (frame==fpFrames.satur) - Current.VisibleFrames &= ~SATURATION; - else if (frame==fpFrames.lnd) - Current.VisibleFrames &= ~VALUE; - } - } -} - -void -Adjust_Preview_Sizes (gint width, - gint height) -{ - gtk_preview_size (GTK_PREVIEW (origPreview), width, height); - gtk_preview_size (GTK_PREVIEW (curPreview), width, height); - gtk_preview_size (GTK_PREVIEW (rPreview), width, height); - gtk_preview_size (GTK_PREVIEW (gPreview), width, height); - gtk_preview_size (GTK_PREVIEW (bPreview), width, height); - gtk_preview_size (GTK_PREVIEW (cPreview), width, height); - gtk_preview_size (GTK_PREVIEW (yPreview), width, height); - gtk_preview_size (GTK_PREVIEW (mPreview), width, height); - gtk_preview_size (GTK_PREVIEW (centerPreview), width, height); - gtk_preview_size (GTK_PREVIEW (lighterPreview), width, height); - gtk_preview_size (GTK_PREVIEW (darkerPreview), width, height); - gtk_preview_size (GTK_PREVIEW (middlePreview), width, height); - gtk_preview_size (GTK_PREVIEW (minusSatPreview), width, height); - gtk_preview_size (GTK_PREVIEW (SatPreview), width, height); - gtk_preview_size (GTK_PREVIEW (plusSatPreview), width, height); -} - -void -selectionMade (GtkWidget *widget, - gpointer data) -{ - Current.Touched[Current.ValueBy] = 1; - - if (data == (gpointer) hue_red) { - Update_Current_FP (HUE, RED); - } else if (data == (gpointer) hue_green) { - Update_Current_FP (HUE, GREEN); - } else if (data == (gpointer) hue_blue) { - Update_Current_FP (HUE, BLUE); - } else if (data == (gpointer) hue_cyan) { - Update_Current_FP (HUE, CYAN); - } else if (data == (gpointer) hue_yellow) { - Update_Current_FP (HUE, YELLOW); - } else if (data == (gpointer) hue_magenta) { - Update_Current_FP (HUE, MAGENTA); - } else if (data == (gpointer) val_darker) { - Update_Current_FP (VALUE, DOWN); - } else if (data == (gpointer) val_lighter) { - Update_Current_FP (VALUE, UP); - } else if (data == (gpointer) sat_more) { - Update_Current_FP (SATURATION, UP); - } else if (data == (gpointer) sat_less) { - Update_Current_FP (SATURATION, DOWN); - } - - refreshPreviews (Current.VisibleFrames); -} - -void -refreshPreviews (gint which) -{ - fp_Create_Nudge (nudgeArray); - fp_render_preview (origPreview, NONEATALL, 0); - fp_render_preview (curPreview, CURRENT, 0); - if (which & HUE) - { - fp_render_preview (rPreview, HUE, RED); - fp_render_preview (gPreview, HUE, GREEN); - fp_render_preview (bPreview, HUE, BLUE); - fp_render_preview (cPreview, HUE, CYAN); - fp_render_preview (yPreview, HUE, YELLOW); - fp_render_preview (mPreview, HUE, MAGENTA); - fp_render_preview (centerPreview, CURRENT, 0); - } - if (which & VALUE) - { - fp_render_preview (lighterPreview, VALUE, UP); - fp_render_preview (middlePreview, CURRENT, 0); - fp_render_preview (darkerPreview, VALUE, DOWN); - } - if (which & SATURATION) - { - fp_render_preview (plusSatPreview, SATURATION, UP); - fp_render_preview (SatPreview, CURRENT, 0); - fp_render_preview (minusSatPreview, SATURATION, DOWN); - } -} - -void -fp_response (GtkWidget *widget, - gint response_id, - gpointer data) -{ - switch (response_id) - { - case RESPONSE_RESET: - resetFilterPacks (); - break; - - case GTK_RESPONSE_OK: - FPint.run = TRUE; - gtk_widget_destroy (widget); - break; - - default: - gtk_widget_destroy (widget); - break; - } -} - -void -fp_scale_update (GtkAdjustment *adjustment, - float *scale_val) -{ - static gfloat prevValue = 0.25; - - *scale_val = adjustment->value; - - if (prevValue != adjustment->value) - { - fp_Create_Nudge (nudgeArray); - refreshPreviews (Current.VisibleFrames); - if (AW.window != NULL && GTK_WIDGET_VISIBLE (AW.window)) - fp_create_smoothness_graph (AW.aliasingPreview); - prevValue = adjustment->value; - } -} - -void -fp_change_current_range (GtkAdjustment *button, - gint *Intensity) -{ - static FP_Intensity prevValue=MIDTONES; - static int notFirstTime=0; - - if (!(notFirstTime++)) return; - if (!GTK_TOGGLE_BUTTON (button)->active) return; - if (*Intensity == prevValue) return; - - Current.Range = *Intensity; - refreshPreviews (Current.VisibleFrames); - if (AW.window != NULL && GTK_WIDGET_VISIBLE (AW.window)) - fp_create_smoothness_graph (AW.aliasingPreview); - prevValue = *Intensity; -} - -void -fp_change_current_pixels_by (GtkWidget *button, - gint *valueBy) -{ - gint prevValue = VALUE; - static gint notFirstTime = 0; - - if (!(notFirstTime++)) - return; - - if (!GTK_TOGGLE_BUTTON(button)->active) - return; - - if (*valueBy == prevValue) - return; - - Current.ValueBy = *valueBy; - refreshPreviews (Current.VisibleFrames); - if (AW.window != NULL && - GTK_WIDGET_VISIBLE (AW.window) && - AW.rangePreview != NULL) - fp_range_preview_spill (AW.rangePreview,Current.ValueBy); - - prevValue = *valueBy; -} - -void -fp_advanced_call (void) -{ - if (AW.window!=NULL) - if (GTK_WIDGET_VISIBLE (AW.window)) - gtk_widget_hide (AW.window); - else - gtk_widget_show (AW.window); - else - fp_advanced_dialog (); -} - -gint -fp_dialog (void) -{ - GtkWidget *bna; - GtkWidget *palette; - GtkWidget *lnd; - GtkWidget *show; - GtkWidget *rough; - GtkWidget *range; - GtkWidget *pixelsBy; - GtkWidget *satur; - GtkWidget *control; - GtkWidget *table; - - reduced = Reduce_The_Image (drawable,mask, - Current.PreviewSize, - Current.SlctnOnly); - - gimp_ui_init ("fp", TRUE); - - /********************************************************************/ - /************************* All the Standard Stuff *******************/ - dlg = gimp_dialog_new (_("Filter Pack Simulation"), "fp", - NULL, 0, - gimp_standard_help_func, HELP_ID, - - GIMP_STOCK_RESET, RESPONSE_RESET, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OK, GTK_RESPONSE_OK, - - NULL); - - g_signal_connect (dlg, "response", - G_CALLBACK (fp_response), - dlg); - - g_signal_connect (dlg, "destroy", - G_CALLBACK (gtk_main_quit), - NULL); - - /********************************************************************/ - - fp_advanced_dialog (); - - fpFrames.bna = bna = fp_create_bna(); - fpFrames.rough = rough = fp_create_rough(); - fpFrames.range = range = fp_create_range(); - fpFrames.palette = palette = fp_create_circle_palette(); - fpFrames.lnd = lnd = fp_create_lnd(); - fpFrames.show = show = fp_create_show(); - fpFrames.satur = satur = fp_create_msnls(); - fpFrames.pixelsBy = pixelsBy = fp_create_pixels_select_by(); - control = fp_create_control(); - /********************************************************************/ - /******************** PUT EVRYTHING TOGETHER ******************/ - - table = gtk_table_new (4, 2, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (table), 4); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_container_set_border_width (GTK_CONTAINER (table), 6); - - gtk_table_attach (GTK_TABLE (table), bna, 0, 2, 0, 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - - gtk_table_attach (GTK_TABLE (table), control, 1, 2, 1, 3, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - - gtk_table_attach (GTK_TABLE (table), rough, 1, 2, 3, 4, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - - gtk_table_attach (GTK_TABLE (table), show, 0, 1, 1, 2, - GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - - gtk_table_attach (GTK_TABLE (table), range, 0, 1, 2, 3, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - - gtk_table_attach (GTK_TABLE (table), pixelsBy, 0, 1, 3, 4, - GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), table, TRUE, TRUE, 0); - gtk_widget_show (table); - gtk_widget_show (dlg); - - refreshPreviews (Current.VisibleFrames); - - gtk_main (); - gdk_flush (); - - return FPint.run; -} - -/***********************************************************/ -/************ Advanced Options Window ******************/ -/***********************************************************/ - -void -fp_advanced_ok (void) -{ - gtk_widget_hide (AW.window); -} - -void -As_You_Drag (GtkWidget *button) -{ - static gboolean notFirstTime = FALSE; - - if (! notFirstTime) - return; - - notFirstTime = TRUE; - - if (GTK_TOGGLE_BUTTON (button)->active) - { - Current.RealTime=TRUE; - gtk_range_set_update_policy (GTK_RANGE (Current.roughnessScale),0); - gtk_range_set_update_policy (GTK_RANGE (Current.aliasingScale),0); - gtk_range_set_update_policy (GTK_RANGE (Current.previewSizeScale),0); - } - else - { - Current.RealTime=FALSE; - gtk_range_set_update_policy (GTK_RANGE (Current.roughnessScale), - GTK_UPDATE_DELAYED); - gtk_range_set_update_policy (GTK_RANGE (Current.aliasingScale), - GTK_UPDATE_DELAYED); - gtk_range_set_update_policy (GTK_RANGE (Current.previewSizeScale), - GTK_UPDATE_DELAYED); - } -} - -void -preview_size_scale_update (GtkAdjustment *adjustment, - float *scale_val) -{ - Current.PreviewSize = adjustment->value; - fp_redraw_all_windows(); -} - -void -fp_advanced_dialog (void) -{ - gchar *rangeNames[] = { N_("Shadows:"), - N_("Midtones:"), - N_("Highlights:") }; - GtkWidget *frame, *mainvbox; - GtkObject *smoothnessData; - GtkWidget *graphFrame, *table, *scale; - GtkWidget *vbox, *label, *labelTable; - GtkWidget *optionsFrame; - gint i; - - AW.window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - gimp_help_connect (AW.window, gimp_standard_help_func, HELP_ID, NULL); - - gtk_window_set_title (GTK_WINDOW (AW.window), - _("Advanced Filter Pack Options")); - - g_signal_connect (AW.window, "delete_event", - G_CALLBACK (sub_dialog_destroy), - NULL); - - mainvbox = gtk_hbox_new (FALSE, 4); - gtk_container_set_border_width (GTK_CONTAINER (mainvbox), 6); - gtk_container_add (GTK_CONTAINER (AW.window), mainvbox); - gtk_widget_show (mainvbox); - - frame = gtk_frame_new (_("Smoothness of Aliasing")); - gtk_box_pack_start (GTK_BOX (mainvbox), frame, TRUE, TRUE, 0); - gtk_widget_show (frame); - - table = gtk_table_new (3, 1, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 4); - gtk_container_set_border_width (GTK_CONTAINER (table), 4); - gtk_container_add (GTK_CONTAINER (frame), table); - gtk_widget_show (table); - - graphFrame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (graphFrame), GTK_SHADOW_IN); - gtk_container_set_border_width (GTK_CONTAINER (graphFrame),0); - gtk_widget_show (graphFrame); - gtk_table_attach (GTK_TABLE (table), graphFrame, 0, 1, 0, 1, - GTK_EXPAND, 0, 0, 0); - - vbox = gtk_vbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (graphFrame), vbox); - gtk_widget_show (vbox); - - AW.aliasingPreview = gtk_preview_new (GTK_PREVIEW_COLOR); - gtk_preview_size (GTK_PREVIEW (AW.aliasingPreview), 256, MAX_ROUGHNESS); - gtk_box_pack_start (GTK_BOX (vbox),AW.aliasingPreview, TRUE, TRUE, 0); - gtk_widget_show (AW.aliasingPreview); - - fp_create_smoothness_graph (AW.aliasingPreview); - - AW.rangePreview = gtk_preview_new (GTK_PREVIEW_COLOR); - gtk_preview_size (GTK_PREVIEW (AW.rangePreview), 256, RANGE_HEIGHT); - gtk_box_pack_start(GTK_BOX(vbox),AW.rangePreview, TRUE, TRUE, 0); - gtk_widget_show (AW.rangePreview); - - fp_range_preview_spill (AW.rangePreview, Current.ValueBy); - - labelTable = gtk_table_new (3, 4, FALSE); - gtk_table_set_col_spacings (GTK_TABLE (labelTable), 4); - gtk_table_set_row_spacings (GTK_TABLE (labelTable), 2); - gtk_widget_show (labelTable); - gtk_table_attach (GTK_TABLE (table), labelTable, 0, 1, 1, 2, - GTK_EXPAND, 0, 0, 0); - - for (i = 0; i < 12; i++) - { - label = Current.rangeLabels[i] = gtk_label_new ("-"); - if (!(i % 4)) - { - gtk_label_set_text (GTK_LABEL(label), gettext (rangeNames[i/4])); - gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0); - } - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (labelTable), label, i%4, i%4+1, i/4, i/4+1, - GTK_EXPAND | GTK_FILL, 0, 0, 0); - } - - /************************************************************/ - - AW.aliasingGraph = gtk_drawing_area_new (); - gtk_widget_set_size_request (AW.aliasingGraph, - 2 * MARGIN + 256, - RANGE_HEIGHT); - gtk_box_pack_start (GTK_BOX (vbox), AW.aliasingGraph, TRUE, TRUE, 0); - gtk_widget_show (AW.aliasingGraph); - gtk_widget_set_events (AW.aliasingGraph, RANGE_ADJUST_MASK); - - g_signal_connect (AW.aliasingGraph, "event", - G_CALLBACK (FP_Range_Change_Events), - &Current); - - /************************************************************/ - - smoothnessData = gtk_adjustment_new (Current.Alias, 0, 1.0, 0.05, 0.01, 0.0); - - Current.aliasingScale = scale = - gtk_hscale_new (GTK_ADJUSTMENT (smoothnessData)); - gtk_widget_set_size_request (scale, 200, -1); - gtk_scale_set_digits (GTK_SCALE (scale), 2); - gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); - gtk_range_set_update_policy (GTK_RANGE (scale), 0); - gtk_table_attach (GTK_TABLE (table), scale, 0, 1, 2, 3, - 0, 0, 0, 0); - gtk_widget_show (scale); - - g_signal_connect (smoothnessData, "value_changed", - G_CALLBACK (fp_scale_update), - &Current.Alias); - - /******************* MISC OPTIONS ***************************/ - - optionsFrame = gtk_frame_new (_("Miscellaneous Options")); - gtk_widget_show (optionsFrame); - - gtk_box_pack_start (GTK_BOX (mainvbox), optionsFrame, TRUE, TRUE, 0); - - - vbox = gtk_vbox_new (FALSE, 4); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); - gtk_container_add (GTK_CONTAINER (optionsFrame), vbox); - gtk_widget_show (vbox); - - Check_Button_In_A_Box (vbox, _("Preview as You Drag"), - GTK_SIGNAL_FUNC (As_You_Drag), - NULL, TRUE); - - frame = gtk_frame_new (_("Preview Size")); - gtk_widget_show (frame); - - smoothnessData = gtk_adjustment_new (Current.PreviewSize, - 50, MAX_PREVIEW_SIZE, - 5, 5, 0.0); - - Current.previewSizeScale = scale = - gtk_hscale_new (GTK_ADJUSTMENT (smoothnessData)); - gtk_container_add (GTK_CONTAINER (frame),scale); - gtk_widget_set_size_request (scale, 100, -1); - gtk_scale_set_digits (GTK_SCALE (scale), 0); - gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP); - gtk_range_set_update_policy (GTK_RANGE (scale), 0); - gtk_widget_show (scale); - - g_signal_connect (smoothnessData, "value_changed", - G_CALLBACK (preview_size_scale_update), - &Current.PreviewSize); - - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); -} diff --git a/plug-ins/fp/fp_misc.c b/plug-ins/fp/fp_misc.c deleted file mode 100644 index 104b630179..0000000000 --- a/plug-ins/fp/fp_misc.c +++ /dev/null @@ -1,447 +0,0 @@ - -#include "config.h" - -#include -#include - -#ifdef __GNUC__ -#warning GTK_DISABLE_DEPRECATED -#endif -#undef GTK_DISABLE_DEPRECATED - -#include - -#include - -#include "fp.h" - - -extern FP_Params Current; - -extern GimpDrawable *drawable, *mask; -extern ReducedImage *reduced; - -extern gint nudgeArray[256]; - -gint colorSign[3][ALL_PRIMARY]= -{{1,-1,-1,-1,1,1},{-1,1,-1,1,1,-1},{-1,-1,1,1,-1,1}}; - - -void initializeFilterPacks() -{ - gint i, j; - for (i=0; i<256; i++) - for (j=BY_HUE; jbpp; - ReducedImage *temp = (ReducedImage *) malloc (sizeof (ReducedImage)); - guchar *tempRGB, *src_row, *tempmask, *src_mask_row, R, G, B; - gint i, j, whichcol, whichrow, x1, x2, y1, y2; - GimpPixelRgn srcPR, srcMask; - gboolean NoSelectionMade=TRUE; - gdouble *tempHSV; - GimpRGB rgb; - GimpHSV hsv; - - gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); - width = x2 - x1; - height = y2 - y1; - - if (width != drawable->width && height != drawable->height) - NoSelectionMade = FALSE; - - if (Slctn == 0) - { - x1 = 0; - x2 = drawable->width; - y1 = 0; - y2 = drawable->height; - } - - if (Slctn == 2) - { - x1 = MAX (0, x1 - width / 2.0); - x2 = MIN (drawable->width, x2 + width / 2.0); - y1 = MAX (0, y1 - height / 2.0); - y2 = MIN (drawable->height, y2 + height / 2.0); - } - - width = x2 - x1; - height = y2 - y1; - - if (width > height) - { - RW = LongerSize; - RH = (gfloat) height * (gfloat) LongerSize / (gfloat) width; - } - else - { - RH = LongerSize; - RW = (gfloat) width * (gfloat) LongerSize / (gfloat) height; - } - - tempRGB = (guchar *) malloc (RW * RH * bytes); - tempHSV = (gdouble *) malloc (RW * RH * bytes * sizeof (gdouble)); - tempmask = (guchar *) malloc (RW * RH); - - gimp_pixel_rgn_init (&srcPR, drawable, x1, y1, width, height, FALSE, FALSE); - gimp_pixel_rgn_init (&srcMask, mask, x1, y1, width, height, FALSE, FALSE); - - src_row = (guchar *) malloc (width * bytes); - src_mask_row = (guchar *) malloc (width * bytes); - - for (i = 0; i < RH; i++) - { - whichrow = (gfloat) i * (gfloat) height / (gfloat) RH; - - gimp_pixel_rgn_get_row (&srcPR, src_row, x1, y1 + whichrow, width); - gimp_pixel_rgn_get_row (&srcMask, src_mask_row, x1, y1 + whichrow, width); - - for (j = 0; j < RW; j++) - { - whichcol = (gfloat) j * (gfloat) width / (gfloat) RW; - - if (NoSelectionMade) - tempmask[i * RW + j] = 255; - else - tempmask[i * RW + j] = src_mask_row[whichcol]; - - R = src_row[whichcol * bytes + 0]; - G = src_row[whichcol * bytes + 1]; - B = src_row[whichcol * bytes + 2]; - - gimp_rgb_set_uchar (&rgb, R, G, B); - gimp_rgb_to_hsv (&rgb, &hsv); - - tempRGB[i * RW * bytes + j * bytes + 0] = R; - tempRGB[i * RW * bytes + j * bytes + 1] = G; - tempRGB[i * RW * bytes + j * bytes + 2] = B; - - tempHSV[i * RW * bytes + j * bytes + 0] = hsv.h; - tempHSV[i * RW * bytes + j * bytes + 1] = hsv.s; - tempHSV[i * RW * bytes + j * bytes + 2] = hsv.v; - - if (bytes == 4) - tempRGB[i * RW * bytes + j * bytes + 3] = - src_row[whichcol * bytes + 3]; - } - } - - temp->width = RW; - temp->height = RH; - temp->rgb = tempRGB; - temp->hsv = tempHSV; - temp->mask = tempmask; - - return temp; -} - -/*************************************************************/ -/************** The Preview Function *************************/ -void -fp_render_preview(GtkWidget *preview, - gint changewhat, - gint changewhich) -{ - guchar *a; - gint Inten, bytes=drawable->bpp; - gint i, j, k, nudge, M, m, middle,JudgeBy; - float partial; - gint RW=reduced->width; - gint RH=reduced->height; - gint backupP[3], P[3], tempSat[JUDGE_BY][256]; - - a =(guchar *) malloc(bytes*RW); - - if (changewhat==SATURATION) - for (k=0; k<256; k++) { - for (JudgeBy=BY_HUE; JudgeByrgb[i*RW*bytes + j*bytes + 0]; - backupP[1] = P[1] = (int) reduced->rgb[i*RW*bytes + j*bytes + 1]; - backupP[2] = P[2] = (int) reduced->rgb[i*RW*bytes + j*bytes + 2]; - - m = MIN(MIN(P[0],P[1]),P[2]); - M = MAX(MAX(P[0],P[1]),P[2]); - middle=(M+m)/2; - for (k=0; k<3; k++) - if (P[k]!=m && P[k]!=M) middle=P[k]; - - partial = reduced->mask[i*RW+j]/255.0; - - for (JudgeBy=BY_HUE; JudgeByhsv[i*RW*bytes + j*bytes + JudgeBy]*255.0; - - /*DO SATURATION FIRST*/ - if (changewhat != NONEATALL) { - if (M!=m) { - for (k=0; k<3; k++) - if (backupP[k] == M) - P[k] = MAX(P[k]+partial*Current.satAdj[JudgeBy][Inten],middle); - else if (backupP[k] == m) - P[k] = MIN(P[k]-partial*Current.satAdj[JudgeBy][Inten],middle); - } - P[0] += partial*Current.redAdj[JudgeBy][Inten]; - P[1] += partial*Current.greenAdj[JudgeBy][Inten]; - P[2] += partial*Current.blueAdj[JudgeBy][Inten]; - } - } - - Inten = reduced->hsv[i*RW*bytes + j*bytes + Current.ValueBy]*255.0; - nudge = partial*nudgeArray[(Inten+Current.Offset)%256]; - - switch (changewhat) { - case HUE: - P[0] += colorSign[RED][changewhich] * nudge; - P[1] += colorSign[GREEN][changewhich] * nudge; - P[2] += colorSign[BLUE][changewhich] * nudge; - break; - - case SATURATION: - for (JudgeBy=BY_HUE; JudgeByrgb[i*RW*bytes+j*bytes+3]/255.0; - a[3*j+k]=transp*a[3*j+k]+(1-transp)*fp_fake_transparency(i,j); - } - } - gtk_preview_draw_row( GTK_PREVIEW(preview),a,0,i,RW); - } - - free(a); - gtk_widget_queue_draw (preview); -} - -void -Update_Current_FP (gint changewhat, - gint changewhich) -{ - int i, nudge; - - for (i=0; i<256; i++) { - - fp_Create_Nudge(nudgeArray); - nudge=nudgeArray[(i+Current.Offset)%256]; - - switch (changewhat) { - case HUE: - Current.redAdj[Current.ValueBy][i] += - colorSign[RED][changewhich] * nudge; - - Current.greenAdj[Current.ValueBy][i] += - colorSign[GREEN][changewhich] * nudge; - - Current.blueAdj[Current.ValueBy][i] += - colorSign[BLUE][changewhich] * nudge; - break; - - case SATURATION: - Current.satAdj[Current.ValueBy][i] += changewhich*nudge; - break; - - case VALUE: - Current.redAdj[Current.ValueBy][i] += changewhich * nudge; - Current.greenAdj[Current.ValueBy][i] += changewhich * nudge; - Current.blueAdj[Current.ValueBy][i] += changewhich * nudge; - break; - - default: - break; - } /* switch */ - - } /* for */ -} - - -void -fp_create_smoothness_graph (GtkWidget *preview) -{ - guchar data[256*3]; - gint nArray[256]; - int i, j, toBeBlack; - - fp_Create_Nudge(nArray); - - for (i=0; i0 ) - return 64; - else - return 196; -}