we'll try it again....

--Sven
CVS
: ----------------------------------------------------------------------
This commit is contained in:
Sven Neumann 1999-03-18 01:06:49 +00:00
parent bf59ac679b
commit c7878365ab
49 changed files with 22090 additions and 0 deletions

7
plug-ins/gap/.cvsignore Normal file
View File

@ -0,0 +1,7 @@
Makefile.in
Makefile
.deps
_libs
.libs
gap_filter
gap_plugins

90
plug-ins/gap/Makefile.am Normal file
View File

@ -0,0 +1,90 @@
## Process this file with automake to produce Makefile.in
pluginlibdir = $(gimpplugindir)/plug-ins
EXTRA_DIST = README README_developers TESTPROT_iter_ALT
pluginlib_PROGRAMS = gap_plugins gap_filter
gap_plugins_SOURCES = \
gap_main.c \
gap_mov_exec.c \
gap_mov_exec.h \
gap_range_ops.c \
gap_range_ops.h \
gap_arr_dialog.c \
gap_arr_dialog.h \
gap_mov_dialog.c \
gap_mov_dialog.h \
gap_layer_copy.c \
gap_layer_copy.h \
gap_split.c \
gap_split.h \
gap_resi_dialog.c \
gap_resi_dialog.h \
gap_mpege.c \
gap_mpege.h \
gap_mod_layer.c \
gap_mod_layer.h \
gap_filter_pdb.c \
gap_filter_pdb.h \
gap_filter_codegen.c \
gap_dbbrowser_utils.c \
gap_dbbrowser_utils.h \
gap_match.c \
gap_match.h \
gap_lib.c \
gap_lib.h \
gap_exchange_image.c \
gap_exchange_image.h \
gap_pdb_calls.c \
gap_pdb_calls.h \
resize.c
gap_filter_SOURCES = \
gap_filter_main.c \
gap_dbbrowser_utils.c \
gap_dbbrowser_utils.h \
gap_filter_foreach.c \
gap_filter_iterators.c \
gap_filter_iterators.h \
gap_filter_pdb.c \
gap_filter_pdb.h \
gap_filter_codegen.c \
gap_arr_dialog.c \
gap_arr_dialog.h \
gap_pdb_calls.c \
gap_pdb_calls.h \
gap_filter.h
INCLUDES = \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
-I$(includedir)
LDADD = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la \
$(GTK_LIBS)
DEPS = \
$(top_builddir)/libgimp/libgimpui.la \
$(top_builddir)/libgimp/libgimp.la
gap_plugins_DEPENDENCIES = $(DEPS)
gap_filter_DEPENDENCIES = $(DEPS)
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
@for subdir in $(SUBDIRS); do \
files=`cd $$subdir; $(MAKE) files | grep -v "make\[[1-9]\]"`; \
for file in $$files; do \
echo $$subdir/$$file; \
done; \
done

1030
plug-ins/gap/README Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,259 @@
This README_developers file should be read by Plug-In authors:
How to make a GIMP Plug-In an "Animated" one:
---------------------------------------------
First of all:
the plugin must be able to operate on a single Drawable,
----------------------------
further it must be able to run with last_values and in interactive mode.
-------------------- -----------
For the Animated Plugin Call we need an Iterator Procedure.
This Procedure is named like the Plugin with the extension "_Iterator".
The Iterator Procedure has to know the Plugin's internal datastructure
and has to modify Its "LastValues" step by step at each call.
The GAP-PDB-Browser <Image>/Filters/Animation/Filter All Layers
checks for the existance of Iterator Procedures in the PDB
1.) <plugin_name>_Iterator
2.) <plugin_name>_iter_ALT
If one of the iterator procedures was found in the PDB, the
"Apply Varying" Button is set sensitive to allow animated calls
for the selected procedure.
If you have gap prerelease 0.93.00 or later you can generate
the "plug_in_XXXX_Iterator"
for a Plugin as seperated Sourcefile, ready to compile.
(The Plugin must be found in the PDB at generation time)
# this example uses the Plugin whirlpinch
1.a # for bourne and ksh users:
GAP_DEBUG=y
export GAP_DEBUG
1.b # for csh users
setenv GAP_DEBUG y
2. # change to the directory, where you like to generate the sourcecode
cd /usr/local/gimp-0.99.17/plug-ins/whirlpinch
3. # start the Gimp
gimp
4. # open or create any image
File->New
5. # call the GAP Plugin for Animated Filter apply
# from within the image
Filters->Animation->Filter all Layers
# if you have set GAP_DEBUG as shown above,
# the Window should contain the Button "Gen Code by name"
# Type the name of your Plugin into the Search Inputfield
# (Click "Search by Name" Button, to check if the Plugin
# is available in the PDB)
# Then click "Gen Code by Name" Button and then "Cancel" Button.
# This will generate 4 files in the current directory:
gen_filter_iter_forward.c
gen_filter_iter_tab.c
plug_in_whirl_pinch_iter_ALT.inc
plug_in_whirl_pinch_iter.c
# You can quit the gimp and delete the 3 files named "gen_filter_iter_*"
6. # compile and link the generated Source, plug_in_whirl_pinch_iter.c
# and install the linked executeable
# in global or private plug-in directory
gimptool --install plug_in_whirl_pinch_iter.c
# (if you dont have gimptool, you can use a copy of the original Plugin's Makefile
# and change the Plugins <name> by <name_iter> to do that job.)
7. # start the gimp again,
# and open or create an Image that has at least 3 Layers.
# Test the "Animated Filter apply"
Filters->Animation->Filter all Layers
# Use the "Apply Varying" Button,
# it should be sensitive now (if all went well so far).
8. # In case of error:
# If you get an Error Message (in the shell, where you started the gimp)
# that looks like:
ERROR: xxxx_Iterator stored Data missmatch in size N != M
# you have to change the generated code manually.
# (check for calls to "gimp_set_data" or "gimp_get_data" that are using
# the plugins name as key argument within the plugin's sourcecode.
# The passed datastructure has to match exactly in size with the generated one
# for the example above the generated structure is:
# plug_in_whirl_pinch_iter.c:
typedef struct t_plug_in_whirl_pinch_Vals
{
gdouble whirl;
gdouble pinch;
gdouble radius;
} t_plug_in_whirl_pinch_Vals;
If you are the Author of a Plugin you may decide to include the _Iterator
within the original Sources of your Plugin. In that case you have to check
the name argument in the run procedure.
Example Code:
query()
{
static GParamDef args_plugin[] =
{
{PARAM_INT32, "run_mode", "non-interactive"},
{PARAM_IMAGE, "image", "the image"},
{PARAM_DRAWABLE, "drawable", "the drawable"},
{PARAM_INT32, "value", "my_parameter value"},
};
static int nargs_plugin = sizeof(args_plugin) / sizeof(args_plugin[0]);
static GParamDef args_iter[] =
{
{PARAM_INT32, "run_mode", "non-interactive"},
{PARAM_INT32, "total_steps", "total number of steps (# of layers-1 to apply the related plug-in)"},
{PARAM_FLOAT, "current_step", "current (for linear iterations this is the layerstack position, otherwise some value inbetween)"},
{PARAM_INT32, "len_struct", "length of stored data structure with id is equal to the plug_in proc_name"},
};
static int nargs_iter = sizeof(args_iter) / sizeof(args_iter[0]);
static GParamDef *return_vals = NULL;
static int nreturn_vals = 0;
gimp_install_procedure("plug_in_XXXX,
"plug_in_XXXX can do ....",
"",
"Authors Name",
"Copyright",
"Date",
"<Image>/Filters/Effects/XXXX",
"RGB*, INDEXED*, GRAY*",
PROC_PLUG_IN,
nargs_plugin, nreturn_vals,
args_plugin, return_vals);
gimp_install_procedure("plug_in_XXXX_Iterator,
"This extension calculates the modified values for one iterationstep for the call of plug_in_XXXX",
"",
"Authors Name",
"Copyright",
"Date",
NULL, /* do not appear in menus */
NULL,
PROC_EXTENSION,
nargs_iter, nreturn_vals,
args_iter, return_vals);
}
static void p_delta_long(long *val, long val_from, long val_to, gint32 total_steps, gdouble current_step)
{
double delta;
if(total_steps < 1) return;
delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);
*val = val_from + delta;
}
static void
run (char *name,
int n_params,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
static GParam values[1];
GStatusType status = STATUS_SUCCESS;
GRunModeType run_mode;
gint32 len_struct;
gint32 total_steps;
gdouble current_step;
long pval; /* plug_in_XXXX has one parameter of type long */
long *pval_from, *pval_to; /* values for 1.st and last layer
* when they were processed by "plug_in_gap_layers_run_animfilter"
*/
*nreturn_vals = 1;
*return_vals = values;
values[0].type = PARAM_STATUS;
run_mode = param[0].data.d_int32;
if (strcmp (name, "plug_in_XXXX") == 0)
{
.... /* start the plugin itself */
}
else if (strcmp (name, "plug_in_XXXX_Iterator") == 0)
{
/* Iterator procedure is usually called from
* "plug_in_gap_layers_run_animfilter"
* (always run noninteractive)
*/
if ((run_mode == RUN_NONINTERACTIVE) && (n_params == 4))
{
total_steps = param[1].data.d_int32;
current_step = param[2].data.d_float;
len_struct = param[3].data.d_int32;
if(len_struct == sizeof(pval))
{
/* get _FROM and _TO data,
* This data was stored by plug_in_gap_layers_run_animfilter
*/
gimp_get_data("plug_in_XXXX_ITER_FROM", pval_from);
gimp_get_data("plug_in_XXXX_ITER_TO", pval_to);
p_delta_long(&pval, *pval_from, *pval_to, total_steps, current_step);
gimp_set_data("plug_in_XXXX", &pval, sizeof(pval));
}
else status = STATUS_CALLING_ERROR;
}
else status = STATUS_CALLING_ERROR;
}
values[0].type = PARAM_STATUS;
values[0].type = PARAM_STATUS;
}
Important for Plugin_Authors:
I have made Iterator Procedures for more than 50 existing Procedures.
(see gap_filter_iterators.c and subdirectories iter_ALT/*/*.inc)
If your Plugin is found in gap_filter_iterators.c, and You make updates
to your Plugin's interface, you should write (or generate) your own _Iterator Procedure,
to keep its Animated capabilities intact.
(You don't need to change gap sources to do that, because the Iterator
named "plug_in_XXXX_Iterator" is used rather than "plug_in_XXXX_Iterator_ALT" )

View File

@ -0,0 +1,299 @@
Here is a result List of the "Animated Filtercall" Tests
I tested more than 100 PDB-Procedures and the GAP's _iter_ALT Procedures
on a 3-Layer Testimage with Menu:
<Image>/Filters/Animation/Filter All Layers using "Apply Varying" Button
---------------------------------------------------
Testresults (used in Makefile 1.1)
--------------------------------------------------
14.03.1999
Test with PDB-Procedures (Plugins) that came with
gimp release 1.1.3
and all the generated (or manually changed) _iter_ALT Procedures
State:
+ ... Passed simple "Aplly Varying" Test OK
- ... Failed Test
. ... not tested
REM ... Removed the generated _iter_ALT Procedure
Plugin did not work with last value interface
but it would make sense if Interface would be OK.
Del ... Deleted the generated _iter_ALT Procedure
It does not make sense to call the Plugin
with varying Values
* ... Iter_ALT modified by Hand
State Procedure_name Testnotes
---------------------------------------------------------------------------
. * Colorify (not part of 1.1.3)
-Del perl_fu_blowinout (not tested, perl )
-Del perl_fu_feedback (not tested, perl )
-Del perl_fu_prep4gif (not tested, perl )
-Del perl_fu_scratches (not tested, perl )
-Del perl_fu_terraltext (not tested, perl )
-Del perl_fu_tex_string_to_float (not tested, perl )
-Del perl_fu_webify (not tested, perl )
-Del perl_fu_windify (not tested, perl )
-Del perl_fu_xach_blocks (not tested, perl )
-Del perl_fu_xach_shadows (not tested, perl )
-Del perl_fu_xachvision (not tested, perl )
- plug_in_CML_explorer
. * plug_in_CentralReflection (not part of 1.1.3)
+ * plug_in_Twist
+ * plug_in_alienmap
.Del plug_in_align_layers
. plug_in_alpha2color (not tested, perl required)
. plug_in_anamorphose (not part of 1.1.3)
.Del plug_in_animationoptimize
.Del plug_in_animationplay
.Del plug_in_animationunoptimize
-REM plug_in_apply_canvas ERROR: no stored data found for Key plug_in_apply_canvas
+ plug_in_applylens
-Del plug_in_autocrop ERROR: no stored data found for Key plug_in_autocrop
-Del plug_in_autostretch_hsv ERROR: no stored data found for Key plug_in_autostretch_hsv
+ plug_in_blinds
+ * plug_in_blur
. * plug_in_blur2 (not part of 1.1.3)
-Del plug_in_blur_randomize ERROR: no stored data found for Key plug_in_blur_randomize
+ plug_in_borderaverage
+ plug_in_bump_map
-Del plug_in_c_astretch ERROR: no stored data found for Key plug_in_c_astretch
+ plug_in_checkerboard
-Del plug_in_color_adjust ERROR: no stored data found for Key plug_in_color_adjust
+ plug_in_color_map
-REM plug_in_colorify ERROR: no stored data found for Key plug_in_colorify
.Del plug_in_compose
- plug_in_convmatrix ERROR: p_plug_in_convmatrix_iter_ALT stored Data missmatch in size 140 != 0
+ plug_in_cubism
.Del plug_in_decompose
.Del plug_in_deinterlace
+ * plug_in_depth_merge
+ * plug_in_despeckle
+ plug_in_destripe
+ plug_in_diffraction
+ plug_in_displace
-Del plug_in_ditherize ERROR: no stored data found for Key plug_in_ditherize (perl)
+ plug_in_edge
+ * plug_in_emboss
. * plug_in_encript (not part of 1.1.3)
+ plug_in_engrave
- * plug_in_exchange (interface changed since 1.0, CRASH: gimp_get_data missing when RUN_WITH_LAST_VALS)
.Del plug_in_export_palette
. * plug_in_figures (not part of 1.1.3)
.Del plug_in_film
-REM plug_in_filter_pack ERROR: no stored data found for Key plug_in_filter_pack
- plug_in_flame
+ plug_in_flarefx
- * plug_in_fractal_trace OK Button disappeared at 1.st press ?????
+ plug_in_gauss_iir
+ plug_in_gauss_rle
.Del plug_in_gfig ERROR: no stored data found for Key plug_in_gfig
. * plug_in_gflare (not part of 1.1.3)
+ plug_in_glasstile
.Del plug_in_gradmap ERROR: no stored data found for Key plug_in_gradmap
+ plug_in_grid
-Del plug_in_guillotine ERROR: no stored data found for Key plug_in_guillotine
. * plug_in_holes (not part of 1.1.3)
-Del plug_in_hot
-Del plug_in_ifs_compose ERROR: no stored data found for Key plug_in_ifs_compose
-Del plug_in_illusion OK Button disappeared at 1.st press ?????
.Del plug_in_image_rot270
.Del plug_in_image_rot90
-Del plug_in_iwarp Has No RUN_WITH_LAST_VALS support, (but can animate
+ plug_in_jigsaw
. plug_in_julia (not part of 1.1.3)
-Del plug_in_laplace ERROR: no stored data found for Key plug_in_laplace
.Del plug_in_layer_rot270
.Del plug_in_layer_rot90
.Del plug_in_layers_import
-Del plug_in_lic CRASH + ERROR: no stored data found for Key plug_in_lic
+ * plug_in_lighting
. * plug_in_magic_eye (not part of 1.1.3)
.Del plug_in_mail_image
-Del plug_in_make_seamless ERROR: no stored data found for Key plug_in_make_seamless
. * plug_in_mandelbrot (not part of 1.1.3)
+ * plug_in_map_object see report below:
.Del plug_in_max_rgb
+ * plug_in_maze (interface changed)
+ plug_in_mblur
+ plug_in_mosaic
+ plug_in_newsprint
+ * plug_in_nlfilt
+ plug_in_noisify
-Del plug_in_normalize ERROR: no stored data found for Key plug_in_normalize
+ * plug_in_nova
+ * plug_in_oilify (interface changed)
- * plug_in_pagecurl ERROR: no stored data found for Key plug_in_pagecurl
- plug_in_paper_tile OK Button disappeared at 1.st press ?????
+ plug_in_pixelize
+ * plug_in_plasma
+ * plug_in_polar_coords (interface changed)
-Del plug_in_qbist
. * plug_in_randomize (not part of 1.1.3)
+ plug_in_randomize_hurl
+ plug_in_randomize_pick
+ plug_in_randomize_slur
. plug_in_refract (not part of 1.1.3)
+ plug_in_ripple
+ plug_in_rotate
+ * plug_in_sample_colorize
+ plug_in_scatter_hsv
.Del plug_in_semiflatten
+ plug_in_sharpen
+ plug_in_shift
+ plug_in_sinus
- plug_in_small_tiles ERROR: no stored data found for Key plug_in_small_tiles
.Del plug_in_smooth_palette
.Del plug_in_sobel
+ * plug_in_solid_noise
+ * plug_in_sparkle
+ plug_in_spread
. plug_in_struc (not part of 1.1.3)
-Del plug_in_the_egg ERROR: no stored data found for Key plug_in_the_egg
-Del plug_in_threshold_alpha ERROR: no stored data found for Key plug_in_threshold_alpha
-Del plug_in_tile
. plug_in_tileit (not part of 1.1.3)
. plug_in_universal_filter (not part of 1.1.3)
+ plug_in_video
-Del plug_in_vinvert ERROR: no stored data found for Key plug_in_vinvert
+ plug_in_vpropagate
. * plug_in_warp (not part of 1.1.3)
+ plug_in_waves
+ plug_in_whirl_pinch
+ plug_in_wind
.Del plug_in_zealouscrop
Summary
+ 55 Procedures
- 31 Procedures
. 51 Procedures
----------------------
137
plug_in_map_object Testreport:
- The MapObject has an implicite feature:
If the handled layer has NO ALPHA Channel (as backgrounds often do)
and the "Transparent background" is ON
it forces the creation of a new image.
(regardless if the "Create new image" option is on or not)
It took me hours to find out about that feature
that looks more like a bug to me.
I would prefere to add the alpha channel in such a case.
If you want to do animated calls to MapObject ("Apply Varying" Button)
please make sure that the background layer has an Alphachannel
(Open Layers & Channels dialog, and "Add Apha Channel"
to the bg layer)
- If you call MapObject a 2nd time in the same gimp session
gimp will crash if one of the drawables (that were used
in the 1.st call) has become invalid.
The BUG is in the GIMP-core Procedure(s)
gimp_layer_get_image_id
gimp_drawable_image_id
(in older GIMP releases these Procedures did return -1
on invalid Ids, in Gimp 1.1.3 it comes to a crash
I hope that this Bug will be fixed in gimp 1.2)
---------------------------------------------------
older Testresults (used in Makefile 1.0)
--------------------------------------------------
with Plugins from the gimp release 0.99.16
Each Plugin listed below was called with varying values.
Some Plugins did not work correct when called in
RUN_WITH_LAST_VALS mode.
TEST: + tested OK
* generated code did not work (changed manually)
? not sure if useful
Del Not ueseful, deleted
*? Colorify_iter_ALT (crash at 1.call)
? plug_in_CML_explorer_iter_ALT
*? plug_in_CentralReflection_iter_ALT (crash at 1.call)
+* plug_in_Twist_iter_ALT
+* plug_in_alienmap_iter_ALT
Del plug_in_align_layers_iter_ALT
+? plug_in_anamorphose_iter_ALT
+ plug_in_applylens_iter_ALT
+ plug_in_blinds_iter_ALT
+* plug_in_blur2_iter_ALT
+ plug_in_bump_map_iter_ALT
+ plug_in_checkerboard_iter_ALT
Del plug_in_coordmap_iter_ALT
+ plug_in_cubism_iter_ALT
Del plug_in_curtain_iter_ALT
Del plug_in_decompose_iter_ALT
Del plug_in_deinterlace_iter_ALT
+*? plug_in_depth_merge_iter_ALT
+*? plug_in_despeckle_iter_ALT (crash at 1.call)
+ plug_in_destripe_iter_ALT
+ plug_in_diffraction_iter_ALT
+ plug_in_displace_iter_ALT
+ plug_in_edge_iter_ALT
+* plug_in_emboss_iter_ALT
* plug_in_encript_iter_ALT (crash at noniteractive calls)
+ plug_in_engrave_iter_ALT
*? plug_in_exchange_iter_ALT
+* plug_in_figures_iter_ALT
+* plug_in_fractal_trace_iter_ALT
+ plug_in_gauss_iir_iter_ALT
+ plug_in_gauss_rle_iter_ALT
* plug_in_gflare_iter_ALT
+ plug_in_glasstile_iter_ALT
+ plug_in_grid_iter_ALT
* plug_in_holes_iter_ALT (crash at 1.call)
+ plug_in_illusion_iter_ALT
+* plug_in_julia_iter_ALT
* plug_in_magic_eye_iter_ALT (crash at 1.call)
Del plug_in_mail_image_iter_ALT
+* plug_in_mandelbrot_iter_ALT
+* plug_in_map_object_iter_ALT
Del plug_in_max_rgb_iter_ALT
+ plug_in_maze_iter_ALT
+ plug_in_mblur_iter_ALT
+ plug_in_mosaic_iter_ALT
+* plug_in_nlfilt_iter_ALT
+ plug_in_noisify_iter_ALT
+* plug_in_nova_iter_ALT
+* plug_in_oilify_iter_ALT
+ plug_in_paper_tile_iter_ALT
+ plug_in_pixelize_iter_ALT
+ plug_in_plasma_iter_ALT
+ plug_in_polar_coords_iter_ALT
+* plug_in_randomize_iter_ALT
+ plug_in_refract_iter_ALT
+ plug_in_ripple_iter_ALT
? plug_in_rotate_iter_ALT
+ plug_in_scatter_hsv_iter_ALT
? plug_in_sharpen_iter_ALT
+ plug_in_shift_iter_ALT
+* plug_in_sinus_iter_ALT
Del plug_in_sobel_iter_ALT
+ plug_in_solid_noise_iter_ALT
+* plug_in_sparkle_iter_ALT
+ plug_in_spread_iter_ALT
+ plug_in_struc_iter_ALT
? plug_in_tileit_iter_ALT
? plug_in_universal_filter_iter_ALT
+ plug_in_video_iter_ALT
+ plug_in_vpropagate_iter_ALT
+* plug_in_warp_iter_ALT
+ plug_in_waves_iter_ALT
+* plug_in_whirl_pinch_iter_ALT
--------------------------------------------------

46
plug-ins/gap/appenv.h Normal file
View File

@ -0,0 +1,46 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __APPENV_H__
#define __APPENV_H__
#include "gdk/gdkx.h"
#include "gtk/gtk.h"
#define DISPLAY ((Display *) GDK_DISPLAY())
/* important macros */
#define BOUNDS(a,x,y) ((a < x) ? x : ((a > y) ? y : a))
#define MINIMUM(x,y) ((x < y) ? x : y)
#define MAXIMUM(x,y) ((x > y) ? x : y)
typedef enum {
MESSAGE_BOX,
CONSOLE
} MessageHandlerType;
extern int no_interface;
extern int no_splash;
extern int no_splash_image;
extern int no_data;
extern int be_verbose;
extern int use_debug_handler;
extern int console_messages;
extern MessageHandlerType message_handler;
#endif /* APPENV_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,168 @@
/* gap_arr_dialog.h
* 1998.May.23 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins (Standard array dialog)
*
* - p_array_dialog Dialog Window with one or more rows
* each row can contain one of the following GAP widgets:
* - float pair widget
* (horizontal slidebar combined with a float input field)
* - int pair widget
* (horizontal slidebar combined with a int input field)
* - Toggle Button widget
* - Textentry widget
* - Float entry widget
* - Int entry widget
* - p_slider_dialog
* simplified call of p_pair_array_dialog,
* using an array with one WGT_INT_PAIR.
* - p_buttons_dialog
*
*
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.96.03; 1998/08/15 hof: p_arr_gtk_init
* version 0.96.00; 1998/07/09 hof: 1.st release
* (re-implementation of gap_sld_dialog.c)
*/
#ifndef _ARR_DIALOG_H
#define _ARR_DIALOG_H
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
typedef enum
{
WGT_LABEL
,WGT_TEXT
,WGT_INT
,WGT_FLT
,WGT_TOGGLE
,WGT_RADIO
,WGT_OPTIONMENU
,WGT_FLT_PAIR
,WGT_INT_PAIR
,WGT_ACT_BUTTON
,WGT_FILESEL
} t_gap_widget;
typedef int (*t_action_func) ( gpointer action_data);
/*
* - If one of the Args has set 'has_default' to TRUE
* the action Area will contain an additional Button 'Default'
*
*/
typedef struct {
t_gap_widget widget_type;
/* common fields for all widget types */
char *label_txt;
char *help_txt;
gint entry_width; /* for all Widgets with an entry */
gint scale_width; /* for the Widgets with a scale */
gint constraint; /* TRUE: check for min/max values */
gint has_default; /* TRUE: default value available */
/* flt_ fileds are used for WGT_FLT and WGT_FLT_PAIR */
char *flt_format; /* NULL or something like "%0.2f" */
gdouble flt_min;
gdouble flt_max;
gdouble flt_step;
gdouble flt_default;
gdouble flt_ret;
gdouble flt_ret_lim;
/* int_ fileds are used for WGT_INT and WGT_INT_PAIR WGT_TOGGLE */
char *int_format; /* NULL or something like "%d" */
gint int_min;
gint int_max;
gint int_step;
gint int_default;
gint int_ret;
gint int_ret_lim; /* for private (arr_dialog.c) use only */
/* togg_ field are used for WGT_TOGGLE */
char *togg_label; /* extra label attached right to toggle button */
/* radio_ fileds are used for WGT_RADIO and WGT_OPTIONMENU */
gint radio_argc;
gint radio_default;
gint radio_ret;
char **radio_argv;
char **radio_help_argv;
/* text_ fileds are used for WGT_TEXT */
gint text_buf_len; /* common length for init, default and ret text_buffers */
char *text_buf_default;
char *text_buf_ret;
GtkWidget *text_filesel; /* for private (arr_dialog.c) use only */
GtkWidget *text_entry; /* for private (arr_dialog.c) use only */
/* action_ fileds are used for WGT_ACT_BUTTON */
t_action_func action_functon;
gpointer action_data;
} t_arr_arg;
typedef struct {
char *but_txt;
gint but_val;
} t_but_arg;
void p_init_arr_arg (t_arr_arg *arr_ptr,
gint widget_type);
gint p_array_dialog (char *title_txt,
char *frame_txt,
int argc,
t_arr_arg argv[]);
long p_slider_dialog(char *title_txt,
char *frame_txt,
char *label_txt,
char *tooltip_txt,
long min, long max, long curr, long constraint);
gint p_buttons_dialog (char *title_txt,
char *frame_txt,
int b_argc,
t_but_arg b_argv[],
gint b_def_val);
gint p_array_std_dialog (char *title_txt,
char *frame_txt,
int argc,
t_arr_arg argv[],
int b_argc,
t_but_arg b_argv[],
gint b_def_val);
gint p_arr_gtk_init(gint flag);
#endif

View File

@ -0,0 +1,791 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
gap_dbbrowser_utils.c (original code dbbrowser_utils.c by Thomas NOEL <thomas@minet.net>
27. jan .1999 hof: update for GIMP 1.1.1 (show help)
09. dec .1998 hof: update for GIMP 1.1
12. jan .1998 hof: added "Gen Code" button
23. dec .1997 hof: GAP variant of DBbrowser
removed apply_callback
added constraint_procedure,
added 2 buttons
added return type
0.08 26th sept 97 by Thomas NOEL <thomas@minet.net> )
*/
#include "gap_dbbrowser_utils.h"
extern int gap_debug;
int
gap_db_browser_dialog(char *title_txt,
char *button_1_txt,
char *button_2_txt,
t_constraint_func constraint_func,
t_constraint_func constraint_func_sel1,
t_constraint_func constraint_func_sel2,
t_gap_db_browse_result *result,
gint init_gtk_flag)
/* create the dialog box */
{
gchar **l_argsv;
gint l_argsc;
dbbrowser_t* dbbrowser;
GtkWidget *button;
GtkWidget *hbox,*searchhbox,*vbox;
GtkWidget *label;
l_argsc = 1;
l_argsv = g_new (gchar *, 1);
l_argsv[0] = g_strdup ("GAP Animated Filter apply");
if (init_gtk_flag)
{
/* gtk init (should be called only once in a plugin-process) */
gtk_init (&l_argsc, &l_argsv);
}
dbbrowser = (gpointer)malloc(sizeof(dbbrowser_t));
/* store pointers to gap constraint procedures */
dbbrowser->constraint_func = constraint_func;
dbbrowser->constraint_func_sel1 = constraint_func_sel1;
dbbrowser->constraint_func_sel2 = constraint_func_sel2;
dbbrowser->result = result;
dbbrowser->codegen_flag = 0; /* default: no code generation */
/* the dialog box */
dbbrowser->dlg = gtk_dialog_new ();
gtk_window_set_title (GTK_WINDOW (dbbrowser->dlg), "Animated Filter apply (init)");
gtk_window_position (GTK_WINDOW (dbbrowser->dlg), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (dbbrowser->dlg), "destroy",
(GtkSignalFunc) dialog_close_callback,
dbbrowser);
/* label (fill 1. table_row) */
label = gtk_label_new(title_txt);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
gtk_widget_show(label);
/* hbox : left=list ; right=description */
hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dlg)->vbox),
hbox, TRUE, TRUE, 0);
gtk_widget_show (hbox);
/* left = vbox : the list and the search entry */
vbox = gtk_vbox_new( FALSE, 0 );
gtk_container_border_width (GTK_CONTAINER (vbox), 3);
gtk_box_pack_start (GTK_BOX (hbox),
vbox, FALSE, TRUE, 0);
gtk_widget_show(vbox);
/* list : list in a scrolled_win */
dbbrowser->clist = gtk_clist_new(1);
dbbrowser->scrolled_win = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (dbbrowser->scrolled_win),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_clist_set_selection_mode (GTK_CLIST (dbbrowser->clist),
GTK_SELECTION_BROWSE);
gtk_widget_set_usize(dbbrowser->clist, DBL_LIST_WIDTH, DBL_HEIGHT);
gtk_signal_connect (GTK_OBJECT (dbbrowser->clist), "select_row",
(GtkSignalFunc) procedure_select_callback,
dbbrowser);
gtk_box_pack_start (GTK_BOX (vbox), dbbrowser->scrolled_win, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (dbbrowser->scrolled_win), dbbrowser->clist);
gtk_widget_show(dbbrowser->clist);
gtk_widget_show(dbbrowser->scrolled_win);
/* search entry */
searchhbox = gtk_hbox_new(FALSE,0);
gtk_box_pack_start (GTK_BOX (vbox),
searchhbox, FALSE, TRUE, 0);
gtk_widget_show(searchhbox);
label = gtk_label_new("Search :");
gtk_misc_set_alignment( GTK_MISC(label), 0.0, 0.5);
gtk_box_pack_start (GTK_BOX (searchhbox),
label, TRUE, TRUE, 0);
gtk_widget_show(label);
dbbrowser->search_entry = gtk_entry_new();
gtk_box_pack_start (GTK_BOX (searchhbox),
dbbrowser->search_entry, TRUE, TRUE, 0);
gtk_widget_show(dbbrowser->search_entry);
/* right = description */
dbbrowser->descr_scroll = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (dbbrowser->descr_scroll),
GTK_POLICY_ALWAYS,
GTK_POLICY_ALWAYS
);
gtk_box_pack_start (GTK_BOX (hbox),
dbbrowser->descr_scroll, TRUE, TRUE, 0);
gtk_widget_set_usize (dbbrowser->descr_scroll, DBL_WIDTH - DBL_LIST_WIDTH, 0);
gtk_widget_show (dbbrowser->descr_scroll);
/* buttons in dlg->action_aera */
gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG(dbbrowser->dlg)->action_area), 0);
if (gap_debug) {
button = gtk_button_new_with_label ("Gen Code by name");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) dialog_button_3_callback, dbbrowser );
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dlg)->action_area),
button, TRUE, TRUE, 0);
gtk_widget_show (button);
}
dbbrowser->name_button = gtk_button_new_with_label ("Search by name");
GTK_WIDGET_SET_FLAGS (dbbrowser->name_button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (dbbrowser->name_button), "clicked",
(GtkSignalFunc) dialog_search_callback, dbbrowser);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dlg)->action_area),
dbbrowser->name_button , TRUE, TRUE, 0);
gtk_widget_show(dbbrowser->name_button);
dbbrowser->blurb_button = gtk_button_new_with_label ("Search by blurb");
GTK_WIDGET_SET_FLAGS (dbbrowser->blurb_button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (dbbrowser->blurb_button), "clicked",
(GtkSignalFunc) dialog_search_callback, dbbrowser);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dlg)->action_area),
dbbrowser->blurb_button , TRUE, TRUE, 0);
gtk_widget_show(dbbrowser->blurb_button);
if (button_1_txt) {
dbbrowser->app_const_button = gtk_button_new_with_label (button_1_txt);
GTK_WIDGET_SET_FLAGS (dbbrowser->app_const_button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (dbbrowser->app_const_button), "clicked",
(GtkSignalFunc) dialog_button_1_callback, dbbrowser );
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dlg)->action_area),
dbbrowser->app_const_button, TRUE, TRUE, 0);
gtk_widget_show (dbbrowser->app_const_button);
} else dbbrowser->app_const_button = NULL;
if (button_2_txt) {
dbbrowser->app_vary_button = gtk_button_new_with_label (button_2_txt);
GTK_WIDGET_SET_FLAGS (dbbrowser->app_vary_button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (dbbrowser->app_vary_button), "clicked",
(GtkSignalFunc) dialog_button_2_callback, dbbrowser );
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dlg)->action_area),
dbbrowser->app_vary_button, TRUE, TRUE, 0);
gtk_widget_show (dbbrowser->app_vary_button);
} else dbbrowser->app_vary_button = NULL;
button = gtk_button_new_with_label ("Cancel");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) dialog_close_callback, dbbrowser);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dbbrowser->dlg)->action_area),
button, TRUE, TRUE, 0);
gtk_widget_show (button);
/* now build the list */
gtk_widget_show (dbbrowser->clist);
gtk_widget_show (dbbrowser->dlg);
/* initialize the "return" value (for "apply") */
dbbrowser->descr_table = NULL;
dbbrowser->selected_proc_name = NULL;
dbbrowser->selected_scheme_proc_name = NULL;
dbbrowser->selected_proc_blurb = NULL;
dbbrowser->selected_proc_help = NULL;
dbbrowser->selected_proc_author = NULL;
dbbrowser->selected_proc_copyright = NULL;
dbbrowser->selected_proc_date = NULL;
dbbrowser->selected_proc_type = 0;
dbbrowser->selected_nparams = 0;
dbbrowser->selected_nreturn_vals = 0;
dbbrowser->selected_params = NULL;
dbbrowser->selected_return_vals = NULL;
dbbrowser->result->selected_proc_name[0] = '\0';
dbbrowser->result->button_nr = -1;
/* first search (all procedures) */
dialog_search_callback( NULL, (gpointer)dbbrowser );
gtk_main ();
gdk_flush ();
return (dbbrowser->result->button_nr);
}
static gint
procedure_select_callback (GtkWidget *widget,
gint row,
gint column,
GdkEventButton * bevent,
gpointer data)
{
dbbrowser_t *dbbrowser = data;
gchar *func;
g_return_val_if_fail (widget != NULL, FALSE);
/* g_return_val_if_fail (bevent != NULL, FALSE); */
g_return_val_if_fail (dbbrowser != NULL, FALSE);
if ((func = (gchar *) (gtk_clist_get_row_data (GTK_CLIST (widget), row))))
dialog_select (dbbrowser, func);
return FALSE;
}
static void
dialog_select (dbbrowser_t *dbbrowser,
gchar *proc_name)
/* update the description box (right) */
{
GtkWidget *label;
GtkWidget *old_table;
GtkWidget *help;
GtkWidget *text = NULL;
GtkWidget *vscrollbar;
gint i,row=0;
if (dbbrowser->selected_proc_name)
g_free(dbbrowser->selected_proc_name);
dbbrowser->selected_proc_name = g_strdup(proc_name);
if (dbbrowser->selected_scheme_proc_name)
g_free(dbbrowser->selected_scheme_proc_name);
dbbrowser->selected_scheme_proc_name =
g_strdup(proc_name);
convert_string(dbbrowser->selected_scheme_proc_name);
if (dbbrowser->selected_proc_blurb) g_free(dbbrowser->selected_proc_blurb);
if (dbbrowser->selected_proc_help) g_free(dbbrowser->selected_proc_help);
if (dbbrowser->selected_proc_author) g_free(dbbrowser->selected_proc_author);
if (dbbrowser->selected_proc_copyright) g_free(dbbrowser->selected_proc_copyright);
if (dbbrowser->selected_proc_date) g_free(dbbrowser->selected_proc_date);
if (dbbrowser->selected_params) g_free(dbbrowser->selected_params);
if (dbbrowser->selected_return_vals) g_free(dbbrowser->selected_return_vals);
gimp_query_procedure (proc_name,
&(dbbrowser->selected_proc_blurb),
&(dbbrowser->selected_proc_help),
&(dbbrowser->selected_proc_author),
&(dbbrowser->selected_proc_copyright),
&(dbbrowser->selected_proc_date),
&(dbbrowser->selected_proc_type),
&(dbbrowser->selected_nparams),
&(dbbrowser->selected_nreturn_vals),
&(dbbrowser->selected_params),
&(dbbrowser->selected_return_vals));
/* save the "old" table */
old_table = dbbrowser->descr_table;
dbbrowser->descr_table = gtk_table_new(
10 + dbbrowser->selected_nparams + dbbrowser->selected_nreturn_vals ,
5 , FALSE );
gtk_table_set_col_spacings( GTK_TABLE(dbbrowser->descr_table), 3);
/* show the name */
label = gtk_label_new("Name :");
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 1, row, row+1, GTK_FILL, GTK_FILL, 3, 6);
gtk_widget_show(label);
label = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(label),dbbrowser->selected_scheme_proc_name);
gtk_entry_set_editable(GTK_ENTRY(label), FALSE);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
1, 4, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
row++;
/* show the description */
label = gtk_label_new("Blurb :");
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 1, row, row+1, GTK_FILL, GTK_FILL, 3, 0);
gtk_widget_show(label);
label = gtk_label_new(dbbrowser->selected_proc_blurb);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
1, 4, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
row++;
label = gtk_hseparator_new(); /* ok, not really a label ... :) */
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 4, row, row+1, GTK_FILL, GTK_FILL, 3, 6);
gtk_widget_show(label);
row++;
/* in parameters */
if (dbbrowser->selected_nparams)
{
label = gtk_label_new("In :");
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 1, row, row+(dbbrowser->selected_nparams),
GTK_FILL, GTK_FILL, 3, 0);
gtk_widget_show(label);
for (i=0;i<(dbbrowser->selected_nparams);i++)
{
/* name */
label = gtk_label_new((dbbrowser->selected_params[i]).name);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
1, 2, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* type */
label = gtk_label_new(GParamType2char((dbbrowser->selected_params[i]).type));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
2, 3, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* description */
label = gtk_label_new((dbbrowser->selected_params[i]).description);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
3, 4, row, row+1, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
row++;
}
}
if ((dbbrowser->selected_nparams) &&
(dbbrowser->selected_nreturn_vals)) {
label = gtk_hseparator_new(); /* ok, not really a label ... :) */
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 4, row, row+1,
GTK_FILL, GTK_FILL, 3, 6);
gtk_widget_show( label );
row++;
}
/* out parameters */
if (dbbrowser->selected_nreturn_vals)
{
label = gtk_label_new("Out :");
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 1, row, row+(dbbrowser->selected_nreturn_vals),
GTK_FILL, GTK_FILL, 3, 0);
gtk_widget_show(label);
for (i=0;i<(dbbrowser->selected_nreturn_vals);i++)
{
/* name */
label = gtk_label_new((dbbrowser->selected_return_vals[i]).name);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
1, 2, row, row+1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* type */
label = gtk_label_new(GParamType2char((dbbrowser->selected_return_vals[i]).type));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
2, 3, row, row+1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* description */
label = gtk_label_new((dbbrowser->selected_return_vals[i]).description);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
3, 4, row, row+1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
row++;
}
}
if ((dbbrowser->selected_nparams) ||
(dbbrowser->selected_nreturn_vals)) {
label = gtk_hseparator_new(); /* ok, not really a label ... :) */
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 4, row, row+1,
GTK_FILL, GTK_FILL, 3, 6);
gtk_widget_show( label );
row++;
}
/* show the help */
if ((dbbrowser->selected_proc_help) && (strlen(dbbrowser->selected_proc_help) > 1))
{
label = gtk_label_new("Help :");
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 1, row, row+1,
GTK_FILL, GTK_FILL, 3, 0);
gtk_widget_show(label);
help = gtk_table_new (2, 2, FALSE);
gtk_table_set_row_spacing (GTK_TABLE (help), 0, 2);
gtk_table_set_col_spacing (GTK_TABLE (help), 0, 2);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), help,
1, 4, row, row+1, GTK_FILL, GTK_FILL, 3, 0);
gtk_widget_show (help);
row++;
text = gtk_text_new (NULL, NULL);
gtk_text_set_editable (GTK_TEXT (text), FALSE);
gtk_text_set_word_wrap(GTK_TEXT(text), TRUE);
gtk_widget_set_usize (text, -1, 60);
gtk_table_attach (GTK_TABLE (help), text, 0, 1, 0, 1,
GTK_EXPAND | GTK_SHRINK | GTK_FILL,
GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (text);
vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
gtk_table_attach (GTK_TABLE (help), vscrollbar, 1, 2, 0, 1,
GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_show (vscrollbar);
label = gtk_hseparator_new(); /* ok, not really a label ... :) */
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 4, row, row+1, GTK_FILL, GTK_FILL, 3, 6);
gtk_widget_show(label);
row++;
}
/* show the author & the copyright */
label = gtk_label_new("Author :");
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 1, row, row+1,
GTK_FILL, GTK_FILL, 3, 0);
gtk_widget_show(label);
label = gtk_label_new(dbbrowser->selected_proc_author);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
1, 4, row, row+1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
row++;
label = gtk_label_new("Date :");
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 1, row, row+1,
GTK_FILL, GTK_FILL, 3, 0);
gtk_widget_show(label);
label = gtk_label_new(dbbrowser->selected_proc_date);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
1, 4, row, row+1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
row++;
label = gtk_label_new("Copyright :");
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
0, 1, row, row+1,
GTK_FILL, GTK_FILL, 3, 0);
gtk_widget_show(label);
label = gtk_label_new(dbbrowser->selected_proc_copyright);
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (dbbrowser->descr_table), label,
1, 4, row, row+1,
GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(label);
row++;
if (old_table) gtk_widget_destroy(old_table);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (dbbrowser->descr_scroll),
dbbrowser->descr_table);
/* now after the table is added to a window add the text */
if (text != NULL)
{
gtk_widget_realize (text);
gtk_text_freeze (GTK_TEXT (text));
gtk_text_insert (GTK_TEXT (text), NULL, NULL, NULL,
dbbrowser->selected_proc_help, -1);
gtk_text_thaw (GTK_TEXT (text));
}
gtk_widget_show(dbbrowser->descr_table);
/* call constraint functions to check sensibility for the apply buttons */
if(dbbrowser->app_const_button != NULL)
{
if(0 != (dbbrowser->constraint_func_sel1)(dbbrowser->selected_proc_name))
{
gtk_widget_set_sensitive (dbbrowser->app_const_button, TRUE);
}
else
{
gtk_widget_set_sensitive (dbbrowser->app_const_button, FALSE);
}
}
if(dbbrowser->app_vary_button != NULL)
{
if(0 != (dbbrowser->constraint_func_sel2)(dbbrowser->selected_proc_name))
{
gtk_widget_set_sensitive (dbbrowser->app_vary_button, TRUE);
}
else
{
gtk_widget_set_sensitive (dbbrowser->app_vary_button, FALSE);
}
}
}
static void
dialog_close_callback (GtkWidget *widget,
gpointer data)
/* end of the dialog */
{
dbbrowser_t* dbbrowser = data;
/* we are in the plug_in : kill the gtk application */
gtk_widget_destroy(dbbrowser->dlg);
gtk_main_quit ();
}
static void
dialog_button_1_callback (GtkWidget *widget,
gpointer data)
/* end of the dialog */
{
dbbrowser_t* dbbrowser = data;
if (dbbrowser->selected_proc_name==NULL) return;
strcpy(dbbrowser->result->selected_proc_name, dbbrowser->selected_proc_name);
dbbrowser->result->button_nr = 0;
gtk_widget_hide(dbbrowser->dlg);
gtk_widget_destroy(dbbrowser->dlg);
gtk_main_quit ();
}
static void
dialog_button_2_callback (GtkWidget *widget,
gpointer data)
/* end of the dialog */
{
dbbrowser_t* dbbrowser = data;
if (dbbrowser->selected_proc_name==NULL) return;
strcpy(dbbrowser->result->selected_proc_name, dbbrowser->selected_proc_name);
dbbrowser->result->button_nr = 1;
gtk_widget_hide(dbbrowser->dlg);
gtk_widget_destroy(dbbrowser->dlg);
gtk_main_quit ();
}
static void
dialog_button_3_callback (GtkWidget *widget,
gpointer data)
/* end of the dialog */
{
dbbrowser_t* dbbrowser = data;
p_remove_codegen_files(); /* remove old versions of generated CODE */
dbbrowser->codegen_flag = 1; /* let dialog_search_callback generate */
dialog_search_callback(dbbrowser->name_button, (gpointer)dbbrowser );
dbbrowser->codegen_flag = 0;
}
static void
dialog_search_callback (GtkWidget *widget,
gpointer data)
/* search in the whole db */
{
char **proc_list;
int num_procs;
int i, j;
int i_added;
dbbrowser_t* dbbrowser = data;
gchar *func_name, *label, *query_text;
GString *query;
gtk_clist_freeze(GTK_CLIST(dbbrowser->clist));
gtk_clist_clear(GTK_CLIST(dbbrowser->clist));
/* search */
if ( widget == (dbbrowser->name_button) )
{
gtk_window_set_title (GTK_WINDOW (dbbrowser->dlg),
"Animated Filter apply (by name - please wait)");
query = g_string_new ("");
query_text = gtk_entry_get_text(GTK_ENTRY(dbbrowser->search_entry));
while (*query_text)
{
if ((*query_text == '_') || (*query_text == '-'))
g_string_append (query, "[-_]");
else
g_string_append_c (query, *query_text);
query_text++;
}
gimp_query_database (query->str,
".*", ".*", ".*", ".*", ".*", ".*",
&num_procs, &proc_list);
g_string_free (query, TRUE);
}
else if ( widget == (dbbrowser->blurb_button) )
{
gtk_window_set_title (GTK_WINDOW (dbbrowser->dlg),
"Animated Filter apply (by blurb - please wait)");
gimp_query_database (".*",
gtk_entry_get_text( GTK_ENTRY(dbbrowser->search_entry) ),
".*", ".*", ".*", ".*", ".*",
&num_procs, &proc_list);
}
else {
gtk_window_set_title (GTK_WINDOW (dbbrowser->dlg),
"Animated Filter apply (please wait)");
gimp_query_database (".*", ".*", ".*", ".*", ".*", ".*", ".*",
&num_procs, &proc_list);
}
i_added = 0;
for (i = 0; i < num_procs; i++)
{
/* the filter constraint_function checks if the
* PDB-proc has a typical interface to operate on a single drawable.
* all other PDB-procedures are not listed in the GAP-dbbrowser
*/
if(0 != (dbbrowser->constraint_func)((char *)proc_list[i]))
{
j = 0;
while((j < i_added) &&
(strcmp(gtk_clist_get_row_data(GTK_CLIST(dbbrowser->clist), j),
proc_list[i]) < 0))
{
j++;
}
i_added++;
label = g_strdup(proc_list[i]);
if((dbbrowser->codegen_flag != 0) && (gap_debug))
{
p_gen_forward_iter_ALT(label);
p_gen_tab_iter_ALT(label);
p_gen_code_iter_ALT(label);
}
convert_string(label);
gtk_clist_insert (GTK_CLIST (GTK_CLIST(dbbrowser->clist)), j,
&label);
func_name = g_strdup (proc_list[i]);
gtk_clist_set_row_data_full(GTK_CLIST(dbbrowser->clist), j,
func_name, g_free);
}
}
if ( dbbrowser->clist ) {
;
}
g_free( proc_list );
gtk_window_set_title (GTK_WINDOW (dbbrowser->dlg),
"Animated Filter apply");
gtk_clist_thaw(GTK_CLIST(dbbrowser->clist));
}
/* utils ... */
static void
convert_string (char *str)
{
while (*str)
{
if (*str == '_') *str = '-';
str++;
}
}
static char*
GParamType2char(GParamType t)
{
switch (t) {
case PARAM_INT32: return "INT32";
case PARAM_INT16: return "INT16";
case PARAM_INT8: return "INT8";
case PARAM_FLOAT: return "FLOAT";
case PARAM_STRING: return "STRING";
case PARAM_INT32ARRAY: return "INT32ARRAY";
case PARAM_INT16ARRAY: return "INT16ARRAY";
case PARAM_INT8ARRAY: return "INT8ARRAY";
case PARAM_FLOATARRAY: return "FLOATARRAY";
case PARAM_STRINGARRAY: return "STRINGARRAY";
case PARAM_COLOR: return "COLOR";
case PARAM_REGION: return "REGION";
case PARAM_DISPLAY: return "DISPLAY";
case PARAM_IMAGE: return "IMAGE";
case PARAM_LAYER: return "LAYER";
case PARAM_CHANNEL: return "CHANNEL";
case PARAM_DRAWABLE: return "DRAWABLE";
case PARAM_SELECTION: return "SELECTION";
case PARAM_BOUNDARY: return "BOUNDARY";
case PARAM_PATH: return "PATH";
case PARAM_PARASITE: return "PARASITE";
case PARAM_STATUS: return "STATUS";
case PARAM_END: return "END";
default: return "UNKNOWN?";
}
}

View File

@ -0,0 +1,128 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
gap_dbbrowser_utils.h (original code dbbrowser_utils.h by Thomas NOEL <thomas@minet.net>
09. dec .1998 hof: update for GIMP 1.1
20. dec .1997 hof: GAP variant of DBbrowser
removed apply_callback
added constraint_procedure,
added 2 buttons
added return type
0.08 26th sept 97 by Thomas NOEL <thomas@minet.net>
*/
#ifndef _GAP_DB_BROWSER_UTILS_H
#define _GAP_DB_BROWSER_UTILS_H
/* configuration */
#define DBL_LIST_WIDTH 220
#define DBL_WIDTH DBL_LIST_WIDTH+400
#define DBL_HEIGHT 250
/* end of configuration */
#include <stdlib.h>
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
# include "gap_filter.h"
typedef struct {
gchar *label;
gchar *func;
} ListEntry_t;
typedef struct {
GtkWidget* dlg;
GtkWidget* search_entry;
GtkWidget* name_button;
GtkWidget* blurb_button;
GtkWidget* app_const_button;
GtkWidget* app_vary_button;
GtkWidget* descr_scroll;
GtkWidget* descr_table;
GtkWidget* clist;
GtkWidget* scrolled_win;
/* the currently selected procedure */
gchar *selected_proc_name;
gchar *selected_scheme_proc_name;
gchar *selected_proc_blurb;
gchar *selected_proc_help;
gchar *selected_proc_author;
gchar *selected_proc_copyright;
gchar *selected_proc_date;
int selected_proc_type;
int selected_nparams;
int selected_nreturn_vals;
GParamDef *selected_params;
GParamDef *selected_return_vals;
t_constraint_func constraint_func;
t_constraint_func constraint_func_sel1;
t_constraint_func constraint_func_sel2;
t_gap_db_browse_result *result;
gint codegen_flag;
} dbbrowser_t;
/* local functions */
static void
dialog_button_1_callback(GtkWidget *, gpointer );
static void
dialog_button_2_callback(GtkWidget *, gpointer );
static void
dialog_button_3_callback(GtkWidget *, gpointer );
static gint
procedure_select_callback (GtkWidget *widget,
gint row,
gint column,
GdkEventButton * bevent,
gpointer data);
static void
dialog_search_callback(GtkWidget *,
gpointer);
static void
dialog_select(dbbrowser_t *dbbrowser,
gchar *proc_name);
static void
dialog_close_callback(GtkWidget *,
gpointer);
static void
convert_string (gchar *str);
static gchar*
GParamType2char(GParamType t);
#endif

View File

@ -0,0 +1,687 @@
/* gap_exchange_image.c
* by hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* basic anim functions:
* This Plugin drops the content of the destination
* image (all layers,channels & guides)
* and then copies the content of a source image to dst. image
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* 0.98.00; 1998/11/30 hof: 1.st release
* (substitute for the procedure "gimp_duplicate_into"
* that was never part of the GIMP core)
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <errno.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_layer_copy.h"
#include "gap_pdb_calls.h"
#include "gap_exchange_image.h"
extern int gap_debug; /* ==0 ... dont print debug infos */
/* ============================================================================
* p_steal_content
*
* steal all elements (layers, channels, selections, guides, colormap)
* from src_image and add them to dst_image.
* ============================================================================
*/
static int
p_steal_content(gint32 dst_image_id, gint32 src_image_id)
{
int l_rc;
int l_idx;
gint l_nlayers;
gint l_nchannels;
gint32 *l_layers_list;
gint32 *l_channels_list;
gint32 l_layer_id;
gint32 l_channel_id;
gint32 l_new_channel_id;
gint32 l_layer_mask_id;
gint32 l_guide_id;
gint32 l_src_fsel_id; /* floating selection (in the src_image) */
gint32 l_src_fsel_attached_to_id; /* the drawable where floating selection is attached to (in the src_image) */
gint32 l_fsel_attached_to_id; /* the drawable id where to attach the floating selection (dst) */
gint32 l_fsel_id; /* the drawable id of the floating selection itself (dst) */
gint32 l_active_layer_id;
gint32 l_active_channel_id;
gint32 l_x1, l_x2, l_y1, l_y2;
guchar *l_cmap;
gint l_ncolors;
l_rc = -1; /* init retcode to Errorstate */
l_layers_list = NULL;
l_channels_list = NULL;
l_active_layer_id = -1;
l_active_channel_id = -1;
l_fsel_attached_to_id = -1; /* -1 assume fsel is not available (and not attached to any drawable) */
l_fsel_id = -1; /* -1 assume there is no floating selection */
if(gap_debug) printf("GAP-DEBUG: START p_steal_content dst_id=%d src_id=%d\n", (int)dst_image_id, (int)src_image_id);
/* check for floating selection */
l_src_fsel_attached_to_id = -1;
l_src_fsel_id = gimp_image_floating_selection(src_image_id);
if(l_src_fsel_id >= 0)
{
if(gap_debug) printf("GAP-DEBUG: call floating_sel_relax fsel_id=%d\n",
(int)l_src_fsel_id);
p_gimp_floating_sel_relax (l_src_fsel_id, FALSE);
l_src_fsel_attached_to_id = p_gimp_image_floating_sel_attached_to(src_image_id);
}
/* steal all layers */
l_layers_list = gimp_image_get_layers(src_image_id, &l_nlayers);
/* foreach layer do */
for(l_idx = l_nlayers -1; l_idx >= 0; l_idx--)
{
l_layer_id = l_layers_list[l_idx];
if(gap_debug) printf("GAP-DEBUG: START p_steal_content layer_id=%d\n", (int)l_layer_id);
if(l_layer_id == gimp_image_get_active_layer(src_image_id))
{
l_active_layer_id = l_layer_id;
}
l_layer_mask_id = gimp_layer_get_mask_id(l_layer_id);
if(l_layer_mask_id >= 0)
{
/* layer has layermask */
if(gap_debug) printf("GAP-DEBUG: START p_steal_content layer_mask_id=%d\n", (int)l_layer_mask_id);
/* check for floating selection */
if(l_layer_mask_id == l_src_fsel_attached_to_id)
{
l_fsel_attached_to_id = l_layer_mask_id; /* the floating selection is attached to this layer_mask */
}
p_gimp_drawable_set_image(l_layer_mask_id, dst_image_id);
}
/* remove layer from source */
gimp_image_remove_layer(src_image_id, l_layer_id);
/* and set the dst_image as it's new Master */
p_gimp_drawable_set_image(l_layer_id, dst_image_id);
if(l_layer_id == l_src_fsel_id)
{
l_fsel_id = l_layer_id; /* this layer is the floating selection */
}
else
{
if(gap_debug) printf("GAP-DEBUG: START p_steal_content add_layer_id=%d\n", (int)l_layer_id);
/* add the layer on top of the images layerstak */
gimp_image_add_layer (dst_image_id, l_layer_id, 0);
if(l_layer_id == l_src_fsel_attached_to_id)
{
l_fsel_attached_to_id = l_layer_id; /* the floating selection is attached to this layer */
}
}
} /* end foreach layer */
/* steal all channels */
l_channels_list = gimp_image_get_channels(src_image_id, &l_nchannels);
/* foreach channel do */
for(l_idx = l_nchannels -1; l_idx >= 0; l_idx--)
{
l_channel_id = l_channels_list[l_idx];
if(gap_debug) printf("GAP-DEBUG: START p_steal_content channel_id=%d\n", (int)l_channel_id);
l_new_channel_id = p_my_channel_copy(dst_image_id, l_channel_id);
if (l_new_channel_id < 0) { goto cleanup; }
/* add channel on top of the channelstack */
gimp_image_add_channel (dst_image_id, l_new_channel_id, 0);
/* adjust channelproperties */
gimp_channel_set_visible (l_new_channel_id, gimp_channel_get_visible(l_channel_id));
gimp_channel_set_show_masked (l_new_channel_id, gimp_channel_get_show_masked(l_channel_id));
if(l_channel_id == l_src_fsel_attached_to_id)
{
l_fsel_attached_to_id = l_channel_id; /* the floating_selection is attached to this channel */
}
if(l_channel_id == gimp_image_get_active_channel(src_image_id))
{
l_active_channel_id = l_channel_id;
}
/* remove channel from source */
gimp_image_remove_channel(src_image_id, l_channel_id);
/* and set the dst_image as it's new Master */
p_gimp_drawable_set_image(l_channel_id, dst_image_id);
} /* end foreach channel */
/* check and see if we have to copy the selection */
l_channel_id = gimp_image_get_selection(src_image_id);
if((p_get_gimp_selection_bounds(src_image_id, &l_x1, &l_y1, &l_x2, &l_y2))
&& (l_channel_id >= 0))
{
if(gap_debug) printf("GAP-DEBUG: START p_steal_content selection_channel_id=%d\n", (int)l_channel_id);
p_gimp_drawable_set_image(l_channel_id, dst_image_id);
p_gimp_selection_load (dst_image_id, l_channel_id);
}
/* attach the floating selection... */
if((l_fsel_id >= 0) && (l_fsel_attached_to_id >= 0))
{
if(gap_debug) printf("GAP-DEBUG: attaching floating_selection id=%d to id %d\n",
(int)l_fsel_id, (int)l_fsel_attached_to_id);
if(p_gimp_floating_sel_attach (l_fsel_id, l_fsel_attached_to_id) < 0)
{
/* in case of error add floating_selection like an ordinary layer
* (if patches are not installed you'll get the error for sure)
*/
printf("GAP: floating_selection is added as top-layer (attach failed)\n");
gimp_image_add_layer (dst_image_id, l_fsel_id, 0);
}
}
/* set active layer/channel */
if(l_active_channel_id >= 0)
{
if(gap_debug) printf("GAP-DEBUG: SET active channel %d\n", (int)l_active_channel_id);
gimp_image_set_active_channel(dst_image_id, l_active_channel_id);
}
if(l_active_layer_id >= 0)
{
if(gap_debug) printf("GAP-DEBUG: SET active layer %d\n", (int)l_active_layer_id);
gimp_image_set_active_layer(dst_image_id, l_active_layer_id);
}
/* Copy the colormap if necessary */
if(gimp_image_base_type(src_image_id) == INDEXED)
{
l_cmap = gimp_image_get_cmap (src_image_id, &l_ncolors);
if(gap_debug) printf("GAP-DEBUG: copy colormap ncolors %d\n", (int)l_ncolors);
gimp_image_set_cmap(dst_image_id, l_cmap, l_ncolors);
}
/* copy guides
* You need GIMP 1.1 or higher for that feature
* (in GIMP 1.0.2 there is no interface for that job
* and guides will be ignored.)
*/
l_guide_id = p_gimp_image_findnext_guide(src_image_id, 0); /* get 1.st guide */
while(l_guide_id > 0)
{
/* get position and orientation for the current guide ID */
p_gimp_image_add_guide(dst_image_id,
p_gimp_image_get_guide_position(src_image_id, l_guide_id),
p_gimp_image_get_guide_orientation(src_image_id, l_guide_id)
);
l_guide_id = p_gimp_image_findnext_guide(src_image_id, l_guide_id);
}
l_rc = 0;
cleanup:
if(l_layers_list) g_free (l_layers_list);
if(l_channels_list) g_free (l_channels_list);
if(gap_debug) printf("GAP-DEBUG: END p_steal_content dst_id=%d src_id=%d rc=%d\n",
(int)dst_image_id, (int)src_image_id, l_rc);
return (l_rc); /* 0 .. OK, or -1 on error */
} /* end p_steal_content */
/* ============================================================================
* p_copy_content
*
* copy all elements (layers, channels, selections, guides, colormap) from src_image
* to dst_image.
* ============================================================================
*/
static int
p_copy_content(gint32 dst_image_id, gint32 src_image_id)
{
int l_rc;
int l_idx;
gint l_nlayers;
gint l_nchannels;
gint32 *l_layers_list;
gint32 *l_channels_list;
gint32 l_layer_id;
gint32 l_channel_id;
gint32 l_new_layer_id;
gint32 l_new_channel_id;
gint32 l_layer_mask_id;
gint32 l_new_layer_mask_id;
gint32 l_guide_id;
gint32 l_src_fsel_id; /* floating selection (in the src_image) */
gint32 l_src_fsel_attached_to_id; /* the drawable where floating selection is attached to (in the src_image) */
gint32 l_fsel_attached_to_id; /* the drawable id where to attach the floating selection (dst) */
gint32 l_fsel_id; /* the drawable id of the floating selection itself (dst) */
gint32 l_active_layer_id;
gint32 l_active_channel_id;
gint l_offset_x;
gint l_offset_y;
gint32 l_x1, l_x2, l_y1, l_y2;
guchar *l_cmap;
gint l_ncolors;
l_rc = -1; /* init retcode to Errorstate */
l_layers_list = NULL;
l_channels_list = NULL;
l_active_layer_id = -1;
l_active_channel_id = -1;
l_fsel_attached_to_id = -1; /* -1 assume fsel is not available (and not attached to any drawable) */
l_fsel_id = -1; /* -1 assume there is no floating selection */
if(gap_debug) printf("GAP-DEBUG: START p_copy_content dst_id=%d src_id=%d\n", (int)dst_image_id, (int)src_image_id);
/* check for floating selection */
l_src_fsel_attached_to_id = -1;
l_src_fsel_id = gimp_image_floating_selection(src_image_id);
if(l_src_fsel_id >= 0)
{
if(gap_debug) printf("GAP-DEBUG: call floating_sel_relax fsel_id=%d\n",
(int)l_src_fsel_id);
p_gimp_floating_sel_relax (l_src_fsel_id, FALSE);
l_src_fsel_attached_to_id = p_gimp_image_floating_sel_attached_to(src_image_id);
}
/* copy all layers */
l_layers_list = gimp_image_get_layers(src_image_id, &l_nlayers);
/* foreach layer do */
for(l_idx = l_nlayers -1; l_idx >= 0; l_idx--)
{
l_layer_id = l_layers_list[l_idx];
if(gap_debug) printf("GAP-DEBUG: START p_copy_content layer_id=%d\n", (int)l_layer_id);
/* copy the layer (including its layermask) */
l_new_layer_id = p_my_layer_copy(dst_image_id, l_layer_id,
gimp_layer_get_opacity(l_layer_id),
gimp_layer_get_mode(l_layer_id),
&l_offset_x,
&l_offset_y
);
if (l_new_layer_id < 0) { goto cleanup; }
if(l_layer_id == l_src_fsel_id)
{
l_fsel_id = l_new_layer_id; /* this layer is the floating selection */
}
else
{
if(gap_debug) printf("GAP-DEBUG: START p_copy_content add_layer_id=%d\n", (int)l_new_layer_id);
/* add the layer on top of the images layerstak */
gimp_image_add_layer (dst_image_id, l_new_layer_id, 0);
if(l_layer_id == l_src_fsel_attached_to_id)
{
l_fsel_attached_to_id = l_new_layer_id; /* the floating selection is attached to this layer */
}
}
/* adjust offsets and other layerproperties */
gimp_layer_set_offsets(l_new_layer_id, l_offset_x, l_offset_y);
gimp_layer_set_visible (l_new_layer_id, gimp_layer_get_visible(l_layer_id));
p_layer_set_linked (l_new_layer_id, p_layer_get_linked(l_layer_id));
gimp_layer_set_preserve_transparency (l_new_layer_id, gimp_layer_get_preserve_transparency(l_layer_id));
if(l_layer_id == gimp_image_get_active_layer(src_image_id))
{
l_active_layer_id = l_new_layer_id;
}
l_layer_mask_id = gimp_layer_get_mask_id(l_layer_id);
if(l_layer_mask_id >= 0)
{
/* layer has layermask */
l_new_layer_mask_id = gimp_layer_get_mask_id(l_new_layer_id);
if(gap_debug) printf("GAP-DEBUG: START p_copy_content layer_mask_id=%d\n", (int)l_layer_mask_id);
/* check for floating selection */
if(l_layer_mask_id == l_src_fsel_attached_to_id)
{
l_fsel_attached_to_id = l_new_layer_mask_id; /* the floating selection is attached to this layer_mask */
}
gimp_layer_set_apply_mask (l_new_layer_id, gimp_layer_get_apply_mask(l_layer_id));
gimp_layer_set_edit_mask (l_new_layer_id, gimp_layer_get_edit_mask(l_layer_id));
gimp_layer_set_show_mask (l_new_layer_id, gimp_layer_get_show_mask(l_layer_id));
}
} /* end foreach layer */
/* copy all channels */
l_channels_list = gimp_image_get_channels(src_image_id, &l_nchannels);
/* foreach channel do */
for(l_idx = l_nchannels -1; l_idx >= 0; l_idx--)
{
l_channel_id = l_channels_list[l_idx];
if(gap_debug) printf("GAP-DEBUG: START p_copy_content channel_id=%d\n", (int)l_channel_id);
l_new_channel_id = p_my_channel_copy(dst_image_id, l_channel_id);
if (l_new_channel_id < 0) { goto cleanup; }
/* add channel on top of the channelstack */
gimp_image_add_channel (dst_image_id, l_new_channel_id, 0);
/* adjust channelproperties */
gimp_channel_set_visible (l_new_channel_id, gimp_channel_get_visible(l_channel_id));
gimp_channel_set_show_masked (l_new_channel_id, gimp_channel_get_show_masked(l_channel_id));
if(l_channel_id == l_src_fsel_attached_to_id)
{
l_fsel_attached_to_id = l_new_channel_id; /* the floating_selection is attached to this channel */
}
if(l_channel_id == gimp_image_get_active_channel(src_image_id))
{
l_active_channel_id = l_new_channel_id;
}
} /* end foreach channel */
/* check and see if we have to copy the selection */
l_channel_id = gimp_image_get_selection(src_image_id);
if((p_get_gimp_selection_bounds(src_image_id, &l_x1, &l_y1, &l_x2, &l_y2))
&& (l_channel_id >= 0))
{
if(gap_debug) printf("GAP-DEBUG: START p_copy_content selection_channel_id=%d\n", (int)l_channel_id);
l_new_channel_id = p_my_channel_copy(dst_image_id, l_channel_id);
if (l_new_channel_id < 0) { goto cleanup; }
p_gimp_selection_load (dst_image_id, l_new_channel_id);
/* delete the channel after load into selection */
gimp_channel_delete(l_new_channel_id);
}
/* attach the floating selection... */
if((l_fsel_id >= 0) && (l_fsel_attached_to_id >= 0))
{
if(gap_debug) printf("GAP-DEBUG: attaching floating_selection id=%d to id %d\n",
(int)l_fsel_id, (int)l_fsel_attached_to_id);
if(p_gimp_floating_sel_attach (l_fsel_id, l_fsel_attached_to_id) < 0)
{
/* in case of error add floating_selection like an ordinary layer
* (if patches are not installed you'll get the error for sure)
*/
printf("GAP: floating_selection is added as top-layer (attach failed)\n");
gimp_image_add_layer (dst_image_id, l_fsel_id, 0);
}
}
/* set active layer/channel */
if(l_active_channel_id >= 0)
{
if(gap_debug) printf("GAP-DEBUG: SET active channel %d\n", (int)l_active_channel_id);
gimp_image_set_active_channel(dst_image_id, l_active_channel_id);
}
if(l_active_layer_id >= 0)
{
if(gap_debug) printf("GAP-DEBUG: SET active layer %d\n", (int)l_active_layer_id);
gimp_image_set_active_layer(dst_image_id, l_active_layer_id);
}
/* Copy the colormap if necessary */
if(gimp_image_base_type(src_image_id) == INDEXED)
{
l_cmap = gimp_image_get_cmap (src_image_id, &l_ncolors);
if(gap_debug) printf("GAP-DEBUG: copy colormap ncolors %d\n", (int)l_ncolors);
gimp_image_set_cmap(dst_image_id, l_cmap, l_ncolors);
}
/* copy guides
* You need GIMP 1.1 or higher for that feature
* (in GIMP 1.0.2 there is no interface for that job
* and guides will be ignored.)
*/
l_guide_id = p_gimp_image_findnext_guide(src_image_id, 0); /* get 1.st guide */
while(l_guide_id > 0)
{
/* get position and orientation for the current guide ID */
p_gimp_image_add_guide(dst_image_id,
p_gimp_image_get_guide_position(src_image_id, l_guide_id),
p_gimp_image_get_guide_orientation(src_image_id, l_guide_id)
);
l_guide_id = p_gimp_image_findnext_guide(src_image_id, l_guide_id);
}
l_rc = 0;
cleanup:
if(l_layers_list) g_free (l_layers_list);
if(l_channels_list) g_free (l_channels_list);
if(gap_debug) printf("GAP-DEBUG: END p_copy_content dst_id=%d src_id=%d rc=%d\n",
(int)dst_image_id, (int)src_image_id, l_rc);
return (l_rc); /* 0 .. OK, or -1 on error */
} /* end p_copy_content */
/* ============================================================================
* p_replace_img
*
* This procedure replaces the content of image_id
* with the content from src_image_id.
* By copying or stealing all its layers and channels.
* (stealing is faster, but requres extensions to the GIMP-core).
* ============================================================================
*/
static int
p_replace_img(gint32 image_id, gint32 src_image_id)
{
int l_rc;
int l_idx;
gint l_nlayers;
gint l_nchannels;
gint32 *l_layers_list;
gint32 *l_channels_list;
gint32 l_layer_id;
gint32 l_channel_id;
gint32 l_guide_id;
gint32 l_old_bg_layer_id;
if(gap_debug) printf("\nGAP-DEBUG: START p_replace_img img_id=%d \n", (int)image_id);
l_old_bg_layer_id = -1;
gimp_image_disable_undo (image_id);
/* remove selection (if there is any) */
p_gimp_selection_none(image_id);
l_channels_list = gimp_image_get_channels(image_id, &l_nchannels);
/* foreach channel do */
for(l_idx = 0; l_idx < l_nchannels; l_idx++)
{
l_channel_id = l_channels_list[l_idx];
gimp_image_remove_channel(image_id, l_channel_id);
gimp_channel_delete(l_channel_id);
}
if(l_channels_list) { g_free (l_channels_list); }
/* delete guides */
l_guide_id = p_gimp_image_findnext_guide(image_id, 0); /* get 1.st guide */
while(l_guide_id > 0)
{
/* delete guide ID */
p_gimp_image_delete_guide(image_id, l_guide_id);
/* get 1.st (of the remaining) guides */
l_guide_id = p_gimp_image_findnext_guide(image_id, 0);
}
/* get list of all (old) dst_layers to delete */
l_layers_list = gimp_image_get_layers(image_id, &l_nlayers);
/* foreach (old) layer of the do */
for(l_idx = 0; l_idx < l_nlayers; l_idx++)
{
l_layer_id = l_layers_list[l_idx];
if(l_idx == l_nlayers -1)
{
/* the background layer is renamed
* (if not GIMP 1.1 will rename the new imported
* Background Layer as "background#2")
* and deleted later.
* Important: the dst_image_id should not be completely empty.
* anytime it may happen, that its display(s) is (are) updated
* and this may crash on empty images.
*/
gimp_layer_set_name(l_layer_id, "--old-bg-layer-will-die-soon");
l_old_bg_layer_id = l_layer_id;
}
else
{
if(gap_debug) printf("GAP-DEBUG: p_replace_img del layer_id=%d \n", (int)l_layer_id);
gimp_image_remove_layer(image_id, l_layer_id);
/* gimp_layer_delete(l_layer_id); */ /* did crash in gimp 1.0.2 ?? and in 1.1 too */
}
}
/* copy (or steal) all layers, channels and guides from src_image */
if (p_pdb_procedure_available("gimp_drawable_set_image") >= 0)
{
/* if the Procedure "gimp_drawable_set_image" is available
* we can steal the layers and channels instead of copying them
* (that gives faster performance)
*/
l_rc = p_steal_content(image_id, src_image_id);
}
else
{
l_rc = p_copy_content(image_id, src_image_id);
}
if(l_old_bg_layer_id >= 0)
{
/* now delete the (old) background layer */
if(gap_debug) printf("GAP-DEBUG: p_replace_img del (old bg) layer_id=%d \n", (int)l_old_bg_layer_id);
gimp_image_remove_layer(image_id, l_old_bg_layer_id);
/* gimp_layer_delete(l_old_bg_layer_id); */ /* did crash in gimp 1.0.2 ?? and in 1.1 too */
}
if (l_layers_list) { g_free (l_layers_list); }
gimp_image_enable_undo (image_id);
if(gap_debug) printf("GAP-DEBUG: END p_replace_img img_id=%d rc=%d\n", (int)image_id, l_rc);
return l_rc; /* OK */
} /* end p_replace_img */
/* ============================================================================
* p_exchange_image
*
*
* ============================================================================
*/
int p_exchange_image(gint32 dst_image_id, gint32 src_image_id)
{
int l_rc;
/* check for equal image type */
if(gimp_image_base_type(src_image_id) != gimp_image_base_type(dst_image_id))
{
printf("GAP: p_exchange_image Image Types are not equal\n");
return -1;
}
/* check for equal width/height */
if((gimp_image_height(src_image_id) != gimp_image_height(dst_image_id))
|| (gimp_image_width(src_image_id) != gimp_image_width(dst_image_id)))
{
printf("GAP: p_exchange_image Image Size is not equal\n");
return -1;
}
/* Now we drop content and copy (or steal) from src_image
* step by step, using many other PDB-Interfaces.
*/
l_rc = p_replace_img(dst_image_id, src_image_id);
return (l_rc);
} /* end p_exchange_image */

View File

@ -0,0 +1,36 @@
/* gap_exchange_image.h
*
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.98.00; 1998/11/26 hof: 1.st release
* (substitute for the procedure "gimp_duplicate_into"
* that was never part of the GIMP core)
*/
#ifndef _GAP_EXCHANGE_IMAGE_H
#define _GAP_EXCHANGE_IMAGE_H
#include "libgimp/gimp.h"
int p_exchange_image(gint32 dst_image_id, gint32 src_image_id);
#endif

94
plug-ins/gap/gap_filter.h Normal file
View File

@ -0,0 +1,94 @@
/* gap_filter.h
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* Headers for gap_filter_*.c (animated filter apply to all imagelayers)
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _GAP_FILTER_H
#define _GAP_FILTER_H
#include "libgimp/gimp.h"
/* max buffer size for plugin' stored valus
*/
#define PLUGIN_DATA_SIZE 8192
/* ------------------------
* gap_filter_foreach.h
* ------------------------
*/
gint gap_proc_anim_apply(GRunModeType run_mode, gint32 image_id, char *l_plugin_name);
/* ------------------------
* gap_filter_iterators.h
* ------------------------
*/
/* Hacked Iterators for some existing Plugins */
gint gap_run_iterators_ALT(char *name, GRunModeType run_mode, gint32 total_steps, gdouble current_step, gint32 len_struct);
void gap_query_iterators_ALT();
/* ------------------------
* gap_dbbrowser.h
* ------------------------
*/
typedef struct {
char selected_proc_name[256];
int button_nr; /* -1 on cancel, 0 .. n */
} t_gap_db_browse_result;
/* proc to check if to add or not to add the procedure to the browsers listbox
* retcode:
* 0 ... do not add
* 1 ... add the procedure to the browsers listbox
*/
typedef int (*t_constraint_func) ( gchar *proc_name);
int
gap_db_browser_dialog (char *title_txt,
char *button_1_txt,
char *button_2_txt,
t_constraint_func constraint_func,
t_constraint_func constraint_func_sel1,
t_constraint_func constraint_func_sel2,
t_gap_db_browse_result *result,
gint init_gtk_flag);
/* ------------------------
* gap_filter_codegen.h
* ------------------------
*/
void p_remove_codegen_files();
gint p_gen_code_iter_ALT (char *proc_name);
gint p_gen_forward_iter_ALT(char *proc_name);
gint p_gen_tab_iter_ALT (char *proc_name);
gint p_gen_code_iter (char *proc_name);
#endif

View File

@ -0,0 +1,747 @@
/* gap_filter_codegen.c
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* - GAP_filter codegenerator procedures for _iterator_ALT procedures
*
* Note: this code is only used in debug mode,
* (for developers (Hackers) to generate code templates
* for _iterator_ALT or _Iterator procedures.)
*/
/* revision history:
* version 0.99.00 1999.03.14 hof: Codegeneration of File ./gen_filter_iter_code.c
* splittet into single Files XX_iter_ALT.inc
* bugfixes in code generation
* version 0.95.04 1998.06.12 hof: p_delta_drawable (enable use of layerstack anims in drawable iteration)
* version 0.93.00 hof: generate Iterator Source
* in one single file (per plugin), ready to compile
* version 0.91.01; Tue Dec 23 hof: 1.st (pre) release
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
/* GIMP includes */
#include "libgimp/gimp.h"
/* GAP includes */
/* int gap_debug = 1; */ /* print debug infos */
/* int gap_debug = 0; */ /* 0: dont print debug infos */
extern int gap_debug;
gint p_gen_code_iter(char *proc_name);
#define GEN_FORWARDFILE_NAME "gen_filter_iter_forward.c"
#define GEN_TABFILE_NAME "gen_filter_iter_tab.c"
void p_remove_codegen_files()
{
remove(GEN_FORWARDFILE_NAME);
remove(GEN_TABFILE_NAME);
printf("overwrite file: %s\n", GEN_FORWARDFILE_NAME);
printf("overwrite file: %s\n", GEN_TABFILE_NAME);
}
static char*
p_type_to_string(GParamType t)
{
switch (t) {
case PARAM_INT32: return "long ";
case PARAM_INT16: return "short ";
case PARAM_INT8: return "char ";
case PARAM_FLOAT: return "gdouble ";
case PARAM_STRING: return "char *";
case PARAM_INT32ARRAY: return "INT32ARRAY";
case PARAM_INT16ARRAY: return "INT16ARRAY";
case PARAM_INT8ARRAY: return "INT8ARRAY";
case PARAM_FLOATARRAY: return "FLOATARRAY";
case PARAM_STRINGARRAY: return "STRINGARRAY";
case PARAM_COLOR: return "t_color ";
case PARAM_REGION: return "REGION";
case PARAM_DISPLAY: return "gint32 ";
case PARAM_IMAGE: return "gint32 ";
case PARAM_LAYER: return "gint32 ";
case PARAM_CHANNEL: return "gint32 ";
case PARAM_DRAWABLE: return "gint32 ";
case PARAM_SELECTION: return "SELECTION";
case PARAM_BOUNDARY: return "BOUNDARY";
case PARAM_PATH: return "PATH";
case PARAM_STATUS: return "STATUS";
case PARAM_END: return "END";
default: return "UNKNOWN?";
}
}
static void p_get_gendate(char *gendate)
{
struct tm *l_t;
long l_ti;
l_ti = time(0L); /* Get UNIX time */
l_t = localtime(&l_ti); /* konvert time to tm struct */
sprintf(gendate, "%02d.%02d.%02d %02d:%02d"
, l_t->tm_mday
, l_t->tm_mon + 1
, l_t->tm_year
, l_t->tm_hour
, l_t->tm_min);
}
static void
p_clean_name(char *name, char *clean_name)
{
char *l_ptr;
l_ptr = clean_name;
while(*name != '\0')
{
if((*name == '-')
|| (*name == '+')
|| (*name == '/')
|| (*name == '%')
|| (*name == '*')
|| (*name == ':')
|| (*name == '!')
|| (*name == '=')
|| (*name == ';')
|| (*name == '^')
|| (*name == ',')
|| (*name == '[')
|| (*name == ']')
|| (*name == '{')
|| (*name == '}')
|| (*name == '(')
|| (*name == ')')
|| (*name == ' ')
|| (*name == '$')
|| (*name == '<')
|| (*name == '|')
|| (*name == '>')
|| (*name == '?')
|| (*name == '~')
)
{
*l_ptr = '_';
}
else
{
*l_ptr = *name;
}
name++;
l_ptr++;
}
*l_ptr = '\0';
}
gint p_gen_code_iter_ALT(char *proc_name)
{
FILE *l_fp;
int l_idx;
int l_nparams;
int l_nreturn_vals;
int l_proc_type;
char *l_proc_blurb;
char *l_proc_help;
char *l_proc_author;
char *l_proc_copyright;
char *l_proc_date;
GParamDef *l_params;
GParamDef *l_return_vals;
gint l_rc;
char l_filename[512];
char l_gendate[30];
char l_clean_proc_name[256];
char l_clean_par_name[256];
l_rc = 0;
p_get_gendate(&l_gendate[0]);
/* Query the gimp application's procedural database
* regarding a particular procedure.
*/
if(gimp_query_procedure (proc_name,
&l_proc_blurb,
&l_proc_help,
&l_proc_author,
&l_proc_copyright,
&l_proc_date,
&l_proc_type,
&l_nparams,
&l_nreturn_vals,
&l_params,
&l_return_vals))
{
p_clean_name(proc_name, &l_clean_proc_name[0]);
/* procedure found in PDB */
if(gap_debug) fprintf(stderr, "DEBUG: found in PDB %s author: %s copyright: %s\n",
proc_name, l_proc_author, l_proc_copyright);
/* check if plugin can be a typical one, that works on one drawable */
if (l_proc_type != PROC_PLUG_IN) { l_rc = -1; }
if (l_nparams < 3) { l_rc = -1; }
if (l_params[0].type != PARAM_INT32) { l_rc = -1; }
if (l_params[1].type != PARAM_IMAGE) { l_rc = -1; }
if (l_params[2].type != PARAM_DRAWABLE) { l_rc = -1; }
sprintf(l_filename, "%s_iter_ALT.inc", l_clean_proc_name);
l_fp = fopen(l_filename, "w");
if(l_fp != NULL)
{
fprintf(l_fp, "/* ----------------------------------------------------------------------\n");
fprintf(l_fp, " * p_%s_iter_ALT \n", l_clean_proc_name);
fprintf(l_fp, " * ----------------------------------------------------------------------\n");
fprintf(l_fp, " */\n");
fprintf(l_fp, "gint p_%s_iter_ALT(GRunModeType run_mode, gint32 total_steps, gdouble current_step, gint32 len_struct) \n", l_clean_proc_name);
fprintf(l_fp, "{\n");
fprintf(l_fp, " typedef struct t_%s_Vals \n", l_clean_proc_name);
fprintf(l_fp, " {\n");
for(l_idx = 3; l_idx < l_nparams; l_idx++)
{
p_clean_name(l_params[l_idx].name, &l_clean_par_name[0]);
fprintf(l_fp, " %s %s;\n",
p_type_to_string(l_params[l_idx].type), l_clean_par_name);
}
fprintf(l_fp, " } t_%s_Vals; \n", l_clean_proc_name);
fprintf(l_fp, "\n");
fprintf(l_fp, " t_%s_Vals buf, *buf_from, *buf_to; \n", l_clean_proc_name);
fprintf(l_fp, "\n");
fprintf(l_fp, " if(len_struct != sizeof(t_%s_Vals)) \n", l_clean_proc_name);
fprintf(l_fp, " {\n");
fprintf(l_fp, " fprintf(stderr, \"ERROR: p_\%s_iter_ALT stored Data missmatch in size %%d != %%d\\n\", \n", l_clean_proc_name);
fprintf(l_fp, " (int)len_struct, sizeof(t_%s_Vals) ); \n", l_clean_proc_name);
fprintf(l_fp, " return -1; /* ERROR */ \n");
fprintf(l_fp, " }\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " gimp_get_data(\"%s_ITER_FROM\", g_plugin_data_from); \n", l_clean_proc_name);
fprintf(l_fp, " gimp_get_data(\"%s_ITER_TO\", g_plugin_data_to); \n", l_clean_proc_name);
fprintf(l_fp, "\n");
fprintf(l_fp, " buf_from = (t_%s_Vals *)&g_plugin_data_from[0]; \n", l_clean_proc_name);
fprintf(l_fp, " buf_to = (t_%s_Vals *)&g_plugin_data_to[0]; \n", l_clean_proc_name);
fprintf(l_fp, " memcpy(&buf, buf_from, sizeof(buf));\n");
fprintf(l_fp, "\n");
for(l_idx = 3; l_idx < l_nparams; l_idx++)
{
p_clean_name(l_params[l_idx].name, &l_clean_par_name[0]);
switch(l_params[l_idx].type)
{
case PARAM_INT32:
fprintf(l_fp, " p_delta_long(&buf.%s, buf_from->%s, buf_to->%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_INT16:
fprintf(l_fp, " p_delta_short(&buf.%s, buf_from->%s, buf_to->%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_INT8:
fprintf(l_fp, " p_delta_char(&buf.%s, buf_from->%s, buf_to->%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_FLOAT:
fprintf(l_fp, " p_delta_gdouble(&buf.%s, buf_from->%s, buf_to->%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_COLOR:
fprintf(l_fp, " p_delta_color(&buf.%s, &buf_from->%s, &buf_to->%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_DRAWABLE:
fprintf(l_fp, " p_delta_drawable(&buf.%s, buf_from->%s, buf_to->%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
default:
break;
}
}
fprintf(l_fp, "\n");
fprintf(l_fp, " gimp_set_data(\"%s\", &buf, sizeof(buf)); \n", l_clean_proc_name);
fprintf(l_fp, "\n");
fprintf(l_fp, " return 0; /* OK */\n");
fprintf(l_fp, "}\n");
fclose(l_fp);
}
/* free the query information */
g_free (l_proc_blurb);
g_free (l_proc_help);
g_free (l_proc_author);
g_free (l_proc_copyright);
g_free (l_proc_date);
g_free (l_params);
g_free (l_return_vals);
}
else
{
return -1;
}
p_gen_code_iter(proc_name);
return l_rc;
} /* p_gen_code_iter_ALT */
gint p_gen_forward_iter_ALT(char *proc_name)
{
FILE *l_fp;
char l_clean_proc_name[256];
p_clean_name(proc_name, &l_clean_proc_name[0]);
l_fp = fopen(GEN_FORWARDFILE_NAME, "a");
if(l_fp != NULL)
{
fprintf(l_fp, "static gint p_%s_iter_ALT (GRunModeType run_mode, gint32 total_steps, gdouble current_step, gint32 len_struct);\n",
l_clean_proc_name);
fclose(l_fp);
}
return 0;
}
gint p_gen_tab_iter_ALT(char *proc_name)
{
FILE *l_fp;
char l_clean_proc_name[256];
p_clean_name(proc_name, &l_clean_proc_name[0]);
l_fp = fopen(GEN_TABFILE_NAME, "a");
if(l_fp != NULL)
{
fprintf(l_fp, " , { \"%s\", p_%s_iter_ALT }\n",
l_clean_proc_name, l_clean_proc_name);
fclose(l_fp);
}
return 0;
}
/* Generate _Itrerator Procedure all in one .c file,
* ready to compile
*/
gint p_gen_code_iter(char *proc_name)
{
FILE *l_fp;
int l_idx;
int l_nparams;
int l_nreturn_vals;
int l_proc_type;
char *l_proc_blurb;
char *l_proc_help;
char *l_proc_author;
char *l_proc_copyright;
char *l_proc_date;
GParamDef *l_params;
GParamDef *l_return_vals;
gint l_rc;
char l_filename[512];
char l_gendate[30];
char l_clean_proc_name[256];
char l_clean_par_name[256];
l_rc = 0;
p_get_gendate(&l_gendate[0]);
/* Query the gimp application's procedural database
* regarding a particular procedure.
*/
if(gimp_query_procedure (proc_name,
&l_proc_blurb,
&l_proc_help,
&l_proc_author,
&l_proc_copyright,
&l_proc_date,
&l_proc_type,
&l_nparams,
&l_nreturn_vals,
&l_params,
&l_return_vals))
{
p_clean_name(proc_name, &l_clean_proc_name[0]);
/* procedure found in PDB */
if(gap_debug) fprintf(stderr, "DEBUG: found in PDB %s\n", proc_name);
/* check if plugin can be a typical one, that works on one drawable */
if (l_proc_type != PROC_PLUG_IN) { l_rc = -1; }
if (l_nparams < 3) { l_rc = -1; }
if (l_params[0].type != PARAM_INT32) { l_rc = -1; }
if (l_params[1].type != PARAM_IMAGE) { l_rc = -1; }
if (l_params[2].type != PARAM_DRAWABLE) { l_rc = -1; }
sprintf(l_filename, "%s_iter.c", l_clean_proc_name);
l_fp = fopen(l_filename, "w");
if(l_fp != NULL)
{
fprintf(l_fp, "/* %s\n", l_filename);
fprintf(l_fp, " * generated by gap_filter_codegen.c\n");
fprintf(l_fp, " * generation date: %s\n", l_gendate);
fprintf(l_fp, " *\n");
fprintf(l_fp, " * generation source Gimp PDB entry name: %s\n", l_clean_proc_name);
fprintf(l_fp, " * version : %s\n", l_proc_date);
fprintf(l_fp, " *\n");
fprintf(l_fp, " * The generated code will not work if the internal data stucture\n");
fprintf(l_fp, " * (used to store and retrieve \"LastValues\") is different to the\n");
fprintf(l_fp, " * PDB Calling Interface.\n");
fprintf(l_fp, " *\n");
fprintf(l_fp, " * In that case you will get an Error message like that:\n");
fprintf(l_fp, " * ERROR: xxxx_Iterator stored Data missmatch in size N != M\n");
fprintf(l_fp, " * if the Iterator is called. \n");
fprintf(l_fp, " * (via \"Filter all Layers\" using \"Apply Varying\" Button)\n");
fprintf(l_fp, " *\n");
fprintf(l_fp, " * When you get this Error, you should change this generated code.\n");
fprintf(l_fp, " * \n");
fprintf(l_fp, " */\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "/* SYTEM (UNIX) includes */ \n");
fprintf(l_fp, "#include <stdio.h>\n");
fprintf(l_fp, "#include <string.h>\n");
fprintf(l_fp, "#include <stdlib.h>\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "/* GIMP includes */\n");
fprintf(l_fp, "#include \"gtk/gtk.h\"\n");
fprintf(l_fp, "#include \"libgimp/gimp.h\"\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "typedef struct { guchar color[3]; } t_color; \n");
fprintf(l_fp, "typedef struct { gint color[3]; } t_gint_color; \n");
fprintf(l_fp, "\n");
fprintf(l_fp, "static void query(void); \n");
fprintf(l_fp, "static void run(char *name, int nparam, GParam *param, int *nretvals, GParam **retvals); \n");
fprintf(l_fp, "\n");
fprintf(l_fp, "GPlugInInfo PLUG_IN_INFO = \n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " NULL, /* init_proc */ \n");
fprintf(l_fp, " NULL, /* quit_proc */ \n");
fprintf(l_fp, " query, /* query_proc */ \n");
fprintf(l_fp, " run, /* run_proc */ \n");
fprintf(l_fp, "}; \n");
fprintf(l_fp, "\n");
fprintf(l_fp, "/* ----------------------------------------------------------------------\n");
fprintf(l_fp, " * iterator functions for basic datatypes \n");
fprintf(l_fp, " * ----------------------------------------------------------------------\n");
fprintf(l_fp, " */\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "static void p_delta_long(long *val, long val_from, long val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " double delta;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if(total_steps < 1) return;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);\n");
fprintf(l_fp, " *val = val_from + delta; \n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "static void p_delta_short(short *val, short val_from, short val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " double delta;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if(total_steps < 1) return;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);\n");
fprintf(l_fp, " *val = val_from + delta;\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "static void p_delta_gint(gint *val, gint val_from, gint val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " double delta;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if(total_steps < 1) return;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);\n");
fprintf(l_fp, " *val = val_from + delta;\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "static void p_delta_char(char *val, char val_from, char val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " double delta;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if(total_steps < 1) return;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);\n");
fprintf(l_fp, " *val = val_from + delta;\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "static void p_delta_gdouble(double *val, double val_from, double val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " double delta;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if(total_steps < 1) return;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);\n");
fprintf(l_fp, " *val = val_from + delta;\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "static void p_delta_float(float *val, float val_from, float val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " double delta;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if(total_steps < 1) return;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);\n");
fprintf(l_fp, " *val = val_from + delta;\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "static void p_delta_color(t_color *val, t_color *val_from, t_color *val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " double delta;\n");
fprintf(l_fp, " int l_idx;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if(total_steps < 1) return;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " for(l_idx = 0; l_idx < 3; l_idx++)\n");
fprintf(l_fp, " {\n");
fprintf(l_fp, " delta = ((double)(val_to->color[l_idx] - val_from->color[l_idx]) / (double)total_steps) * ((double)total_steps - current_step);\n");
fprintf(l_fp, " val->color[l_idx] = val_from->color[l_idx] + delta;\n");
fprintf(l_fp, " }\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "static void p_delta_gint_color(t_gint_color *val, t_gint_color *val_from, t_gint_color *val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " double delta;\n");
fprintf(l_fp, " int l_idx;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if(total_steps < 1) return;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " for(l_idx = 0; l_idx < 3; l_idx++)\n");
fprintf(l_fp, " {\n");
fprintf(l_fp, " delta = ((double)(val_to->color[l_idx] - val_from->color[l_idx]) / (double)total_steps) * ((double)total_steps - current_step);\n");
fprintf(l_fp, " val->color[l_idx] = val_from->color[l_idx] + delta;\n");
fprintf(l_fp, " }\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "static void p_delta_drawable(gint32 *val, gint32 val_from, gint32 val_to, gint32 total_steps, gdouble current_step)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " gint l_nlayers;\n");
fprintf(l_fp, " gint32 *l_layers_list;\n");
fprintf(l_fp, " gint32 l_tmp_image_id;\n");
fprintf(l_fp, " gint l_idx, l_idx_from, l_idx_to;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " l_tmp_image_id = gimp_drawable_image_id(val_from);\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " /* check if from and to values are both valid drawables within the same image */\n");
fprintf(l_fp, " if ((l_tmp_image_id > 0)\n");
fprintf(l_fp, " && (l_tmp_image_id = gimp_drawable_image_id(val_to)))\n");
fprintf(l_fp, " {\n");
fprintf(l_fp, " l_idx_from = -1;\n");
fprintf(l_fp, " l_idx_to = -1;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " /* check the layerstack index of from and to drawable */\n");
fprintf(l_fp, " l_layers_list = gimp_image_get_layers(l_tmp_image_id, &l_nlayers);\n");
fprintf(l_fp, " for (l_idx = l_nlayers -1; l_idx >= 0; l_idx--)\n");
fprintf(l_fp, " {\n");
fprintf(l_fp, " if( l_layers_list[l_idx] == val_from ) l_idx_from = l_idx;\n");
fprintf(l_fp, " if( l_layers_list[l_idx] == val_to ) l_idx_to = l_idx;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if((l_idx_from != -1) && (l_idx_to != -1))\n");
fprintf(l_fp, " {\n");
fprintf(l_fp, " /* OK found both index values, iterate the index (proceed to next layer) */\n");
fprintf(l_fp, " p_delta_gint(&l_idx, l_idx_from, l_idx_to, total_steps, current_step);\n");
fprintf(l_fp, " *val = l_layers_list[l_idx];\n");
fprintf(l_fp, " break;\n");
fprintf(l_fp, " }\n");
fprintf(l_fp, " }\n");
fprintf(l_fp, " g_free (l_layers_list);\n");
fprintf(l_fp, " }\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "/* ----------------------------------------------------------------------\n");
fprintf(l_fp, " * p_%s_iter \n", l_clean_proc_name);
fprintf(l_fp, " * ----------------------------------------------------------------------\n");
fprintf(l_fp, " */\n");
fprintf(l_fp, "gint p_%s_iter(GRunModeType run_mode, gint32 total_steps, gdouble current_step, gint32 len_struct) \n", l_clean_proc_name);
fprintf(l_fp, "{\n");
fprintf(l_fp, " typedef struct t_%s_Vals \n", l_clean_proc_name);
fprintf(l_fp, " {\n");
for(l_idx = 3; l_idx < l_nparams; l_idx++)
{
p_clean_name(l_params[l_idx].name, &l_clean_par_name[0]);
fprintf(l_fp, " %s %s;\n",
p_type_to_string(l_params[l_idx].type), l_clean_par_name);
}
fprintf(l_fp, " } t_%s_Vals; \n", l_clean_proc_name);
fprintf(l_fp, "\n");
fprintf(l_fp, " t_%s_Vals buf, buf_from, buf_to; \n", l_clean_proc_name);
fprintf(l_fp, "\n");
fprintf(l_fp, " if(len_struct != sizeof(t_%s_Vals)) \n", l_clean_proc_name);
fprintf(l_fp, " {\n");
fprintf(l_fp, " fprintf(stderr, \"ERROR: p_\%s_iter stored Data missmatch in size %%d != %%d\\n\", \n", l_clean_proc_name);
fprintf(l_fp, " (int)len_struct, sizeof(t_%s_Vals) ); \n", l_clean_proc_name);
fprintf(l_fp, " return -1; /* ERROR */ \n");
fprintf(l_fp, " }\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " gimp_get_data(\"%s_ITER_FROM\", &buf_from); \n", l_clean_proc_name);
fprintf(l_fp, " gimp_get_data(\"%s_ITER_TO\", &buf_to); \n", l_clean_proc_name);
fprintf(l_fp, " memcpy(&buf, &buf_from, sizeof(buf));\n");
fprintf(l_fp, "\n");
for(l_idx = 3; l_idx < l_nparams; l_idx++)
{
p_clean_name(l_params[l_idx].name, &l_clean_par_name[0]);
switch(l_params[l_idx].type)
{
case PARAM_INT32:
fprintf(l_fp, " p_delta_long(&buf.%s, buf_from.%s, buf_to.%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_INT16:
fprintf(l_fp, " p_delta_short(&buf.%s, buf_from.%s, buf_to.%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_INT8:
fprintf(l_fp, " p_delta_char(&buf.%s, buf_from.%s, buf_to.%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_FLOAT:
fprintf(l_fp, " p_delta_gdouble(&buf.%s, buf_from.%s, buf_to.%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_COLOR:
fprintf(l_fp, " p_delta_color(&buf.%s, &buf_from.%s, &buf_to.%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
case PARAM_DRAWABLE:
fprintf(l_fp, " p_delta_drawable(&buf.%s, buf_from.%s, buf_to.%s, total_steps, current_step);\n",
l_clean_par_name, l_clean_par_name, l_clean_par_name);
break;
default:
break;
}
}
fprintf(l_fp, "\n");
fprintf(l_fp, " gimp_set_data(\"%s\", &buf, sizeof(buf)); \n", l_clean_proc_name);
fprintf(l_fp, "\n");
fprintf(l_fp, " return 0; /* OK */\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "MAIN ()\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "/* ----------------------------------------------------------------------\n");
fprintf(l_fp, " * install (query) _Iterator\n");
fprintf(l_fp, " * ----------------------------------------------------------------------\n");
fprintf(l_fp, " */\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "static void query ()\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " char l_blurb_text[300];\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " static GParamDef args_iter[] =\n");
fprintf(l_fp, " {\n");
fprintf(l_fp, " {PARAM_INT32, \"run_mode\", \"non-interactive\"},\n");
fprintf(l_fp, " {PARAM_INT32, \"total_steps\", \"total number of steps (# of layers-1 to apply the related plug-in)\"},\n");
fprintf(l_fp, " {PARAM_FLOAT, \"current_step\", \"current (for linear iterations this is the layerstack position, otherwise some value inbetween)\"},\n");
fprintf(l_fp, " {PARAM_INT32, \"len_struct\", \"length of stored data structure with id is equal to the plug_in proc_name\"},\n");
fprintf(l_fp, " };\n");
fprintf(l_fp, " static int nargs_iter = sizeof(args_iter) / sizeof(args_iter[0]);\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " static GParamDef *return_vals = NULL;\n");
fprintf(l_fp, " static int nreturn_vals = 0;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " sprintf(l_blurb_text, \"This extension calculates the modified values for one iterationstep for the call of %s\");\n", l_clean_proc_name);
fprintf(l_fp, "\n");
fprintf(l_fp, " gimp_install_procedure(\"%s_Iterator\",\n", l_clean_proc_name);
fprintf(l_fp, " l_blurb_text,\n");
fprintf(l_fp, " \"\",\n");
fprintf(l_fp, " \"Wolfgang Hofer\",\n");
fprintf(l_fp, " \"Wolfgang Hofer\",\n");
fprintf(l_fp, " \"%s\",\n", l_gendate); /* generation date */
fprintf(l_fp, " NULL, /* do not appear in menus */\n");
fprintf(l_fp, " NULL,\n");
fprintf(l_fp, " PROC_EXTENSION,\n");
fprintf(l_fp, " nargs_iter, nreturn_vals,\n");
fprintf(l_fp, " args_iter, return_vals);\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "}\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "/* ----------------------------------------------------------------------\n");
fprintf(l_fp, " * run Iterator\n");
fprintf(l_fp, " * ----------------------------------------------------------------------\n");
fprintf(l_fp, " */\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "static void\n");
fprintf(l_fp, "run (char *name,\n");
fprintf(l_fp, " int n_params,\n");
fprintf(l_fp, " GParam *param,\n");
fprintf(l_fp, " int *nreturn_vals,\n");
fprintf(l_fp, " GParam **return_vals)\n");
fprintf(l_fp, "{\n");
fprintf(l_fp, " static GParam values[1];\n");
fprintf(l_fp, " GRunModeType run_mode;\n");
fprintf(l_fp, " GStatusType status = STATUS_SUCCESS;\n");
fprintf(l_fp, " gint32 image_id;\n");
fprintf(l_fp, " gint32 len_struct;\n");
fprintf(l_fp, " gint32 total_steps;\n");
fprintf(l_fp, " gdouble current_step;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " gint32 l_rc;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " *nreturn_vals = 1;\n");
fprintf(l_fp, " *return_vals = values;\n");
fprintf(l_fp, " l_rc = 0;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " run_mode = param[0].data.d_int32;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " if ((run_mode == RUN_NONINTERACTIVE) && (n_params == 4))\n");
fprintf(l_fp, " {\n");
fprintf(l_fp, " total_steps = param[1].data.d_int32;\n");
fprintf(l_fp, " current_step = param[2].data.d_float;\n");
fprintf(l_fp, " len_struct = param[3].data.d_int32;\n");
fprintf(l_fp, " l_rc = p_%s_iter(run_mode, total_steps, current_step, len_struct);\n", l_clean_proc_name);
fprintf(l_fp, " if(l_rc < 0)\n");
fprintf(l_fp, " {\n");
fprintf(l_fp, " status = STATUS_EXECUTION_ERROR;\n");
fprintf(l_fp, " }\n");
fprintf(l_fp, " }\n");
fprintf(l_fp, " else status = STATUS_CALLING_ERROR;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, " values[0].type = PARAM_STATUS;\n");
fprintf(l_fp, " values[0].data.d_status = status;\n");
fprintf(l_fp, "\n");
fprintf(l_fp, "}\n");
fclose(l_fp);
}
/* free the query information */
g_free (l_proc_blurb);
g_free (l_proc_help);
g_free (l_proc_author);
g_free (l_proc_copyright);
g_free (l_proc_date);
g_free (l_params);
g_free (l_return_vals);
}
else
{
return -1;
}
return l_rc;
} /* p_gen_code_iter */

View File

@ -0,0 +1,573 @@
/* gap_filter_foreach.c
* 1997.12.23 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* - GAP_filter foreach: call any Filter (==Plugin Proc)
* with varying settings for all
* layers within one Image.
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.97.00 hof: - modul splitted (2.nd part is now gap_filter_pdb.c)
* version 0.96.03 hof: - pitstop dialog provides optional backup on each step
* (and skip option)
* version 0.96.00 hof: - now using gap_arr_dialog.h
* version 0.92.00 hof: - pitstop dialog
* give user a chance to stop after interactive plugin calls
* if you dont want the dialog export GAP_FILTER_PITSTOP="N"
* - fixed bug in restore of layervisibility
* - codegen via explicite button (in gap_debug mode)
* version 0.91.01; Tue Dec 23 hof: 1.st (pre) release
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_arr_dialog.h"
#include "gap_filter.h"
#include "gap_filter_pdb.h"
#include "gap_lib.h"
/* ------------------------
* global gap DEBUG switch
* ------------------------
*/
/* int gap_debug = 1; */ /* print debug infos */
/* int gap_debug = 0; */ /* 0: dont print debug infos */
extern int gap_debug;
static gint32 g_current_image_id;
void p_gdisplays_update_full(gint32 image_id)
{
GParam* l_params;
gint l_retvals;
if(p_procedure_available("gimp_image_update_full", PTYP_ANY) >= 0)
{
l_params = gimp_run_procedure ("gimp_image_update_full",
&l_retvals,
PARAM_IMAGE, image_id,
PARAM_END);
/* Note: gimp_displays_update_full is not available in the official release gimp 0.99.16
* (dont care if procedure is not there,
* --> the user may not see the current layer, because
* gimp_displays_flush() does not update on changes
* of the visibility.
*/
g_free(l_params);
}
gimp_displays_flush();
}
/* pitstop dialog
* return -1 on cancel, 0 .. on continue, 1 .. on skip
*/
static gint p_pitstop(GRunModeType run_mode, char *plugin_name, gint text_flag,
char *step_backup_file, gint len_step_backup_file,
gint32 layer_idx)
{
char *l_env;
char l_msg[512];
static t_but_arg l_but_argv[3];
gint l_but_argc;
gint l_argc;
static t_arr_arg l_argv[1];
int l_continue;
char l_skip_txt[20];
p_init_arr_arg(&l_argv[0], WGT_FILESEL);
l_argv[0].label_txt ="backup to file";
l_argv[0].entry_width = 140; /* pixel */
l_argv[0].help_txt = "Make backup of the image after each step";
l_argv[0].text_buf_len = len_step_backup_file;
l_argv[0].text_buf_ret = step_backup_file;
l_but_argv[0].but_txt = "Continue";
l_but_argv[0].but_val = 0;
l_but_argv[1].but_txt = "Cancel";
l_but_argv[1].but_val = -1;
sprintf(l_skip_txt, "Skip %d", (int)layer_idx);
l_but_argv[2].but_txt = l_skip_txt;
l_but_argv[2].but_val = 1;
l_but_argc = 2;
l_argc = 0;
/* optional dialog between both calls (to see the effect of 1.call) */
if(run_mode == RUN_INTERACTIVE)
{
l_env = getenv("GAP_FILTER_PITSTOP");
if(l_env != NULL)
{
if((*l_env == 'N') || (*l_env == 'n'))
{
return 0; /* continue without question */
}
}
if(text_flag == 0)
{
sprintf(l_msg, "2.nd call of %s\n(define end-settings)", plugin_name);
}
else
{
sprintf(l_msg, "Non-Interactive call of %s\n(for all layers inbetween)", plugin_name);
l_but_argc = 3;
l_argc = 1;
}
l_continue = p_array_std_dialog ("Animated Filter apply", l_msg,
l_argc, l_argv,
l_but_argc, l_but_argv, 0);
if(l_continue < 0) return -1;
else return l_continue;
}
return 0; /* continue without question */
} /* end p_pitstop */
static void p_visibilty_restore(gint32 image_id, gint nlayers, int *visible_tab, char *plugin_name)
{
gint32 *l_layers_list;
gint l_nlayers2;
gint32 l_idx;
l_layers_list = gimp_image_get_layers(image_id, &l_nlayers2);
if(l_nlayers2 == nlayers)
{
for(l_idx = 0; l_idx < nlayers; l_idx++)
{
gimp_layer_set_visible(l_layers_list[l_idx], visible_tab[l_idx]);
if(gap_debug) printf("visibilty restore [%d] %d\n", (int)l_idx, (int)visible_tab[l_idx]);
}
p_gdisplays_update_full(image_id);
}
else
{
printf("Error: Plugin %s has changed Nr. of layers from %d to %d\ncould not restore Layer visibilty.\n",
plugin_name, (int)nlayers, (int)l_nlayers2);
}
g_free (l_layers_list);
}
static gint32 p_get_indexed_layerid(gint32 image_id, gint *nlayers, gint32 idx, char *plugin_name)
{
gint32 *l_layers_list;
gint32 l_layer_id;
gint l_nlayers2;
l_layers_list = gimp_image_get_layers(image_id, &l_nlayers2);
if(l_layers_list == NULL)
{
printf("Warning: cant get layers (maybe the image was closed)\n");
return -1;
}
if((l_nlayers2 != *nlayers) && (*nlayers > 0))
{
printf("Error: Plugin %s has changed Nr. of layers from %d to %d\nAnim Filter apply stopped.\n",
plugin_name, (int)*nlayers, (int)l_nlayers2);
return -1;
}
*nlayers = l_nlayers2;
l_layer_id = l_layers_list[idx];
g_free (l_layers_list);
return (l_layer_id);
}
/* ============================================================================
* p_foreach_multilayer
* apply the given plugin to each layer of the image.
* returns image_id of the new created multilayer image
* (or -1 on error)
* ============================================================================
*/
int p_foreach_multilayer(GRunModeType run_mode, gint32 image_id,
char *plugin_name, t_apply_mode apply_mode)
{
static char l_key_from[512];
static char l_key_to[512];
char *l_plugin_iterator;
gint32 l_layer_id;
gint32 l_top_layer;
gint32 l_idx;
gint l_nlayers;
gdouble l_percentage, l_percentage_step;
GParam *l_params;
gint l_retvals;
int l_rc;
gint l_plugin_data_len;
long l_child_pid;
/* int l_status; */
int *l_visible_tab;
char l_step_backup_file[120];
gint l_pit_rc;
l_rc = 0;
l_plugin_data_len = 0;
l_nlayers = 0;
l_visible_tab = NULL;
l_step_backup_file[0] = '\0';
/* check for the Plugin */
l_rc = p_procedure_available(plugin_name, PTYP_CAN_OPERATE_ON_DRAWABLE);
if(l_rc < 0)
{
fprintf(stderr, "ERROR: Plugin not available or wrong type %s\n", plugin_name);
return -1;
}
/* check for matching Iterator PluginProcedures */
l_plugin_iterator = p_get_iterator_proc(plugin_name);
l_percentage = 0.0;
if(run_mode == RUN_INTERACTIVE)
{
gimp_progress_init("Applying Filter to all Layers ..");
}
l_layer_id = p_get_indexed_layerid(image_id, &l_nlayers, 0, plugin_name);
if(l_layer_id >= 0)
{
if(l_nlayers < 1)
{
fprintf(stderr, "ERROR: need at 1 Layers to apply plugin !\n");
}
else
{
/* allocate a table to store the visibility attributes for each layer */
l_visible_tab = (gint*) malloc((l_nlayers +1) * sizeof (gint));
if(l_visible_tab == NULL)
return -1;
/* save the visibility of all layers */
for(l_idx = 0; l_idx < l_nlayers; l_idx++)
{
l_layer_id = p_get_indexed_layerid(image_id, &l_nlayers, l_idx, plugin_name);
l_visible_tab[l_idx] = gimp_layer_get_visible(l_layer_id);
/* make the backround visible, all others invisible
* (so the user can see the effect of the 1.st applied _FROM filter)
*/
if(l_idx == (l_nlayers -1)) gimp_layer_set_visible(l_layer_id, TRUE);
else gimp_layer_set_visible(l_layer_id, FALSE);
}
p_gdisplays_update_full(image_id);
l_percentage_step = 1.0 / l_nlayers;
if((l_plugin_iterator != NULL) && (l_nlayers > 1) && (apply_mode == PTYP_VARYING_LINEAR ))
{
l_child_pid = 0; /* fork(); */
if(l_child_pid < 0)
{
fprintf(stderr, "ERROR: fork failed !\n");
return -1;
}
/* if(l_child_pid != 0) */
{
/* parent process: call plugin Interactive for background layer[n] */
/* if(gap_debug) fprintf(stderr, "forked child process pid=%ld\n", l_child_pid); */
if(gap_debug) fprintf(stderr, "DEBUG start 1.st Interactive call (_FROM values)\n");
l_idx = l_nlayers -1;
l_layer_id = p_get_indexed_layerid(image_id, &l_nlayers, l_idx, plugin_name);
if(l_layer_id < 0)
{
l_rc = -1;
}
else
{
if(gap_debug) fprintf(stderr, "DEBUG: apllying %s on Layerstack %d id=%d\n", plugin_name, (int)l_idx, (int)l_layer_id);
l_rc = p_call_plugin(plugin_name, image_id, l_layer_id, RUN_INTERACTIVE);
/* get values, then store with suffix "_ITER_FROM" */
l_plugin_data_len = p_get_data(plugin_name);
if(l_plugin_data_len > 0)
{
sprintf(l_key_from, "%s_ITER_FROM", plugin_name);
p_set_data(l_key_from, l_plugin_data_len);
}
else l_rc = -1;
if(run_mode == RUN_INTERACTIVE)
{
l_percentage += l_percentage_step;
gimp_progress_update (l_percentage);
}
}
}
/* else */
if((l_rc >= 0) && (l_nlayers > 1))
{
/* child process: call plugin Interactive for top layer [0] */
if(gap_debug) fprintf(stderr, "DEBUG start 2.nd Interactive call (_TO values)\n");
/* optional dialog between both calls (to see the effect of 1.call) */
if(p_pitstop(run_mode, plugin_name, 0,
l_step_backup_file, sizeof(l_step_backup_file), 0
)
< 0)
{
if(gap_debug) fprintf(stderr, "TERMINATED: by pitstop dialog\n");
/* restore the visibility of all layers */
p_visibilty_restore(image_id, l_nlayers, l_visible_tab, plugin_name);
free(l_visible_tab);
return -1;
}
else
{
l_layer_id = p_get_indexed_layerid(image_id, &l_nlayers, 0, plugin_name);
if(l_layer_id < 0)
{
l_rc = -1;
}
else
{
/* make _TO layer visible */
gimp_layer_set_visible(l_layer_id, TRUE);
p_gdisplays_update_full(image_id);
if(gap_debug) fprintf(stderr, "DEBUG: apllying %s on Layerstack 0 id=%d\n", plugin_name, (int)l_layer_id);
l_rc = p_call_plugin(plugin_name, image_id, l_layer_id, RUN_INTERACTIVE);
/* get values, then store with suffix "_ITER_TO" */
l_plugin_data_len = p_get_data(plugin_name);
if(l_plugin_data_len > 0)
{
sprintf(l_key_to, "%s_ITER_TO", plugin_name);
p_set_data(l_key_to, l_plugin_data_len);
}
else l_rc = -1;
if(run_mode == RUN_INTERACTIVE)
{
l_percentage += l_percentage_step;
gimp_progress_update (l_percentage);
}
/* if(gap_debug) fprintf(stderr, "DEBUG child process exit %d\n", (int)l_rc); */
/* exit(l_rc); */ /* end of childprocess */
}
}
}
l_top_layer = 1;
/* wait until exit of childprocess */
/* waitpid(l_child_pid, &l_status, 0); */
}
else
{
/* no iterator available, call plugin with constant values
* for each layer
*/
/* call plugin only ONCE Interactive for background layer[n] */
l_layer_id = p_get_indexed_layerid(image_id, &l_nlayers, l_nlayers -1, plugin_name);
if(l_layer_id < 0)
{
l_rc = -1;
}
else
{
if(gap_debug) fprintf(stderr, "DEBUG: NO Varying, apllying %s on Layer id=%d\n", plugin_name, (int)l_layer_id);
l_rc = p_call_plugin(plugin_name, image_id, l_layer_id, RUN_INTERACTIVE);
l_top_layer = 0;
if(run_mode == RUN_INTERACTIVE)
{
l_percentage += l_percentage_step;
gimp_progress_update (l_percentage);
}
}
}
if((l_rc >= 0) && (l_nlayers > 2))
{
/* call plugin foreach layer inbetween
* with runmode RUN_WITH_LAST_VALS
* and modify the last values
*/
l_pit_rc = 1;
for(l_idx = l_nlayers - 2; l_idx >= l_top_layer; l_idx--)
{
if(l_rc < 0) break;
if(l_pit_rc > 0) /* last pit_rc was a skip, so ask again for the next layer */
{
l_pit_rc = p_pitstop(run_mode, plugin_name, 1,
l_step_backup_file, sizeof(l_step_backup_file),
l_idx );
}
if(l_pit_rc < 0)
{
if(gap_debug) fprintf(stderr, "TERMINATED: by pitstop dialog\n");
l_rc = -1;
}
l_layer_id = p_get_indexed_layerid(image_id, &l_nlayers, l_idx, plugin_name);
if(l_layer_id < 0)
{
l_rc = -1;
break;
}
if(gap_debug) fprintf(stderr, "DEBUG: apllying %s on Layerstack %d id=%d\n", plugin_name, (int)l_idx, (int)l_layer_id);
if((l_plugin_iterator != NULL) && (apply_mode == PTYP_VARYING_LINEAR ))
{
/* call plugin-specific iterator, to modify
* the plugin's last_values
*/
if(gap_debug) fprintf(stderr, "DEBUG: calling iterator %s current step:%d\n",
l_plugin_iterator, (int)l_idx);
l_params = gimp_run_procedure (l_plugin_iterator,
&l_retvals,
PARAM_INT32, RUN_NONINTERACTIVE,
PARAM_INT32, l_nlayers -1, /* total steps */
PARAM_FLOAT, (gdouble)l_idx, /* current step */
PARAM_INT32, l_plugin_data_len, /* length of stored data struct */
PARAM_END);
if (l_params[0].data.d_status == FALSE)
{
fprintf(stderr, "ERROR: iterator %s failed\n", l_plugin_iterator);
l_rc = -1;
}
g_free(l_params);
}
if(l_rc < 0) break;
if(l_pit_rc == 0) /* 0 == continue without further dialogs */
{
/* call the plugin itself with runmode RUN_WITH_LAST_VALUES */
l_rc = p_call_plugin(plugin_name, image_id, l_layer_id, RUN_WITH_LAST_VALS);
/* check if to save each step to backup file */
if((l_step_backup_file[0] != '\0') && (l_step_backup_file[0] != ' '))
{
printf("Saving image to backupfile:%s step = %d\n",
l_step_backup_file, (int)l_idx);
p_save_xcf(image_id, l_step_backup_file);
}
}
if(run_mode == RUN_INTERACTIVE)
{
l_percentage += l_percentage_step;
gimp_progress_update (l_percentage);
}
} /* end for */
}
/* restore the visibility of all layers */
p_visibilty_restore(image_id, l_nlayers, l_visible_tab, plugin_name);
free(l_visible_tab);
}
}
if(l_plugin_iterator != NULL) free(l_plugin_iterator);
return l_rc;
} /* end p_foreach_multilayer */
/* ============================================================================
* gap_proc_anim_apply
* ============================================================================
*/
gint gap_proc_anim_apply(GRunModeType run_mode, gint32 image_id, char *plugin_name)
{
t_gap_db_browse_result l_browser_result;
t_apply_mode l_apply_mode;
l_apply_mode = PAPP_CONSTANT;
g_current_image_id = image_id;
if(run_mode == RUN_INTERACTIVE)
{
if(gap_db_browser_dialog("Select Filter for Animated apply",
"Apply Constant",
"Apply Varying",
p_constraint_proc,
p_constraint_proc_sel1,
p_constraint_proc_sel2,
&l_browser_result,
TRUE /* call gtk_init */
)
< 0)
{
if(gap_debug) fprintf(stderr, "DEBUG: gap_db_browser_dialog cancelled\n");
return -1;
}
p_arr_gtk_init(FALSE); /* disable the initial gtk_init in gap_arr_dialog's
* (gtk_init was done by the browser dialog)
*/
strcpy(plugin_name, l_browser_result.selected_proc_name);
if(l_browser_result.button_nr == 1) l_apply_mode = PTYP_VARYING_LINEAR;
if(gap_debug) fprintf(stderr, "DEBUG: gap_db_browser_dialog SELECTED:%s\n", plugin_name);
}
return(p_foreach_multilayer(run_mode,
image_id,
plugin_name,
l_apply_mode ));
}

View File

@ -0,0 +1,678 @@
/* gap_filter_iterators.c
*
* 1998.01.29 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* - Implementation of XXX_Iterator_ALT Procedures
* for those Plugins of the gimp.0.99.17 release
* - that can operate on a single drawable,
* - and have paramters for varying.
*
* for now i made some Iterator Plugins using the ending _ALT,
* If New plugins were added to the gimp, or existing ones were updated,
* the Authors should supply original _Iterator Procedures
* (without the _ALT ending)
* This Procedures are then used instead of my (Hacked _ALT) versions.
* to modify the settings for the plugin when called step by step
* on animated multilayer Images.
* without name conflicts.
*
* The 2.nd section of this file was generated by gap_filter_codegen.c:p_gen_code_iter_ALT
* using the PDB at version gimp 0.99.18 as base.
* Unforunately, some of the plugins are using datastructures
* to store their "Last Values"
* that are differnt from its calling parameters (as described in the PDB)
* Therfore I had to adjust (edit by hand) the generted structures to fit the
* plugins internal settings.
*
* Common things to all Iteratur Plugins:
* Interface: run_mode # is always RUN_NONINTERACTIVE
* total_steps # total number of handled layers (drawables)
* current_step # current layer (beginning wit 0)
* has type gdouble for later extensions
* to non-linear iterations.
* the iterator always computes linear inbetween steps,
* but the (central) caller may fake step 1.2345 in the future
* for logaritmic iterations or userdefined curves.
*
* Naming Convention:
* Iterators must have the name of the plugin (PDB proc_name), whose values
* are iterated, with Suffix
* "_Iterator" or
* "_Iterator_ALT" (if not provided within the original Plugin's sources)
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Change Log:
* 1999.03.14 hof: added iterators for gimp 1.1.3 prerelease
* iterator code reorganized in _iter_ALT.inc Files
* 1998.06.12 hof: added p_delta_drawable (Iterate layers in the layerstack)
* this enables to apply an animated bumpmap.
* 1998.01.29 hof: 1st release
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_filter.h"
#include "gap_filter_iterators.h"
static char g_plugin_data_from[PLUGIN_DATA_SIZE + 1];
static char g_plugin_data_to[PLUGIN_DATA_SIZE + 1];
extern int gap_debug;
typedef struct {
guchar color[3];
} t_color;
typedef struct {
gint color[3];
} t_gint_color;
/* ----------------------------------------------------------------------
* iterator functions for basic datatypes
* (were called from the generated procedures)
* ----------------------------------------------------------------------
*/
static void p_delta_long(long *val, long val_from, long val_to, gint32 total_steps, gdouble current_step)
{
double delta;
if(total_steps < 1) return;
delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);
*val = val_from + delta;
if(gap_debug) fprintf(stderr, "DEBUG: p_delta_long from: %ld to: %ld curr: %ld delta: %f\n",
val_from, val_to, *val, delta);
}
static void p_delta_short(short *val, short val_from, short val_to, gint32 total_steps, gdouble current_step)
{
double delta;
if(total_steps < 1) return;
delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);
*val = val_from + delta;
}
static void p_delta_gint(gint *val, gint val_from, gint val_to, gint32 total_steps, gdouble current_step)
{
double delta;
if(total_steps < 1) return;
delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);
*val = val_from + delta;
}
static void p_delta_char(char *val, char val_from, char val_to, gint32 total_steps, gdouble current_step)
{
double delta;
if(total_steps < 1) return;
delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);
*val = val_from + delta;
}
static void p_delta_guchar(guchar *val, char val_from, char val_to, gint32 total_steps, gdouble current_step)
{
double delta;
if(total_steps < 1) return;
delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);
*val = val_from + delta;
}
static void p_delta_gdouble(double *val, double val_from, double val_to, gint32 total_steps, gdouble current_step)
{
double delta;
if(total_steps < 1) return;
delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);
*val = val_from + delta;
if(gap_debug) fprintf(stderr, "DEBUG: p_delta_gdouble total: %d from: %f to: %f curr: %f delta: %f\n",
(int)total_steps, val_from, val_to, *val, delta);
}
static void p_delta_float(float *val, float val_from, float val_to, gint32 total_steps, gdouble current_step)
{
double delta;
if(total_steps < 1) return;
delta = ((double)(val_to - val_from) / (double)total_steps) * ((double)total_steps - current_step);
*val = val_from + delta;
if(gap_debug) fprintf(stderr, "DEBUG: p_delta_gdouble total: %d from: %f to: %f curr: %f delta: %f\n",
(int)total_steps, val_from, val_to, *val, delta);
}
static void p_delta_color(t_color *val, t_color *val_from, t_color *val_to, gint32 total_steps, gdouble current_step)
{
double delta;
int l_idx;
if(total_steps < 1) return;
for(l_idx = 0; l_idx < 3; l_idx++)
{
delta = ((double)(val_to->color[l_idx] - val_from->color[l_idx]) / (double)total_steps) * ((double)total_steps - current_step);
val->color[l_idx] = val_from->color[l_idx] + delta;
}
}
static void p_delta_gint_color(t_gint_color *val, t_gint_color *val_from, t_gint_color *val_to, gint32 total_steps, gdouble current_step)
{
double delta;
int l_idx;
if(total_steps < 1) return;
for(l_idx = 0; l_idx < 3; l_idx++)
{
delta = ((double)(val_to->color[l_idx] - val_from->color[l_idx]) / (double)total_steps) * ((double)total_steps - current_step);
val->color[l_idx] = val_from->color[l_idx] + delta;
}
}
static void p_delta_drawable(gint32 *val, gint32 val_from, gint32 val_to, gint32 total_steps, gdouble current_step)
{
gint l_nlayers;
gint32 *l_layers_list;
gint32 l_tmp_image_id;
gint l_idx, l_idx_from, l_idx_to;
if((val_from < 0) || (val_to < 0))
{
return;
}
l_tmp_image_id = gimp_drawable_image_id(val_from);
/* check if from and to values are both valid drawables within the same image */
if ((l_tmp_image_id > 0)
&& (l_tmp_image_id = gimp_drawable_image_id(val_to)))
{
l_idx_from = -1;
l_idx_to = -1;
/* check the layerstack index of from and to drawable */
l_layers_list = gimp_image_get_layers(l_tmp_image_id, &l_nlayers);
for (l_idx = l_nlayers -1; l_idx >= 0; l_idx--)
{
if( l_layers_list[l_idx] == val_from ) l_idx_from = l_idx;
if( l_layers_list[l_idx] == val_to ) l_idx_to = l_idx;
if((l_idx_from != -1) && (l_idx_to != -1))
{
/* OK found both index values, iterate the index (proceed to next layer) */
p_delta_gint(&l_idx, l_idx_from, l_idx_to, total_steps, current_step);
*val = l_layers_list[l_idx];
break;
}
}
g_free (l_layers_list);
}
}
/* ----------------------------------------------------------------------
* iterator UTILITIES for Gck Vectors, Material and Light Sewttings
* ----------------------------------------------------------------------
*/
typedef struct
{
double color[4]; /* r,g,b,a */
} t_GckRGB;
typedef struct
{
double coord[3]; /* x,y,z; */
} t_GckVector3;
typedef enum {
POINT_LIGHT,
DIRECTIONAL_LIGHT,
SPOT_LIGHT,
NO_LIGHT
} t_LightType;
typedef enum {
IMAGE_BUMP,
WAVES_BUMP
} t_MapType;
typedef struct
{
gdouble ambient_int;
gdouble diffuse_int;
gdouble diffuse_ref;
gdouble specular_ref;
gdouble highlight;
t_GckRGB color;
} t_MaterialSettings;
typedef struct
{
t_LightType type;
t_GckVector3 position;
t_GckVector3 direction;
t_GckRGB color;
gdouble intensity;
} t_LightSettings;
static void p_delta_GckRGB(t_GckRGB *val, t_GckRGB *val_from, t_GckRGB *val_to, gint32 total_steps, gdouble current_step)
{
double delta;
int l_idx;
if(total_steps < 1) return;
for(l_idx = 0; l_idx < 4; l_idx++)
{
delta = ((double)(val_to->color[l_idx] - val_from->color[l_idx]) / (double)total_steps) * ((double)total_steps - current_step);
val->color[l_idx] = val_from->color[l_idx] + delta;
}
}
static void p_delta_GckVector3(t_GckVector3 *val, t_GckVector3 *val_from, t_GckVector3 *val_to, gint32 total_steps, gdouble current_step)
{
double delta;
int l_idx;
if(total_steps < 1) return;
for(l_idx = 0; l_idx < 3; l_idx++)
{
delta = ((double)(val_to->coord[l_idx] - val_from->coord[l_idx]) / (double)total_steps) * ((double)total_steps - current_step);
val->coord[l_idx] = val_from->coord[l_idx] + delta;
}
}
static void p_delta_MaterialSettings(t_MaterialSettings *val, t_MaterialSettings *val_from, t_MaterialSettings *val_to, gint32 total_steps, gdouble current_step)
{
p_delta_gdouble(&val->ambient_int, val_from->ambient_int, val_to->ambient_int, total_steps, current_step);
p_delta_gdouble(&val->diffuse_int, val_from->diffuse_int, val_to->diffuse_int, total_steps, current_step);
p_delta_gdouble(&val->diffuse_ref, val_from->diffuse_ref, val_to->diffuse_ref, total_steps, current_step);
p_delta_gdouble(&val->specular_ref, val_from->specular_ref, val_to->specular_ref, total_steps, current_step);
p_delta_gdouble(&val->highlight, val_from->highlight, val_to->highlight, total_steps, current_step);
p_delta_GckRGB(&val->color, &val_from->color, &val_to->color, total_steps, current_step);
}
static void p_delta_LightSettings(t_LightSettings *val, t_LightSettings *val_from, t_LightSettings *val_to, gint32 total_steps, gdouble current_step)
{
/* no delta is done for LightType */
p_delta_GckVector3(&val->position, &val_from->position, &val_to->position, total_steps, current_step);
p_delta_GckVector3(&val->direction, &val_from->direction, &val_to->direction, total_steps, current_step);
p_delta_GckRGB(&val->color, &val_from->color, &val_to->color, total_steps, current_step);
p_delta_gdouble(&val->intensity, val_from->intensity, val_to->intensity, total_steps, current_step);
}
/* ---------------------------------------- 2.nd Section
* ----------------------------------------
* INCLUDE the generated p_XXX_iter_ALT procedures
* ----------------------------------------
* ----------------------------------------
*/
#include "iter_ALT/mod/plug_in_Twist_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_alienmap_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_applylens_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_blur_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_depth_merge_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_despeckle_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_emboss_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_exchange_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_lighting_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_map_object_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_maze_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_nlfilt_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_nova_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_oilify_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_pagecurl_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_plasma_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_polar_coords_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_sample_colorize_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_sinus_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_solid_noise_iter_ALT.inc"
#include "iter_ALT/mod/plug_in_sparkle_iter_ALT.inc"
#include "iter_ALT/old/Colorify_iter_ALT.inc"
#include "iter_ALT/old/plug_in_CentralReflection_iter_ALT.inc"
#include "iter_ALT/old/plug_in_anamorphose_iter_ALT.inc"
#include "iter_ALT/old/plug_in_blur2_iter_ALT.inc"
#include "iter_ALT/old/plug_in_encript_iter_ALT.inc"
#include "iter_ALT/old/plug_in_figures_iter_ALT.inc"
#include "iter_ALT/old/plug_in_gflare_iter_ALT.inc"
#include "iter_ALT/old/plug_in_holes_iter_ALT.inc"
#include "iter_ALT/old/plug_in_julia_iter_ALT.inc"
#include "iter_ALT/old/plug_in_magic_eye_iter_ALT.inc"
#include "iter_ALT/old/plug_in_mandelbrot_iter_ALT.inc"
#include "iter_ALT/old/plug_in_randomize_iter_ALT.inc"
#include "iter_ALT/old/plug_in_refract_iter_ALT.inc"
#include "iter_ALT/old/plug_in_struc_iter_ALT.inc"
#include "iter_ALT/old/plug_in_tileit_iter_ALT.inc"
#include "iter_ALT/old/plug_in_universal_filter_iter_ALT.inc"
#include "iter_ALT/old/plug_in_warp_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_CML_explorer_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_alpha2color_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_blinds_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_borderaverage_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_bump_map_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_checkerboard_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_color_map_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_colorify_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_convmatrix_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_cubism_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_destripe_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_diffraction_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_displace_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_edge_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_engrave_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_flame_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_flarefx_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_fractal_trace_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_gauss_iir_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_gauss_rle_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_gfig_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_glasstile_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_grid_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_jigsaw_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_make_seamless_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_mblur_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_mosaic_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_newsprint_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_noisify_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_paper_tile_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_pixelize_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_randomize_hurl_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_randomize_pick_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_randomize_slur_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_ripple_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_rotate_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_scatter_hsv_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_sharpen_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_shift_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_spread_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_video_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_vpropagate_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_waves_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_whirl_pinch_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_wind_iter_ALT.inc"
#include "iter_ALT/gen/plug_in_zealouscrop_iter_ALT.inc"
/* table of proc_names and funtion pointers to iter_ALT procedures */
/* del ... Deleted (does not make sense to animate)
* + ... generated code did not work (changed manually)
*/
static t_iter_ALT_tab g_iter_ALT_tab[] =
{
{ "Colorify", p_Colorify_iter_ALT }
/*, { "perl_fu_blowinout", p_perl_fu_blowinout_iter_ALT } */
/*, { "perl_fu_feedback", p_perl_fu_feedback_iter_ALT } */
/*, { "perl_fu_prep4gif", p_perl_fu_prep4gif_iter_ALT } */
/*, { "perl_fu_scratches", p_perl_fu_scratches_iter_ALT } */
/*, { "perl_fu_terraltext", p_perl_fu_terraltext_iter_ALT } */
/*, { "perl_fu_tex_string_to_float", p_perl_fu_tex_string_to_float_iter_ALT } */
/*, { "perl_fu_webify", p_perl_fu_webify_iter_ALT } */
/*, { "perl_fu_windify", p_perl_fu_windify_iter_ALT } */
/*, { "perl_fu_xach_blocks", p_perl_fu_xach_blocks_iter_ALT } */
/*, { "perl_fu_xach_shadows", p_perl_fu_xach_shadows_iter_ALT } */
/*, { "perl_fu_xachvision", p_perl_fu_xachvision_iter_ALT } */
, { "plug_in_CML_explorer", p_plug_in_CML_explorer_iter_ALT }
, { "plug_in_CentralReflection", p_plug_in_CentralReflection_iter_ALT }
, { "plug_in_Twist", p_plug_in_Twist_iter_ALT }
, { "plug_in_alienmap", p_plug_in_alienmap_iter_ALT }
/*, { "plug_in_align_layers", p_plug_in_align_layers_iter_ALT } */
, { "plug_in_alpha2color", p_plug_in_alpha2color_iter_ALT }
, { "plug_in_anamorphose", p_plug_in_anamorphose_iter_ALT }
/*, { "plug_in_animationoptimize", p_plug_in_animationoptimize_iter_ALT } */
/*, { "plug_in_animationplay", p_plug_in_animationplay_iter_ALT } */
/*, { "plug_in_animationunoptimize", p_plug_in_animationunoptimize_iter_ALT } */
/*, { "plug_in_apply_canvas", p_plug_in_apply_canvas_iter_ALT } */
, { "plug_in_applylens", p_plug_in_applylens_iter_ALT }
/*, { "plug_in_autocrop", p_plug_in_autocrop_iter_ALT } */
/*, { "plug_in_autostretch_hsv", p_plug_in_autostretch_hsv_iter_ALT } */
, { "plug_in_blinds", p_plug_in_blinds_iter_ALT }
, { "plug_in_blur", p_plug_in_blur_iter_ALT }
, { "plug_in_blur2", p_plug_in_blur2_iter_ALT }
/*, { "plug_in_blur_randomize", p_plug_in_blur_randomize_iter_ALT } */
, { "plug_in_borderaverage", p_plug_in_borderaverage_iter_ALT }
, { "plug_in_bump_map", p_plug_in_bump_map_iter_ALT }
/*, { "plug_in_c_astretch", p_plug_in_c_astretch_iter_ALT } */
, { "plug_in_checkerboard", p_plug_in_checkerboard_iter_ALT }
/*, { "plug_in_color_adjust", p_plug_in_color_adjust_iter_ALT } */
, { "plug_in_color_map", p_plug_in_color_map_iter_ALT }
/*, { "plug_in_colorify", p_plug_in_colorify_iter_ALT } */
/*, { "plug_in_compose", p_plug_in_compose_iter_ALT } */
, { "plug_in_convmatrix", p_plug_in_convmatrix_iter_ALT }
, { "plug_in_cubism", p_plug_in_cubism_iter_ALT }
/*, { "plug_in_decompose", p_plug_in_decompose_iter_ALT } */
/*, { "plug_in_deinterlace", p_plug_in_deinterlace_iter_ALT } */
, { "plug_in_depth_merge", p_plug_in_depth_merge_iter_ALT }
, { "plug_in_despeckle", p_plug_in_despeckle_iter_ALT }
, { "plug_in_destripe", p_plug_in_destripe_iter_ALT }
, { "plug_in_diffraction", p_plug_in_diffraction_iter_ALT }
, { "plug_in_displace", p_plug_in_displace_iter_ALT }
/*, { "plug_in_ditherize", p_plug_in_ditherize_iter_ALT } */
, { "plug_in_edge", p_plug_in_edge_iter_ALT }
, { "plug_in_emboss", p_plug_in_emboss_iter_ALT }
, { "plug_in_encript", p_plug_in_encript_iter_ALT }
, { "plug_in_engrave", p_plug_in_engrave_iter_ALT }
, { "plug_in_exchange", p_plug_in_exchange_iter_ALT }
/*, { "plug_in_export_palette", p_plug_in_export_palette_iter_ALT } */
, { "plug_in_figures", p_plug_in_figures_iter_ALT }
/*, { "plug_in_film", p_plug_in_film_iter_ALT } */
/*, { "plug_in_filter_pack", p_plug_in_filter_pack_iter_ALT } */
, { "plug_in_flame", p_plug_in_flame_iter_ALT }
, { "plug_in_flarefx", p_plug_in_flarefx_iter_ALT }
, { "plug_in_fractal_trace", p_plug_in_fractal_trace_iter_ALT }
, { "plug_in_gauss_iir", p_plug_in_gauss_iir_iter_ALT }
, { "plug_in_gauss_rle", p_plug_in_gauss_rle_iter_ALT }
, { "plug_in_gfig", p_plug_in_gfig_iter_ALT }
, { "plug_in_gflare", p_plug_in_gflare_iter_ALT }
, { "plug_in_glasstile", p_plug_in_glasstile_iter_ALT }
/*, { "plug_in_gradmap", p_plug_in_gradmap_iter_ALT } */
, { "plug_in_grid", p_plug_in_grid_iter_ALT }
/*, { "plug_in_guillotine", p_plug_in_guillotine_iter_ALT } */
, { "plug_in_holes", p_plug_in_holes_iter_ALT }
/*, { "plug_in_hot", p_plug_in_hot_iter_ALT } */
/*, { "plug_in_ifs_compose", p_plug_in_ifs_compose_iter_ALT } */
/*, { "plug_in_illusion", p_plug_in_illusion_iter_ALT } */
/*, { "plug_in_image_rot270", p_plug_in_image_rot270_iter_ALT } */
/*, { "plug_in_image_rot90", p_plug_in_image_rot90_iter_ALT } */
/*, { "plug_in_iwarp", p_plug_in_iwarp_iter_ALT } */
, { "plug_in_jigsaw", p_plug_in_jigsaw_iter_ALT }
, { "plug_in_julia", p_plug_in_julia_iter_ALT }
/*, { "plug_in_laplace", p_plug_in_laplace_iter_ALT } */
/*, { "plug_in_layer_rot270", p_plug_in_layer_rot270_iter_ALT } */
/*, { "plug_in_layer_rot90", p_plug_in_layer_rot90_iter_ALT } */
/*, { "plug_in_layers_import", p_plug_in_layers_import_iter_ALT } */
/*, { "plug_in_lic", p_plug_in_lic_iter_ALT } */
, { "plug_in_lighting", p_plug_in_lighting_iter_ALT }
, { "plug_in_magic_eye", p_plug_in_magic_eye_iter_ALT }
/*, { "plug_in_mail_image", p_plug_in_mail_image_iter_ALT } */
, { "plug_in_make_seamless", p_plug_in_make_seamless_iter_ALT }
, { "plug_in_mandelbrot", p_plug_in_mandelbrot_iter_ALT }
, { "plug_in_map_object", p_plug_in_map_object_iter_ALT }
/*, { "plug_in_max_rgb", p_plug_in_max_rgb_iter_ALT } */
, { "plug_in_maze", p_plug_in_maze_iter_ALT }
, { "plug_in_mblur", p_plug_in_mblur_iter_ALT }
, { "plug_in_mosaic", p_plug_in_mosaic_iter_ALT }
, { "plug_in_newsprint", p_plug_in_newsprint_iter_ALT }
, { "plug_in_nlfilt", p_plug_in_nlfilt_iter_ALT }
, { "plug_in_noisify", p_plug_in_noisify_iter_ALT }
/*, { "plug_in_normalize", p_plug_in_normalize_iter_ALT } */
, { "plug_in_nova", p_plug_in_nova_iter_ALT }
, { "plug_in_oilify", p_plug_in_oilify_iter_ALT }
, { "plug_in_pagecurl", p_plug_in_pagecurl_iter_ALT }
, { "plug_in_paper_tile", p_plug_in_paper_tile_iter_ALT }
, { "plug_in_pixelize", p_plug_in_pixelize_iter_ALT }
, { "plug_in_plasma", p_plug_in_plasma_iter_ALT }
, { "plug_in_polar_coords", p_plug_in_polar_coords_iter_ALT }
/*, { "plug_in_qbist", p_plug_in_qbist_iter_ALT } */
, { "plug_in_randomize", p_plug_in_randomize_iter_ALT }
, { "plug_in_randomize_hurl", p_plug_in_randomize_hurl_iter_ALT }
, { "plug_in_randomize_pick", p_plug_in_randomize_pick_iter_ALT }
, { "plug_in_randomize_slur", p_plug_in_randomize_slur_iter_ALT }
, { "plug_in_refract", p_plug_in_refract_iter_ALT }
, { "plug_in_ripple", p_plug_in_ripple_iter_ALT }
, { "plug_in_rotate", p_plug_in_rotate_iter_ALT }
, { "plug_in_sample_colorize", p_plug_in_sample_colorize_iter_ALT }
, { "plug_in_scatter_hsv", p_plug_in_scatter_hsv_iter_ALT }
/*, { "plug_in_semiflatten", p_plug_in_semiflatten_iter_ALT } */
, { "plug_in_sharpen", p_plug_in_sharpen_iter_ALT }
, { "plug_in_shift", p_plug_in_shift_iter_ALT }
, { "plug_in_sinus", p_plug_in_sinus_iter_ALT }
/*, { "plug_in_small_tiles", p_plug_in_small_tiles_iter_ALT } */
/*, { "plug_in_smooth_palette", p_plug_in_smooth_palette_iter_ALT } */
/*, { "plug_in_sobel", p_plug_in_sobel_iter_ALT } */
, { "plug_in_solid_noise", p_plug_in_solid_noise_iter_ALT }
, { "plug_in_sparkle", p_plug_in_sparkle_iter_ALT }
, { "plug_in_spread", p_plug_in_spread_iter_ALT }
, { "plug_in_struc", p_plug_in_struc_iter_ALT }
/*, { "plug_in_the_egg", p_plug_in_the_egg_iter_ALT } */
/*, { "plug_in_threshold_alpha", p_plug_in_threshold_alpha_iter_ALT } */
/*, { "plug_in_tile", p_plug_in_tile_iter_ALT } */
, { "plug_in_tileit", p_plug_in_tileit_iter_ALT }
, { "plug_in_universal_filter", p_plug_in_universal_filter_iter_ALT }
, { "plug_in_video", p_plug_in_video_iter_ALT }
/*, { "plug_in_vinvert", p_plug_in_vinvert_iter_ALT } */
, { "plug_in_vpropagate", p_plug_in_vpropagate_iter_ALT }
, { "plug_in_warp", p_plug_in_warp_iter_ALT }
, { "plug_in_waves", p_plug_in_waves_iter_ALT }
, { "plug_in_whirl_pinch", p_plug_in_whirl_pinch_iter_ALT }
, { "plug_in_wind", p_plug_in_wind_iter_ALT }
/*, { "plug_in_zealouscrop", p_plug_in_zealouscrop_iter_ALT } */
}; /* end g_iter_ALT_tab */
#define MAX_ITER_ALT ( sizeof(g_iter_ALT_tab) / sizeof(t_iter_ALT_tab) )
/* ----------------------------------------------------------------------
* install (query) iterators_ALT
* ----------------------------------------------------------------------
*/
static void p_install_proc_iter_ALT(char *name)
{
char l_iter_proc_name[256];
char l_blurb_text[300];
static GParamDef args_iter[] =
{
{PARAM_INT32, "run_mode", "non-interactive"},
{PARAM_INT32, "total_steps", "total number of steps (# of layers-1 to apply the related plug-in)"},
{PARAM_FLOAT, "current_step", "current (for linear iterations this is the layerstack position, otherwise some value inbetween)"},
{PARAM_INT32, "len_struct", "length of stored data structure with id is equal to the plug_in proc_name"},
};
static int nargs_iter = sizeof(args_iter) / sizeof(args_iter[0]);
static GParamDef *return_vals = NULL;
static int nreturn_vals = 0;
sprintf(l_iter_proc_name, "%s_Iterator_ALT", name);
sprintf(l_blurb_text, "This extension calculates the modified values for one iterationstep for the call of %s", name);
gimp_install_procedure(l_iter_proc_name,
l_blurb_text,
"",
"Wolfgang Hofer",
"Wolfgang Hofer",
"Dec. 1997",
NULL, /* do not appear in menus */
NULL,
PROC_EXTENSION,
nargs_iter, nreturn_vals,
args_iter, return_vals);
}
void gap_query_iterators_ALT()
{
int l_idx;
for(l_idx = 0; l_idx < MAX_ITER_ALT; l_idx++)
{
p_install_proc_iter_ALT (g_iter_ALT_tab[l_idx].proc_name);
}
}
/* ----------------------------------------------------------------------
* run iterators_ALT
* ----------------------------------------------------------------------
*/
gint gap_run_iterators_ALT(char *name, GRunModeType run_mode, gint32 total_steps, gdouble current_step, gint32 len_struct)
{
gint l_rc;
int l_idx;
char *l_name;
int l_cut;
l_name = g_strdup(name);
l_cut = strlen(l_name) - strlen("_Iterator_ALT");
if(l_cut < 1)
{
fprintf(stderr, "ERROR: gap_run_iterators_ALT: proc_name ending _Iterator_ALT missing%s\n", name);
return -1;
}
if(strcmp(&l_name[l_cut], "_Iterator_ALT") != 0)
{
fprintf(stderr, "ERROR: gap_run_iterators_ALT: proc_name ending _Iterator_ALT missing%s\n", name);
return -1;
}
l_name[l_cut] = '\0'; /* cut off "_Iterator_ALT" from l_name end */
l_rc = -1;
for(l_idx = 0; l_idx < MAX_ITER_ALT; l_idx++)
{
if (strcmp (l_name, g_iter_ALT_tab[l_idx].proc_name) == 0)
{
if(gap_debug) fprintf(stderr, "DEBUG: gap_run_iterators_ALT: FOUND %s\n", l_name);
l_rc = (g_iter_ALT_tab[l_idx].proc_func)(run_mode, total_steps, current_step, len_struct);
}
}
if(l_rc < 0) fprintf(stderr, "ERROR: gap_run_iterators_ALT: NOT FOUND proc_name=%s (%s)\n", name, l_name);
return l_rc;
}

View File

@ -0,0 +1,50 @@
/* gap_filter_iterators.h
*
* 1997.12.18 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* - Headers for XXX_Iterator_ALT Procedures
*
* for now i made some Iterator Plugins using the ending _ALT,
* If New plugins were added to the gimp, or existing ones were updated,
* the Authors should supply original _Iterator Procedures
* (without the _ALT ending)
* This Procedures are then used instead of my (Hacked _ALT) versions.
* to modify the settings for the plugin when called step by step
* on animated multilayer Images.
* without name conflicts.
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _GAP_FILTER_ITERATORS_H
#define _GAP_FILTER_ITERATORS_H
typedef gint (*t_iter_ALT_func) (GRunModeType run_mode, gint32 total_steps, gdouble current_step, gint32 len_struct);
typedef struct t_iter_ALT_tab
{
char *proc_name;
t_iter_ALT_func proc_func;
} t_iter_ALT_tab;
#endif

View File

@ -0,0 +1,205 @@
/* gap_filter_main.c
* 1997.12.18 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* - MAIN of GAP_filter foreach: call any Filter (==Plugin Proc)
* with varying settings for all
* layers within one Image.
* - query registration of gap_foreach Procedure
* and for all Iterator_ALT Procedures
* - run invoke the gap_foreach procedure by its PDB name
*
*
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_filter.h"
static char *gap_filter_version = "0.92.00; 1998/01/16";
/* revision history:
* version 0.92.00 hof: set gap_debug from environment
* version 0.91.01; Tue Dec 23 hof: 1.st (pre) release
*/
/* ------------------------
* global gap DEBUG switch
* ------------------------
*/
/* int gap_debug = 1; */ /* print debug infos */
/* int gap_debug = 0; */ /* 0: dont print debug infos */
int gap_debug = 0;
static void query(void);
static void run(char *name, int nparam, GParam *param,
int *nretvals, GParam **retvals);
GPlugInInfo PLUG_IN_INFO =
{
NULL, /* init_proc */
NULL, /* quit_proc */
query, /* query_proc */
run, /* run_proc */
};
MAIN ()
static void
query ()
{
static GParamDef args_foreach[] =
{
{PARAM_INT32, "run_mode", "Interactive, non-interactive"},
{PARAM_IMAGE, "image", "Input image"},
{PARAM_DRAWABLE, "drawable", "Input drawable (unused)"},
{PARAM_STRING, "proc_name", "name of plugin procedure to run for each layer)"},
};
static int nargs_foreach = sizeof(args_foreach) / sizeof(args_foreach[0]);
static GParamDef *return_vals = NULL;
static int nreturn_vals = 0;
gimp_install_procedure("plug_in_gap_layers_run_animfilter",
"This plugin calls another plugin for each layer of an image, varying its settings (to produce animated effects). The called plugin must work on a single drawable and must be able to RUN_WITH_LAST_VALS",
"",
"Wolfgang Hofer (hof@hotbot.com)",
"Wolfgang Hofer",
gap_filter_version,
"<Image>/Filters/Animation/Filter all Layers",
"RGB*, INDEXED*, GRAY*",
PROC_PLUG_IN,
nargs_foreach, nreturn_vals,
args_foreach, return_vals);
/* ------------------ ALTernative Iterators ------------------------------ */
gap_query_iterators_ALT();
} /* end query */
static void
run (char *name,
int n_params,
GParam *param,
int *nreturn_vals,
GParam **return_vals)
{
#define MAX_PLUGIN_NAME_LEN 256
char l_plugin_name[MAX_PLUGIN_NAME_LEN];
static GParam values[1];
GRunModeType run_mode;
GStatusType status = STATUS_SUCCESS;
gint32 image_id;
gint32 len_struct;
gint32 total_steps;
gdouble current_step;
gint32 l_rc;
char *l_env;
*nreturn_vals = 1;
*return_vals = values;
l_rc = 0;
l_env = getenv("GAP_DEBUG");
if(l_env != NULL)
{
if((*l_env != 'n') && (*l_env != 'N')) gap_debug = 1;
}
run_mode = param[0].data.d_int32;
if(gap_debug) fprintf(stderr, "\n\ngap_filter_main: debug name = %s\n", name);
if (strcmp (name, "plug_in_gap_layers_run_animfilter") == 0)
{
if (run_mode == RUN_NONINTERACTIVE)
{
if (n_params != 4)
{
status = STATUS_CALLING_ERROR;
}
else
{
strncpy(l_plugin_name, param[3].data.d_string, MAX_PLUGIN_NAME_LEN -1);
l_plugin_name[MAX_PLUGIN_NAME_LEN -1] = '\0';
}
}
else if(run_mode == RUN_WITH_LAST_VALS)
{
/* probably get last values (name of last plugin) */
gimp_get_data("plug_in_gap_layers_run_animfilter", l_plugin_name);
}
if (status == STATUS_SUCCESS)
{
image_id = param[1].data.d_image;
l_rc = gap_proc_anim_apply(run_mode, image_id, l_plugin_name);
gimp_set_data("plug_in_gap_layers_run_animfilter", l_plugin_name, sizeof(l_plugin_name));
}
}
else
{
if ((run_mode == RUN_NONINTERACTIVE) && (n_params == 4))
{
total_steps = param[1].data.d_int32;
current_step = param[2].data.d_float;
len_struct = param[3].data.d_int32;
l_rc = gap_run_iterators_ALT(name, run_mode, total_steps, current_step, len_struct);
}
else status = STATUS_CALLING_ERROR;
}
if(l_rc < 0)
{
status = STATUS_EXECUTION_ERROR;
}
if (run_mode != RUN_NONINTERACTIVE)
gimp_displays_flush();
values[0].type = PARAM_STATUS;
values[0].data.d_status = status;
}

View File

@ -0,0 +1,489 @@
/* gap_filter_pdb.c
* 1998.10.14 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* - GAP_filter pdb: functions for calling any Filter (==Plugin Proc)
* that operates on a drawable
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.97.00 hof: - created module (as extract gap_filter_foreach)
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_arr_dialog.h"
#include "gap_filter.h"
#include "gap_filter_pdb.h"
#include "gap_lib.h"
/* ------------------------
* global gap DEBUG switch
* ------------------------
*/
/* int gap_debug = 1; */ /* print debug infos */
/* int gap_debug = 0; */ /* 0: dont print debug infos */
extern int gap_debug;
static char g_plugin_data[PLUGIN_DATA_SIZE + 1];
static gint32 g_current_image_id;
gint p_call_plugin(char *plugin_name, gint32 image_id, gint32 layer_id, GRunModeType run_mode)
{
GDrawable *l_drawable;
GParam *l_ret_params;
GParam *l_argv;
gint l_retvals;
int l_idx;
int l_nparams;
int l_nreturn_vals;
int l_proc_type;
char *l_proc_blurb;
char *l_proc_help;
char *l_proc_author;
char *l_proc_copyright;
char *l_proc_date;
GParamDef *l_params;
GParamDef *l_return_vals;
l_drawable = gimp_drawable_get(layer_id); /* use the background layer */
/* query for plugin_name to get its argument types */
if (FALSE == gimp_query_procedure (plugin_name,
&l_proc_blurb,
&l_proc_help,
&l_proc_author,
&l_proc_copyright,
&l_proc_date,
&l_proc_type,
&l_nparams,
&l_nreturn_vals,
&l_params,
&l_return_vals))
{
fprintf(stderr, "ERROR: Plugin not available, Name was %s\n", plugin_name);
return -1;
}
/* construct the procedures arguments */
l_argv = g_new (GParam, l_nparams);
memset (l_argv, 0, (sizeof (GParam) * l_nparams));
/* initialize the argument types */
for (l_idx = 0; l_idx < l_nparams; l_idx++)
{
l_argv[l_idx].type = l_params[l_idx].type;
switch(l_params[l_idx].type)
{
case PARAM_DISPLAY:
l_argv[l_idx].data.d_display = -1;
break;
case PARAM_DRAWABLE:
case PARAM_LAYER:
case PARAM_CHANNEL:
l_argv[l_idx].data.d_drawable = -1;
break;
case PARAM_IMAGE:
l_argv[l_idx].data.d_image = -1;
break;
case PARAM_INT32:
case PARAM_INT16:
case PARAM_INT8:
l_argv[l_idx].data.d_int32 = 0;
break;
case PARAM_FLOAT:
l_argv[l_idx].data.d_float = 0.0;
break;
case PARAM_STRING:
l_argv[l_idx].data.d_string = NULL;
break;
default:
l_argv[l_idx].data.d_int32 = 0;
break;
}
}
/* init the standard parameters, that should be common to all plugins */
l_argv[0].data.d_int32 = run_mode;
l_argv[1].data.d_image = image_id;
l_argv[2].data.d_drawable = l_drawable->id;
/* run the plug-in procedure */
l_ret_params = gimp_run_procedure2 (plugin_name, &l_retvals, l_nparams, l_argv);
/* free up arguments and values */
g_free (l_argv);
/* free the query information */
g_free (l_proc_blurb);
g_free (l_proc_help);
g_free (l_proc_author);
g_free (l_proc_copyright);
g_free (l_proc_date);
g_free (l_params);
g_free (l_return_vals);
if (l_ret_params[0].data.d_status == FALSE)
{
fprintf(stderr, "ERROR: p_call_plugin %s failed.\n", plugin_name);
g_free(l_ret_params);
return -1;
}
else
{
if(gap_debug) fprintf(stderr, "DEBUG: p_call_plugin: %s successful.\n", plugin_name);
g_free(l_ret_params);
return 0;
}
}
int
p_save_xcf(gint32 image_id, char *sav_name)
{
GParam* l_params;
gint l_retvals;
/* save current image as xcf file
* xcf_save does operate on the complete image,
* the drawable is ignored. (we can supply a dummy value)
*/
l_params = gimp_run_procedure ("gimp_xcf_save",
&l_retvals,
PARAM_INT32, RUN_NONINTERACTIVE,
PARAM_IMAGE, image_id,
PARAM_DRAWABLE, 0,
PARAM_STRING, sav_name,
PARAM_STRING, sav_name, /* raw name ? */
PARAM_END);
if (l_params[0].data.d_status == FALSE) return(-1);
return 0;
}
/* ============================================================================
* p_get_data
* try to get the plugin's data (key is usually the name of the plugin)
* and check for the length of the retrieved data.
* if all done OK return the length of the retrieved data,
* return -1 in case of errors.
*
* RISK: this procedure may crash if the retrieved data
* is longer than PLUGIN_DATA_SIZE and gimp_get_data_size
* is not available
* (there was no way for a plugin to findout the length
* in older GIMP releases)
* ============================================================================
*/
gint p_get_data(char *key)
{
int l_len;
#ifdef GIMP_HAVE_PROCEDURAL_DB_GET_DATA_SIZE
l_len = gimp_get_data_size (key);
if(l_len >= PLUGIN_DATA_SIZE)
{
fprintf(stderr, "ERROR: stored data too big Key %s (%d > %d)\n",
key, (int)l_len, (int)PLUGIN_DATA_SIZE);
return -1;
}
gimp_get_data(key, g_plugin_data);
#else
{
int l_l1, l_l2;
memset(g_plugin_data, 'X', PLUGIN_DATA_SIZE);
gimp_get_data(key, g_plugin_data);
for(l_l1 = PLUGIN_DATA_SIZE -1; l_l1 >= 0; l_l1--)
{
if (g_plugin_data[l_l1] != 'X' )
break;
}
memset(g_plugin_data, '\0', PLUGIN_DATA_SIZE);
gimp_get_data(key, g_plugin_data);
for(l_l2 = PLUGIN_DATA_SIZE -1; l_l2 >= 0; l_l2--)
{
if (g_plugin_data[l_l2] != '\0' )
break;
}
if(l_l1 > l_l2) l_len = l_l1;
else l_len = l_l2;
l_len++; /* length is index of last valid byte + 1 */
}
#endif
if(l_len < 1)
{
fprintf(stderr, "ERROR: no stored data found for Key %s\n", key);
return -1;
}
if(gap_debug) fprintf(stderr, "DEBUG p_get_data Key:%s retrieved bytes %d\n", key, (int)l_len);
return (l_len);
}
/* ============================================================================
* p_set_data
*
* set g_plugin_data
* ============================================================================
*/
void p_set_data(char *key, gint plugin_data_len)
{
gimp_set_data(key, g_plugin_data, plugin_data_len);
}
/* ============================================================================
* p_procedure_available
* ============================================================================
*/
gint p_procedure_available(char *proc_name, t_proc_type ptype)
{
int l_nparams;
int l_nreturn_vals;
int l_proc_type;
char *l_proc_blurb;
char *l_proc_help;
char *l_proc_author;
char *l_proc_copyright;
char *l_proc_date;
GParamDef *l_params;
GParamDef *l_return_vals;
gint l_rc;
l_rc = 0;
/* Query the gimp application's procedural database
* regarding a particular procedure.
*/
if(gimp_query_procedure (proc_name,
&l_proc_blurb,
&l_proc_help,
&l_proc_author,
&l_proc_copyright,
&l_proc_date,
&l_proc_type,
&l_nparams,
&l_nreturn_vals,
&l_params,
&l_return_vals))
{
/* procedure found in PDB */
if(gap_debug) fprintf(stderr, "DEBUG: found in PDB %s\n", proc_name);
switch(ptype)
{
case PTYP_ITERATOR:
/* check exactly for Input Parametertypes (common to all Iterators) */
if (l_proc_type != PROC_EXTENSION ) { l_rc = -1; break; }
if (l_nparams != 4) { l_rc = -1; break; }
if (l_params[0].type != PARAM_INT32) { l_rc = -1; break; }
if (l_params[1].type != PARAM_INT32) { l_rc = -1; break; }
if (l_params[2].type != PARAM_FLOAT) { l_rc = -1; break; }
if (l_params[3].type != PARAM_INT32) { l_rc = -1; break; }
break;
case PTYP_CAN_OPERATE_ON_DRAWABLE:
/* check if plugin can be a typical one, that works on one drawable */
if (l_proc_type != PROC_PLUG_IN) { l_rc = -1; break; }
if (l_nparams < 3) { l_rc = -1; break; }
if (l_params[0].type != PARAM_INT32) { l_rc = -1; break; }
if (l_params[1].type != PARAM_IMAGE) { l_rc = -1; break; }
if (l_params[2].type != PARAM_DRAWABLE) { l_rc = -1; break; }
break;
default:
break;
}
/* free the query information */
g_free (l_proc_blurb);
g_free (l_proc_help);
g_free (l_proc_author);
g_free (l_proc_copyright);
g_free (l_proc_date);
g_free (l_params);
g_free (l_return_vals);
}
else
{
return -1;
}
return l_rc;
} /* end p_procedure_available */
/* ============================================================================
* p_get_iterator_proc
* check the PDB for Iterator Procedures (suffix "_Iterator" or "_Iterator_ALT"
* return Pointer to the name of the Iterator Procedure
* or NULL if not found (or malloc error)
* ============================================================================
*/
char * p_get_iterator_proc(char *plugin_name)
{
char *l_plugin_iterator;
/* check for matching Iterator PluginProcedures */
l_plugin_iterator = malloc(strlen(plugin_name) + strlen("_Iterator_ALT") +2);
if(l_plugin_iterator != NULL)
{
sprintf(l_plugin_iterator, "%s_Iterator", plugin_name);
/* check if iterator is available in PDB */
if(p_procedure_available(l_plugin_iterator, PTYP_ITERATOR) < 0)
{
sprintf(l_plugin_iterator, "%s_Iterator_ALT", plugin_name);
/* check for alternative Iterator _Iterator_ALT
* for now i made some Iterator Plugins using the ending _ALT,
* If New plugins were added or existing ones were updated
* the Authors should supply original _Iterator Procedures
* to be used instead of my Hacked versions without name conflicts.
*/
if(p_procedure_available(l_plugin_iterator, PTYP_ITERATOR) < 0)
{
/* both iterator names are not available */
free(l_plugin_iterator);
l_plugin_iterator = NULL;
}
}
}
return (l_plugin_iterator);
} /* end p_get_iterator_proc */
/* ============================================================================
* constraint procedures
*
* aer responsible for:
* - sensitivity of the dbbrowser's Apply Buttons
* - filter for dbbrowser's listbox
* ============================================================================
*/
int p_constraint_proc_sel1(gchar *proc_name)
{
int l_rc;
GImageType l_base_type;
/* here we should check, if proc_name
* can operate on the current Imagetype (RGB, INDEXED, GRAY)
* if not, 0 should be returned.
*
* I did not find a way to do this with the PDB Interface of gimp 0.99.16
*/
return 1;
l_rc = 0; /* 0 .. set Apply Button in_sensitive */
l_base_type =gimp_image_base_type(g_current_image_id);
switch(l_base_type)
{
case RGB:
case GRAY:
case INDEXED:
l_rc = 1;
break;
}
return l_rc;
}
int p_constraint_proc_sel2(gchar *proc_name)
{
char *l_plugin_iterator;
int l_rc;
l_rc = p_constraint_proc_sel1(proc_name);
if(l_rc != 0)
{
l_plugin_iterator = p_get_iterator_proc(proc_name);
if(l_plugin_iterator != NULL)
{
free(l_plugin_iterator);
return 1; /* 1 .. set "Apply Varying" Button sensitive */
}
}
return 0; /* 0 .. set "Apply Varying" Button in_sensitive */
}
int p_constraint_proc(gchar *proc_name)
{
int l_rc;
if(strncmp(proc_name, "file", 4) == 0)
{
/* Do not add file Plugins (check if name starts with "file") */
return 0;
}
if(strncmp(proc_name, "plug_in_gap_", 12) == 0)
{
/* Do not add GAP Plugins (check if name starts with "plug_in_gap_") */
return 0;
}
l_rc = p_procedure_available(proc_name, PTYP_CAN_OPERATE_ON_DRAWABLE);
if(l_rc < 0)
{
/* Do not add, Plugin not available or wrong type */
return 0;
}
return 1; /* 1 add the plugin procedure */
}

View File

@ -0,0 +1,64 @@
/* gap_filter_pdb.h
*
* GAP ... Gimp Animation Plugins
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _GAP_FILTER_PDB_H
#define _GAP_FILTER_PDB_H
#include "libgimp/gimp.h"
/* max buffer size for plugin' stored valus
*/
#define PLUGIN_DATA_SIZE 8192
typedef enum
{ PTYP_ANY = 0,
PTYP_ITERATOR = 1,
PTYP_CAN_OPERATE_ON_DRAWABLE = 2
} t_proc_type;
typedef enum
{ PAPP_CONSTANT = 0,
PTYP_VARYING_LINEAR = 1
} t_apply_mode;
/* ------------------------
* gap_filter_pdb.h
* ------------------------
*/
gint p_call_plugin(char *plugin_name, gint32 image_id, gint32 layer_id, GRunModeType run_mode);
int p_save_xcf(gint32 image_id, char *sav_name);
gint p_get_data(char *key);
void p_set_data(char *key, gint plugin_data_len);
gint p_procedure_available(char *proc_name, t_proc_type ptype);
char * p_get_iterator_proc(char *plugin_name);
int p_constraint_proc_sel1(gchar *proc_name);
int p_constraint_proc_sel2(gchar *proc_name);
int p_constraint_proc(gchar *proc_name);
#endif

View File

@ -0,0 +1,162 @@
/* gap_layer_copy.c
* by hof (Wolfgang Hofer)
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.99.00 1999.03.03 hof: use the regular gimp_layer_copy and gimp_channel_copy
* (removed private variant)
* version 0.98.00 1998.11.26 hof: added channel copy
* version 1998.11.26 hof: bugfix have to copy the layer's layer_mask too.
* type check of destination image
* version 0.96.00 hof: bugfix memory leak (must set src_tile to unref after use)
* version 0.93.01 hof: when creating the destination layer
* add alpha channel if needed in extra call
* version 0.90.00; hof: 1.st (pre) release
*/
/* SYTEM (UNIX) includes */
/* GIMP includes */
/* GAP includes */
#include "gap_layer_copy.h"
#include "gap_pdb_calls.h"
extern int gap_debug; /* ==0 ... dont print debug infos */
/* ============================================================================
* p_my_layer_copy
* copy src_layer to the dst_image,
* return the id of the new created layer (the copy)
* NOTE: source layer MUST have same type (bpp) for now
* it would be fine to extend the code to convert between any type
* ============================================================================
*/
gint32 p_my_layer_copy (gint32 dst_image_id,
gint32 src_layer_id,
gdouble opacity, /* 0.0 upto 100.0 */
GLayerMode mode,
gint *src_offset_x,
gint *src_offset_y )
{
gint32 l_new_layer_id;
gint32 l_ret_id;
char *l_name;
GDrawableType l_src_type;
if(gap_debug) printf("GAP p_my_layer_copy: START\n");
l_ret_id = -1; /* prepare error retcode -1 */
l_name = NULL;
if(opacity > 99.99) opacity = 100.0;
if(opacity < 0.0) opacity = 0.0;
l_name = gimp_layer_get_name(src_layer_id);
l_src_type = gimp_layer_type(src_layer_id);
switch(l_src_type)
{
case RGB_IMAGE: /* 0 */
case RGBA_IMAGE: /* 1 */
if(gimp_image_base_type(dst_image_id) != RGB) { return -1; }
break;
case GRAY_IMAGE: /* 2 */
case GRAYA_IMAGE: /* 3 */
if(gimp_image_base_type(dst_image_id) != GRAY) { return -1; }
break;
case INDEXED_IMAGE: /* 4 */
case INDEXEDA_IMAGE: /* 5 */
if(gimp_image_base_type(dst_image_id) != INDEXED) { return -1; }
break;
}
/* copy the layer */
l_new_layer_id = gimp_layer_copy(src_layer_id);
if(l_new_layer_id >= 0)
{
if(p_gimp_drawable_set_image(l_new_layer_id, dst_image_id) >= 0)
{
if(! gimp_drawable_has_alpha(l_new_layer_id))
{
/* have to add alpha channel */
gimp_layer_add_alpha(l_new_layer_id);
}
/* findout the offsets of the original layer within the source Image */
gimp_drawable_offsets(src_layer_id, src_offset_x, src_offset_y );
gimp_layer_set_name(l_new_layer_id, l_name);
gimp_layer_set_opacity(l_new_layer_id, opacity);
gimp_layer_set_mode(l_new_layer_id, mode);
l_ret_id = l_new_layer_id; /* all done OK */
}
}
if(l_name != NULL) { g_free (l_name); }
if(gap_debug) printf("GAP p_my_layer_copy: ret %d\n", (int)l_ret_id);
return l_ret_id;
} /* end p_my_layer_copy */
/* ============================================================================
* p_my_channel_copy
* copy a channel to dst_IMAGE
* ============================================================================
*/
gint32 p_my_channel_copy (gint32 dst_image_id,
gint32 src_channel_id)
{
gint32 l_new_channel_id;
gint32 l_ret_id;
char *l_name;
if(gap_debug) printf("GAP :p_my_channel_copy START\n");
l_ret_id = -1; /* prepare error retcode -1 */
l_name = NULL;
/* create new channel in destination image */
l_name = gimp_channel_get_name(src_channel_id);
/* copy the channel */
l_new_channel_id = gimp_channel_copy(src_channel_id);
if(l_new_channel_id >= 0)
{
if(p_gimp_drawable_set_image(l_new_channel_id, dst_image_id) >= 0)
{
gimp_channel_set_name(l_new_channel_id, l_name);
l_ret_id = l_new_channel_id; /* all done OK */
}
}
if(l_name != NULL) { g_free (l_name); }
if(gap_debug) printf("GAP :p_my_channel_copy id=%d\n", (int)l_ret_id);
return l_ret_id;
} /* end p_my_channel_copy */

View File

@ -0,0 +1,58 @@
/* my_layer_copy.h
* 1997.11.06 hof (Wolfgang Hofer)
*
*
* this procedure works similar to gimp_layer_copy(src_id);
* ==> gimp_layer_copy works only for layers within the same image !!
* ==> Workaround:
* p_my_layer_copy is my 'private' version of layercopy
* that can copy layers from another image of the same type.
*
* returns the id of the new layer
* and the offests of the original within the source image
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.98.00 1998.11.26 hof: added channel copy
* version 0.90.00; hof: 1.st (pre) release
*/
#ifndef _GAP_LAYER_COPY_H
#define _GAP_LAYER_COPY_H
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <stdlib.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
gint32 p_my_layer_copy (gint32 dst_image_id,
gint32 src_layer_id,
gdouble opacity, /* 0.0 upto 100.0 */
GLayerMode mode,
gint *src_offset_x,
gint *src_offset_y );
gint32 p_my_channel_copy (gint32 dst_image_id,
gint32 src_channel_id);
#endif

2068
plug-ins/gap/gap_lib.c Normal file

File diff suppressed because it is too large Load Diff

117
plug-ins/gap/gap_lib.h Normal file
View File

@ -0,0 +1,117 @@
/* gap_lib.h
* 1997.11.01 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* basic anim functions
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* 0.99.00; 1999/03/15 hof: prepared for win/dos filename conventions
* 0.96.02; 1998/08/05 hof: extended gap_dup (duplicate range instead of singele frame)
* added gap_shift (framesequence shift)
* 0.96.00; 1998/06/27 hof: added gap animation sizechange plugins
* (moved range_ops to seperate .h file)
* 0.94.01; 1998/04/27 hof: added flatten_mode to plugin: gap_range_to_multilayer
* 0.90.00; hof: 1.st (pre) release
*/
#ifndef _GAP_LIB_H
#define _GAP_LIB_H
#include "libgimp/gimp.h"
/* G_DIR_SEPARATOR (is defined in glib.h if you have glib-1.2.0 or later) */
#ifdef NATIVE_WIN32
/* Filenames in WIN/DOS Style */
#ifndef G_DIR_SEPARATOR
#define G_DIR_SEPARATOR '\\'
#endif
#define DIR_ROOT ':'
#else /* !NATIVE_WIN32 */
/* Filenames in UNIX Style */
#ifndef G_DIR_SEPARATOR
#define G_DIR_SEPARATOR '/'
#endif
#define DIR_ROOT '/'
#endif /* !NATIVE_WIN32 */
typedef struct t_anim_info {
gint32 image_id;
char *basename; /* may include path */
long frame_nr;
char *extension;
char *new_filename;
char *old_filename;
GRunModeType run_mode;
long width;
long height;
long type;
long frame_cnt;
long curr_frame_nr;
long first_frame_nr;
long last_frame_nr;
} t_anim_info;
/* procedures used in other gap*.c files */
int p_file_exists(char *fname);
int p_file_copy(char *fname, char *fname_copy);
void p_free_ainfo(t_anim_info **ainfo);
char* p_alloc_basename(char *imagename, long *number);
char* p_alloc_extension(char *imagename);
t_anim_info* p_alloc_ainfo(gint32 image_id, GRunModeType run_mode);
int p_dir_ainfo(t_anim_info *ainfo_ptr);
int p_chk_framerange(t_anim_info *ainfo_ptr);
int p_chk_framechange(t_anim_info *ainfo_ptr);
int p_save_named_frame (gint32 image_id, char *sav_name);
int p_load_named_frame (gint32 image_id, char *lod_name);
gint32 p_load_image (char *lod_name);
gint32 p_save_named_image(gint32 image_id, char *sav_name, GRunModeType run_mode);
char* p_alloc_fname(char *basename, long nr, char *extension);
char* p_gzip (char *orig_name, char *new_name, char *zip);
/* animation menu fuctions provided by gap_lib.c */
int gap_next(GRunModeType run_mode, gint32 image_id);
int gap_prev(GRunModeType run_mode, gint32 image_id);
int gap_first(GRunModeType run_mode, gint32 image_id);
int gap_last(GRunModeType run_mode, gint32 image_id);
int gap_goto(GRunModeType run_mode, gint32 image_id, int nr);
int gap_dup(GRunModeType run_mode, gint32 image_id, int nr, long range_from, long range_to);
int gap_del(GRunModeType run_mode, gint32 image_id, int nr);
int gap_exchg(GRunModeType run_mode, gint32 image_id, int nr);
int gap_shift(GRunModeType run_mode, gint32 image_id, int nr, long range_from, long range_to);
void p_msg_win(GRunModeType run_mode, char *msg);
#endif

1214
plug-ins/gap/gap_main.c Normal file

File diff suppressed because it is too large Load Diff

325
plug-ins/gap/gap_match.c Normal file
View File

@ -0,0 +1,325 @@
/* gap_match.c
* 1998.10.14 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* layername and layerstacknumber matching procedures
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.97.00 1998.10.14 hof: - created module
*/
/* SYSTEM (UNIX) includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
/* GIMP includes */
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_match.h"
int
p_is_empty (char *str)
{
if(str == NULL) return(TRUE);
if(*str == '\0') return(TRUE);
while(*str != '\0')
{
if(*str != ' ') return(FALSE);
str++;
}
return(TRUE);
}
/* ============================================================================
* p_substitute_framenr
* copy new_layername to buffer
* and substitute [####] by curr frame number
* ============================================================================
*/
void
p_substitute_framenr (char *buffer, int buff_len, char *new_layername, long curr)
{
int l_idx;
int l_digits;
int l_cpy;
char l_fmt_str[21];
l_fmt_str[0] = '%';
l_fmt_str[1] = '0';
l_digits = 0;
l_idx = 0;
if(new_layername != NULL)
{
while((l_idx < (buff_len-1)) && (*new_layername != '\0') )
{
l_cpy = 1;
switch(*new_layername)
{
case '[':
if((new_layername[1] == '#') && (l_digits == 0))
{
l_cpy = 0;
l_digits = 1;
}
break;
case '#':
if(l_digits > 0)
{
l_cpy = 0;
l_digits++;
}
break;
case ']':
if(l_digits > 0)
{
l_digits--;
sprintf(&l_fmt_str[2], "%dd", l_digits);
sprintf(&buffer[l_idx], l_fmt_str, (int)curr);
l_idx += l_digits;
l_digits = 0;
l_cpy = 0;
}
break;
default:
l_digits = 0;
break;
}
if(l_cpy != 0)
{
buffer[l_idx] = (*new_layername);
l_idx++;
}
new_layername++;
}
}
buffer[l_idx] = '\0';
} /* end p_substitute_framenr */
void str_toupper(char *str)
{
if(str != NULL)
{
while(*str != '\0')
{
*str = toupper(*str);
str++;
}
}
}
/* match layer_idx (int) with pattern
* pattern contains a list like that:
* "0, 3-4, 7, 10"
*/
int p_match_number(gint32 layer_idx, char *pattern)
{
char l_digit_buff[128];
char *l_ptr;
int l_idx;
gint32 l_num, l_range_start;
l_idx = 0;
l_num = -1; l_range_start = -1;
for(l_ptr = pattern; 1 == 1; l_ptr++)
{
if(isdigit(*l_ptr))
{
l_digit_buff[l_idx] = *l_ptr; /* collect digits here */
l_idx++;
}
else
{
if(l_idx > 0)
{
/* now we are one character past a number */
l_digit_buff[l_idx] = '\0';
l_num = atol(l_digit_buff); /* scann the number */
if(l_num == layer_idx)
{
return(TRUE); /* matches number exactly */
}
if((l_range_start >= 0)
&& (layer_idx >= l_range_start) && (layer_idx <= l_num ))
{
return(TRUE); /* matches given range */
}
l_range_start = -1; /* disable number for opening a range */
l_idx = 0;
}
switch(*l_ptr)
{
case '\0':
return (FALSE);
break;
case ' ':
case '\t':
break;
case ',':
l_num = -1; /* disable number for opening a range */
break;
case '-':
if (l_num >= 0)
{
l_range_start = l_num; /* prev. number opens a range */
}
break;
default:
/* found illegal characters */
/* return (FALSE); */
l_num = -1; /* disable number for opening a range */
l_range_start = -1; /* disable number for opening a range */
break;
}
}
} /* end for */
return(FALSE);
} /* end p_match_number */
/* simple stringmatching without wildcards */
int p_match_name(char *layername, char *pattern, gint32 mode, gint32 case_sensitive)
{
int l_idx;
int l_llen;
int l_plen;
char *l_name_ptr;
char *l_patt_ptr;
char l_name_buff[256];
char l_patt_buff[256];
if(pattern == NULL) return (FALSE);
if(layername == NULL) return (FALSE);
if(case_sensitive)
{
/* case sensitive can compare on the originals */
l_name_ptr = layername;
l_patt_ptr = pattern;
}
else
{
/* ignore case by converting everything to UPPER before comare */
strcpy (l_name_buff, layername);
strcpy (l_patt_buff, pattern);
str_toupper (l_name_buff);
str_toupper (l_patt_buff);
l_name_ptr = l_name_buff;
l_patt_ptr = l_patt_buff;
}
switch (mode)
{
case MTCH_EQUAL:
if (0 == strcmp(l_name_ptr, l_patt_ptr))
{
return(TRUE);
}
break;
case MTCH_START:
l_plen = strlen(l_patt_ptr);
if (0 == strncmp(l_name_ptr, l_patt_ptr, l_plen))
{
return(TRUE);
}
break;
case MTCH_END:
l_llen = strlen(l_name_ptr);
l_plen = strlen(l_patt_ptr);
if(l_llen > l_plen)
{
if(0 == strncmp(&l_name_ptr[l_llen - l_plen], l_patt_ptr, l_plen))
{
return(TRUE);
}
}
break;
case MTCH_ANYWHERE:
l_llen = strlen(l_name_ptr);
l_plen = strlen(l_patt_ptr);
for(l_idx = 0; l_idx <= (l_llen - l_plen); l_idx++)
{
if (strncmp(&l_name_ptr[l_idx], l_patt_ptr, l_plen) == 0)
{
return (TRUE);
}
}
break;
default:
break;
}
return (FALSE);
}
int p_match_layer(gint32 layer_idx, char *layername, char *pattern,
gint32 mode, gint32 case_sensitive, gint32 invert,
gint nlayers, gint32 layer_id)
{
int l_rc;
switch(mode)
{
case MTCH_NUMBERLIST:
l_rc = p_match_number(layer_idx, pattern);
break;
case MTCH_INV_NUMBERLIST:
l_rc = p_match_number((nlayers -1) - layer_idx, pattern);
break;
case MTCH_ALL_VISIBLE:
l_rc = gimp_layer_get_visible(layer_id);
break;
default:
l_rc = p_match_name(layername, pattern, mode, case_sensitive);
break;
}
if(invert == TRUE)
{
if(l_rc == FALSE) { return(TRUE); }
return(FALSE);
}
return (l_rc);
}

53
plug-ins/gap/gap_match.h Normal file
View File

@ -0,0 +1,53 @@
/* gap_match.h
*
* GAP ... Gimp Animation Plugins
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.97.00 1998.10.14 hof: - created module
*/
#ifndef _GAP_MATCH_H
#define _GAP_MATCH_H
#include "libgimp/gimp.h"
#define MTCH_EQUAL 0
#define MTCH_START 1
#define MTCH_END 2
#define MTCH_ANYWHERE 3
#define MTCH_NUMBERLIST 4
#define MTCH_INV_NUMBERLIST 5
#define MTCH_ALL_VISIBLE 6
int p_is_empty (char *str);
void p_substitute_framenr (char *buffer, int buff_len, char *new_layername, long curr);
void str_toupper(char *str);
int p_match_number(gint32 layer_id, char *pattern);
int p_match_name(char *layername, char *pattern, gint32 mode, gint32 case_sensitive);
int p_match_layer(gint32 layer_idx, char *layername, char *pattern,
gint32 mode, gint32 case_sensitive, gint32 invert,
gint nlayers, gint32 layer_id);
#endif

1203
plug-ins/gap/gap_mod_layer.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
/* gap_mod_layer.h
* 1998.10.14 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains:
* modify Layer (perform actions (like raise, set visible, apply filter)
* - foreach selected layer
* - in each frame of the selected framerange)
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.98.00 1998.11.27 hof: - use new module gap_pdb_calls.h
* version 0.97.00 hof: - created module (as extract gap_fileter_foreach)
*/
#ifndef _GAP_MOD_LAYER_H
#define _GAP_MOD_LAYER_H
#define MAX_LAYERNAME 128
/* action_mode values */
#define ACM_SET_VISIBLE 0
#define ACM_SET_INVISIBLE 1
#define ACM_SET_LINKED 2
#define ACM_SET_UNLINKED 3
#define ACM_RAISE 4
#define ACM_LOWER 5
#define ACM_MERGE_EXPAND 6
#define ACM_MERGE_IMG 7
#define ACM_MERGE_BG 8
#define ACM_APPLY_FILTER 9
#define ACM_DUPLICATE 10
#define ACM_DELETE 11
#define ACM_RENAME 12
typedef struct
{
gint32 layer_id;
gint visible;
gint selected;
} t_LayliElem;
t_LayliElem *p_alloc_layli(gint32 image_id, gint32 *l_sel_cnt, gint *nlayers,
gint32 sel_mode,
gint32 sel_case,
gint32 sel_invert,
char *sel_pattern );
int p_get_1st_selected (t_LayliElem * layli_ptr, gint nlayers);
void p_prevent_empty_image(gint32 image_id);
gint gap_mod_layer(GRunModeType run_mode, gint32 image_id,
gint32 range_from, gint32 range_to,
gint32 action_mode, gint32 sel_mode,
gint32 sel_case, gint32 sel_invert,
char *sel_pattern, char *new_layername);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,127 @@
/* gap_mov_dialog.h
* 1997.11.06 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* Dialog Window for gap_mov
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _GAP_MOV_DIALOG_H
#define _GAP_MOV_DIALOG_H
/* revision history:
* version 0.96.02; 1998.07.25 hof: added clip_to_img
*/
typedef enum
{
GAP_STEP_LOOP = 0,
GAP_STEP_LOOP_REV = 1,
GAP_STEP_ONCE = 2,
GAP_STEP_ONCE_REV = 3,
GAP_STEP_PING_PONG = 4,
GAP_STEP_NONE = 5
} t_mov_stepmodes;
typedef enum
{
GAP_HANDLE_LEFT_TOP = 0,
GAP_HANDLE_LEFT_BOT = 1,
GAP_HANDLE_RIGHT_TOP = 2,
GAP_HANDLE_RIGHT_BOT = 3,
GAP_HANDLE_CENTER = 4
} t_mov_handle;
typedef struct {
long dst_frame_nr; /* current destination frame_nr */
long src_layer_idx; /* index of current layer */
gint32 *src_layers; /* array of source images layer id's */
long src_last_layer; /* index of last layer 0 upto n-1 */
gdouble currX, currY;
gdouble deltaX, deltaY;
gint l_handleX;
gint l_handleY;
gdouble currOpacity;
gdouble deltaOpacity;
gdouble currWidth;
gdouble deltaWidth;
gdouble currHeight;
gdouble deltaHeight;
gdouble currRotation;
gdouble deltaRotation;
} t_mov_current;
typedef struct {
gint p_x, p_y; /* +- koordinates */
gint opacity; /* 0 upto 100% */
gint w_resize; /* width resize 10 upto 300% */
gint h_resize; /* height resize 10 upto 300% */
gint rotation; /* rotatation +- degrees */
} t_mov_point;
#define GAP_MOV_MAX_POINT 256
/*
* Notes:
* - exchange of frames (load replace)
* keeps an images id, but all its
* layers were allocated new.
* this results in new layer_id's
* For this reason the source image MUST NOT be one of the Frames
* of the destination Animation !!
* - Rotation is now supported (since gap 0.95) (data structs are prepared for)
*/
typedef struct {
gint32 src_image_id; /* source image */
gint32 src_layer_id; /* id of layer (to begin with) */
int src_handle;
int src_stepmode;
int src_paintmode;
gint src_only_visible; /* TRUE FALSE */
gint clip_to_img; /* TRUE FALSE */
gint point_idx; /* 0 upto MAX_POINT -1 */
gint point_idx_max; /* 0 upto MAX_POINT -1 */
t_mov_point point[GAP_MOV_MAX_POINT];
gint dst_range_start; /* use current frame as default */
gint dst_range_end;
gint dst_layerstack;
gint dst_combination_mode; /* GLayerMode */
/* for dialog only */
gint32 dst_image_id; /* frame image */
gint32 tmp_image_id; /* temp. flattened preview image */
} t_mov_values;
typedef struct {
t_anim_info *dst_ainfo_ptr; /* destination frames */
t_mov_values *val_ptr;
} t_mov_data;
long p_move_dialog (t_mov_data *mov_ptr);
void p_set_handle_offsets(t_mov_values *val_ptr, t_mov_current *cur_ptr);
int p_mov_render(gint32 image_id, t_mov_values *val_ptr, t_mov_current *cur_ptr);
#endif

453
plug-ins/gap/gap_mov_exec.c Normal file
View File

@ -0,0 +1,453 @@
/* gap_mov_exec.c
* 1997.11.06 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* Move : procedures for copying source layer(s) to multiple frames
* (varying Koordinates, opacity, size ...)
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.93.04 hof: Window with Info Message if no Source Image was selected in MovePath
* version 0.90.00; hof: 1.st (pre) release 14.Dec.1997
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_layer_copy.h"
#include "gap_lib.h"
#include "gap_mov_dialog.h"
#include "gap_mov_exec.h"
extern int gap_debug; /* ==0 ... dont print debug infos */
static int p_mov_call_render(t_mov_data *mov_ptr, t_mov_current *cur_ptr);
static void p_mov_advance_src_layer(t_mov_current *cur_ptr, int src_stepmode);
static long p_mov_execute(t_mov_data *mov_ptr);
/* ============================================================================
* p_mov_call_render
* load current frame, render and save back to disk
* ============================================================================
*/
int p_mov_call_render(t_mov_data *mov_ptr, t_mov_current *cur_ptr)
{
t_anim_info *ainfo_ptr;
gint32 l_tmp_image_id;
int l_rc;
l_rc = 0;
ainfo_ptr = mov_ptr->dst_ainfo_ptr;
if(ainfo_ptr->new_filename != NULL) free(ainfo_ptr->new_filename);
ainfo_ptr->new_filename = p_alloc_fname(ainfo_ptr->basename,
cur_ptr->dst_frame_nr,
ainfo_ptr->extension);
if(ainfo_ptr->new_filename == NULL)
return -1;
/* load next frame to render */
l_tmp_image_id = p_load_image(ainfo_ptr->new_filename);
if(l_tmp_image_id < 0)
return -1;
/* call render procedure for current image */
if(0 == p_mov_render(l_tmp_image_id, mov_ptr->val_ptr, cur_ptr))
{
/* if OK: save the rendered frame back to disk */
if(p_save_named_frame(l_tmp_image_id, ainfo_ptr->new_filename) < 0)
l_rc = -1;
}
else l_rc = -1;
/* destroy the tmp image */
gimp_image_delete(l_tmp_image_id);
return l_rc;
} /* end p_mov_call_render */
/* ============================================================================
* p_mov_advance_src_layer
* advance layer index according to stepmode
* ============================================================================
*/
void p_mov_advance_src_layer(t_mov_current *cur_ptr, int src_stepmode)
{
static int l_ping = -1;
if(gap_debug) printf("p_mov_advance_src_layer: stepmode=%d last_layer=%d idx=%d\n",
(int)src_stepmode,
(int)cur_ptr->src_last_layer,
(int)cur_ptr->src_layer_idx
);
/* note: top layer has index 0
* therfore reverse loops have to count up
*/
if((cur_ptr->src_last_layer > 0 ) && (src_stepmode != GAP_STEP_NONE))
{
switch(src_stepmode)
{
case GAP_STEP_ONCE_REV:
cur_ptr->src_layer_idx++;
if(cur_ptr->src_layer_idx > cur_ptr->src_last_layer)
{
cur_ptr->src_layer_idx = cur_ptr->src_last_layer;
}
break;
case GAP_STEP_ONCE:
cur_ptr->src_layer_idx--;
if(cur_ptr->src_layer_idx < 0)
{
cur_ptr->src_layer_idx = 0;
}
break;
case GAP_STEP_PING_PONG:
cur_ptr->src_layer_idx += l_ping;
if(l_ping < 0)
{
if(cur_ptr->src_layer_idx < 0)
{
cur_ptr->src_layer_idx = 1;
l_ping = 1;
}
}
else
{
if(cur_ptr->src_layer_idx > cur_ptr->src_last_layer)
{
cur_ptr->src_layer_idx = cur_ptr->src_last_layer - 1;
l_ping = -1;
}
}
break;
case GAP_STEP_LOOP_REV:
cur_ptr->src_layer_idx++;
if(cur_ptr->src_layer_idx > cur_ptr->src_last_layer)
{
cur_ptr->src_layer_idx = 0;
}
break;
case GAP_STEP_LOOP:
default:
cur_ptr->src_layer_idx--;
if(cur_ptr->src_layer_idx < 0)
{
cur_ptr->src_layer_idx = cur_ptr->src_last_layer;
}
break;
}
}
} /* end p_advance_src_layer */
/* ============================================================================
* p_mov_execute
* Copy layer(s) from Sourceimage to given destination frame range,
* varying koordinates and opacity of the copied layer.
* To each affected destination frame exactly one is added.
* The source layer is iterated through all layers of the sourceimage
* according to stemmode parameter.
* For the placement the layers act as if their size is equal to their
* Sourceimages size.
* ============================================================================
*/
long p_mov_execute(t_mov_data *mov_ptr)
{
int l_idx;
t_mov_current l_current_data;
t_mov_current *cur_ptr;
t_mov_values *val_ptr;
gdouble l_percentage;
gdouble l_fpl; /* frames_per_line */
long l_fpl2; /* frames_per_line rounded to integer*/
long l_frame_step;
gdouble l_frames;
long l_cnt;
long l_points;
long l_ptidx;
long l_fridx;
gdouble l_flt_count;
int l_rc;
int l_nlayers;
if(mov_ptr->val_ptr->src_image_id < 0)
{
p_msg_win(mov_ptr->dst_ainfo_ptr->run_mode,
"No Source Image was selected\n(Please open a 2nd Image of the same type before opening Move Path)");
return -1;
}
l_percentage = 0.0;
if(mov_ptr->dst_ainfo_ptr->run_mode == RUN_INTERACTIVE)
{
gimp_progress_init("Copying Layers into Frames ..");
}
if(gap_debug)
{
printf("p_mov_execute: values got from dialog:\n");
printf("src_image_id :%ld\n", (long)mov_ptr->val_ptr->src_image_id);
printf("src_layer_id :%ld\n", (long)mov_ptr->val_ptr->src_layer_id);
printf("src_handle :%d\n", mov_ptr->val_ptr->src_handle);
printf("src_stepmode :%d\n", mov_ptr->val_ptr->src_stepmode);
printf("src_paintmode :%d\n", mov_ptr->val_ptr->src_paintmode);
printf("clip_to_img :%d\n", mov_ptr->val_ptr->clip_to_img);
printf("dst_range_start :%d\n", (int)mov_ptr->val_ptr->dst_range_start);
printf("dst_range_end :%d\n", (int)mov_ptr->val_ptr->dst_range_end);
printf("dst_layerstack :%d\n", (int)mov_ptr->val_ptr->dst_layerstack);
for(l_idx = 0; l_idx <= mov_ptr->val_ptr->point_idx_max; l_idx++)
{
printf("p_x[%d] :%d\n", l_idx, mov_ptr->val_ptr->point[l_idx].p_x);
printf("p_y[%d] : :%d\n", l_idx, mov_ptr->val_ptr->point[l_idx].p_y);
printf("opacity[%d] :%d\n", l_idx, mov_ptr->val_ptr->point[l_idx].opacity);
printf("w_resize[%d] :%d\n", l_idx, mov_ptr->val_ptr->point[l_idx].w_resize);
printf("h_resize[%d] :%d\n", l_idx, mov_ptr->val_ptr->point[l_idx].h_resize);
printf("rotation[%d] :%d\n", l_idx, mov_ptr->val_ptr->point[l_idx].rotation);
}
printf("\n");
}
l_rc = 0;
cur_ptr = &l_current_data;
val_ptr = mov_ptr->val_ptr;
/* set offsets (in cur_ptr) according to handle mode and src_img dimension */
p_set_handle_offsets(val_ptr, cur_ptr);
/* test for invers range */
if(val_ptr->dst_range_start > val_ptr->dst_range_end)
{
/* step down */
l_frame_step = -1;
l_cnt = 1 + (val_ptr->dst_range_start - val_ptr->dst_range_end);
}
else
{
l_frame_step = 1;
l_cnt = 1 + (val_ptr->dst_range_end - val_ptr->dst_range_start);
}
l_frames = (gdouble)l_cnt; /* nr. of affected frames */
l_points = val_ptr->point_idx_max +1; /* nr. of available points */
if(l_points > l_frames)
{
/* cut off some points if we got more than frames */
val_ptr->point[l_cnt].p_x = val_ptr->point[l_cnt].p_x;
val_ptr->point[l_cnt].p_y = val_ptr->point[l_cnt].p_y;
val_ptr->point[l_cnt].opacity = val_ptr->point[l_cnt].opacity;
val_ptr->point[l_cnt].w_resize = val_ptr->point[l_cnt].w_resize;
val_ptr->point[l_cnt].h_resize = val_ptr->point[l_cnt].h_resize;
val_ptr->point[l_cnt].rotation = val_ptr->point[l_cnt].rotation;
l_points = l_cnt;
}
cur_ptr->dst_frame_nr = val_ptr->dst_range_start;
cur_ptr->src_layers = gimp_image_get_layers (val_ptr->src_image_id, &l_nlayers);
if(cur_ptr->src_layers == NULL)
{
printf("ERROR (in p_mov_execute): Got no layers from SrcImage\n");
return -1;
}
if(l_nlayers < 1)
{
printf("ERROR (in p_mov_execute): Source Image has no layers\n");
return -1;
}
cur_ptr->src_last_layer = l_nlayers -1;
/* findout index of src_layer_id */
for(cur_ptr->src_layer_idx = 0;
cur_ptr->src_layer_idx < l_nlayers;
cur_ptr->src_layer_idx++)
{
if(cur_ptr->src_layers[cur_ptr->src_layer_idx] == val_ptr->src_layer_id)
break;
}
cur_ptr->src_last_layer = l_nlayers -1; /* index of last layer */
cur_ptr->currX = (gdouble)val_ptr->point[0].p_x;
cur_ptr->currY = (gdouble)val_ptr->point[0].p_y;
cur_ptr->currOpacity = (gdouble)val_ptr->point[0].opacity;
cur_ptr->currWidth = (gdouble)val_ptr->point[0].w_resize;
cur_ptr->currHeight = (gdouble)val_ptr->point[0].h_resize;
cur_ptr->currRotation = (gdouble)val_ptr->point[0].rotation;
/* RENDER add current src_layer to current frame */
l_rc = p_mov_call_render(mov_ptr, cur_ptr);
/* how many frames are affected from one line of the moving path */
l_fpl = ((gdouble)l_frames - 1.0) / ((gdouble)(l_points -1));
l_fpl2 = (l_fpl + 0.5);
l_ptidx = 1;
l_flt_count = 0.0;
/* loop for each frame within the range (may step up or down) */
cur_ptr->dst_frame_nr = val_ptr->dst_range_start;
for(l_fridx = 1; l_fridx < l_cnt; l_fridx++)
{
if(gap_debug) printf("p_mov_execute: l_fridx=%ld, l_flt_count=%f, l_rc=%d\n",
l_fridx, l_flt_count, (int)l_rc);
if(l_rc != 0) break;
/* advance frame_nr, (1st frame was done outside this loop) */
cur_ptr->dst_frame_nr += l_frame_step; /* +1 or -1 */
if((gdouble)l_fridx > l_flt_count)
{
/* re-adjust current values. (only to avoid rounding errors)
* current values should already contain the point values[l_ptidx]
*/
cur_ptr->currX = (gdouble)val_ptr->point[l_ptidx -1].p_x;
cur_ptr->currY = (gdouble)val_ptr->point[l_ptidx -1].p_y;
cur_ptr->currOpacity = (gdouble)val_ptr->point[l_ptidx -1].opacity;
cur_ptr->currWidth = (gdouble)val_ptr->point[l_ptidx -1].w_resize;
cur_ptr->currHeight = (gdouble)val_ptr->point[l_ptidx -1].h_resize;
cur_ptr->currRotation = (gdouble)val_ptr->point[l_ptidx -1].rotation;
/* change deltas for next line of the move path */
cur_ptr->deltaX = ((gdouble)val_ptr->point[l_ptidx].p_x - (gdouble)val_ptr->point[l_ptidx -1].p_x) / (gdouble)l_fpl2;
cur_ptr->deltaY = ((gdouble)val_ptr->point[l_ptidx].p_y - (gdouble)val_ptr->point[l_ptidx -1].p_y) / (gdouble)l_fpl2;
cur_ptr->deltaOpacity = ((gdouble)val_ptr->point[l_ptidx].opacity - (gdouble)val_ptr->point[l_ptidx -1].opacity) / (gdouble)l_fpl2;
cur_ptr->deltaWidth = ((gdouble)val_ptr->point[l_ptidx].w_resize - (gdouble)val_ptr->point[l_ptidx -1].w_resize) / (gdouble)l_fpl2;
cur_ptr->deltaHeight = ((gdouble)val_ptr->point[l_ptidx].h_resize - (gdouble)val_ptr->point[l_ptidx -1].h_resize) / (gdouble)l_fpl2;
cur_ptr->deltaRotation = ((gdouble)val_ptr->point[l_ptidx].rotation - (gdouble)val_ptr->point[l_ptidx -1].rotation) / (gdouble)l_fpl2;
l_ptidx++;
l_flt_count += l_fpl;
}
/* advance settings for next frame */
p_mov_advance_src_layer(cur_ptr, val_ptr->src_stepmode);
cur_ptr->currX += cur_ptr->deltaX;
cur_ptr->currY += cur_ptr->deltaY;
cur_ptr->currOpacity += cur_ptr->deltaOpacity;
cur_ptr->currWidth += cur_ptr->deltaWidth;
cur_ptr->currHeight += cur_ptr->deltaHeight;
cur_ptr->currRotation += cur_ptr->deltaRotation;
/* RENDER add current src_layer to current frame */
l_rc = p_mov_call_render(mov_ptr, cur_ptr);
/* show progress */
if(mov_ptr->dst_ainfo_ptr->run_mode == RUN_INTERACTIVE)
{
l_percentage = (gdouble)l_fridx / (gdouble)(l_cnt -1);
gimp_progress_update (l_percentage);
}
}
if(cur_ptr->src_layers != NULL) g_free(cur_ptr->src_layers);
return l_rc;
} /* end p_mov_execute */
/* ============================================================================
* gap_move
* ============================================================================
*/
int gap_move(GRunModeType run_mode, gint32 image_id)
{
int l_rc;
t_anim_info *ainfo_ptr;
t_mov_data l_mov_data;
l_rc = -1;
ainfo_ptr = p_alloc_ainfo(image_id, run_mode);
if(ainfo_ptr != NULL)
{
l_mov_data.val_ptr = malloc(sizeof(t_mov_values));
if(NULL != l_mov_data.val_ptr)
{
if (0 == p_dir_ainfo(ainfo_ptr))
{
if(0 != p_chk_framerange(ainfo_ptr)) return -1;
l_mov_data.dst_ainfo_ptr = ainfo_ptr;
if(run_mode == RUN_INTERACTIVE)
{
l_rc = p_move_dialog (&l_mov_data);
if(0 != p_chk_framechange(ainfo_ptr))
{
l_rc = -1;
}
}
else
{
l_rc = -1; /* run NON_INTERACTIVE not implemented (define args) */
}
if(l_rc >= 0)
{
l_rc = p_save_named_frame(ainfo_ptr->image_id, ainfo_ptr->old_filename);
if(l_rc >= 0)
{
l_rc = p_mov_execute(&l_mov_data);
/* go back to the frame_nr where move operation was started from */
p_load_named_frame(ainfo_ptr->image_id, ainfo_ptr->old_filename);
}
}
}
free(l_mov_data.val_ptr);
}
p_free_ainfo(&ainfo_ptr);
}
return(l_rc);
} /* end gap_move */

View File

@ -0,0 +1,43 @@
/* gap_lib.h
* 1997.11.01 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* basic anim functions
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* 0.96.00; 1998/06/27 hof: added gap animation sizechange plugins
* (moved range_ops to seperate .h file)
* 0.94.01; 1998/04/27 hof: added flatten_mode to plugin: gap_range_to_multilayer
* 0.90.00; hof: 1.st (pre) release
*/
#ifndef _GAP_MOV_EXEC_H
#define _GAP_MOV_EXEC_H
#include "libgimp/gimp.h"
int gap_move(GRunModeType run_mode, gint32 image_id);
#endif

1029
plug-ins/gap/gap_mpege.c Normal file

File diff suppressed because it is too large Load Diff

55
plug-ins/gap/gap_mpege.h Normal file
View File

@ -0,0 +1,55 @@
/* gap_mpege.h
* 1998.07.04 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* 0.96.00; 1998/07/02 hof: first release
*/
#ifndef _GAP_MPEGE_H
#define _GAP_MPEGE_H
#include "libgimp/gimp.h"
/* Animation sizechange modes */
typedef enum
{
MPEG_ENCODE
, MPEG2ENCODE
} t_gap_mpeg_encoder;
int gap_mpeg_encode(GRunModeType run_mode,
gint32 image_id,
t_gap_mpeg_encoder encoder
/* ,
char *output,
gint bitrate,
gdouble framerate
*/
);
#endif

View File

@ -0,0 +1,835 @@
/* gap_pdb_calls.c
*
* this module contains calls of procedures in the GIMPs Procedural Database
*
* IMPORTANT Notes:
* some Procedures have changed their Interface from GIMP 1.0.2 to GIMP 1.1
* in that cases the procedure parameters are checked and the call is done
* in 1.0.2 or 1.1 style repectivly.
*
* some of these procedures are not available in the official GIMP 1.0.2 releases
* (and prior releases)
*
* The missing procedures (except guides) are available as patches to the gimp core.
* If you dont install the patches GAP will NOT work on GIMP 1.0.2 and older versions.
*
* GIMP 1.1 will provide all the procedures to run GAP at full fuctionality.
* There are no Patches required to run GAP in the latest GIMP 1.1
* development version
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.98.00; 1998/11/28 hof: 1.st (pre) release (GAP port to GIMP 1.1)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* GIMP includes */
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_pdb_calls.h"
extern int gap_debug;
/* ============================================================================
* p_pdb_procedure_available
* if requested procedure is available in the PDB return the number of args
* (0 upto n) that are needed to call the procedure.
* if not available return -1
* ============================================================================
*/
gint p_pdb_procedure_available(char *proc_name)
{
/* Note: It would be nice to call "gimp_layer_get_linked" direct,
* but there is not such an Interface in gimp 0.99.16
* Workaround:
* I did a patch to implement the "gimp_layer_get_linked"
* procedure, and call it via PDB call if available.
* if not available FALSE is returned.
*/
int l_nparams;
int l_nreturn_vals;
int l_proc_type;
char *l_proc_blurb;
char *l_proc_help;
char *l_proc_author;
char *l_proc_copyright;
char *l_proc_date;
GParamDef *l_params;
GParamDef *l_return_vals;
gint l_rc;
l_rc = 0;
/* Query the gimp application's procedural database
* regarding a particular procedure.
*/
if(gimp_query_procedure (proc_name,
&l_proc_blurb,
&l_proc_help,
&l_proc_author,
&l_proc_copyright,
&l_proc_date,
&l_proc_type,
&l_nparams,
&l_nreturn_vals,
&l_params,
&l_return_vals))
{
/* procedure found in PDB */
return (l_nparams);
}
printf("Warning: Procedure %s not found.\n", proc_name);
return -1;
} /* end p_pdb_procedure_available */
/* ---------------------- PDB procedure calls -------------------------- */
/* ============================================================================
* p_get_gimp_selection_bounds
*
* ============================================================================
*/
gint
p_get_gimp_selection_bounds (gint32 image_id, gint32 *x1, gint32 *y1, gint32 *x2, gint32 *y2)
{
static char *l_get_sel_bounds_proc = "gimp_selection_bounds";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_get_sel_bounds_proc) >= 0)
{
return_vals = gimp_run_procedure (l_get_sel_bounds_proc,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
*x1 = return_vals[2].data.d_int32;
*y1 = return_vals[3].data.d_int32;
*x2 = return_vals[4].data.d_int32;
*y2 = return_vals[5].data.d_int32;
return(return_vals[1].data.d_int32);
}
printf("GAP: Error: PDB call of %s failed staus=%d\n",
l_get_sel_bounds_proc, (int)return_vals[0].data.d_status);
}
else
{
printf("GAP: Error: Procedure %s not found.\n",l_get_sel_bounds_proc);
}
return(FALSE);
} /* end p_get_gimp_selection_bounds */
/* ============================================================================
* p_gimp_selection_load
*
* ============================================================================
*/
gint
p_gimp_selection_load (gint32 image_id, gint32 channel_id)
{
static char *l_sel_load = "gimp_selection_load";
GParam *return_vals;
int nreturn_vals;
int l_nparams;
l_nparams = p_pdb_procedure_available(l_sel_load);
if (l_nparams >= 0)
{
/* check if it can take exactly one channel_id as input (gimp1.1) */
if(l_nparams == 1)
{
/* use the new Interface (Gimp 1.1 style)
* (1.1 knows the image_id where the channel belongs to)
*/
return_vals = gimp_run_procedure (l_sel_load,
&nreturn_vals,
PARAM_CHANNEL, channel_id,
PARAM_END);
}
else
{
/* use the old Interface (Gimp 1.0.2 style) */
return_vals = gimp_run_procedure (l_sel_load,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_CHANNEL, channel_id,
PARAM_END);
}
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return(TRUE);
}
printf("GAP: Error: PDB call of %s failed status=%d\n",
l_sel_load, (int)return_vals[0].data.d_status);
}
else
{
printf("GAP: Error: Procedure %s not found.\n",l_sel_load);
}
return(FALSE);
} /* end p_gimp_selection_load */
/* ============================================================================
* p_layer_set_linked
* set linked state of the layer
* ============================================================================
*/
int
p_layer_set_linked (gint32 layer_id, gint32 new_state)
{
static char *l_set_linked_proc = "gimp_layer_set_linked";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_set_linked_proc) >= 0)
{
return_vals = gimp_run_procedure (l_set_linked_proc,
&nreturn_vals,
PARAM_LAYER, layer_id,
PARAM_INT32, new_state, /* TRUE or FALSE */
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return (0);
}
printf("GAP: Error: p_layer_set_linked to state %d failed\n",(int)new_state);
}
else
{
printf("GAP: Warning: Procedure %s not found. (Layer Can not be set to linked)\n",l_set_linked_proc);
}
return(-1);
} /* end p_layer_set_linked */
/* ============================================================================
* p_layer_get_linked
*
* ============================================================================
*/
gint p_layer_get_linked(gint32 layer_id)
{
/* Note: The Procedure "gimp_layer_get_linked" is part of GIMP 1.1
* but there is not such an Interface in gimp 1.0.2
*/
static char *l_get_linked_proc = "gimp_layer_get_linked";
int l_nparams;
int l_nreturn_vals;
int l_proc_type;
char *l_proc_blurb;
char *l_proc_help;
char *l_proc_author;
char *l_proc_copyright;
char *l_proc_date;
GParamDef *l_params;
GParamDef *l_return_vals;
gint l_rc;
GParam *return_vals;
int nreturn_vals;
gint32 is_linked;
l_rc = 0;
/* Query the gimp application's procedural database
* regarding a particular procedure.
*/
if(gimp_query_procedure (l_get_linked_proc,
&l_proc_blurb,
&l_proc_help,
&l_proc_author,
&l_proc_copyright,
&l_proc_date,
&l_proc_type,
&l_nparams,
&l_nreturn_vals,
&l_params,
&l_return_vals))
{
/* procedure found in PDB */
/* check if it can take exactly one layerid as input
* and give one result int32 parameter (TRUE/FALSE)
*/
if (l_nparams != 1) { l_rc = -1; }
if (l_params[0].type != PARAM_LAYER) { l_rc = -1; }
if (l_nreturn_vals != 1) { l_rc = -1; }
if (l_return_vals[0].type != PARAM_INT32) { l_rc = -1; }
/* free the query information */
g_free (l_proc_blurb);
g_free (l_proc_help);
g_free (l_proc_author);
g_free (l_proc_copyright);
g_free (l_proc_date);
g_free (l_params);
g_free (l_return_vals);
if(l_rc != 0)
{
printf("Warning: Procedure %s has unexpected Interface. (Can not operate on linked layers)\n",l_get_linked_proc);
printf("expected: 1, 1, PARAM_LAYER = %d PARAM_INT32 = %d\n", (int)PARAM_LAYER, (int)PARAM_INT32);
printf("l_nparams = %d\n", (int)l_nparams);
printf("l_nreturn_vals = %d\n", (int)l_nreturn_vals);
printf("l_params[0].type = %d\n", (int)l_params[0].type);
printf("l_return_vals[0].type = %d\n", (int)l_return_vals[0].type);
return FALSE;
}
}
else
{
printf("Warning: Procedure %s not found. (Can not operate on linked layers)\n",l_get_linked_proc);
return FALSE;
}
/* run the procedure */
is_linked = FALSE;
return_vals = gimp_run_procedure (l_get_linked_proc,
&nreturn_vals,
PARAM_LAYER, layer_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
is_linked = return_vals[1].data.d_int32;
}
gimp_destroy_params (return_vals, nreturn_vals);
return is_linked;
}
/* ============================================================================
* p_gimp_image_floating_sel_attached_to
*
* ============================================================================
*/
gint32 p_gimp_image_floating_sel_attached_to(gint32 image_id)
{
static char *l_fsel_attached_to_proc = "gimp_image_floating_sel_attached_to";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_fsel_attached_to_proc) >= 0)
{
return_vals = gimp_run_procedure (l_fsel_attached_to_proc,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return(return_vals[1].data.d_drawable);
}
printf("GAP: Error: PDB call of %s failed\n", l_fsel_attached_to_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_fsel_attached_to_proc,
"(cant find out drawable where f-sel is attached to)");
}
return(-1);
} /* end p_gimp_image_floating_sel_attached_to */
/* ============================================================================
* p_gimp_floating_sel_attach
*
* ============================================================================
*/
gint p_gimp_floating_sel_attach(gint32 layer_id, gint32 drawable_id)
{
static char *l_fsel_attach_proc = "gimp_floating_sel_attach";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_fsel_attach_proc) >= 0)
{
return_vals = gimp_run_procedure (l_fsel_attach_proc,
&nreturn_vals,
PARAM_LAYER, layer_id,
PARAM_DRAWABLE, drawable_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return (0);
}
printf("GAP: Error: PDB call of %s failed\n", l_fsel_attach_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_fsel_attach_proc,
"(cannot attach floating selection)");
}
return(-1);
} /* end p_gimp_floating_sel_attach */
/* ============================================================================
* p_gimp_floating_sel_rigor
*
* ============================================================================
*/
gint p_gimp_floating_sel_rigor(gint32 layer_id, gint32 undo)
{
static char *l_fsel_rigor_proc = "gimp_floating_sel_rigor";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_fsel_rigor_proc) >= 0)
{
return_vals = gimp_run_procedure (l_fsel_rigor_proc,
&nreturn_vals,
PARAM_LAYER, layer_id,
PARAM_INT32, undo,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return (0);
}
printf("GAP: Error: PDB call of %s failed\n", l_fsel_rigor_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_fsel_rigor_proc,
"(cannot attach floating selection)");
}
return(-1);
} /* end p_gimp_floating_sel_rigor */
/* ============================================================================
* p_gimp_floating_sel_relax
*
* ============================================================================
*/
gint p_gimp_floating_sel_relax(gint32 layer_id, gint32 undo)
{
static char *l_fsel_relax_proc = "gimp_floating_sel_relax";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_fsel_relax_proc) >= 0)
{
return_vals = gimp_run_procedure (l_fsel_relax_proc,
&nreturn_vals,
PARAM_LAYER, layer_id,
PARAM_INT32, undo,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return (0);
}
printf("GAP: Error: PDB call of %s failed\n", l_fsel_relax_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_fsel_relax_proc,
"(cannot attach floating selection)");
}
return(-1);
} /* end p_gimp_floating_sel_relax */
/* ============================================================================
* p_gimp_image_add_guide
*
* ============================================================================
*/
gint32 p_gimp_image_add_guide(gint32 image_id, gint32 position, gint32 orientation)
{
static char *l_add_guide_proc;
GParam *return_vals;
int nreturn_vals;
if(orientation == 0 ) /* in GIMP 1.1 we could use (orientation == ORIENTATION_VERTICAL) */
{
l_add_guide_proc = "gimp_image_add_vguide";
}
else
{
l_add_guide_proc = "gimp_image_add_hguide";
}
if (p_pdb_procedure_available(l_add_guide_proc) >= 0)
{
return_vals = gimp_run_procedure (l_add_guide_proc,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_INT32, position,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return(return_vals[1].data.d_int32); /* return the guide ID */
}
printf("GAP: Error: PDB call of %s failed\n", l_add_guide_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_add_guide_proc,
"(cannot add guide)");
}
return(-1);
} /* end p_gimp_image_add_guide */
/* ============================================================================
* p_gimp_image_findnext_guide
*
* This procedure takes an image and a guide_id as input and finds the guide_id
* of the successor of the given guide_id in the image's Guide list.
* If the supplied guide_id is 0, the procedure will return the first Guide.
* The procedure will return 0 if given the final guide_id as an argument
* or the image has no guides.
*
* ============================================================================
*/
gint32 p_gimp_image_findnext_guide(gint32 image_id, gint32 guide_id)
{
static char *l_findnext_guide_proc = "gimp_image_findnext_guide";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_findnext_guide_proc) >= 0)
{
return_vals = gimp_run_procedure (l_findnext_guide_proc,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_INT32, guide_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return(return_vals[1].data.d_int32); /* return the next guide ID */
}
printf("GAP: Error: PDB call of %s failed\n", l_findnext_guide_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_findnext_guide_proc,
"(if image has guides they are not saved)");
}
return(-1);
} /* end p_gimp_image_findnext_guide */
/* ============================================================================
* p_gimp_image_get_guide_position
*
* ============================================================================
*/
gint32 p_gimp_image_get_guide_position(gint32 image_id, gint32 guide_id)
{
static char *l_get_guide_pos_proc = "gimp_image_get_guide_position";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_get_guide_pos_proc) >= 0)
{
return_vals = gimp_run_procedure (l_get_guide_pos_proc,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_INT32, guide_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return(return_vals[1].data.d_int32); /* return the guide position */
}
printf("GAP: Error: PDB call of %s failed\n", l_get_guide_pos_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_get_guide_pos_proc,
"(cannot save guides)");
}
return(-1);
} /* end p_gimp_image_get_guide_position */
/* ============================================================================
* p_gimp_image_get_guide_orientation
*
* ============================================================================
*/
gint32 p_gimp_image_get_guide_orientation(gint32 image_id, gint32 guide_id)
{
static char *l_get_guide_pos_orient = "gimp_image_get_guide_orientation";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_get_guide_pos_orient) >= 0)
{
return_vals = gimp_run_procedure (l_get_guide_pos_orient,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_INT32, guide_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return(return_vals[1].data.d_int32); /* return the guide orientation */
}
printf("GAP: Error: PDB call of %s failed\n", l_get_guide_pos_orient);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_get_guide_pos_orient,
"(cannot save guides)");
}
return(-1);
} /* end p_gimp_image_get_guide_orientation */
/* ============================================================================
* p_gimp_image_delete_guide
*
* ============================================================================
*/
gint32 p_gimp_image_delete_guide(gint32 image_id, gint32 guide_id)
{
static char *l_delete_guide_proc = "gimp_image_delete_guide";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_delete_guide_proc) >= 0)
{
return_vals = gimp_run_procedure (l_delete_guide_proc,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_INT32, guide_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return(return_vals[1].data.d_int32); /* return the next guide ID */
}
printf("GAP: Error: PDB call of %s failed\n", l_delete_guide_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_delete_guide_proc,
"(cant remove old guides)");
}
return(-1);
} /* end p_gimp_image_delete_guide */
/* ============================================================================
* p_gimp_selection_none
*
* ============================================================================
*/
gint p_gimp_selection_none(gint32 image_id)
{
static char *l_sel_none_proc = "gimp_selection_none";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_sel_none_proc) >= 0)
{
return_vals = gimp_run_procedure (l_sel_none_proc,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return (0);
}
printf("GAP: Error: PDB call of %s failed\n", l_sel_none_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_sel_none_proc,
"(cannot remove selection)");
}
return(-1);
} /* end p_gimp_selection_none */
/* ============================================================================
* p_gimp_rotate
* PDB call of 'gimp_rotate'
* ============================================================================
*/
gint p_gimp_rotate(gint32 image_id, gint32 drawable_id, gint32 interpolation, gdouble angle_deg)
{
static char *l_rotate_proc = "gimp_rotate";
GParam *return_vals;
int nreturn_vals;
gdouble l_angle_rad;
int l_nparams;
int l_rc;
l_rc = -1;
l_angle_rad = (angle_deg * 3.14159) / 180.0;
l_nparams = p_pdb_procedure_available(l_rotate_proc);
if (l_nparams >= 0)
{
if (l_nparams == 3)
{
/* use the new Interface (Gimp 1.1 style)
* (1.1 knows the image_id where the drawable belongs to)
*/
return_vals = gimp_run_procedure (l_rotate_proc,
&nreturn_vals,
PARAM_DRAWABLE, drawable_id,
PARAM_INT32, interpolation,
PARAM_FLOAT, l_angle_rad,
PARAM_END);
}
else
{
/* use the old Interface (Gimp 1.0.2 style) */
return_vals = gimp_run_procedure (l_rotate_proc,
&nreturn_vals,
PARAM_IMAGE, image_id,
PARAM_DRAWABLE, drawable_id,
PARAM_INT32, interpolation,
PARAM_FLOAT, l_angle_rad,
PARAM_END);
}
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
l_rc = 0;
}
else
{
printf("gap: %s call failed %d\n", l_rotate_proc, (int)return_vals[0].data.d_status);
}
gimp_destroy_params (return_vals, nreturn_vals);
}
else
{
printf("GAP: Error: Procedure %s not found.\n",l_rotate_proc);
}
return (l_rc);
} /* end p_gimp_rotate */
/* ============================================================================
* p_gimp_channel_ops_duplicate
* call gimp_channel_ops_duplicate via procedural database
* (i could not find a direct call interface in gimp0.99.15)
* ============================================================================
*/
gint32 p_gimp_channel_ops_duplicate (gint32 image_ID)
{
GParam *return_vals;
int nreturn_vals;
gint32 new_image_ID;
return_vals = gimp_run_procedure ("gimp_channel_ops_duplicate",
&nreturn_vals,
PARAM_IMAGE, image_ID,
PARAM_END);
new_image_ID = -1;
if (return_vals[0].data.d_status == STATUS_SUCCESS)
new_image_ID = return_vals[1].data.d_image;
gimp_destroy_params (return_vals, nreturn_vals);
return new_image_ID;
} /* end p_gimp_channel_ops_duplicate */
/* ============================================================================
* p_gimp_drawable_set_image
*
* ============================================================================
*/
gint p_gimp_drawable_set_image(gint32 drawable_id, gint32 image_id)
{
static char *l_drawable_set_img_proc = "gimp_drawable_set_image";
GParam *return_vals;
int nreturn_vals;
if (p_pdb_procedure_available(l_drawable_set_img_proc) >= 0)
{
return_vals = gimp_run_procedure (l_drawable_set_img_proc,
&nreturn_vals,
PARAM_DRAWABLE, drawable_id,
PARAM_IMAGE, image_id,
PARAM_END);
if (return_vals[0].data.d_status == STATUS_SUCCESS)
{
return (0);
}
printf("GAP: Error: PDB call of %s failed\n", l_drawable_set_img_proc);
}
else
{
printf("GAP: Warning: Procedure %s not found. %s\n",
l_drawable_set_img_proc,
"(cannot attach floating selection)");
}
return(-1);
} /* end p_gimp_drawable_set_image */

View File

@ -0,0 +1,56 @@
/* gap_pdb_calls.h
*
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* version 0.98.00; 1998/11/30 hof: all PDB-calls of GIMP PDB-Procedures
*/
#ifndef _GAP_PDB_CALLS_H
#define _GAP_PDB_CALLS_H
#include "libgimp/gimp.h"
gint p_pdb_procedure_available(char *proc_name);
gint p_get_gimp_selection_bounds (gint32 image_id, gint32 *x1, gint32 *y1, gint32 *x2, gint32 *y2);
gint p_gimp_selection_load (gint32 image_id, gint32 channel_id);
int p_layer_set_linked (gint32 layer_id, gint32 new_state);
gint p_layer_get_linked(gint32 layer_id);
gint32 p_gimp_image_floating_sel_attached_to(gint32 image_id);
gint p_gimp_floating_sel_attach(gint32 layer_id, gint32 drawable_id);
gint p_gimp_floating_sel_rigor(gint32 layer_id, gint32 undo);
gint p_gimp_floating_sel_relax(gint32 layer_id, gint32 undo);
gint32 p_gimp_image_add_guide(gint32 image_id, gint32 position, gint32 orientation);
gint32 p_gimp_image_findnext_guide(gint32 image_id, gint32 guide_id);
gint32 p_gimp_image_get_guide_position(gint32 image_id, gint32 guide_id);
gint32 p_gimp_image_get_guide_orientation(gint32 image_id, gint32 guide_id);
gint32 p_gimp_image_delete_guide(gint32 image_id, gint32 guide_id);
gint p_gimp_selection_none(gint32 image_id);
gint p_gimp_rotate(gint32 image_id, gint32 drawable_id, gint32 interpolation, gdouble angle_deg);
gint32 p_gimp_channel_ops_duplicate (gint32 image_ID);
gint p_gimp_drawable_set_image(gint32 drawable_id, gint32 image_id);
#endif

1599
plug-ins/gap/gap_range_ops.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,93 @@
/* gap_range_ops.h
* 1998.07.03 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* GAP operations on frame Ranges (from - to)
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* 0.97.00; 1998/10/19 hof: extended gap_range_to_multilayer layer seletion
* 0.96.03; 1998/08/31 hof: gap_range_to_multilayer: all params available
* in non-interactive runmode
* 0.96.00; 1998/07/02 hof: (extracted from gap_lib.h)
* 0.94.01; 1998/04/27 hof: added flatten_mode to plugin: gap_range_to_multilayer
*/
#ifndef _GAP_RANGE_OPS_H
#define _GAP_RANGE_OPS_H
#include "libgimp/gimp.h"
/* flatten mode bits used in gap_range_to_multilayer */
#define FLAM_MERG_EXPAND 0
#define FLAM_MERG_CLIP_IMG 1
#define FLAM_MERG_CLIP_BG 2
#define FLAM_MERG_FLAT 3
/* Animation sizechange modes */
typedef enum
{
ASIZ_SCALE
, ASIZ_RESIZE
, ASIZ_CROP
} t_gap_asiz;
gint32 gap_range_to_multilayer(GRunModeType run_mode,
gint32 image_id,
long range_from, long range_to,
long flatten_mode, long bg_visible,
long framerate, char *frame_basename, int frame_basename_len,
gint32 sel_mode, gint32 sel_case,
gint32 sel_invert, char *sel_pattern
);
int gap_range_flatten(GRunModeType run_mode,
gint32 image_id,
long range_from, long range_to);
int gap_range_layer_del(GRunModeType run_mode,
gint32 image_id,
long range_from, long range_to, long position);
int gap_range_conv(GRunModeType run_mode,
gint32 image_id,
long range_from, long range_to,
long flatten,
GImageType dest_type,
gint32 dest_colors,
gint32 dest_dither,
char *basename,
char *extension);
int gap_anim_sizechange(GRunModeType run_mode,
t_gap_asiz asiz_mode,
gint32 image_id,
long size_x,
long size_y,
long offs_x,
long offs_y);
#endif

View File

@ -0,0 +1,166 @@
/* gap_resi_dialog.c
* 1998.07.01 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains the resize and scale Dialog for AnimFrames.
* (It just is a shell to call Gimp's resize / scale Dialog
* as it is coded in the Gimp kernel $GIMP_HOME/app/resize.c )
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history
* 0.96.00; 1998/07/01 hof: first release
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
#include "libgimp/gimpui.h"
#include "resize.h"
/* GAP includes */
#include "gap_lib.h"
#include "gap_range_ops.h"
#include "gap_resi_dialog.h"
typedef struct
{
GtkWidget * shell;
Resize * resize;
int gimage_id;
} ImageResize;
typedef struct {
GtkWidget *dlg;
gint run;
} t_res_int;
static void
res_cancel_callback (GtkWidget *widget,
gpointer data)
{
gtk_main_quit ();
}
static void
res_ok_callback (GtkWidget *widget,
gpointer data)
{
t_res_int *resi_ptr;
resi_ptr = (t_res_int *)data;
resi_ptr->run = TRUE;
gtk_widget_destroy (GTK_WIDGET (resi_ptr->dlg));
}
gint
p_resi_dialog (gint32 image_id, t_gap_asiz asiz_mode, char *title_text,
long *size_x, long *size_y,
long *offs_x, long *offs_y)
{
gchar **l_argsv;
gint l_argsc;
gint l_width;
gint l_height;
t_res_int l_resint;
Resize *l_rp;
GtkWidget *button;
GtkWidget *vbox;
ImageResize *image_resize;
l_resint.run = FALSE;
/* get info about the image (size is common to all frames) */
l_width = gimp_image_width(image_id);
l_height = gimp_image_height(image_id);
/* gtk init */
l_argsc = 1;
l_argsv = g_new (gchar *, 1);
l_argsv[0] = g_strdup ("gap_res_dialog");
gtk_init (&l_argsc, &l_argsv);
/* the ImageResize structure */
image_resize = (ImageResize *) g_malloc (sizeof (ImageResize));
image_resize->gimage_id = image_id;
if(asiz_mode == ASIZ_RESIZE)
{
image_resize->resize = resize_widget_new (ResizeWidget, l_width, l_height);
}
else
{
image_resize->resize = resize_widget_new (ScaleWidget, l_width, l_height);
}
/* the dialog */
image_resize->shell = gtk_dialog_new ();
l_resint.dlg = image_resize->shell;
gtk_window_set_title (GTK_WINDOW (image_resize->shell), title_text);
gtk_window_position (GTK_WINDOW (image_resize->shell), GTK_WIN_POS_MOUSE);
gtk_signal_connect (GTK_OBJECT (image_resize->shell), "destroy",
(GtkSignalFunc) res_cancel_callback,
NULL);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_border_width (GTK_CONTAINER (vbox), 1);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_resize->shell)->vbox), vbox, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (vbox), image_resize->resize->resize_widget, FALSE, FALSE, 0);
/* Action area */
button = gtk_button_new_with_label ("OK");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) res_ok_callback,
&l_resint);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_resize->shell)->action_area), button, TRUE, TRUE, 0);
gtk_widget_grab_default (button);
gtk_widget_show (button);
button = gtk_button_new_with_label ("Cancel");
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
(GtkSignalFunc) res_cancel_callback,
NULL);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (image_resize->shell)->action_area), button, TRUE, TRUE, 0);
gtk_widget_show (button);
gtk_widget_show (image_resize->resize->resize_widget);
gtk_widget_show (vbox);
gtk_widget_show (image_resize->shell);
gtk_main ();
gdk_flush ();
l_rp = image_resize->resize;
*size_x = l_rp->width;
*size_y = l_rp->height;
*offs_x = l_rp->off_x;
*offs_y = l_rp->off_y;
return (l_resint.run);
}

View File

@ -0,0 +1,46 @@
/* gap_resi_dialog.h
* 1998.07.01 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains the resize and scale Dialog for AnimFrames.
* (It just is a shell to call Gimp's resize / scale Dialog )
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history
* 0.96.00; 1998/07/01 hof: first release
*/
#ifndef _RESI_DIALOG_H
#define _RESI_DIALOG_H
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_range_ops.h"
gint p_resi_dialog (gint32 image_id,
t_gap_asiz asiz_mode,
char *title_text,
long *size_x, long *size_y,
long *offs_x, long *offs_y);
#endif

321
plug-ins/gap/gap_split.c Normal file
View File

@ -0,0 +1,321 @@
/* gap_range_ops.c
* 1997.11.06 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* This Module contains
* - gap_split_image
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history
* 0.96.00; 1998/07/01 hof: - added scale, resize and crop
* (affects full range == all anim frames)
* - now using gap_arr_dialog.h
* 0.94.01; 1998/04/28 hof: added flatten_mode to plugin: gap_range_to_multilayer
* 0.92.00 1998.01.10 hof: bugfix in p_frames_to_multilayer
* layers need alpha (to be raise/lower able)
* 0.90.00 first development release
*/
/* SYTEM (UNIX) includes */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
/* GIMP includes */
#include "gtk/gtk.h"
#include "libgimp/gimp.h"
/* GAP includes */
#include "gap_layer_copy.h"
#include "gap_lib.h"
#include "gap_arr_dialog.h"
extern int gap_debug; /* ==0 ... dont print debug infos */
/* ============================================================================
* p_split_image
*
* returns value >= 0 if all is ok return the image_id of
* the new created image (the last handled anim frame)
* (or -1 on error)
* ============================================================================
*/
static int
p_split_image(t_anim_info *ainfo_ptr,
char *new_extension,
gint invers, gint no_alpha)
{
GImageType l_type;
guint l_width, l_height;
GRunModeType l_run_mode;
gint32 l_new_image_id;
gint l_nlayers;
gint32 *l_layers_list;
gint32 l_src_layer_id;
gint32 l_cp_layer_id;
gint l_src_offset_x, l_src_offset_y; /* layeroffsets as they were in src_image */
gdouble l_percentage, l_percentage_step;
char *l_sav_name;
gint32 l_rc;
int l_idx;
long l_layer_idx;
l_rc = -1;
l_percentage = 0.0;
l_run_mode = ainfo_ptr->run_mode;
if(ainfo_ptr->run_mode == RUN_INTERACTIVE)
{
gimp_progress_init("Splitting into Frames ..");
}
l_new_image_id = -1;
/* get info about the image */
l_width = gimp_image_width(ainfo_ptr->image_id);
l_height = gimp_image_height(ainfo_ptr->image_id);
l_type = gimp_image_base_type(ainfo_ptr->image_id);
l_layers_list = gimp_image_get_layers(ainfo_ptr->image_id, &l_nlayers);
if(l_layers_list != NULL)
{
l_percentage_step = 1.0 / (l_nlayers);
for(l_idx = 0; l_idx < l_nlayers; l_idx++)
{
if(l_new_image_id >= 0)
{
/* destroy the tmp image (it was saved to disk before) */
gimp_image_delete(l_new_image_id);
}
if(invers == TRUE) l_layer_idx = l_idx;
else l_layer_idx = (l_nlayers - 1 ) - l_idx;
l_src_layer_id = l_layers_list[l_layer_idx];
/* create new image */
l_new_image_id = gimp_image_new(l_width, l_height,l_type);
if(l_new_image_id < 0)
{
l_rc = -1;
break;
}
/* copy the layer */
l_cp_layer_id = p_my_layer_copy(l_new_image_id,
l_src_layer_id,
100.0, /* Opacity */
0, /* NORMAL */
&l_src_offset_x,
&l_src_offset_y);
/* add the copied layer to current destination image */
gimp_image_add_layer(l_new_image_id, l_cp_layer_id, 0);
gimp_layer_set_offsets(l_cp_layer_id, l_src_offset_x, l_src_offset_y);
/* delete alpha channel ? */
if (no_alpha == TRUE)
{
/* add a dummy layer (flatten needs at least 2 layers) */
l_cp_layer_id = gimp_layer_new(l_new_image_id, "dummy",
4, 4, /* width, height */
l_type,
0.0, /* Opacity full transparent */
0); /* NORMAL */
gimp_image_add_layer(l_new_image_id, l_cp_layer_id, 0);
gimp_image_flatten (l_new_image_id);
}
/* build the name for output image */
l_sav_name = p_alloc_fname(ainfo_ptr->basename,
(l_idx +1), /* start at 1 (not at 0) */
new_extension);
if(l_sav_name != NULL)
{
/* save with selected save procedure
* (regardless if image was flattened or not)
*/
l_rc = p_save_named_image(l_new_image_id, l_sav_name, l_run_mode);
if(l_rc < 0)
{
p_msg_win(ainfo_ptr->run_mode, "Split Frames: SAVE operation FAILED\n- desired save plugin cant handle type\n- or desired save plugin not available\n");
break;
}
l_run_mode = RUN_NONINTERACTIVE; /* for all further calls */
/* set image name */
gimp_image_set_filename (l_new_image_id, l_sav_name);
/* prepare return value */
l_rc = l_new_image_id;
free(l_sav_name);
}
/* save as frame */
/* show progress bar */
if(ainfo_ptr->run_mode == RUN_INTERACTIVE)
{
l_percentage += l_percentage_step;
gimp_progress_update (l_percentage);
}
}
g_free (l_layers_list);
}
return l_rc;
} /* end p_split_image */
/* ============================================================================
* p_split_dialog
*
* return 0 (OK)
* or -1 in case of Error or cancel
* ============================================================================
*/
static long
p_split_dialog(t_anim_info *ainfo_ptr, gint *inverse_order, gint *no_alpha, char *extension, gint len_ext)
{
static t_arr_arg argv[4];
char buf[128];
sprintf(buf, "%s\n%s\n(%s_0001.%s)\n",
"Make a frame (diskfile) from each Layer",
"frames are named: base_nr.extension",
ainfo_ptr->basename, extension);
p_init_arr_arg(&argv[0], WGT_LABEL);
argv[0].label_txt = &buf[0];
p_init_arr_arg(&argv[1], WGT_TEXT);
argv[1].label_txt ="Extension:";
argv[1].help_txt ="extension of resulting frames \n(is also used to define Fileformat)";
argv[1].text_buf_len = len_ext;
argv[1].text_buf_ret = extension;
p_init_arr_arg(&argv[2], WGT_TOGGLE);
argv[2].label_txt = "Inverse Order :";
argv[2].help_txt = "Start frame 0001 at Top Layer";
argv[2].int_ret = 0;
p_init_arr_arg(&argv[3], WGT_TOGGLE);
argv[3].label_txt = "Flatten :";
argv[3].help_txt = "Remove Alpha Channel in resulting Frames, \ntransparent parts are filled with BG color";
argv[3].int_ret = 0;
if(TRUE == p_array_dialog("Split Image into Frames",
"Split Settings :",
4, argv))
{
*inverse_order = argv[2].int_ret;
*no_alpha = argv[3].int_ret;
return 0;
}
else
{
return -1;
}
} /* end p_split_dialog */
/* ============================================================================
* gap_split_image
* Split one (multilayer) image into anim-frames
* one frame per layer.
* ============================================================================
*/
int gap_split_image(GRunModeType run_mode,
gint32 image_id,
gint32 inverse_order,
gint32 no_alpha,
char *extension)
{
gint32 l_new_image_id;
gint32 l_rc;
gint32 l_inverse_order;
gint32 l_no_alpha;
t_anim_info *ainfo_ptr;
char l_extension[32];
strcpy(l_extension, ".xcf");
l_rc = -1;
ainfo_ptr = p_alloc_ainfo(image_id, run_mode);
if(ainfo_ptr != NULL)
{
if (0 == p_dir_ainfo(ainfo_ptr))
{
if(ainfo_ptr->frame_cnt != 0)
{
p_msg_win(run_mode,
"OPERATION CANCELLED\nThis image is already an AnimFrame\nTry again on a Duplicate\n(image/channel ops/duplicate)");
return -1;
}
else
{
if(run_mode == RUN_INTERACTIVE)
{
l_rc = p_split_dialog (ainfo_ptr, &l_inverse_order, &l_no_alpha, &l_extension[0], sizeof(l_extension));
}
else
{
l_inverse_order = inverse_order;
l_no_alpha = no_alpha;
strncpy(l_extension, extension, sizeof(l_extension) -1);
l_extension[sizeof(l_extension) -1] = '\0';
}
if(l_rc >= 0)
{
l_new_image_id = p_split_image(ainfo_ptr,
l_extension,
l_inverse_order,
l_no_alpha);
/* create a display for the new created image
* (it is the first or the last frame of the
* new created animation sequence)
*/
gimp_display_new(l_new_image_id);
l_rc = l_new_image_id;
}
}
}
p_free_ainfo(&ainfo_ptr);
}
return(l_rc);
} /* end gap_split_image */

47
plug-ins/gap/gap_split.h Normal file
View File

@ -0,0 +1,47 @@
/* gap_lib.h
* 1997.11.01 hof (Wolfgang Hofer)
*
* GAP ... Gimp Animation Plugins
*
* Split Image to Anim Frames (seperate Images on disk)
*
*/
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* revision history:
* 0.96.00; 1998/07/03 hof: 1.st releas
*/
#ifndef _GAP_SPLIT_H
#define _GAP_SPLIT_H
#include "libgimp/gimp.h"
int gap_split_image(GRunModeType run_mode,
gint32 image_id,
gint32 inverse_order,
gint32 no_alpha,
char *extension);
#endif

View File

@ -0,0 +1,46 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __APPENV_H__
#define __APPENV_H__
#include "gdk/gdkx.h"
#include "gtk/gtk.h"
#define DISPLAY ((Display *) GDK_DISPLAY())
/* important macros */
#define BOUNDS(a,x,y) ((a < x) ? x : ((a > y) ? y : a))
#define MINIMUM(x,y) ((x < y) ? x : y)
#define MAXIMUM(x,y) ((x > y) ? x : y)
typedef enum {
MESSAGE_BOX,
CONSOLE
} MessageHandlerType;
extern int no_interface;
extern int no_splash;
extern int no_splash_image;
extern int no_data;
extern int be_verbose;
extern int use_debug_handler;
extern int console_messages;
extern MessageHandlerType message_handler;
#endif /* APPENV_H */

View File

@ -0,0 +1,822 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "appenv.h"
#include "resize.h"
#define EVENT_MASK GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK
#define DRAWING_AREA_SIZE 200
#define TEXT_WIDTH 35
typedef struct _ResizePrivate ResizePrivate;
struct _ResizePrivate
{
GtkWidget *width_text;
GtkWidget *height_text;
GtkWidget *ratio_x_text;
GtkWidget *ratio_y_text;
GtkWidget *off_x_text;
GtkWidget *off_y_text;
GtkWidget *drawing_area;
double ratio;
int constrain;
int old_width, old_height;
int area_width, area_height;
int start_x, start_y;
int orig_x, orig_y;
};
static void resize_draw (Resize *);
static int resize_bound_off_x (Resize *, int);
static int resize_bound_off_y (Resize *, int);
static void off_x_update (GtkWidget *w, gpointer data);
static void off_y_update (GtkWidget *w, gpointer data);
static void width_update (GtkWidget *w, gpointer data);
static void height_update (GtkWidget *w, gpointer data);
static void ratio_x_update (GtkWidget *w, gpointer data);
static void ratio_y_update (GtkWidget *w, gpointer data);
static void constrain_update (GtkWidget *w, gpointer data);
static gint resize_events (GtkWidget *area, GdkEvent *event);
Resize *
resize_widget_new (ResizeType type,
int width,
int height)
{
Resize *resize;
ResizePrivate *private;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *frame;
GtkWidget *constrain;
GtkWidget *table;
char size[12];
char ratio_text[12];
table = NULL;
resize = g_new (Resize, 1);
private = g_new (ResizePrivate, 1);
resize->type = type;
resize->private_part = private;
resize->width = width;
resize->height = height;
resize->ratio_x = 1.0;
resize->ratio_y = 1.0;
resize->off_x = 0;
resize->off_y = 0;
private->old_width = width;
private->old_height = height;
private->constrain = TRUE;
/* Get the image width and height variables, based on the gimage */
if (width > height)
private->ratio = (double) DRAWING_AREA_SIZE / (double) width;
else
private->ratio = (double) DRAWING_AREA_SIZE / (double) height;
private->area_width = (int) (private->ratio * width);
private->area_height = (int) (private->ratio * height);
switch (type)
{
case ScaleWidget:
resize->resize_widget = gtk_frame_new ("Scale");
table = gtk_table_new (4, 2, TRUE);
break;
case ResizeWidget:
resize->resize_widget = gtk_frame_new ("Resize");
table = gtk_table_new (6, 2, TRUE);
break;
}
gtk_frame_set_shadow_type (GTK_FRAME (resize->resize_widget), GTK_SHADOW_ETCHED_IN);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_border_width (GTK_CONTAINER (vbox), 5);
gtk_container_add (GTK_CONTAINER (resize->resize_widget), vbox);
gtk_container_border_width (GTK_CONTAINER (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
/* the width label and entry */
sprintf (size, "%d", width);
label = gtk_label_new ("New width:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->width_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->width_text, 1, 2, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->width_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->width_text), size);
gtk_signal_connect (GTK_OBJECT (private->width_text), "changed",
(GtkSignalFunc) width_update,
resize);
gtk_widget_show (private->width_text);
/* the height label and entry */
sprintf (size, "%d", height);
label = gtk_label_new ("New height:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->height_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->height_text, 1, 2, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->height_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->height_text), size);
gtk_signal_connect (GTK_OBJECT (private->height_text), "changed",
(GtkSignalFunc) height_update,
resize);
gtk_widget_show (private->height_text);
/* the x scale ratio label and entry */
sprintf (ratio_text, "%0.4f", resize->ratio_x);
label = gtk_label_new ("X ratio:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->ratio_x_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->ratio_x_text, 1, 2, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->ratio_x_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->ratio_x_text), ratio_text);
gtk_signal_connect (GTK_OBJECT (private->ratio_x_text), "changed",
(GtkSignalFunc) ratio_x_update,
resize);
gtk_widget_show (private->ratio_x_text);
/* the y scale ratio label and entry */
sprintf (ratio_text, "%0.4f", resize->ratio_y);
label = gtk_label_new ("Y ratio:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->ratio_y_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->ratio_y_text, 1, 2, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->ratio_y_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->ratio_y_text), ratio_text);
gtk_signal_connect (GTK_OBJECT (private->ratio_y_text), "changed",
(GtkSignalFunc) ratio_y_update,
resize);
gtk_widget_show (private->ratio_y_text);
if (type == ResizeWidget)
{
/* the off_x label and entry */
sprintf (size, "%d", 0);
label = gtk_label_new ("X Offset:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->off_x_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->off_x_text, 1, 2, 4, 5,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->off_x_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_connect (GTK_OBJECT (private->off_x_text), "changed",
(GtkSignalFunc) off_x_update,
resize);
gtk_widget_show (private->off_x_text);
/* the off_y label and entry */
sprintf (size, "%d", 0);
label = gtk_label_new ("Y Offset:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 5, 6,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->off_y_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->off_y_text, 1, 2, 5, 6,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->off_y_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_connect (GTK_OBJECT (private->off_y_text), "changed",
(GtkSignalFunc) off_y_update,
resize);
gtk_widget_show (private->off_y_text);
}
/* the constrain toggle button */
constrain = gtk_check_button_new_with_label ("Constrain Ratio");
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (constrain), private->constrain);
gtk_box_pack_start (GTK_BOX (vbox), constrain, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (constrain), "toggled",
(GtkSignalFunc) constrain_update,
resize);
gtk_widget_show (constrain);
if (type == ResizeWidget)
{
/* frame to hold drawing area */
hbox = gtk_hbox_new (FALSE, 1);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 2);
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, FALSE, 0);
private->drawing_area = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (private->drawing_area),
private->area_width, private->area_height);
gtk_widget_set_events (private->drawing_area, EVENT_MASK);
gtk_signal_connect (GTK_OBJECT (private->drawing_area), "event",
(GtkSignalFunc) resize_events,
NULL);
gtk_object_set_user_data (GTK_OBJECT (private->drawing_area), resize);
gtk_container_add (GTK_CONTAINER (frame), private->drawing_area);
gtk_widget_show (private->drawing_area);
gtk_widget_show (frame);
gtk_widget_show (hbox);
}
gtk_widget_show (table);
gtk_widget_show (vbox);
return resize;
}
void
resize_widget_free (Resize *resize)
{
g_free (resize->private_part);
g_free (resize);
}
static void
resize_draw (Resize *resize)
{
GtkWidget *widget;
ResizePrivate *private;
int aw, ah;
int x, y;
int w, h;
/* Only need to draw if it's a resize widget */
if (resize->type != ResizeWidget)
return;
private = (ResizePrivate *) resize->private_part;
widget = private->drawing_area;
/* If we're making the size larger */
if (private->old_width <= resize->width)
w = resize->width;
/* otherwise, if we're making the size smaller */
else
w = private->old_width * 2 - resize->width;
/* If we're making the size larger */
if (private->old_height <= resize->height)
h = resize->height;
/* otherwise, if we're making the size smaller */
else
h = private->old_height * 2 - resize->height;
if (w > h)
private->ratio = (double) DRAWING_AREA_SIZE / (double) w;
else
private->ratio = (double) DRAWING_AREA_SIZE / (double) h;
aw = (int) (private->ratio * w);
ah = (int) (private->ratio * h);
if (aw != private->area_width || ah != private->area_height)
{
private->area_width = aw;
private->area_height = ah;
gtk_widget_set_usize (private->drawing_area, aw, ah);
}
if (private->old_width <= resize->width)
x = private->ratio * resize->off_x;
else
x = private->ratio * (resize->off_x + private->old_width - resize->width);
if (private->old_height <= resize->height)
y = private->ratio * resize->off_y;
else
y = private->ratio * (resize->off_y + private->old_height - resize->height);
w = private->ratio * private->old_width;
h = private->ratio * private->old_height;
gdk_window_clear (private->drawing_area->window);
gtk_draw_shadow (widget->style, widget->window,
GTK_STATE_NORMAL, GTK_SHADOW_OUT,
x, y, w, h);
/* If we're making the size smaller */
if (private->old_width > resize->width ||
private->old_height > resize->height)
{
if (private->old_width > resize->width)
{
x = private->ratio * (private->old_width - resize->width);
w = private->ratio * resize->width;
}
else
{
x = -1;
w = aw + 2;
}
if (private->old_height > resize->height)
{
y = private->ratio * (private->old_height - resize->height);
h = private->ratio * resize->height;
}
else
{
y = -1;
h = ah + 2;
}
gdk_draw_rectangle (private->drawing_area->window,
widget->style->black_gc, 0,
x, y, w, h);
}
}
static int
resize_bound_off_x (Resize *resize,
int off_x)
{
ResizePrivate *private;
private = (ResizePrivate *) resize->private_part;
if (private->old_width <= resize->width)
off_x = BOUNDS (off_x, 0, (resize->width - private->old_width));
else
off_x = BOUNDS (off_x, (resize->width - private->old_width), 0);
return off_x;
}
static int
resize_bound_off_y (Resize *resize,
int off_y)
{
ResizePrivate *private;
private = (ResizePrivate *) resize->private_part;
if (private->old_height <= resize->height)
off_y = BOUNDS (off_y, 0, (resize->height - private->old_height));
else
off_y = BOUNDS (off_y, (resize->height - private->old_height), 0);
return off_y;
}
static void
constrain_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
if (GTK_TOGGLE_BUTTON (w)->active)
private->constrain = TRUE;
else
private->constrain = FALSE;
}
static void
off_x_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
int offset;
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
offset = atoi (str);
offset = resize_bound_off_x (resize, offset);
if (offset != resize->off_x)
{
resize->off_x = offset;
resize_draw (resize);
}
}
static void
off_y_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
int offset;
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
offset = atoi (str);
offset = resize_bound_off_y (resize, offset);
if (offset != resize->off_y)
{
resize->off_y = offset;
resize_draw (resize);
}
}
static void
width_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
double ratio;
int new_height;
char size[12];
char ratio_text[12];
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
resize->width = atoi (str);
ratio = (double) resize->width / (double) private->old_width;
resize->ratio_x = ratio;
sprintf (ratio_text, "%0.4f", ratio);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_x_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_x_text), data);
if (resize->type == ResizeWidget)
{
resize->off_x = resize_bound_off_x (resize, (resize->width - private->old_width) / 2);
sprintf (size, "%d", resize->off_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_x_text), data);
}
if (private->constrain && resize->width != 0)
{
private->constrain = FALSE;
new_height = (int) (private->old_height * ratio);
if (new_height == 0) new_height = 1;
if (new_height != resize->height)
{
resize->height = new_height;
sprintf (size, "%d", resize->height);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->height_text), data);
gtk_entry_set_text (GTK_ENTRY (private->height_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->height_text), data);
resize->ratio_y = ratio;
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_y_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_y_text), data);
if (resize->type == ResizeWidget)
{
resize->off_y = resize_bound_off_y (resize, (resize->height - private->old_height) / 2);
sprintf (size, "%d", resize->off_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_y_text), data);
}
}
private->constrain = TRUE;
}
resize_draw (resize);
}
static void
height_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
double ratio;
int new_width;
char size[12];
char ratio_text[12];
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
resize->height = atoi (str);
ratio = (double) resize->height / (double) private->old_height;
resize->ratio_y = ratio;
sprintf (ratio_text, "%0.4f", ratio);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_y_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_y_text), data);
if (resize->type == ResizeWidget)
{
resize->off_y = resize_bound_off_y (resize, (resize->height - private->old_height) / 2);
sprintf (size, "%d", resize->off_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_y_text), data);
}
if (private->constrain && resize->height != 0)
{
private->constrain = FALSE;
ratio = (double) resize->height / (double) private->old_height;
new_width = (int) (private->old_width * ratio);
if (new_width == 0) new_width = 1;
if (new_width != resize->width)
{
resize->width = new_width;
sprintf (size, "%d", resize->width);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->width_text), data);
gtk_entry_set_text (GTK_ENTRY (private->width_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->width_text), data);
resize->ratio_x = ratio;
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_x_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_x_text), data);
if (resize->type == ResizeWidget)
{
resize->off_x = resize_bound_off_x (resize, (resize->width - private->old_width) / 2);
sprintf (size, "%d", resize->off_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_x_text), data);
}
}
private->constrain = TRUE;
}
resize_draw (resize);
}
static void
ratio_x_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
int new_width;
int new_height;
char size[12];
char ratio_text[12];
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
resize->ratio_x = atof (str);
new_width = (int) ((double) private->old_width * resize->ratio_x);
if (new_width != resize->width)
{
resize->width = new_width;
sprintf (size, "%d", new_width);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->width_text), data);
gtk_entry_set_text (GTK_ENTRY (private->width_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->width_text), data);
if (resize->type == ResizeWidget)
{
resize->off_x = resize_bound_off_x (resize, (resize->width - private->old_width) / 2);
sprintf (size, "%d", resize->off_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_x_text), data);
}
}
if (private->constrain && resize->width != 0)
{
private->constrain = FALSE;
resize->ratio_y = resize->ratio_x;
new_height = (int) (private->old_height * resize->ratio_y);
if (new_height == 0) new_height = 1;
if (new_height != resize->height)
{
resize->height = new_height;
sprintf (size, "%d", resize->height);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->height_text), data);
gtk_entry_set_text (GTK_ENTRY (private->height_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->height_text), data);
sprintf (ratio_text, "%0.4f", resize->ratio_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_y_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_y_text), data);
if (resize->type == ResizeWidget)
{
resize->off_y = resize_bound_off_y (resize, (resize->height - private->old_height) / 2);
sprintf (size, "%d", resize->off_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_y_text), data);
}
}
private->constrain = TRUE;
}
resize_draw (resize);
}
static void
ratio_y_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
int new_width;
int new_height;
char size[12];
char ratio_text[12];
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
resize->ratio_y = atof (str);
new_height = (int) ((double) private->old_height * resize->ratio_y);
if (new_height != resize->height)
{
resize->height = new_height;
sprintf (size, "%d", new_height);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->height_text), data);
gtk_entry_set_text (GTK_ENTRY (private->height_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->height_text), data);
if (resize->type == ResizeWidget)
{
resize->off_y = resize_bound_off_y (resize, (resize->height - private->old_height) / 2);
sprintf (size, "%d", resize->off_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_y_text), data);
}
}
if (private->constrain && resize->height != 0)
{
private->constrain = FALSE;
resize->ratio_x = resize->ratio_y;
new_width = (int) (private->old_width * resize->ratio_x);
if (new_width == 0) new_width = 1;
if (new_width != resize->width)
{
resize->width = new_width;
sprintf (size, "%d", resize->width);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->width_text), data);
gtk_entry_set_text (GTK_ENTRY (private->width_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->width_text), data);
sprintf (ratio_text, "%0.4f", resize->ratio_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_x_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_x_text), data);
if (resize->type == ResizeWidget)
{
resize->off_x = resize_bound_off_x (resize, (resize->width - private->old_width) / 2);
sprintf (size, "%d", resize->off_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_x_text), data);
}
}
private->constrain = TRUE;
}
resize_draw (resize);
}
static gint
resize_events (GtkWidget *widget,
GdkEvent *event)
{
Resize *resize;
ResizePrivate *private;
int dx, dy;
int off_x, off_y;
char size[12];
resize = (Resize *) gtk_object_get_user_data (GTK_OBJECT (widget));
private = (ResizePrivate *) resize->private_part;
switch (event->type)
{
case GDK_EXPOSE:
resize_draw (resize);
break;
case GDK_BUTTON_PRESS:
gdk_pointer_grab (private->drawing_area->window, FALSE,
(GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK),
NULL, NULL, event->button.time);
private->orig_x = resize->off_x;
private->orig_y = resize->off_y;
private->start_x = event->button.x;
private->start_y = event->button.y;
break;
case GDK_MOTION_NOTIFY:
/* X offset */
dx = event->motion.x - private->start_x;
off_x = private->orig_x + dx / private->ratio;
off_x = resize_bound_off_x (resize, off_x);
sprintf (size, "%d", off_x);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
/* Y offset */
dy = event->motion.y - private->start_y;
off_y = private->orig_y + dy / private->ratio;
off_y = resize_bound_off_y (resize, off_y);
sprintf (size, "%d", off_y);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
break;
case GDK_BUTTON_RELEASE:
gdk_pointer_ungrab (event->button.time);
break;
default:
break;
}
return FALSE;
}

View File

@ -0,0 +1,51 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __RESIZE_H__
#define __RESIZE_H__
typedef enum
{
ScaleWidget,
ResizeWidget
} ResizeType;
typedef struct _Resize Resize;
struct _Resize
{
/* The calling procedure is respondible for showing this widget */
GtkWidget *resize_widget;
ResizeType type;
int width;
int height;
double ratio_x;
double ratio_y;
int off_x;
int off_y;
/* Don't touch this :) */
void * private_part;
};
Resize * resize_widget_new (ResizeType type,
int width,
int height);
void resize_widget_free (Resize * resize);
#endif /* __RESIZE_H__ */

822
plug-ins/gap/resize.c Normal file
View File

@ -0,0 +1,822 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "appenv.h"
#include "resize.h"
#define EVENT_MASK GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK
#define DRAWING_AREA_SIZE 200
#define TEXT_WIDTH 35
typedef struct _ResizePrivate ResizePrivate;
struct _ResizePrivate
{
GtkWidget *width_text;
GtkWidget *height_text;
GtkWidget *ratio_x_text;
GtkWidget *ratio_y_text;
GtkWidget *off_x_text;
GtkWidget *off_y_text;
GtkWidget *drawing_area;
double ratio;
int constrain;
int old_width, old_height;
int area_width, area_height;
int start_x, start_y;
int orig_x, orig_y;
};
static void resize_draw (Resize *);
static int resize_bound_off_x (Resize *, int);
static int resize_bound_off_y (Resize *, int);
static void off_x_update (GtkWidget *w, gpointer data);
static void off_y_update (GtkWidget *w, gpointer data);
static void width_update (GtkWidget *w, gpointer data);
static void height_update (GtkWidget *w, gpointer data);
static void ratio_x_update (GtkWidget *w, gpointer data);
static void ratio_y_update (GtkWidget *w, gpointer data);
static void constrain_update (GtkWidget *w, gpointer data);
static gint resize_events (GtkWidget *area, GdkEvent *event);
Resize *
resize_widget_new (ResizeType type,
int width,
int height)
{
Resize *resize;
ResizePrivate *private;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *frame;
GtkWidget *constrain;
GtkWidget *table;
char size[12];
char ratio_text[12];
table = NULL;
resize = g_new (Resize, 1);
private = g_new (ResizePrivate, 1);
resize->type = type;
resize->private_part = private;
resize->width = width;
resize->height = height;
resize->ratio_x = 1.0;
resize->ratio_y = 1.0;
resize->off_x = 0;
resize->off_y = 0;
private->old_width = width;
private->old_height = height;
private->constrain = TRUE;
/* Get the image width and height variables, based on the gimage */
if (width > height)
private->ratio = (double) DRAWING_AREA_SIZE / (double) width;
else
private->ratio = (double) DRAWING_AREA_SIZE / (double) height;
private->area_width = (int) (private->ratio * width);
private->area_height = (int) (private->ratio * height);
switch (type)
{
case ScaleWidget:
resize->resize_widget = gtk_frame_new ("Scale");
table = gtk_table_new (4, 2, TRUE);
break;
case ResizeWidget:
resize->resize_widget = gtk_frame_new ("Resize");
table = gtk_table_new (6, 2, TRUE);
break;
}
gtk_frame_set_shadow_type (GTK_FRAME (resize->resize_widget), GTK_SHADOW_ETCHED_IN);
/* the main vbox */
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_border_width (GTK_CONTAINER (vbox), 5);
gtk_container_add (GTK_CONTAINER (resize->resize_widget), vbox);
gtk_container_border_width (GTK_CONTAINER (table), 2);
gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
/* the width label and entry */
sprintf (size, "%d", width);
label = gtk_label_new ("New width:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->width_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->width_text, 1, 2, 0, 1,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->width_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->width_text), size);
gtk_signal_connect (GTK_OBJECT (private->width_text), "changed",
(GtkSignalFunc) width_update,
resize);
gtk_widget_show (private->width_text);
/* the height label and entry */
sprintf (size, "%d", height);
label = gtk_label_new ("New height:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->height_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->height_text, 1, 2, 1, 2,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->height_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->height_text), size);
gtk_signal_connect (GTK_OBJECT (private->height_text), "changed",
(GtkSignalFunc) height_update,
resize);
gtk_widget_show (private->height_text);
/* the x scale ratio label and entry */
sprintf (ratio_text, "%0.4f", resize->ratio_x);
label = gtk_label_new ("X ratio:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->ratio_x_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->ratio_x_text, 1, 2, 2, 3,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->ratio_x_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->ratio_x_text), ratio_text);
gtk_signal_connect (GTK_OBJECT (private->ratio_x_text), "changed",
(GtkSignalFunc) ratio_x_update,
resize);
gtk_widget_show (private->ratio_x_text);
/* the y scale ratio label and entry */
sprintf (ratio_text, "%0.4f", resize->ratio_y);
label = gtk_label_new ("Y ratio:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->ratio_y_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->ratio_y_text, 1, 2, 3, 4,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->ratio_y_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->ratio_y_text), ratio_text);
gtk_signal_connect (GTK_OBJECT (private->ratio_y_text), "changed",
(GtkSignalFunc) ratio_y_update,
resize);
gtk_widget_show (private->ratio_y_text);
if (type == ResizeWidget)
{
/* the off_x label and entry */
sprintf (size, "%d", 0);
label = gtk_label_new ("X Offset:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->off_x_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->off_x_text, 1, 2, 4, 5,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->off_x_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_connect (GTK_OBJECT (private->off_x_text), "changed",
(GtkSignalFunc) off_x_update,
resize);
gtk_widget_show (private->off_x_text);
/* the off_y label and entry */
sprintf (size, "%d", 0);
label = gtk_label_new ("Y Offset:");
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 5, 6,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_show (label);
private->off_y_text = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), private->off_y_text, 1, 2, 5, 6,
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
gtk_widget_set_usize (private->off_y_text, TEXT_WIDTH, 25);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_connect (GTK_OBJECT (private->off_y_text), "changed",
(GtkSignalFunc) off_y_update,
resize);
gtk_widget_show (private->off_y_text);
}
/* the constrain toggle button */
constrain = gtk_check_button_new_with_label ("Constrain Ratio");
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (constrain), private->constrain);
gtk_box_pack_start (GTK_BOX (vbox), constrain, FALSE, FALSE, 0);
gtk_signal_connect (GTK_OBJECT (constrain), "toggled",
(GtkSignalFunc) constrain_update,
resize);
gtk_widget_show (constrain);
if (type == ResizeWidget)
{
/* frame to hold drawing area */
hbox = gtk_hbox_new (FALSE, 1);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, FALSE, 0);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_container_border_width (GTK_CONTAINER (frame), 2);
gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, FALSE, 0);
private->drawing_area = gtk_drawing_area_new ();
gtk_drawing_area_size (GTK_DRAWING_AREA (private->drawing_area),
private->area_width, private->area_height);
gtk_widget_set_events (private->drawing_area, EVENT_MASK);
gtk_signal_connect (GTK_OBJECT (private->drawing_area), "event",
(GtkSignalFunc) resize_events,
NULL);
gtk_object_set_user_data (GTK_OBJECT (private->drawing_area), resize);
gtk_container_add (GTK_CONTAINER (frame), private->drawing_area);
gtk_widget_show (private->drawing_area);
gtk_widget_show (frame);
gtk_widget_show (hbox);
}
gtk_widget_show (table);
gtk_widget_show (vbox);
return resize;
}
void
resize_widget_free (Resize *resize)
{
g_free (resize->private_part);
g_free (resize);
}
static void
resize_draw (Resize *resize)
{
GtkWidget *widget;
ResizePrivate *private;
int aw, ah;
int x, y;
int w, h;
/* Only need to draw if it's a resize widget */
if (resize->type != ResizeWidget)
return;
private = (ResizePrivate *) resize->private_part;
widget = private->drawing_area;
/* If we're making the size larger */
if (private->old_width <= resize->width)
w = resize->width;
/* otherwise, if we're making the size smaller */
else
w = private->old_width * 2 - resize->width;
/* If we're making the size larger */
if (private->old_height <= resize->height)
h = resize->height;
/* otherwise, if we're making the size smaller */
else
h = private->old_height * 2 - resize->height;
if (w > h)
private->ratio = (double) DRAWING_AREA_SIZE / (double) w;
else
private->ratio = (double) DRAWING_AREA_SIZE / (double) h;
aw = (int) (private->ratio * w);
ah = (int) (private->ratio * h);
if (aw != private->area_width || ah != private->area_height)
{
private->area_width = aw;
private->area_height = ah;
gtk_widget_set_usize (private->drawing_area, aw, ah);
}
if (private->old_width <= resize->width)
x = private->ratio * resize->off_x;
else
x = private->ratio * (resize->off_x + private->old_width - resize->width);
if (private->old_height <= resize->height)
y = private->ratio * resize->off_y;
else
y = private->ratio * (resize->off_y + private->old_height - resize->height);
w = private->ratio * private->old_width;
h = private->ratio * private->old_height;
gdk_window_clear (private->drawing_area->window);
gtk_draw_shadow (widget->style, widget->window,
GTK_STATE_NORMAL, GTK_SHADOW_OUT,
x, y, w, h);
/* If we're making the size smaller */
if (private->old_width > resize->width ||
private->old_height > resize->height)
{
if (private->old_width > resize->width)
{
x = private->ratio * (private->old_width - resize->width);
w = private->ratio * resize->width;
}
else
{
x = -1;
w = aw + 2;
}
if (private->old_height > resize->height)
{
y = private->ratio * (private->old_height - resize->height);
h = private->ratio * resize->height;
}
else
{
y = -1;
h = ah + 2;
}
gdk_draw_rectangle (private->drawing_area->window,
widget->style->black_gc, 0,
x, y, w, h);
}
}
static int
resize_bound_off_x (Resize *resize,
int off_x)
{
ResizePrivate *private;
private = (ResizePrivate *) resize->private_part;
if (private->old_width <= resize->width)
off_x = BOUNDS (off_x, 0, (resize->width - private->old_width));
else
off_x = BOUNDS (off_x, (resize->width - private->old_width), 0);
return off_x;
}
static int
resize_bound_off_y (Resize *resize,
int off_y)
{
ResizePrivate *private;
private = (ResizePrivate *) resize->private_part;
if (private->old_height <= resize->height)
off_y = BOUNDS (off_y, 0, (resize->height - private->old_height));
else
off_y = BOUNDS (off_y, (resize->height - private->old_height), 0);
return off_y;
}
static void
constrain_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
if (GTK_TOGGLE_BUTTON (w)->active)
private->constrain = TRUE;
else
private->constrain = FALSE;
}
static void
off_x_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
int offset;
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
offset = atoi (str);
offset = resize_bound_off_x (resize, offset);
if (offset != resize->off_x)
{
resize->off_x = offset;
resize_draw (resize);
}
}
static void
off_y_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
int offset;
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
offset = atoi (str);
offset = resize_bound_off_y (resize, offset);
if (offset != resize->off_y)
{
resize->off_y = offset;
resize_draw (resize);
}
}
static void
width_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
double ratio;
int new_height;
char size[12];
char ratio_text[12];
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
resize->width = atoi (str);
ratio = (double) resize->width / (double) private->old_width;
resize->ratio_x = ratio;
sprintf (ratio_text, "%0.4f", ratio);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_x_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_x_text), data);
if (resize->type == ResizeWidget)
{
resize->off_x = resize_bound_off_x (resize, (resize->width - private->old_width) / 2);
sprintf (size, "%d", resize->off_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_x_text), data);
}
if (private->constrain && resize->width != 0)
{
private->constrain = FALSE;
new_height = (int) (private->old_height * ratio);
if (new_height == 0) new_height = 1;
if (new_height != resize->height)
{
resize->height = new_height;
sprintf (size, "%d", resize->height);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->height_text), data);
gtk_entry_set_text (GTK_ENTRY (private->height_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->height_text), data);
resize->ratio_y = ratio;
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_y_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_y_text), data);
if (resize->type == ResizeWidget)
{
resize->off_y = resize_bound_off_y (resize, (resize->height - private->old_height) / 2);
sprintf (size, "%d", resize->off_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_y_text), data);
}
}
private->constrain = TRUE;
}
resize_draw (resize);
}
static void
height_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
double ratio;
int new_width;
char size[12];
char ratio_text[12];
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
resize->height = atoi (str);
ratio = (double) resize->height / (double) private->old_height;
resize->ratio_y = ratio;
sprintf (ratio_text, "%0.4f", ratio);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_y_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_y_text), data);
if (resize->type == ResizeWidget)
{
resize->off_y = resize_bound_off_y (resize, (resize->height - private->old_height) / 2);
sprintf (size, "%d", resize->off_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_y_text), data);
}
if (private->constrain && resize->height != 0)
{
private->constrain = FALSE;
ratio = (double) resize->height / (double) private->old_height;
new_width = (int) (private->old_width * ratio);
if (new_width == 0) new_width = 1;
if (new_width != resize->width)
{
resize->width = new_width;
sprintf (size, "%d", resize->width);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->width_text), data);
gtk_entry_set_text (GTK_ENTRY (private->width_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->width_text), data);
resize->ratio_x = ratio;
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_x_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_x_text), data);
if (resize->type == ResizeWidget)
{
resize->off_x = resize_bound_off_x (resize, (resize->width - private->old_width) / 2);
sprintf (size, "%d", resize->off_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_x_text), data);
}
}
private->constrain = TRUE;
}
resize_draw (resize);
}
static void
ratio_x_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
int new_width;
int new_height;
char size[12];
char ratio_text[12];
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
resize->ratio_x = atof (str);
new_width = (int) ((double) private->old_width * resize->ratio_x);
if (new_width != resize->width)
{
resize->width = new_width;
sprintf (size, "%d", new_width);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->width_text), data);
gtk_entry_set_text (GTK_ENTRY (private->width_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->width_text), data);
if (resize->type == ResizeWidget)
{
resize->off_x = resize_bound_off_x (resize, (resize->width - private->old_width) / 2);
sprintf (size, "%d", resize->off_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_x_text), data);
}
}
if (private->constrain && resize->width != 0)
{
private->constrain = FALSE;
resize->ratio_y = resize->ratio_x;
new_height = (int) (private->old_height * resize->ratio_y);
if (new_height == 0) new_height = 1;
if (new_height != resize->height)
{
resize->height = new_height;
sprintf (size, "%d", resize->height);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->height_text), data);
gtk_entry_set_text (GTK_ENTRY (private->height_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->height_text), data);
sprintf (ratio_text, "%0.4f", resize->ratio_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_y_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_y_text), data);
if (resize->type == ResizeWidget)
{
resize->off_y = resize_bound_off_y (resize, (resize->height - private->old_height) / 2);
sprintf (size, "%d", resize->off_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_y_text), data);
}
}
private->constrain = TRUE;
}
resize_draw (resize);
}
static void
ratio_y_update (GtkWidget *w,
gpointer data)
{
Resize *resize;
ResizePrivate *private;
char *str;
int new_width;
int new_height;
char size[12];
char ratio_text[12];
resize = (Resize *) data;
private = (ResizePrivate *) resize->private_part;
str = gtk_entry_get_text (GTK_ENTRY (w));
resize->ratio_y = atof (str);
new_height = (int) ((double) private->old_height * resize->ratio_y);
if (new_height != resize->height)
{
resize->height = new_height;
sprintf (size, "%d", new_height);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->height_text), data);
gtk_entry_set_text (GTK_ENTRY (private->height_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->height_text), data);
if (resize->type == ResizeWidget)
{
resize->off_y = resize_bound_off_y (resize, (resize->height - private->old_height) / 2);
sprintf (size, "%d", resize->off_y);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_y_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_y_text), data);
}
}
if (private->constrain && resize->height != 0)
{
private->constrain = FALSE;
resize->ratio_x = resize->ratio_y;
new_width = (int) (private->old_width * resize->ratio_x);
if (new_width == 0) new_width = 1;
if (new_width != resize->width)
{
resize->width = new_width;
sprintf (size, "%d", resize->width);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->width_text), data);
gtk_entry_set_text (GTK_ENTRY (private->width_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->width_text), data);
sprintf (ratio_text, "%0.4f", resize->ratio_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->ratio_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->ratio_x_text), ratio_text);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->ratio_x_text), data);
if (resize->type == ResizeWidget)
{
resize->off_x = resize_bound_off_x (resize, (resize->width - private->old_width) / 2);
sprintf (size, "%d", resize->off_x);
gtk_signal_handler_block_by_data (GTK_OBJECT (private->off_x_text), data);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
gtk_signal_handler_unblock_by_data (GTK_OBJECT (private->off_x_text), data);
}
}
private->constrain = TRUE;
}
resize_draw (resize);
}
static gint
resize_events (GtkWidget *widget,
GdkEvent *event)
{
Resize *resize;
ResizePrivate *private;
int dx, dy;
int off_x, off_y;
char size[12];
resize = (Resize *) gtk_object_get_user_data (GTK_OBJECT (widget));
private = (ResizePrivate *) resize->private_part;
switch (event->type)
{
case GDK_EXPOSE:
resize_draw (resize);
break;
case GDK_BUTTON_PRESS:
gdk_pointer_grab (private->drawing_area->window, FALSE,
(GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON_RELEASE_MASK),
NULL, NULL, event->button.time);
private->orig_x = resize->off_x;
private->orig_y = resize->off_y;
private->start_x = event->button.x;
private->start_y = event->button.y;
break;
case GDK_MOTION_NOTIFY:
/* X offset */
dx = event->motion.x - private->start_x;
off_x = private->orig_x + dx / private->ratio;
off_x = resize_bound_off_x (resize, off_x);
sprintf (size, "%d", off_x);
gtk_entry_set_text (GTK_ENTRY (private->off_x_text), size);
/* Y offset */
dy = event->motion.y - private->start_y;
off_y = private->orig_y + dy / private->ratio;
off_y = resize_bound_off_y (resize, off_y);
sprintf (size, "%d", off_y);
gtk_entry_set_text (GTK_ENTRY (private->off_y_text), size);
break;
case GDK_BUTTON_RELEASE:
gdk_pointer_ungrab (event->button.time);
break;
default:
break;
}
return FALSE;
}

51
plug-ins/gap/resize.h Normal file
View File

@ -0,0 +1,51 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __RESIZE_H__
#define __RESIZE_H__
typedef enum
{
ScaleWidget,
ResizeWidget
} ResizeType;
typedef struct _Resize Resize;
struct _Resize
{
/* The calling procedure is respondible for showing this widget */
GtkWidget *resize_widget;
ResizeType type;
int width;
int height;
double ratio_x;
double ratio_y;
int off_x;
int off_y;
/* Don't touch this :) */
void * private_part;
};
Resize * resize_widget_new (ResizeType type,
int width,
int height);
void resize_widget_free (Resize * resize);
#endif /* __RESIZE_H__ */

View File

@ -0,0 +1,119 @@
; The GIMP -- an image manipulation program
; Copyright (C) 1995 Spencer Kimball and Peter Mattis
;
; Selection to AnimationImage
; This script requires plug-in-gap-layers-run-animfilter (that is part of
; the gap Plugin-collection, available in the plugin registry)
;
; - Takes the Current selection and saves it n-times (as multiple layers) in one seperate image.
; (base functions taken from Selection to Image ((c) by Adrian Likins adrian@gimp.org)
; - added number of copies and
; - optional { BG-FILL | TRANS-FILL }
; - if there was no selection at begin the selection is cleared at end
; - optional call of plug-in-gap-layers-run-animfilter
; (to create animation effects by applying any available PDB filter foreach copy
; (==layer) of the generated image
; with constant or varying values)
; - if we just copied some layers set the generated brush-image clean at end
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
(define (script-fu-selection-to-anim-image image drawable copies bgfill filter-all)
(let* (
(idx 0)
(draw-type (car (gimp-drawable-type-with-alpha drawable)))
(image-type (car (gimp-image-base-type image)))
(old-bg (car (gimp-palette-get-background))))
(set! selection-bounds (gimp-selection-bounds image))
(set! select-offset-x (cadr selection-bounds))
(set! select-offset-y (caddr selection-bounds))
(set! selection-width (- (cadr (cddr selection-bounds)) select-offset-x))
(set! selection-height (- (caddr (cddr selection-bounds)) select-offset-y))
(gimp-image-disable-undo image)
(if (= (car (gimp-selection-is-empty image)) TRUE)
(begin
; if the layer has no alpha select all
(if (= (car (gimp-drawable-has-alpha drawable)) FALSE)
(begin
(gimp-selection-all image)
)
(begin
(gimp-selection-layer-alpha image drawable)
)
)
(set! from-selection FALSE)
)
(begin
(set! from-selection TRUE)
)
)
(gimp-edit-copy image drawable)
(set! brush-image (car (gimp-image-new selection-width selection-height image-type)))
(while (< idx copies)
(set! draw-name (string-append "frame_" (number->string idx)))
(set! brush-draw (car (gimp-layer-new brush-image selection-width selection-height draw-type draw-name 100 NORMAL)))
(gimp-image-add-layer brush-image brush-draw 0)
(if (= bgfill TRUE)
(gimp-drawable-fill brush-draw BG-IMAGE-FILL)
(gimp-drawable-fill brush-draw TRANS-IMAGE-FILL)
)
(let ((floating-sel (car (gimp-edit-paste brush-image brush-draw FALSE))))
(gimp-floating-sel-anchor floating-sel)
)
(set! idx (+ idx 1))
)
(if (= from-selection FALSE)
(gimp-selection-none image)
)
(gimp-palette-set-background old-bg)
(gimp-image-enable-undo image)
(gimp-image-set-active-layer image drawable)
(gimp-image-clean-all brush-image)
(gimp-display-new brush-image)
(gimp-displays-flush))
(if (= filter-all TRUE)
; INTERACTIVE animated call of any other plugin
; (drawable and plugin name are dummy parameters
; the plug-in to run is selcted by the built in PDB-browserdialog
; of plug-in-gap-layers-run-animfilter)
(plug-in-gap-layers-run-animfilter 0 brush-image brush-draw "plug-in-bend")
)
)
(script-fu-register "script-fu-selection-to-anim-image"
"<Image>/Script-Fu/Animators/Sel To AnimImage"
"Create a multilayer image from current selection and apply any PDB Filter to all layer-copies"
"Wolfgang Hofer <hof@hotbot.com>"
"Wolfgang Hofer"
"20/05/98"
"RGB RGBA GRAY GRAYA"
SF-IMAGE "Image" 0
SF-DRAWABLE "Drawable" 0
SF-VALUE "Number of copies" "10"
SF-TOGGLE "Fill with BG Color?" TRUE
SF-TOGGLE "Anim-Filter for all copies?" TRUE
)