gimp/plug-ins/common/compose.c

1490 lines
48 KiB
C
Raw Normal View History

/* GIMP - The GNU Image Manipulation Program
1997-11-25 06:05:25 +08:00
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Compose plug-in (C) 1997,1999 Peter Kirchgessner
* e-mail: peter@kirchgessner.net, WWW: http://www.kirchgessner.net
1997-11-25 06:05:25 +08:00
*
* This program is free software: you can redistribute it and/or modify
1997-11-25 06:05:25 +08:00
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
1997-11-25 06:05:25 +08:00
* (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, see <https://www.gnu.org/licenses/>.
1997-11-25 06:05:25 +08:00
*/
/*
* This plug-in composes RGB-images from several types of channels
*/
/* Lab colorspace support originally written by Alexey Dyachenko,
* merged into the official plug-in by Sven Neumann.
*
* Support for channels empty or filled with a single mask value
* added by Sylvain FORET.
1997-11-25 06:05:25 +08:00
*/
2013-07-07 21:55:42 +08:00
/*
* All redundant _256 versions of YCbCr* are here only for compatibility .
* They can be dropped for GIMP 3.0
*/
#include "config.h"
1997-11-25 06:05:25 +08:00
#include <string.h>
2000-01-11 23:48:00 +08:00
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
#include "libgimp/stdplugins-intl.h"
#define COMPOSE_PROC "plug-in-compose"
#define DRAWABLE_COMPOSE_PROC "plug-in-drawable-compose"
#define RECOMPOSE_PROC "plug-in-recompose"
#define PLUG_IN_BINARY "compose"
#define PLUG_IN_ROLE "gimp-compose"
2013-07-07 21:55:42 +08:00
/* Maximum number of images to compose */
#define MAX_COMPOSE_IMAGES 4
typedef struct
{
2019-08-30 01:22:50 +08:00
gboolean is_object;
union
2019-08-30 01:22:50 +08:00
{
gpointer object; /* Input images or drawable */
guchar val; /* Mask value to compose with */
} comp;
} ComposeInput;
2013-07-07 21:55:42 +08:00
/* Description of a component */
typedef struct
{
const gchar *babl_name;
const gchar *name;
const gchar *icon;
const float range_min; /* val min of the component */
const float range_max; /* val max of the component */
const gboolean is_perceptual; /* Take the componenent from an Y' or Y buffer */
} COMPONENT_DSC;
/* Description of a composition */
typedef struct
{
const gchar *babl_model;
const gchar *compose_type; /* Type of composition ("RGB", "RGBA",...) */
gint num_images; /* Number of input images needed */
/* Channel information */
2013-07-07 21:55:42 +08:00
const COMPONENT_DSC components[MAX_COMPOSE_IMAGES];
const gchar *filename; /* Name of new image */
} COMPOSE_DSC;
2019-08-30 01:22:50 +08:00
typedef struct
{
ComposeInput inputs[MAX_COMPOSE_IMAGES]; /* Image or mask value of input */
gchar compose_type[32]; /* type of composition */
gboolean do_recompose;
GimpLayer *source_layer; /* for recomposing */
} ComposeVals;
2019-08-30 01:22:50 +08:00
/* Dialog structure */
typedef struct
{
gint width, height; /* Size of selected image */
GtkWidget *channel_label[MAX_COMPOSE_IMAGES]; /* The labels to change */
GtkWidget *channel_icon[MAX_COMPOSE_IMAGES]; /* The icons */
GtkWidget *channel_menu[MAX_COMPOSE_IMAGES]; /* The menus */
GtkWidget *color_scales[MAX_COMPOSE_IMAGES]; /* The values color scales */
GtkWidget *color_spins[MAX_COMPOSE_IMAGES]; /* The values spin buttons */
ComposeInput selected[MAX_COMPOSE_IMAGES]; /* Image Ids or mask values from menus */
gint compose_idx; /* Compose type */
} ComposeInterface;
typedef struct _Compose Compose;
typedef struct _ComposeClass ComposeClass;
struct _Compose
{
GimpPlugIn parent_instance;
};
struct _ComposeClass
{
GimpPlugInClass parent_class;
};
#define COMPOSE_TYPE (compose_get_type ())
#define COMPOSE (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COMPOSE_TYPE, Compose))
GType compose_get_type (void) G_GNUC_CONST;
static GList * compose_query_procedures (GimpPlugIn *plug_in);
static GimpProcedure * compose_create_procedure (GimpPlugIn *plug_in,
const gchar *name);
static GimpValueArray * compose_run (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
GimpDrawable *drawable,
const GimpValueArray *args,
gpointer run_data);
static void cpn_affine_transform (GeglBuffer *buffer,
gdouble min,
gdouble max);
static void fill_buffer_from_components (GeglBuffer *temp[MAX_COMPOSE_IMAGES],
GeglBuffer *dst,
gint num_cpn,
ComposeInput *inputs,
gdouble mask_vals[MAX_COMPOSE_IMAGES]);
2019-08-30 01:22:50 +08:00
static void perform_composition (COMPOSE_DSC curr_compose_dsc,
GeglBuffer *buffer_src[MAX_COMPOSE_IMAGES],
GeglBuffer *buffer_dst,
ComposeInput *inputs,
gint num_images);
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
static GimpImage * compose (const gchar *compose_type,
ComposeInput *inputs,
gboolean compose_by_drawable);
1997-11-25 06:05:25 +08:00
static GimpImage * create_new_image (GFile *file,
2019-08-30 01:22:50 +08:00
guint width,
guint height,
GimpImageType gdtype,
GimpPrecision precision,
GimpLayer **layer,
GeglBuffer **buffer);
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
static gboolean compose_dialog (const gchar *compose_type,
GimpDrawable *drawable);
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
static gboolean check_gray (GimpImage *image,
GimpItem *drawable,
gpointer data);
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
static void combo_callback (GimpIntComboBox *cbox,
gpointer data);
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
static void scale_callback (GtkAdjustment *adj,
ComposeInput *input);
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
static void check_response (GtkWidget *dialog,
gint response,
gpointer data);
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
static void type_combo_callback (GimpIntComboBox *combo,
gpointer data);
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
G_DEFINE_TYPE (Compose, compose, GIMP_TYPE_PLUG_IN)
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
GIMP_MAIN (COMPOSE_TYPE)
2013-07-07 21:55:42 +08:00
/* Decompositions availables.
* All the following values have to be kept in sync with those of decompose.c
*/
#define CPN_RGBA_R { "R", N_("_Red:"), GIMP_ICON_CHANNEL_RED, 0.0, 1.0, FALSE}
#define CPN_RGBA_G { "G", N_("_Green:"), GIMP_ICON_CHANNEL_GREEN, 0.0, 1.0, FALSE}
#define CPN_RGBA_B { "B", N_("_Blue:"), GIMP_ICON_CHANNEL_BLUE, 0.0, 1.0, FALSE}
#define CPN_RGBA_A { "A", N_("_Alpha:"), GIMP_ICON_CHANNEL_ALPHA, 0.0, 1.0, TRUE}
2013-07-07 21:55:42 +08:00
#define CPN_HSV_H { "hue", N_("_Hue:"), NULL, 0.0, 1.0, TRUE}
#define CPN_HSV_S { "saturation", N_("_Saturation:"), NULL, 0.0, 1.0, TRUE}
#define CPN_HSV_V { "value", N_("_Value:"), NULL, 0.0, 1.0, TRUE}
2013-07-07 21:55:42 +08:00
#define CPN_HSL_H { "hue", N_("_Hue:"), NULL, 0.0, 1.0, TRUE}
#define CPN_HSL_S { "saturation", N_("_Saturation:"), NULL, 0.0, 1.0, TRUE}
#define CPN_HSL_L { "lightness", N_("_Lightness:"), NULL, 0.0, 1.0, TRUE}
2013-07-07 21:55:42 +08:00
#define CPN_CMYK_C { "cyan", N_("_Cyan:"), NULL, 0.0, 1.0, TRUE}
#define CPN_CMYK_M { "magenta", N_("_Magenta:"), NULL, 0.0, 1.0, TRUE}
#define CPN_CMYK_Y { "yellow", N_("_Yellow:"), NULL, 0.0, 1.0, TRUE}
#define CPN_CMYK_K { "key", N_("_Black:"), NULL, 0.0, 1.0, TRUE}
2013-07-07 21:55:42 +08:00
#define CPN_CMY_C { "cyan", N_("_Cyan:"), NULL, 0.0, 1.0, TRUE}
#define CPN_CMY_M { "magenta", N_("_Magenta:"), NULL, 0.0, 1.0, TRUE}
#define CPN_CMY_Y { "yellow", N_("_Yellow:"), NULL, 0.0, 1.0, TRUE}
2013-07-07 21:55:42 +08:00
#define CPN_LAB_L { "CIE L", N_("_L:"), NULL, 0.0, 100.0, TRUE}
#define CPN_LAB_A { "CIE a", N_("_A:"), NULL, -127.5, 127.5, TRUE}
#define CPN_LAB_B { "CIE b", N_("_B:"), NULL, -127.5, 127.5, TRUE}
#define CPN_LCH_L { "CIE L", N_("_L"), NULL, 0.0, 100.0, TRUE}
#define CPN_LCH_C { "CIE C(ab)", N_("_C"), NULL, 0.0, 200.0, TRUE}
#define CPN_LCH_H { "CIE H(ab)", N_("_H"), NULL, 0.0, 360.0, TRUE}
2013-07-07 21:55:42 +08:00
#define CPN_YCBCR_Y { "Y'", N_("_Luma y470:"), NULL, 0.0, 1.0, TRUE }
#define CPN_YCBCR_CB { "Cb", N_("_Blueness cb470:"), NULL, -0.5, 0.5, TRUE }
#define CPN_YCBCR_CR { "Cr", N_("_Redness cr470:"), NULL, -0.5, 0.5, TRUE }
2013-07-07 21:55:42 +08:00
#define CPN_YCBCR709_Y { "Y'", N_("_Luma y709:"), NULL, 0.0, 1.0, TRUE }
#define CPN_YCBCR709_CB { "Cb", N_("_Blueness cb709:"), NULL, -0.5, 0.5, TRUE }
#define CPN_YCBCR709_CR { "Cr", N_("_Redness cr709:"), NULL, -0.5, 0.5, TRUE }
1997-11-25 06:05:25 +08:00
static COMPOSE_DSC compose_dsc[] =
{
2013-07-07 21:55:42 +08:00
{ "RGB",
N_("RGB"), 3,
{ CPN_RGBA_R,
CPN_RGBA_G,
CPN_RGBA_B },
"rgb-compose" },
{ "RGBA",
N_("RGBA"), 4,
{ CPN_RGBA_R,
CPN_RGBA_G,
CPN_RGBA_B,
CPN_RGBA_A },
"rgba-compose" },
{ "HSV",
N_("HSV"), 3,
{ CPN_HSV_H,
CPN_HSV_S,
CPN_HSV_V },
"hsv-compose" },
{ "HSL",
N_("HSL"), 3,
{ CPN_HSL_H,
CPN_HSL_S,
CPN_HSL_L },
"hsl-compose" },
{ "CMY",
N_("CMY"), 3,
{ CPN_CMY_C,
CPN_CMY_M,
CPN_CMY_Y },
"cmy-compose" },
{ "CMYK",
N_("CMYK"), 4,
{ CPN_CMYK_C,
CPN_CMYK_M,
CPN_CMYK_Y,
CPN_CMYK_K },
"cmyk-compose" },
{ "CIE Lab",
N_("LAB"), 3,
{ CPN_LAB_L,
CPN_LAB_A,
CPN_LAB_B },
"lab-compose" },
{ "CIE LCH(ab)",
N_("LCH"), 3,
{ CPN_LCH_L,
CPN_LCH_C,
CPN_LCH_H },
"lch-compose" },
2013-07-07 21:55:42 +08:00
{ "Y'CbCr",
N_("YCbCr_ITU_R470"), 3,
{ CPN_YCBCR_Y,
CPN_YCBCR_CB,
CPN_YCBCR_CR },
"ycbcr470-compose" },
{ "Y'CbCr709",
N_("YCbCr_ITU_R709"), 3,
{ CPN_YCBCR709_Y,
CPN_YCBCR709_CB,
CPN_YCBCR709_CR },
"ycbcr709-compose" },
{ "Y'CbCr",
N_("YCbCr_ITU_R470_256"), 3,
{ CPN_YCBCR_Y,
CPN_YCBCR_CB,
CPN_YCBCR_CR },
"ycbcr470F-compose" },
{ "Y'CbCr709",
N_("YCbCr_ITU_R709_256"), 3,
{ CPN_YCBCR709_Y,
CPN_YCBCR709_CB,
CPN_YCBCR709_CR },
"ycbcr709F-compose" }
1997-11-25 06:05:25 +08:00
};
static ComposeVals composevals =
{
2019-08-30 01:22:50 +08:00
{{ 0, }}, /* Image IDs of images to compose or mask values */
"rgb", /* Type of composition */
FALSE, /* Do recompose */
NULL /* source layer */
1997-11-25 06:05:25 +08:00
};
static ComposeInterface composeint =
{
0, 0, /* width, height */
{ NULL }, /* Label Widgets */
{ NULL }, /* Icon Widgets */
{ NULL }, /* Menu Widgets */
{ NULL }, /* Color Scale Widgets */
{ NULL }, /* Color Spin Widgets */
2019-08-30 01:22:50 +08:00
{{ 0, }}, /* Image Ids or mask values from menus */
0 /* Compose type */
1997-11-25 06:05:25 +08:00
};
2019-08-30 01:22:50 +08:00
static void
compose_class_init (ComposeClass *klass)
{
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
plug_in_class->query_procedures = compose_query_procedures;
plug_in_class->create_procedure = compose_create_procedure;
}
1997-11-25 06:05:25 +08:00
static void
2019-08-30 01:22:50 +08:00
compose_init (Compose *compose)
1997-11-25 06:05:25 +08:00
{
2019-08-30 01:22:50 +08:00
}
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
static GList *
compose_query_procedures (GimpPlugIn *plug_in)
{
GList *list = NULL;
2019-08-30 01:22:50 +08:00
list = g_list_append (list, g_strdup (COMPOSE_PROC));
list = g_list_append (list, g_strdup (DRAWABLE_COMPOSE_PROC));
list = g_list_append (list, g_strdup (RECOMPOSE_PROC));
2019-08-30 01:22:50 +08:00
return list;
}
static GimpProcedure *
compose_create_procedure (GimpPlugIn *plug_in,
const gchar *name)
{
GimpProcedure *procedure = NULL;
GString *type_desc;
gint i;
type_desc = g_string_new ("What to compose: ");
g_string_append_c (type_desc, '"');
g_string_append (type_desc, compose_dsc[0].compose_type);
g_string_append_c (type_desc, '"');
for (i = 1; i < G_N_ELEMENTS (compose_dsc); i++)
{
g_string_append (type_desc, ", ");
g_string_append_c (type_desc, '"');
g_string_append (type_desc, compose_dsc[i].compose_type);
g_string_append_c (type_desc, '"');
}
2019-08-30 01:22:50 +08:00
if (! strcmp (name, COMPOSE_PROC))
{
procedure = gimp_image_procedure_new (plug_in, name,
GIMP_PDB_PROC_TYPE_PLUGIN,
2019-08-30 01:22:50 +08:00
compose_run, NULL, NULL);
gimp_procedure_set_image_types (procedure, "GRAY*");
gimp_procedure_set_menu_label (procedure, N_("C_ompose..."));
gimp_procedure_add_menu_path (procedure, "<Image>/Colors/Components");
gimp_procedure_set_documentation (procedure,
N_("Create an image using multiple "
"gray images as color channels"),
"This function creates a new image from "
"multiple gray images",
name);
gimp_procedure_set_attribution (procedure,
"Peter Kirchgessner",
"Peter Kirchgessner (peter@kirchgessner.net)",
"1997");
GIMP_PROC_ARG_IMAGE (procedure, "image-2",
"Image 2",
"Second input image",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_IMAGE (procedure, "image-3",
"Image 3",
"Third input image",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_IMAGE (procedure, "image-4",
"Image 4",
"Fourth input image",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_STRING (procedure, "compose-type",
"Compose type",
type_desc->str,
NULL,
G_PARAM_READWRITE);
GIMP_PROC_VAL_IMAGE (procedure, "new-image",
"New image",
"Output image",
FALSE,
G_PARAM_READWRITE);
}
else if (! strcmp (name, DRAWABLE_COMPOSE_PROC))
{
procedure = gimp_image_procedure_new (plug_in, name,
GIMP_PDB_PROC_TYPE_PLUGIN,
2019-08-30 01:22:50 +08:00
compose_run, NULL, NULL);
gimp_procedure_set_image_types (procedure, "GRAY*");
gimp_procedure_set_documentation (procedure,
"Compose an image from multiple "
"drawables of gray images",
"This function creates a new image from "
"multiple drawables of gray images",
name);
gimp_procedure_set_attribution (procedure,
"Peter Kirchgessner",
"Peter Kirchgessner (peter@kirchgessner.net)",
"1998");
GIMP_PROC_ARG_DRAWABLE (procedure, "drawable-2",
"Drawable 2",
"Second input drawable",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DRAWABLE (procedure, "drawable-3",
"Drawable 3",
"Third input drawable",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_DRAWABLE (procedure, "drawable-4",
"Drawable 4",
"Fourth input drawable",
TRUE,
G_PARAM_READWRITE);
GIMP_PROC_ARG_STRING (procedure, "compose-type",
"Compose type",
type_desc->str,
NULL,
G_PARAM_READWRITE);
GIMP_PROC_VAL_IMAGE (procedure, "new-image",
"New image",
"Output image",
FALSE,
G_PARAM_READWRITE);
}
else if (! strcmp (name, RECOMPOSE_PROC))
{
procedure = gimp_image_procedure_new (plug_in, name,
GIMP_PDB_PROC_TYPE_PLUGIN,
2019-08-30 01:22:50 +08:00
compose_run, NULL, NULL);
gimp_procedure_set_image_types (procedure, "GRAY*");
gimp_procedure_set_menu_label (procedure, N_("R_ecompose"));
gimp_procedure_add_menu_path (procedure, "<Image>/Colors/Components");
gimp_procedure_set_documentation (procedure,
N_("Recompose an image that was "
"previously decomposed"),
"This function recombines the grayscale "
"layers produced by Decompose "
"into a single RGB or RGBA layer, and "
"replaces the originally decomposed "
"layer with the result.",
name);
gimp_procedure_set_attribution (procedure,
"Bill Skaggs",
"Bill Skaggs",
"2004");
}
g_string_free (type_desc, TRUE);
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
return procedure;
}
2019-08-30 01:22:50 +08:00
static GimpValueArray *
compose_run (GimpProcedure *procedure,
GimpRunMode run_mode,
GimpImage *image,
GimpDrawable *drawable,
const GimpValueArray *args,
gpointer run_data)
1997-11-25 06:05:25 +08:00
{
2019-08-30 01:22:50 +08:00
GimpValueArray *return_vals;
const gchar *name = gimp_procedure_get_name (procedure);
gint compose_by_drawable;
gint i;
1997-11-25 06:05:25 +08:00
INIT_I18N ();
2013-07-07 21:55:42 +08:00
gegl_init (NULL, NULL);
configure.in removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so * configure.in * Makefile.am: removed tips files, AC_SUBST GIMP_PLUGINS and GIMP_MODULES so you can easily skip those parts of the build * acinclude.m4 * config.sub * config.guess * ltconfig * ltmain.sh: libtool 1.3.2 * app/fileops.c: shuffle #includes to avoid warning about MIN and MAX [ The following is a big i18n patch from David Monniaux <david.monniaux@ens.fr> ] * tips/gimp_conseils.fr.txt * tips/gimp_tips.txt * tips/Makefile.am * configure.in: moved tips to separate dir * po-plugins: new dir for plug-in translation files * configure.in: add po-plugins dir and POTFILES processing * app/boundary.c * app/brightness_contrast.c * app/by_color_select.c * app/color_balance.c * app/convert.c * app/curves.c * app/free_select.c * app/gdisplay.c * app/gimpimage.c * app/gimpunit.c * app/gradient.c * app/gradient_select.c * app/install.c * app/session.c: various i18n tweaks * app/tips_dialog.c: localize tips filename * libgimp/gimpunit.c * libgimp/gimpunitmenu.c: #include "config.h" * plug-ins/CEL * plug-ins/CML_explorer * plug-ins/Lighting * plug-ins/apply_lens * plug-ins/autostretch_hsv * plug-ins/blur * plug-ins/bmp * plug-ins/borderaverage * plug-ins/bumpmap * plug-ins/bz2 * plug-ins/checkerboard * plug-ins/colorify * plug-ins/compose * plug-ins/convmatrix * plug-ins/cubism * plug-ins/depthmerge * plug-ins/destripe * plug-ins/gif * plug-ins/gifload * plug-ins/jpeg * plug-ins/mail * plug-ins/oilify * plug-ins/png * plug-ins/print * plug-ins/ps * plug-ins/xbm * plug-ins/xpm * plug-ins/xwd: plug-in i18n stuff -Yosh
1999-05-30 00:35:47 +08:00
2019-08-30 01:22:50 +08:00
compose_by_drawable = ! strcmp (name, DRAWABLE_COMPOSE_PROC);
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
if (! strcmp (name, RECOMPOSE_PROC))
1997-11-25 06:05:25 +08:00
{
2019-08-30 01:22:50 +08:00
GimpParasite *parasite = gimp_image_get_parasite (image,
"decompose-data");
if (! parasite)
{
g_message (_("You can only run 'Recompose' if the active image "
"was originally produced by 'Decompose'."));
2019-08-30 01:22:50 +08:00
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
NULL);
}
else
app/gimpprogress.c app/nav_window.c app/ops_buttons.c app/undo_history.c 2001-12-29 Michael Natterer <mitch@gimp.org> * app/gimpprogress.c * app/nav_window.c * app/ops_buttons.c * app/undo_history.c * app/display/gimpdisplayshell.c * app/gui/about-dialog.c * app/gui/brush-editor.c * app/gui/channels-commands.c * app/gui/color-area.c * app/gui/color-notebook.c * app/gui/color-select.c * app/gui/colormap-dialog.c * app/gui/convert-dialog.c * app/gui/device-status-dialog.c * app/gui/file-new-dialog.c * app/gui/file-open-dialog.c * app/gui/file-save-dialog.c * app/gui/gradient-editor.c * app/gui/info-dialog.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-editor.c * app/gui/palettes-commands.c * app/gui/paths-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/splash.c * app/gui/tips-dialog.c * app/gui/toolbox.c * app/gui/user-install-dialog.c * app/tools/gimpbrightnesscontrasttool.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpcolorbalancetool.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpcurvestool.c * app/tools/gimphuesaturationtool.c * app/tools/gimpinktool.c * app/tools/gimplevelstool.c * app/tools/gimpposterizetool.c * app/tools/gimprotatetool.c * app/tools/gimpthresholdtool.c * app/tools/paint_options.c * app/tools/selection_options.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcolorpanel.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpconstrainedhwrapbox.c * app/widgets/gimpcontainergridview.c * app/widgets/gimpcontainerlistview.c * app/widgets/gimpcontainermenuimpl.c * app/widgets/gimpdialogfactory.c * app/widgets/gimpdnd.c * app/widgets/gimpdock.c * app/widgets/gimpdockbook.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.c * app/widgets/gimpfontselection-dialog.c * app/widgets/gimphistogramview.c * app/widgets/gimpitemfactory.c * app/widgets/gimplayerlistitem.c * app/widgets/gimplistitem.[ch] * app/widgets/gimpmenuitem.c * app/widgets/gimppreview.[ch] * app/widgets/gtkhwrapbox.c * app/widgets/gtkvwrapbox.c * app/widgets/gtkwrapbox.c * libgimp/gimpbrushmenu.c * libgimp/gimpexport.c * libgimp/gimpgradientmenu.c * libgimp/gimpmenu.c * libgimp/gimppatternmenu.c * libgimpwidgets/gimpbutton.c * libgimpwidgets/gimpchainbutton.[ch] * libgimpwidgets/gimpcolorarea.h * libgimpwidgets/gimpcolorbutton.c * libgimpwidgets/gimpfileselection.c * libgimpwidgets/gimphelpui.c * libgimpwidgets/gimpoffsetarea.c * libgimpwidgets/gimppatheditor.c * libgimpwidgets/gimppixmap.h * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpstock.[ch] * libgimpwidgets/gimpwidgets.h * plug-ins/FractalExplorer/Dialogs.c * plug-ins/FractalExplorer/Events.c * plug-ins/FractalExplorer/FractalExplorer.c * plug-ins/Lighting/lighting_ui.c * plug-ins/MapObject/mapobject_ui.c * plug-ins/bmp/bmpwrite.c * plug-ins/dbbrowser/dbbrowser_utils.c * plug-ins/fits/fits.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/fp/fp_misc.c * plug-ins/gfig/gfig.c * plug-ins/gflare/gflare.c * plug-ins/gfli/gfli.c * plug-ins/gimpressionist/*.c * plug-ins/imagemap/*.[ch] * plug-ins/maze/maze_face.c * plug-ins/mosaic/mosaic.c * plug-ins/pagecurl/pagecurl.c * plug-ins/print/print_gimp.h * plug-ins/rcm/rcm_callback.c * plug-ins/rcm/rcm_dialog.c * plug-ins/rcm/rcm_misc.c * plug-ins/script-fu/script-fu-console.c * plug-ins/script-fu/script-fu-scripts.c * plug-ins/script-fu/script-fu-server.c * plug-ins/sel2path/sel2path.c * plug-ins/sel2path/sel2path_adv_dialog.c * plug-ins/sgi/sgi.c * plug-ins/webbrowser/webbrowser.c * plug-ins/xjt/xjt.c * plug-ins/common/[A-n]*.c: compile with GTK_DISABLE_DEPRECATED defined. Not everything is fully ported yet, had to #undef GTK_DISABLE_DEPRECATED in many places and added #warnings when doing so. * pixmaps/Makefile.am * pixmaps/chain.xpm: removed. * themes/Default/Makefile.am * themes/Default/images/Makefile.am * themes/Default/images/stock-button-hchain-broken.png * themes/Default/images/stock-button-hchain.png * themes/Default/images/stock-button-vchain-broken.png * themes/Default/images/stock-button-vchain.png: new stock icons.
2001-12-29 21:26:29 +08:00
{
2019-08-30 01:22:50 +08:00
gint source;
gint input[4] = { 0, };
gint nret;
nret = sscanf (gimp_parasite_data (parasite),
"source=%d type=%31s %d %d %d %d",
2019-08-30 01:22:50 +08:00
&source,
composevals.compose_type,
2019-08-30 01:22:50 +08:00
input,
input + 1,
input + 2,
input + 3);
gimp_parasite_free (parasite);
1997-11-25 06:05:25 +08:00
if (nret < 5)
{
g_message (_("Error scanning 'decompose-data' parasite: "
"too few layers found"));
2019-08-30 01:22:50 +08:00
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
NULL);
}
2019-08-30 01:22:50 +08:00
compose_by_drawable = TRUE;
composevals.do_recompose = TRUE;
composevals.source_layer = gimp_layer_get_by_id (source);
2019-08-30 01:22:50 +08:00
if (! composevals.source_layer)
{
2019-08-30 01:22:50 +08:00
g_message (_("Cannot recompose: Specified source layer ID %d "
"not found"),
source);
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
NULL);
}
for (i = 0; i < MAX_COMPOSE_IMAGES; i++)
{
composevals.inputs[i].is_object = TRUE;
composevals.inputs[i].comp.object = gimp_drawable_get_by_id (input[i]);
2019-08-30 01:22:50 +08:00
/* fourth input is optional */
if (i == 2 && nret == 5)
break;
if (! composevals.inputs[i].comp.object)
{
g_message (_("Cannot recompose: Specified layer #%d ID %d "
"not found"),
i + 1, input[i]);
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
NULL);
}
}
}
}
else
{
composevals.do_recompose = FALSE;
1997-11-25 06:05:25 +08:00
switch (run_mode)
{
case GIMP_RUN_INTERACTIVE:
gimp_get_data (name, &composevals);
1997-11-25 06:05:25 +08:00
compose_by_drawable = TRUE;
2019-08-30 01:22:50 +08:00
/* Get a drawable-ID of the image */
if (! strcmp (name, COMPOSE_PROC))
{
2019-08-30 01:22:50 +08:00
GimpLayer **layers;
gint nlayers;
2019-08-30 01:22:50 +08:00
layers = gimp_image_get_layers (image, &nlayers);
if (! layers)
{
g_message (_("Could not get layers for image %d"),
2019-08-30 01:22:50 +08:00
(gint) gimp_image_get_id (image));
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
NULL);
}
2019-08-30 01:22:50 +08:00
drawable = GIMP_DRAWABLE (layers[0]);
2019-08-30 01:22:50 +08:00
g_free (layers);
}
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
if (! compose_dialog (composevals.compose_type, drawable))
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_CANCEL,
NULL);
break;
case GIMP_RUN_NONINTERACTIVE:
2019-08-30 01:22:50 +08:00
if (compose_by_drawable)
{
2019-08-30 01:22:50 +08:00
composevals.inputs[0].comp.object = drawable;
composevals.inputs[1].comp.object = GIMP_VALUES_GET_DRAWABLE (args, 0);
composevals.inputs[2].comp.object = GIMP_VALUES_GET_DRAWABLE (args, 1);
composevals.inputs[3].comp.object = GIMP_VALUES_GET_DRAWABLE (args, 2);
}
else
{
2019-08-30 01:22:50 +08:00
composevals.inputs[0].comp.object = image;
composevals.inputs[1].comp.object = GIMP_VALUES_GET_IMAGE (args, 0);
composevals.inputs[2].comp.object = GIMP_VALUES_GET_IMAGE (args, 1);
composevals.inputs[3].comp.object = GIMP_VALUES_GET_IMAGE (args, 2);
}
2019-08-30 01:22:50 +08:00
g_strlcpy (composevals.compose_type,
GIMP_VALUES_GET_STRING (args, 3),
sizeof (composevals.compose_type));
2019-08-30 01:22:50 +08:00
for (i = 0; i < MAX_COMPOSE_IMAGES; i++)
{
if (! composevals.inputs[i].comp.object)
{
2019-08-30 01:22:50 +08:00
composevals.inputs[i].is_object = FALSE;
composevals.inputs[i].comp.val = 0;
}
else
{
composevals.inputs[i].is_object = TRUE;
}
}
break;
case GIMP_RUN_WITH_LAST_VALS:
gimp_get_data (name, &composevals);
compose_by_drawable = TRUE;
break;
default:
break;
}
1997-11-25 06:05:25 +08:00
}
2019-08-30 01:22:50 +08:00
gimp_progress_init (_("Composing"));
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
image = compose (composevals.compose_type,
composevals.inputs,
compose_by_drawable);
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
if (! image)
return gimp_procedure_new_return_values (procedure,
GIMP_PDB_EXECUTION_ERROR,
NULL);
2019-08-30 01:22:50 +08:00
if (composevals.do_recompose)
{
gimp_displays_flush ();
}
else
{
gimp_image_undo_enable (image);
gimp_image_clean_all (image);
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
if (run_mode != GIMP_RUN_NONINTERACTIVE)
gimp_display_new (image);
1997-11-25 06:05:25 +08:00
}
2019-08-30 01:22:50 +08:00
if (run_mode == GIMP_RUN_INTERACTIVE)
gimp_set_data (name, &composevals, sizeof (ComposeVals));
return_vals = gimp_procedure_new_return_values (procedure,
GIMP_PDB_SUCCESS,
NULL);
if (strcmp (name, RECOMPOSE_PROC))
GIMP_VALUES_SET_IMAGE (return_vals, 1, image);
2019-08-30 01:22:50 +08:00
return return_vals;
1997-11-25 06:05:25 +08:00
}
2013-07-07 21:55:42 +08:00
static void
cpn_affine_transform (GeglBuffer *buffer,
gdouble min,
gdouble max)
2013-07-07 21:55:42 +08:00
{
GeglBufferIterator *gi;
const gdouble scale = max - min;
const gdouble offset = min;
2013-07-07 21:55:42 +08:00
/* We want to scale values linearly, regardless of the format of the buffer */
gegl_buffer_set_format (buffer, babl_format ("Y double"));
gi = gegl_buffer_iterator_new (buffer, NULL, 0, NULL,
GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE, 1);
2013-07-07 21:55:42 +08:00
while (gegl_buffer_iterator_next (gi))
{
gdouble *data = gi->items[0].data;
guint k;
2013-07-07 21:55:42 +08:00
for (k = 0; k < gi->length; k++)
{
data[k] = data[k] * scale + offset;
}
}
}
static void
fill_buffer_from_components (GeglBuffer *temp[MAX_COMPOSE_IMAGES],
GeglBuffer *dst,
gint num_cpn,
ComposeInput *inputs,
gdouble mask_vals[MAX_COMPOSE_IMAGES])
{
GeglBufferIterator *gi;
gint j;
2013-07-07 21:55:42 +08:00
gi = gegl_buffer_iterator_new (dst, NULL, 0, NULL,
GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE, 10);
2013-07-07 21:55:42 +08:00
for (j = 0; j < num_cpn; j++)
{
2019-08-30 01:22:50 +08:00
if (inputs[j].is_object)
2013-07-07 21:55:42 +08:00
gegl_buffer_iterator_add (gi, temp[j], NULL, 0, NULL,
GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
2013-07-07 21:55:42 +08:00
}
while (gegl_buffer_iterator_next (gi))
{
gdouble *src_data[MAX_COMPOSE_IMAGES];
gdouble *dst_data = (gdouble*) gi->items[0].data;
gulong k, count;
2013-07-07 21:55:42 +08:00
count = 1;
for (j = 0; j < num_cpn; j++)
2019-08-30 01:22:50 +08:00
if (inputs[j].is_object)
src_data[j] = (gdouble*) gi->items[count++].data;
2013-07-07 21:55:42 +08:00
for (k = 0; k < gi->length; k++)
{
gulong pos = k * num_cpn;
for (j = 0; j < num_cpn; j++)
{
2019-08-30 01:22:50 +08:00
if (inputs[j].is_object)
dst_data[pos+j] = src_data[j][k];
else
dst_data[pos+j] = mask_vals[j];
}
2013-07-07 21:55:42 +08:00
}
}
}
static void
perform_composition (COMPOSE_DSC curr_compose_dsc,
GeglBuffer *buffer_src[MAX_COMPOSE_IMAGES],
GeglBuffer *buffer_dst,
ComposeInput *inputs,
gint num_images)
{
const Babl *dst_format;
GeglBuffer *temp[MAX_COMPOSE_IMAGES];
GeglBuffer *dst_temp;
const GeglRectangle *extent = NULL;
const COMPONENT_DSC *components;
gdouble mask_vals[MAX_COMPOSE_IMAGES];
gint i;
components = curr_compose_dsc.components;
/* Get all individual components in gray buffers */
for (i = 0; i < num_images; i++)
{
COMPONENT_DSC cpn_dsc = components[i];
const Babl *gray_format;
if (cpn_dsc.is_perceptual)
gray_format = babl_format ("Y' double");
else
gray_format = babl_format ("Y double");
2019-08-30 01:22:50 +08:00
if (! inputs[i].is_object)
2013-07-07 21:55:42 +08:00
{
const Babl *fish = babl_fish (babl_format ("Y' u8"), gray_format);
babl_process (fish, &inputs[i].comp.val, &mask_vals[i], 1);
mask_vals[i] = mask_vals[i] * (cpn_dsc.range_max - cpn_dsc.range_min) + cpn_dsc.range_min;
}
else
{
extent = gegl_buffer_get_extent (buffer_src[i]);
temp[i] = gegl_buffer_new (extent, gray_format);
gegl_buffer_copy (buffer_src[i], NULL, GEGL_ABYSS_NONE, temp[i], NULL);
2013-07-07 21:55:42 +08:00
if (cpn_dsc.range_min != 0.0 || cpn_dsc.range_max != 1.0)
cpn_affine_transform (temp[i], cpn_dsc.range_min, cpn_dsc.range_max);
}
gimp_progress_update ((gdouble) i / (gdouble) (num_images + 1.0));
}
dst_format = babl_format_new (babl_model (curr_compose_dsc.babl_model),
babl_type ("double"),
babl_component (components[0].babl_name),
num_images > 1 ? babl_component (components[1].babl_name) : NULL,
num_images > 2 ? babl_component (components[2].babl_name) : NULL,
num_images > 3 ? babl_component (components[3].babl_name) : NULL,
NULL);
/* extent is not NULL because there is at least one drawable */
dst_temp = gegl_buffer_new (extent, dst_format);
/* Gather all individual components in the dst_format buffer */
fill_buffer_from_components (temp, dst_temp, num_images, inputs, mask_vals);
gimp_progress_update ((gdouble) num_images / (gdouble) (num_images + 1.0));
/* Copy back to the format GIMP wants (and perform the conversion in itself) */
gegl_buffer_copy (dst_temp, NULL, GEGL_ABYSS_NONE, buffer_dst, NULL);
2013-07-07 21:55:42 +08:00
for (i = 0; i< num_images; i++)
2019-08-30 01:22:50 +08:00
if (inputs[i].is_object)
2013-07-07 21:55:42 +08:00
g_object_unref (temp[i]);
g_object_unref (dst_temp);
}
1997-11-25 06:05:25 +08:00
/* Compose an image from several gray-images */
2019-08-30 01:22:50 +08:00
static GimpImage *
compose (const gchar *compose_type,
ComposeInput *inputs,
gboolean compose_by_drawable)
{
2013-07-07 21:55:42 +08:00
gint width, height;
gint num_images, compose_idx;
gint i, j;
gint num_layers;
2019-08-30 01:22:50 +08:00
GimpLayer *layer_dst;
GimpImage *image_dst;
gint first_object;
GimpImageType gdtype_dst;
GeglBuffer *buffer_src[MAX_COMPOSE_IMAGES];
GeglBuffer *buffer_dst;
2013-07-07 21:55:42 +08:00
GimpPrecision precision;
1997-11-25 06:05:25 +08:00
/* Search type of composing */
compose_idx = -1;
for (j = 0; j < G_N_ELEMENTS (compose_dsc); j++)
{
added -DG_DISABLE_DEPRECATED and -DGDK_DISABLE_COMPAT_H. 2001-08-29 Michael Natterer <mitch@gimp.org> * configure.in: added -DG_DISABLE_DEPRECATED and -DGDK_DISABLE_COMPAT_H. * app/batch.c * app/file-utils.c * app/gdisplay.c * app/gdisplay_ops.c * app/gimprc.[ch] * app/module_db.c * app/nav_window.c * app/undo_history.c * app/core/gimpgradient.c * app/core/gimpimagefile.c * app/core/gimppalette.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/error-console-dialog.c * app/gui/file-commands.c * app/gui/file-open-dialog.c * app/gui/file-save-dialog.c * app/gui/gradient-editor.c * app/gui/info-window.c * app/gui/menus.c * app/gui/palette-import-dialog.c * app/tools/gimpbycolorselecttool.c * app/widgets/gimpcontainerview-utils.c * app/widgets/gimpdatafactoryview.c * libgimp/gimpmenu.c * plug-ins/common/bz2.c * plug-ins/common/compose.c * plug-ins/common/csource.c * plug-ins/common/decompose.c * plug-ins/common/gz.c * plug-ins/common/uniteditor.c * plug-ins/common/wmf.c * plug-ins/common/xbm.c * plug-ins/rcm/rcm_dialog.c * plug-ins/script-fu/interp_slib.c * plug-ins/script-fu/script-fu-console.c * plug-ins/script-fu/script-fu-scripts.c * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gimprc.pdb * app/pdb/fileops_cmds.c * app/pdb/gimprc_cmds.c: removed deprecated stuff like g_basename(), g_dirname(), g_strup() and friends. Added some "const gchar *" declarations while I was on it. Added some G_N_ELEMENTS() macros instead of declaring a useless variable for the number of items. * app/widgets/gtkhwrapbox.[ch] * app/widgets/gtkvwrapbox.[ch] * app/widgets/gtkwrapbox.[ch]: replaced with the latest versions from GLE, ported by the master himself. * app/gui/toolbox.c: changed accordingly. * app/plug_in.c * libgimp/gimp.c * libgimpbase/gimpwire.[ch]: use evil hacks to get binary mode from the new GIOChannel implementation (upstream bugreport already posted).
2001-08-30 01:48:28 +08:00
if (g_ascii_strcasecmp (compose_type, compose_dsc[j].compose_type) == 0)
{
compose_idx = j;
break;
}
}
1997-11-25 06:05:25 +08:00
if (compose_idx < 0)
2019-08-30 01:22:50 +08:00
return NULL;
1997-11-25 06:05:25 +08:00
num_images = compose_dsc[compose_idx].num_images;
/* Check that at least one image or one drawable is provided */
2019-08-30 01:22:50 +08:00
first_object = -1;
for (i = 0; i < num_images; i++)
{
2019-08-30 01:22:50 +08:00
if (inputs[i].is_object)
{
2019-08-30 01:22:50 +08:00
first_object = i;
break;
}
}
2019-08-30 01:22:50 +08:00
if (first_object == -1)
{
g_message (_("At least one image is needed to compose"));
2019-08-30 01:22:50 +08:00
return NULL;
}
/* Check image sizes */
if (compose_by_drawable)
1997-11-25 06:05:25 +08:00
{
2019-08-30 01:22:50 +08:00
GimpImage *first_image = gimp_item_get_image (inputs[first_object].comp.object);
2013-07-07 21:55:42 +08:00
2019-08-30 01:22:50 +08:00
width = gimp_drawable_width (inputs[first_object].comp.object);
height = gimp_drawable_height (inputs[first_object].comp.object);
2013-07-07 21:55:42 +08:00
precision = gimp_image_get_precision (first_image);
2019-08-30 01:22:50 +08:00
for (j = first_object + 1; j < num_images; j++)
{
2019-08-30 01:22:50 +08:00
if (inputs[j].is_object)
{
2019-08-30 01:22:50 +08:00
if ((width != gimp_drawable_width (inputs[j].comp.object)) ||
(height != gimp_drawable_height (inputs[j].comp.object)))
{
g_message (_("Drawables have different size"));
2019-08-30 01:22:50 +08:00
return NULL;
}
}
}
for (j = 0; j < num_images; j++)
{
2019-08-30 01:22:50 +08:00
if (inputs[j].is_object)
buffer_src[j] = gimp_drawable_get_buffer (inputs[j].comp.object);
else
2013-07-07 21:55:42 +08:00
buffer_src[j] = NULL;
}
1997-11-25 06:05:25 +08:00
}
2019-08-30 01:22:50 +08:00
else /* Compose by image */
1997-11-25 06:05:25 +08:00
{
2019-08-30 01:22:50 +08:00
width = gimp_image_width (inputs[first_object].comp.object);
height = gimp_image_height (inputs[first_object].comp.object);
2019-08-30 01:22:50 +08:00
precision = gimp_image_get_precision (inputs[first_object].comp.object);
2019-08-30 01:22:50 +08:00
for (j = first_object + 1; j < num_images; j++)
{
2019-08-30 01:22:50 +08:00
if (inputs[j].is_object)
{
2019-08-30 01:22:50 +08:00
if ((width != gimp_image_width (inputs[j].comp.object)) ||
(height != gimp_image_height (inputs[j].comp.object)))
{
g_message (_("Images have different size"));
2019-08-30 01:22:50 +08:00
return NULL;
}
}
}
/* Get first layer/drawable for all input images */
for (j = 0; j < num_images; j++)
{
2019-08-30 01:22:50 +08:00
if (inputs[j].is_object)
{
2019-08-30 01:22:50 +08:00
GimpLayer **layers;
/* Get first layer of image */
2019-08-30 01:22:50 +08:00
layers = gimp_image_get_layers (inputs[j].comp.object, &num_layers);
2019-08-30 01:22:50 +08:00
if (! layers)
{
g_message (_("Error in getting layer IDs"));
2019-08-30 01:22:50 +08:00
return NULL;
}
/* Get drawable for layer */
2019-08-30 01:22:50 +08:00
buffer_src[j] = gimp_drawable_get_buffer (GIMP_DRAWABLE (layers[0]));
g_free (layers);
}
}
}
/* Unless recomposing, create new image */
if (composevals.do_recompose)
{
2019-08-30 01:22:50 +08:00
layer_dst = composevals.source_layer;
image_dst = gimp_item_get_image (GIMP_ITEM (layer_dst));
buffer_dst = gimp_drawable_get_shadow_buffer (GIMP_DRAWABLE (layer_dst));
}
else
{
2013-07-07 21:55:42 +08:00
gdtype_dst = ((babl_model (compose_dsc[compose_idx].babl_model) == babl_model ("RGBA")) ?
GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE);
image_dst = create_new_image (g_file_new_for_path (compose_dsc[compose_idx].filename),
2019-08-30 01:22:50 +08:00
width, height, gdtype_dst, precision,
&layer_dst, &buffer_dst);
}
if (! compose_by_drawable)
{
gdouble xres, yres;
2019-08-30 01:22:50 +08:00
gimp_image_get_resolution (inputs[first_object].comp.object, &xres, &yres);
gimp_image_set_resolution (image_dst, xres, yres);
}
2013-07-07 21:55:42 +08:00
perform_composition (compose_dsc[compose_idx],
buffer_src,
buffer_dst,
inputs,
num_images);
gimp_progress_update (1.0);
1997-11-25 06:05:25 +08:00
for (j = 0; j < num_images; j++)
{
2019-08-30 01:22:50 +08:00
if (inputs[j].is_object)
2013-07-07 21:55:42 +08:00
g_object_unref (buffer_src[j]);
}
2013-07-07 21:55:42 +08:00
g_object_unref (buffer_dst);
if (composevals.do_recompose)
2019-08-30 01:22:50 +08:00
gimp_drawable_merge_shadow (GIMP_DRAWABLE (layer_dst), TRUE);
2019-08-30 01:22:50 +08:00
gimp_drawable_update (GIMP_DRAWABLE (layer_dst), 0, 0,
gimp_drawable_width (GIMP_DRAWABLE (layer_dst)),
gimp_drawable_height (GIMP_DRAWABLE (layer_dst)));
2019-08-30 01:22:50 +08:00
return image_dst;
1997-11-25 06:05:25 +08:00
}
2019-08-30 01:22:50 +08:00
/* Create an image. Sets layer_ID, drawable and rgn. Returns image */
static GimpImage *
create_new_image (GFile *file,
guint width,
guint height,
GimpImageType gdtype,
2013-07-07 21:55:42 +08:00
GimpPrecision precision,
2019-08-30 01:22:50 +08:00
GimpLayer **layer,
2013-07-07 21:55:42 +08:00
GeglBuffer **buffer)
{
2019-08-30 01:22:50 +08:00
GimpImage *image;
GimpImageBaseType gitype;
if ((gdtype == GIMP_GRAY_IMAGE) || (gdtype == GIMP_GRAYA_IMAGE))
gitype = GIMP_GRAY;
else if ((gdtype == GIMP_INDEXED_IMAGE) || (gdtype == GIMP_INDEXEDA_IMAGE))
gitype = GIMP_INDEXED;
else
gitype = GIMP_RGB;
2019-08-30 01:22:50 +08:00
image = gimp_image_new_with_precision (width, height, gitype, precision);
2019-08-30 01:22:50 +08:00
gimp_image_undo_disable (image);
gimp_image_set_file (image, file);
2019-08-30 01:22:50 +08:00
*layer = gimp_layer_new (image, _("Background"), width, height,
gdtype,
100,
gimp_image_get_default_new_layer_mode (image));
gimp_image_insert_layer (image, *layer, NULL, 0);
2019-08-30 01:22:50 +08:00
*buffer = gimp_drawable_get_buffer (GIMP_DRAWABLE (*layer));
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
return image;
1997-11-25 06:05:25 +08:00
}
static gboolean
2019-08-30 01:22:50 +08:00
compose_dialog (const gchar *compose_type,
GimpDrawable *drawable)
1997-11-25 06:05:25 +08:00
{
GtkWidget *dialog;
GtkWidget *main_vbox;
GtkWidget *frame;
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *label;
GtkWidget *combo;
GtkWidget *grid;
GtkSizeGroup *size_group;
2019-08-30 01:22:50 +08:00
GimpLayer **layer_list;
gint nlayers;
gint j;
gboolean run;
1997-11-25 06:05:25 +08:00
/* Check default compose type */
composeint.compose_idx = 0;
for (j = 0; j < G_N_ELEMENTS (compose_dsc); j++)
{
added -DG_DISABLE_DEPRECATED and -DGDK_DISABLE_COMPAT_H. 2001-08-29 Michael Natterer <mitch@gimp.org> * configure.in: added -DG_DISABLE_DEPRECATED and -DGDK_DISABLE_COMPAT_H. * app/batch.c * app/file-utils.c * app/gdisplay.c * app/gdisplay_ops.c * app/gimprc.[ch] * app/module_db.c * app/nav_window.c * app/undo_history.c * app/core/gimpgradient.c * app/core/gimpimagefile.c * app/core/gimppalette.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/error-console-dialog.c * app/gui/file-commands.c * app/gui/file-open-dialog.c * app/gui/file-save-dialog.c * app/gui/gradient-editor.c * app/gui/info-window.c * app/gui/menus.c * app/gui/palette-import-dialog.c * app/tools/gimpbycolorselecttool.c * app/widgets/gimpcontainerview-utils.c * app/widgets/gimpdatafactoryview.c * libgimp/gimpmenu.c * plug-ins/common/bz2.c * plug-ins/common/compose.c * plug-ins/common/csource.c * plug-ins/common/decompose.c * plug-ins/common/gz.c * plug-ins/common/uniteditor.c * plug-ins/common/wmf.c * plug-ins/common/xbm.c * plug-ins/rcm/rcm_dialog.c * plug-ins/script-fu/interp_slib.c * plug-ins/script-fu/script-fu-console.c * plug-ins/script-fu/script-fu-scripts.c * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gimprc.pdb * app/pdb/fileops_cmds.c * app/pdb/gimprc_cmds.c: removed deprecated stuff like g_basename(), g_dirname(), g_strup() and friends. Added some "const gchar *" declarations while I was on it. Added some G_N_ELEMENTS() macros instead of declaring a useless variable for the number of items. * app/widgets/gtkhwrapbox.[ch] * app/widgets/gtkvwrapbox.[ch] * app/widgets/gtkwrapbox.[ch]: replaced with the latest versions from GLE, ported by the master himself. * app/gui/toolbox.c: changed accordingly. * app/plug_in.c * libgimp/gimp.c * libgimpbase/gimpwire.[ch]: use evil hacks to get binary mode from the new GIOChannel implementation (upstream bugreport already posted).
2001-08-30 01:48:28 +08:00
if (g_ascii_strcasecmp (compose_type, compose_dsc[j].compose_type) == 0)
{
composeint.compose_idx = j;
break;
}
}
/* Save original image width/height */
2019-08-30 01:22:50 +08:00
composeint.width = gimp_drawable_width (drawable);
composeint.height = gimp_drawable_height (drawable);
gimp_ui_init (PLUG_IN_BINARY);
1997-11-25 06:05:25 +08:00
2019-08-30 01:22:50 +08:00
layer_list = gimp_image_get_layers (gimp_item_get_image (GIMP_ITEM (drawable)),
&nlayers);
dialog = gimp_dialog_new (_("Compose"), PLUG_IN_ROLE,
NULL, 0,
gimp_standard_help_func, COMPOSE_PROC,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_OK"), GTK_RESPONSE_OK,
NULL);
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
g_signal_connect (dialog, "response",
G_CALLBACK (check_response),
NULL);
gimp_window_set_transient (GTK_WINDOW (dialog));
2011-09-30 18:17:53 +08:00
main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
main_vbox, TRUE, TRUE, 0);
gtk_widget_show (main_vbox);
/* Compose type combo */
frame = gimp_frame_new (_("Compose Channels"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
2011-09-30 18:17:53 +08:00
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_container_add (GTK_CONTAINER (frame), hbox);
1997-11-25 06:05:25 +08:00
gtk_widget_show (hbox);
size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
label = gtk_label_new_with_mnemonic (_("Color _model:"));
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
gtk_size_group_add_widget (size_group, label);
g_object_unref (size_group);
combo = g_object_new (GIMP_TYPE_INT_COMBO_BOX, NULL);
for (j = 0; j < G_N_ELEMENTS (compose_dsc); j++)
{
gchar *label = g_strdup (gettext (compose_dsc[j].compose_type));
gchar *l;
for (l = label; *l; l++)
if (*l == '-' || *l == '_')
*l = ' ';
gimp_int_combo_box_append (GIMP_INT_COMBO_BOX (combo),
GIMP_INT_STORE_LABEL, label,
GIMP_INT_STORE_VALUE, j,
-1);
g_free (label);
}
gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
gtk_widget_show (combo);
1997-11-25 06:05:25 +08:00
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
1997-11-25 06:05:25 +08:00
/* Channel representation grid */
1997-11-25 06:05:25 +08:00
frame = gimp_frame_new (_("Channel Representations"));
gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
1997-11-25 06:05:25 +08:00
2011-09-30 18:17:53 +08:00
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_container_add (GTK_CONTAINER (frame), vbox);
gtk_widget_show (vbox);
1997-11-25 06:05:25 +08:00
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
gtk_widget_show (grid);
1997-11-25 06:05:25 +08:00
for (j = 0; j < MAX_COMPOSE_IMAGES; j++)
2000-01-11 23:48:00 +08:00
{
GtkWidget *image;
GtkWidget *label;
GtkWidget *combo;
GtkAdjustment *scale;
GtkTreeIter iter;
GtkTreeModel *model;
2011-09-30 18:17:53 +08:00
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_grid_attach (GTK_GRID (grid), hbox, 0, j, 1, 1);
// GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show (hbox);
gtk_size_group_add_widget (size_group, hbox);
composeint.channel_icon[j] = image = gtk_image_new ();
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
gtk_widget_show (image);
composeint.channel_label[j] = label = gtk_label_new_with_mnemonic ("");
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2000-01-11 23:48:00 +08:00
gtk_widget_show (label);
1997-11-25 06:05:25 +08:00
if (composeint.compose_idx >= 0 &&
nlayers >= compose_dsc[composeint.compose_idx].num_images &&
j < nlayers)
{
2019-08-30 01:22:50 +08:00
composeint.selected[j].comp.object = layer_list[j];
}
else
{
2019-08-30 01:22:50 +08:00
composeint.selected[j].comp.object = drawable;
}
2019-08-30 01:22:50 +08:00
composeint.selected[j].is_object = TRUE;
combo = gimp_drawable_combo_box_new (check_gray, NULL, NULL);
composeint.channel_menu[j] = combo;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
GIMP_INT_STORE_VALUE, -1,
GIMP_INT_STORE_LABEL, _("Mask value"),
GIMP_INT_STORE_ICON_NAME, GIMP_ICON_CHANNEL_GRAY,
-1);
gtk_grid_attach (GTK_GRID (grid), combo, 1, j, 1, 1);
// GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_widget_show (combo);
2000-01-11 23:48:00 +08:00
gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
scale = gimp_color_scale_entry_new (GTK_GRID (grid), 2, j, NULL,
100, 4,
255.0, 0.0, 255.0, 1.0, 10.0, 0,
NULL, NULL);
composeint.color_scales[j] = GIMP_SCALE_ENTRY_SCALE (scale);
composeint.color_spins[j] = GIMP_SCALE_ENTRY_SPINBUTTON (scale);
gtk_widget_set_sensitive (composeint.color_scales[j], FALSE);
gtk_widget_set_sensitive (composeint.color_spins[j], FALSE);
g_signal_connect (scale, "value-changed",
G_CALLBACK (scale_callback),
&composeint.selected[j]);
/* This has to be connected last otherwise it will emit before
* combo_callback has any scale and spinbutton to work with
*/
gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
2019-08-30 01:22:50 +08:00
gimp_item_get_id (composeint.selected[j].comp.object),
G_CALLBACK (combo_callback),
GINT_TO_POINTER (j), NULL);
2000-01-11 23:48:00 +08:00
}
1997-11-25 06:05:25 +08:00
g_free (layer_list);
/* Calls the combo callback and sets icons, labels and sensitivity */
gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo),
composeint.compose_idx,
G_CALLBACK (type_combo_callback),
NULL, NULL);
1997-11-25 06:05:25 +08:00
gtk_widget_show (dialog);
1997-11-25 06:05:25 +08:00
run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gtk_widget_destroy (dialog);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
if (run)
{
gint j;
for (j = 0; j < MAX_COMPOSE_IMAGES; j++)
{
2019-08-30 01:22:50 +08:00
composevals.inputs[j].is_object = composeint.selected[j].is_object;
2019-08-30 01:22:50 +08:00
if (composevals.inputs[j].is_object)
composevals.inputs[j].comp.object = composeint.selected[j].comp.object;
else
composevals.inputs[j].comp.val = composeint.selected[j].comp.val;
}
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
strcpy (composevals.compose_type,
compose_dsc[composeint.compose_idx].compose_type);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
}
1997-11-25 06:05:25 +08:00
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
return run;
1997-11-25 06:05:25 +08:00
}
/* Compose interface functions */
static gboolean
2019-08-30 01:22:50 +08:00
check_gray (GimpImage *image,
GimpItem *drawable,
gpointer data)
1997-11-25 06:05:25 +08:00
{
2019-08-30 01:22:50 +08:00
return ((gimp_image_base_type (image) == GIMP_GRAY) &&
(gimp_image_width (image) == composeint.width) &&
(gimp_image_height (image) == composeint.height));
1997-11-25 06:05:25 +08:00
}
static void
check_response (GtkWidget *dialog,
gint response,
gpointer data)
{
switch (response)
{
case GTK_RESPONSE_OK:
{
gint i;
gint nb = 0;
gboolean has_image = FALSE;
nb = compose_dsc[composeint.compose_idx].num_images;
for (i = 0; i < nb; i++)
{
2019-08-30 01:22:50 +08:00
if (composeint.selected[i].is_object)
{
has_image = TRUE;
break;
}
}
if (! has_image)
{
GtkWidget *d;
g_signal_stop_emission_by_name (dialog, "response");
d = gtk_message_dialog_new (GTK_WINDOW (dialog),
GTK_DIALOG_DESTROY_WITH_PARENT |
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
_("At least one image is needed to compose"));
gtk_dialog_run (GTK_DIALOG (d));
gtk_widget_destroy (d);
}
}
break;
default:
break;
}
}
static void
combo_callback (GimpIntComboBox *widget,
gpointer data)
{
gint id;
gint n;
gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &id);
n = GPOINTER_TO_INT (data);
if (id == -1)
{
gtk_widget_set_sensitive (composeint.color_scales[n], TRUE);
gtk_widget_set_sensitive (composeint.color_spins[n], TRUE);
2019-08-30 01:22:50 +08:00
composeint.selected[n].is_object = FALSE;
composeint.selected[n].comp.val =
gtk_range_get_value (GTK_RANGE (composeint.color_scales[n]));
}
else
{
gtk_widget_set_sensitive (composeint.color_scales[n], FALSE);
gtk_widget_set_sensitive (composeint.color_spins[n], FALSE);
2019-08-30 01:22:50 +08:00
composeint.selected[n].is_object = TRUE;
composeint.selected[n].comp.object = gimp_drawable_get_by_id (id);
}
}
static void
scale_callback (GtkAdjustment *adj,
ComposeInput *input)
{
input->comp.val = gtk_adjustment_get_value (adj);
}
1997-11-25 06:05:25 +08:00
static void
type_combo_callback (GimpIntComboBox *combo,
gpointer data)
1997-11-25 06:05:25 +08:00
{
if (gimp_int_combo_box_get_active (combo, &composeint.compose_idx))
{
gboolean combo4;
gboolean scale4;
gint compose_idx;
gint j;
compose_idx = composeint.compose_idx;
for (j = 0; j < MAX_COMPOSE_IMAGES; j++)
{
GtkWidget *label = composeint.channel_label[j];
GtkWidget *image = composeint.channel_icon[j];
2013-07-07 21:55:42 +08:00
const gchar *text = compose_dsc[compose_idx].components[j].name;
const gchar *icon = compose_dsc[compose_idx].components[j].icon;
gtk_label_set_text_with_mnemonic (GTK_LABEL (label),
text ? gettext (text) : "");
if (icon)
{
gtk_image_set_from_icon_name (GTK_IMAGE (image),
icon, GTK_ICON_SIZE_BUTTON);
gtk_widget_show (image);
}
else
{
gtk_image_clear (GTK_IMAGE (image));
gtk_widget_hide (image);
}
}
/* Set sensitivity of last menu */
2013-07-07 21:55:42 +08:00
combo4 = (compose_dsc[compose_idx].num_images == 4);
gtk_widget_set_sensitive (composeint.channel_menu[3], combo4);
2019-08-30 01:22:50 +08:00
scale4 = combo4 && !composeint.selected[3].is_object;
gtk_widget_set_sensitive (composeint.color_scales[3], scale4);
gtk_widget_set_sensitive (composeint.color_spins[3], scale4);
}
1997-11-25 06:05:25 +08:00
}