2006-12-10 05:33:38 +08:00
|
|
|
/* GIMP - The GNU Image Manipulation Program
|
1997-11-25 06:05:25 +08:00
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
2009-01-18 06:28:01 +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
|
2009-01-18 06:28:01 +08:00
|
|
|
* 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
|
2009-01-18 06:28:01 +08:00
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
2000-12-15 23:54:17 +08:00
|
|
|
|
app/appenv.h New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc
1999-09-01 Tor Lillqvist <tml@iki.fi>
* app/appenv.h
* libgimp/gimpmath.h: New file. Includes <math.h>. Move G_PI,
RINT(), ROUND() etc from app/appenv.h here, so plug-ins can
use them, too. Remove some commented-out old stuff in appenv.h.
* libgimp/gimp.h: Include gimpmath.h.
* libgimp/gimp.c (gimp_main): Win32: Don't install signal
handlers, we can't do anything useful in the handler ourselves
anyway (it would be nice to print out a backtrace, but that seems
pretty hard to do, even if not impossible). Let Windows inform the
user about the crash. If the plug-in was compiled with MSVC, and
the user also has it, she is offered a chance to start the
debugger automatically anyway.
* app/*several*.c: Include gimpmath.h for G_PI etc. Don't include
<math.h>, as gimpmath.h includes it.
* plug-ins/*/*many*.c: Include config.h. Don't include <math.h>.
Remove all the duplicated definitions of G_PI and rint(). Use
RINT() instead of rint().
* app/app_procs.[ch]: app_exit() takes a gboolean.
* app/batch.c
* app/commands.c
* app/interface.c: Call app_exit() with FALSE or TRUE.
* app/main.c (on_error): Call gimp_fatal_error. (main): Don't
install any signal handler on Win32 here, either.
* app/errors.c (gimp_fatal_error, gimp_terminate): Win32: Format
the message and call MessageBox with it. g_on_error_query doesn't
do anything useful on Win32, and printf'ing a message to stdout or
stderr doesn't do anything, either, in a windowing application.
1999-09-02 04:30:56 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#include <string.h>
|
app/appenv.h New file. Includes <math.h>. Move G_PI, RINT(), ROUND() etc
1999-09-01 Tor Lillqvist <tml@iki.fi>
* app/appenv.h
* libgimp/gimpmath.h: New file. Includes <math.h>. Move G_PI,
RINT(), ROUND() etc from app/appenv.h here, so plug-ins can
use them, too. Remove some commented-out old stuff in appenv.h.
* libgimp/gimp.h: Include gimpmath.h.
* libgimp/gimp.c (gimp_main): Win32: Don't install signal
handlers, we can't do anything useful in the handler ourselves
anyway (it would be nice to print out a backtrace, but that seems
pretty hard to do, even if not impossible). Let Windows inform the
user about the crash. If the plug-in was compiled with MSVC, and
the user also has it, she is offered a chance to start the
debugger automatically anyway.
* app/*several*.c: Include gimpmath.h for G_PI etc. Don't include
<math.h>, as gimpmath.h includes it.
* plug-ins/*/*many*.c: Include config.h. Don't include <math.h>.
Remove all the duplicated definitions of G_PI and rint(). Use
RINT() instead of rint().
* app/app_procs.[ch]: app_exit() takes a gboolean.
* app/batch.c
* app/commands.c
* app/interface.c: Call app_exit() with FALSE or TRUE.
* app/main.c (on_error): Call gimp_fatal_error. (main): Don't
install any signal handler on Win32 here, either.
* app/errors.c (gimp_fatal_error, gimp_terminate): Win32: Format
the message and call MessageBox with it. g_on_error_query doesn't
do anything useful on Win32, and printf'ing a message to stdout or
stderr doesn't do anything, either, in a windowing application.
1999-09-02 04:30:56 +08:00
|
|
|
|
2008-10-10 04:24:04 +08:00
|
|
|
#include <gegl.h>
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2001-01-29 21:51:23 +08:00
|
|
|
#include "libgimpcolor/gimpcolor.h"
|
2001-01-24 07:56:18 +08:00
|
|
|
|
2001-05-10 06:34:59 +08:00
|
|
|
#include "core-types.h"
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2001-05-15 19:25:25 +08:00
|
|
|
#include "base/boundary.h"
|
|
|
|
#include "base/gimplut.h"
|
2001-05-23 07:05:35 +08:00
|
|
|
#include "base/lut-funcs.h"
|
2001-05-15 19:25:25 +08:00
|
|
|
#include "base/pixel-processor.h"
|
|
|
|
#include "base/pixel-region.h"
|
|
|
|
#include "base/tile.h"
|
|
|
|
#include "base/tile-manager.h"
|
|
|
|
|
2001-04-07 23:58:26 +08:00
|
|
|
#include "paint-funcs/paint-funcs.h"
|
|
|
|
|
2003-09-02 01:56:44 +08:00
|
|
|
#include "paint/gimppaintcore-stroke.h"
|
2004-01-22 08:16:49 +08:00
|
|
|
#include "paint/gimppaintoptions.h"
|
2003-09-02 01:56:44 +08:00
|
|
|
|
2004-01-22 08:16:49 +08:00
|
|
|
#include "gimp.h"
|
2003-08-21 23:54:47 +08:00
|
|
|
#include "gimp-utils.h"
|
2004-01-27 00:18:16 +08:00
|
|
|
#include "gimpcontainer.h"
|
2008-11-12 18:56:06 +08:00
|
|
|
#include "gimperror.h"
|
2000-12-29 23:22:01 +08:00
|
|
|
#include "gimpimage.h"
|
2005-09-19 20:44:06 +08:00
|
|
|
#include "gimpimage-quick-mask.h"
|
2003-05-12 23:56:36 +08:00
|
|
|
#include "gimpimage-undo.h"
|
2003-02-14 22:14:29 +08:00
|
|
|
#include "gimpimage-undo-push.h"
|
2001-02-02 02:44:22 +08:00
|
|
|
#include "gimpchannel.h"
|
2008-11-08 08:16:40 +08:00
|
|
|
#include "gimpchannel-project.h"
|
2010-07-21 05:09:19 +08:00
|
|
|
#include "gimpchannel-select.h"
|
2004-01-22 08:16:49 +08:00
|
|
|
#include "gimpcontext.h"
|
2003-09-30 10:44:17 +08:00
|
|
|
#include "gimpdrawable-stroke.h"
|
2004-07-05 19:18:34 +08:00
|
|
|
#include "gimpmarshal.h"
|
2003-09-02 01:56:44 +08:00
|
|
|
#include "gimppaintinfo.h"
|
2005-07-12 03:21:52 +08:00
|
|
|
#include "gimppickable.h"
|
2008-10-24 15:37:46 +08:00
|
|
|
#include "gimpstrokeoptions.h"
|
2001-07-08 06:49:01 +08:00
|
|
|
|
2003-03-26 00:38:19 +08:00
|
|
|
#include "gimp-intl.h"
|
2000-04-28 01:27:28 +08:00
|
|
|
|
|
|
|
|
2004-07-05 19:18:34 +08:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
COLOR_CHANGED,
|
|
|
|
LAST_SIGNAL
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2005-12-11 03:24:36 +08:00
|
|
|
static void gimp_channel_pickable_iface_init (GimpPickableInterface *iface);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2008-10-24 15:37:46 +08:00
|
|
|
static void gimp_channel_finalize (GObject *object);
|
|
|
|
|
|
|
|
static gint64 gimp_channel_get_memsize (GimpObject *object,
|
|
|
|
gint64 *gui_size);
|
|
|
|
|
|
|
|
static gchar * gimp_channel_get_description (GimpViewable *viewable,
|
|
|
|
gchar **tooltip);
|
|
|
|
|
2009-08-30 01:47:52 +08:00
|
|
|
static gboolean gimp_channel_is_attached (const GimpItem *item);
|
2010-02-06 23:17:23 +08:00
|
|
|
static GimpItemTree * gimp_channel_get_tree (GimpItem *item);
|
2008-10-24 15:37:46 +08:00
|
|
|
static GimpItem * gimp_channel_duplicate (GimpItem *item,
|
|
|
|
GType new_type);
|
|
|
|
static void gimp_channel_convert (GimpItem *item,
|
|
|
|
GimpImage *dest_image);
|
|
|
|
static void gimp_channel_translate (GimpItem *item,
|
|
|
|
gint off_x,
|
|
|
|
gint off_y,
|
|
|
|
gboolean push_undo);
|
|
|
|
static void gimp_channel_scale (GimpItem *item,
|
|
|
|
gint new_width,
|
|
|
|
gint new_height,
|
|
|
|
gint new_offset_x,
|
|
|
|
gint new_offset_y,
|
2004-02-09 08:09:20 +08:00
|
|
|
GimpInterpolationType interp_type,
|
2008-10-24 15:37:46 +08:00
|
|
|
GimpProgress *progress);
|
|
|
|
static void gimp_channel_resize (GimpItem *item,
|
|
|
|
GimpContext *context,
|
|
|
|
gint new_width,
|
|
|
|
gint new_height,
|
|
|
|
gint offx,
|
|
|
|
gint offy);
|
|
|
|
static void gimp_channel_flip (GimpItem *item,
|
|
|
|
GimpContext *context,
|
2003-09-03 07:07:40 +08:00
|
|
|
GimpOrientationType flip_type,
|
2008-10-24 15:37:46 +08:00
|
|
|
gdouble axis,
|
|
|
|
gboolean flip_result);
|
|
|
|
static void gimp_channel_rotate (GimpItem *item,
|
|
|
|
GimpContext *context,
|
|
|
|
GimpRotationType flip_type,
|
|
|
|
gdouble center_x,
|
|
|
|
gdouble center_y,
|
|
|
|
gboolean flip_result);
|
|
|
|
static void gimp_channel_transform (GimpItem *item,
|
|
|
|
GimpContext *context,
|
2003-09-03 07:07:40 +08:00
|
|
|
const GimpMatrix3 *matrix,
|
|
|
|
GimpTransformDirection direction,
|
|
|
|
GimpInterpolationType interpolation_type,
|
2008-10-24 15:37:46 +08:00
|
|
|
gint recursion_level,
|
2006-12-25 00:48:08 +08:00
|
|
|
GimpTransformResize clip_result,
|
2008-10-24 15:37:46 +08:00
|
|
|
GimpProgress *progress);
|
|
|
|
static gboolean gimp_channel_stroke (GimpItem *item,
|
|
|
|
GimpDrawable *drawable,
|
|
|
|
GimpStrokeOptions *stroke_options,
|
2008-10-25 19:59:03 +08:00
|
|
|
gboolean push_undo,
|
2008-10-24 15:37:46 +08:00
|
|
|
GimpProgress *progress,
|
|
|
|
GError **error);
|
2010-07-21 05:09:19 +08:00
|
|
|
static void gimp_channel_to_selection (GimpItem *item,
|
|
|
|
GimpChannelOps op,
|
|
|
|
gboolean antialias,
|
|
|
|
gboolean feather,
|
|
|
|
gdouble feather_radius_x,
|
|
|
|
gdouble feather_radius_y);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2003-10-06 22:40:12 +08:00
|
|
|
static void gimp_channel_invalidate_boundary (GimpDrawable *drawable);
|
|
|
|
static void gimp_channel_get_active_components (const GimpDrawable *drawable,
|
|
|
|
gboolean *active);
|
|
|
|
|
2008-10-24 15:37:46 +08:00
|
|
|
static void gimp_channel_apply_region (GimpDrawable *drawable,
|
|
|
|
PixelRegion *src2PR,
|
|
|
|
gboolean push_undo,
|
|
|
|
const gchar *undo_desc,
|
|
|
|
gdouble opacity,
|
2003-10-06 22:40:12 +08:00
|
|
|
GimpLayerModeEffects mode,
|
2008-10-24 15:37:46 +08:00
|
|
|
TileManager *src1_tiles,
|
2008-11-09 03:52:18 +08:00
|
|
|
PixelRegion *destPR,
|
2008-10-24 15:37:46 +08:00
|
|
|
gint x,
|
|
|
|
gint y);
|
|
|
|
static void gimp_channel_replace_region (GimpDrawable *drawable,
|
|
|
|
PixelRegion *src2PR,
|
|
|
|
gboolean push_undo,
|
|
|
|
const gchar *undo_desc,
|
|
|
|
gdouble opacity,
|
|
|
|
PixelRegion *maskPR,
|
|
|
|
gint x,
|
|
|
|
gint y);
|
|
|
|
static void gimp_channel_set_tiles (GimpDrawable *drawable,
|
|
|
|
gboolean push_undo,
|
|
|
|
const gchar *undo_desc,
|
|
|
|
TileManager *tiles,
|
|
|
|
GimpImageType type,
|
|
|
|
gint offset_x,
|
|
|
|
gint offset_y);
|
2008-11-03 00:39:38 +08:00
|
|
|
static GeglNode * gimp_channel_get_node (GimpItem *item);
|
2008-10-24 15:37:46 +08:00
|
|
|
static void gimp_channel_swap_pixels (GimpDrawable *drawable,
|
|
|
|
TileManager *tiles,
|
|
|
|
gboolean sparse,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint width,
|
|
|
|
gint height);
|
|
|
|
|
|
|
|
static gint gimp_channel_get_opacity_at (GimpPickable *pickable,
|
|
|
|
gint x,
|
|
|
|
gint y);
|
|
|
|
|
|
|
|
static gboolean gimp_channel_real_boundary (GimpChannel *channel,
|
|
|
|
const BoundSeg **segs_in,
|
|
|
|
const BoundSeg **segs_out,
|
|
|
|
gint *num_segs_in,
|
|
|
|
gint *num_segs_out,
|
|
|
|
gint x1,
|
|
|
|
gint y1,
|
|
|
|
gint x2,
|
|
|
|
gint y2);
|
|
|
|
static gboolean gimp_channel_real_bounds (GimpChannel *channel,
|
|
|
|
gint *x1,
|
|
|
|
gint *y1,
|
|
|
|
gint *x2,
|
|
|
|
gint *y2);
|
|
|
|
static gboolean gimp_channel_real_is_empty (GimpChannel *channel);
|
|
|
|
static void gimp_channel_real_feather (GimpChannel *channel,
|
|
|
|
gdouble radius_x,
|
|
|
|
gdouble radius_y,
|
|
|
|
gboolean push_undo);
|
|
|
|
static void gimp_channel_real_sharpen (GimpChannel *channel,
|
|
|
|
gboolean push_undo);
|
|
|
|
static void gimp_channel_real_clear (GimpChannel *channel,
|
|
|
|
const gchar *undo_desc,
|
|
|
|
gboolean push_undo);
|
|
|
|
static void gimp_channel_real_all (GimpChannel *channel,
|
|
|
|
gboolean push_undo);
|
|
|
|
static void gimp_channel_real_invert (GimpChannel *channel,
|
|
|
|
gboolean push_undo);
|
|
|
|
static void gimp_channel_real_border (GimpChannel *channel,
|
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
|
|
|
gboolean feather,
|
|
|
|
gboolean edge_lock,
|
|
|
|
gboolean push_undo);
|
|
|
|
static void gimp_channel_real_grow (GimpChannel *channel,
|
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
|
|
|
gboolean push_undo);
|
|
|
|
static void gimp_channel_real_shrink (GimpChannel *channel,
|
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
|
|
|
gboolean edge_lock,
|
|
|
|
gboolean push_undo);
|
|
|
|
|
|
|
|
static void gimp_channel_validate_tile (TileManager *tm,
|
|
|
|
Tile *tile);
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2000-12-17 06:02:10 +08:00
|
|
|
|
2005-12-11 03:24:36 +08:00
|
|
|
G_DEFINE_TYPE_WITH_CODE (GimpChannel, gimp_channel, GIMP_TYPE_DRAWABLE,
|
|
|
|
G_IMPLEMENT_INTERFACE (GIMP_TYPE_PICKABLE,
|
2006-05-15 17:46:31 +08:00
|
|
|
gimp_channel_pickable_iface_init))
|
2004-07-05 19:18:34 +08:00
|
|
|
|
2005-12-11 03:24:36 +08:00
|
|
|
#define parent_class gimp_channel_parent_class
|
1998-01-22 15:02:57 +08:00
|
|
|
|
2005-12-11 03:24:36 +08:00
|
|
|
static guint channel_signals[LAST_SIGNAL] = { 0 };
|
1998-01-22 15:02:57 +08:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
2001-01-10 08:36:54 +08:00
|
|
|
gimp_channel_class_init (GimpChannelClass *klass)
|
1998-01-22 15:02:57 +08:00
|
|
|
{
|
2004-03-17 00:23:06 +08:00
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
|
|
|
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
|
|
|
|
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
|
|
|
|
GimpDrawableClass *drawable_class = GIMP_DRAWABLE_CLASS (klass);
|
2001-01-10 08:36:54 +08:00
|
|
|
|
2004-07-05 19:18:34 +08:00
|
|
|
channel_signals[COLOR_CHANGED] =
|
|
|
|
g_signal_new ("color-changed",
|
2006-04-12 20:49:29 +08:00
|
|
|
G_TYPE_FROM_CLASS (klass),
|
|
|
|
G_SIGNAL_RUN_FIRST,
|
|
|
|
G_STRUCT_OFFSET (GimpChannelClass, color_changed),
|
|
|
|
NULL, NULL,
|
|
|
|
gimp_marshal_VOID__VOID,
|
|
|
|
G_TYPE_NONE, 0);
|
2004-07-05 19:18:34 +08:00
|
|
|
|
2003-10-06 22:40:12 +08:00
|
|
|
object_class->finalize = gimp_channel_finalize;
|
|
|
|
|
|
|
|
gimp_object_class->get_memsize = gimp_channel_get_memsize;
|
|
|
|
|
2004-09-26 00:52:49 +08:00
|
|
|
viewable_class->get_description = gimp_channel_get_description;
|
2003-10-06 22:40:12 +08:00
|
|
|
viewable_class->default_stock_id = "gimp-channel";
|
|
|
|
|
2008-10-11 18:29:19 +08:00
|
|
|
item_class->is_attached = gimp_channel_is_attached;
|
2010-02-06 23:17:23 +08:00
|
|
|
item_class->get_tree = gimp_channel_get_tree;
|
2008-10-11 18:29:19 +08:00
|
|
|
item_class->duplicate = gimp_channel_duplicate;
|
|
|
|
item_class->convert = gimp_channel_convert;
|
|
|
|
item_class->translate = gimp_channel_translate;
|
|
|
|
item_class->scale = gimp_channel_scale;
|
|
|
|
item_class->resize = gimp_channel_resize;
|
|
|
|
item_class->flip = gimp_channel_flip;
|
|
|
|
item_class->rotate = gimp_channel_rotate;
|
|
|
|
item_class->transform = gimp_channel_transform;
|
|
|
|
item_class->stroke = gimp_channel_stroke;
|
2010-07-21 05:09:19 +08:00
|
|
|
item_class->to_selection = gimp_channel_to_selection;
|
2008-11-03 00:39:38 +08:00
|
|
|
item_class->get_node = gimp_channel_get_node;
|
2008-10-11 18:29:19 +08:00
|
|
|
item_class->default_name = _("Channel");
|
2010-06-08 19:24:11 +08:00
|
|
|
item_class->rename_desc = C_("undo-type", "Rename Channel");
|
|
|
|
item_class->translate_desc = C_("undo-type", "Move Channel");
|
|
|
|
item_class->scale_desc = C_("undo-type", "Scale Channel");
|
|
|
|
item_class->resize_desc = C_("undo-type", "Resize Channel");
|
|
|
|
item_class->flip_desc = C_("undo-type", "Flip Channel");
|
|
|
|
item_class->rotate_desc = C_("undo-type", "Rotate Channel");
|
|
|
|
item_class->transform_desc = C_("undo-type", "Transform Channel");
|
|
|
|
item_class->stroke_desc = C_("undo-type", "Stroke Channel");
|
2010-07-21 05:09:19 +08:00
|
|
|
item_class->to_selection_desc = C_("undo-type", "Channel to Selection");
|
2010-07-09 00:08:13 +08:00
|
|
|
item_class->reorder_desc = C_("undo-type", "Reorder Channel");
|
|
|
|
item_class->raise_desc = C_("undo-type", "Raise Channel");
|
|
|
|
item_class->raise_to_top_desc = C_("undo-type", "Raise Channel to Top");
|
|
|
|
item_class->lower_desc = C_("undo-type", "Lower Channel");
|
|
|
|
item_class->lower_to_bottom_desc = C_("undo-type", "Lower Channel to Bottom");
|
|
|
|
item_class->raise_failed = _("Channel cannot be raised higher.");
|
|
|
|
item_class->lower_failed = _("Channel cannot be lowered more.");
|
2003-10-06 22:40:12 +08:00
|
|
|
|
|
|
|
drawable_class->invalidate_boundary = gimp_channel_invalidate_boundary;
|
|
|
|
drawable_class->get_active_components = gimp_channel_get_active_components;
|
|
|
|
drawable_class->apply_region = gimp_channel_apply_region;
|
|
|
|
drawable_class->replace_region = gimp_channel_replace_region;
|
2008-11-08 08:16:40 +08:00
|
|
|
drawable_class->project_region = gimp_channel_project_region;
|
2004-03-13 21:56:09 +08:00
|
|
|
drawable_class->set_tiles = gimp_channel_set_tiles;
|
2004-03-15 22:10:30 +08:00
|
|
|
drawable_class->swap_pixels = gimp_channel_swap_pixels;
|
2003-10-06 22:40:12 +08:00
|
|
|
|
|
|
|
klass->boundary = gimp_channel_real_boundary;
|
|
|
|
klass->bounds = gimp_channel_real_bounds;
|
|
|
|
klass->is_empty = gimp_channel_real_is_empty;
|
|
|
|
klass->feather = gimp_channel_real_feather;
|
|
|
|
klass->sharpen = gimp_channel_real_sharpen;
|
|
|
|
klass->clear = gimp_channel_real_clear;
|
|
|
|
klass->all = gimp_channel_real_all;
|
|
|
|
klass->invert = gimp_channel_real_invert;
|
|
|
|
klass->border = gimp_channel_real_border;
|
|
|
|
klass->grow = gimp_channel_real_grow;
|
|
|
|
klass->shrink = gimp_channel_real_shrink;
|
|
|
|
|
2010-06-08 19:24:11 +08:00
|
|
|
klass->feather_desc = C_("undo-type", "Feather Channel");
|
|
|
|
klass->sharpen_desc = C_("undo-type", "Sharpen Channel");
|
|
|
|
klass->clear_desc = C_("undo-type", "Clear Channel");
|
|
|
|
klass->all_desc = C_("undo-type", "Fill Channel");
|
|
|
|
klass->invert_desc = C_("undo-type", "Invert Channel");
|
|
|
|
klass->border_desc = C_("undo-type", "Border Channel");
|
|
|
|
klass->grow_desc = C_("undo-type", "Grow Channel");
|
|
|
|
klass->shrink_desc = C_("undo-type", "Shrink Channel");
|
1998-01-22 15:02:57 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_init (GimpChannel *channel)
|
|
|
|
{
|
2002-03-04 01:38:12 +08:00
|
|
|
gimp_rgba_set (&channel->color, 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE);
|
2001-01-29 21:51:23 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
channel->show_masked = FALSE;
|
2001-01-29 21:51:23 +08:00
|
|
|
|
|
|
|
/* Selection mask variables */
|
2003-01-11 01:55:53 +08:00
|
|
|
channel->boundary_known = FALSE;
|
2001-01-29 21:51:23 +08:00
|
|
|
channel->segs_in = NULL;
|
|
|
|
channel->segs_out = NULL;
|
|
|
|
channel->num_segs_in = 0;
|
|
|
|
channel->num_segs_out = 0;
|
2003-01-11 01:55:53 +08:00
|
|
|
channel->empty = FALSE;
|
|
|
|
channel->bounds_known = FALSE;
|
2001-01-29 21:51:23 +08:00
|
|
|
channel->x1 = 0;
|
|
|
|
channel->y1 = 0;
|
|
|
|
channel->x2 = 0;
|
|
|
|
channel->y2 = 0;
|
1998-01-22 15:02:57 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2005-07-12 03:21:52 +08:00
|
|
|
static void
|
2005-12-11 03:24:36 +08:00
|
|
|
gimp_channel_pickable_iface_init (GimpPickableInterface *iface)
|
2005-07-12 03:21:52 +08:00
|
|
|
{
|
2005-12-11 03:24:36 +08:00
|
|
|
iface->get_opacity_at = gimp_channel_get_opacity_at;
|
2005-07-12 03:21:52 +08:00
|
|
|
}
|
|
|
|
|
2001-01-29 21:51:23 +08:00
|
|
|
static void
|
2001-08-11 22:39:19 +08:00
|
|
|
gimp_channel_finalize (GObject *object)
|
2001-01-29 21:51:23 +08:00
|
|
|
{
|
2004-01-12 21:57:30 +08:00
|
|
|
GimpChannel *channel = GIMP_CHANNEL (object);
|
2001-01-29 21:51:23 +08:00
|
|
|
|
|
|
|
if (channel->segs_in)
|
2001-08-11 22:39:19 +08:00
|
|
|
{
|
|
|
|
g_free (channel->segs_in);
|
|
|
|
channel->segs_in = NULL;
|
|
|
|
}
|
|
|
|
|
2001-01-29 21:51:23 +08:00
|
|
|
if (channel->segs_out)
|
2001-08-11 22:39:19 +08:00
|
|
|
{
|
|
|
|
g_free (channel->segs_out);
|
|
|
|
channel->segs_out = NULL;
|
|
|
|
}
|
2001-01-29 21:51:23 +08:00
|
|
|
|
2001-08-11 22:39:19 +08:00
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
2001-01-29 21:51:23 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-11-17 01:51:36 +08:00
|
|
|
static gint64
|
2003-08-25 18:49:33 +08:00
|
|
|
gimp_channel_get_memsize (GimpObject *object,
|
2003-11-17 01:51:36 +08:00
|
|
|
gint64 *gui_size)
|
2002-01-31 00:14:26 +08:00
|
|
|
{
|
2003-11-17 01:51:36 +08:00
|
|
|
GimpChannel *channel = GIMP_CHANNEL (object);
|
2002-01-31 00:14:26 +08:00
|
|
|
|
2003-08-25 18:49:33 +08:00
|
|
|
*gui_size += channel->num_segs_in * sizeof (BoundSeg);
|
|
|
|
*gui_size += channel->num_segs_out * sizeof (BoundSeg);
|
2002-01-31 00:14:26 +08:00
|
|
|
|
2003-08-25 18:49:33 +08:00
|
|
|
return GIMP_OBJECT_CLASS (parent_class)->get_memsize (object, gui_size);
|
2002-01-31 00:14:26 +08:00
|
|
|
}
|
|
|
|
|
2004-09-26 00:52:49 +08:00
|
|
|
static gchar *
|
|
|
|
gimp_channel_get_description (GimpViewable *viewable,
|
|
|
|
gchar **tooltip)
|
|
|
|
{
|
2005-09-19 20:44:06 +08:00
|
|
|
if (! strcmp (GIMP_IMAGE_QUICK_MASK_NAME,
|
2009-09-01 04:47:18 +08:00
|
|
|
gimp_object_get_name (viewable)))
|
2004-09-26 00:52:49 +08:00
|
|
|
{
|
|
|
|
return g_strdup (_("Quick Mask"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return GIMP_VIEWABLE_CLASS (parent_class)->get_description (viewable,
|
|
|
|
tooltip);
|
|
|
|
}
|
|
|
|
|
2004-01-27 00:18:16 +08:00
|
|
|
static gboolean
|
2009-08-30 01:47:52 +08:00
|
|
|
gimp_channel_is_attached (const GimpItem *item)
|
2004-01-27 00:18:16 +08:00
|
|
|
{
|
2010-02-04 06:00:31 +08:00
|
|
|
GimpImage *image = gimp_item_get_image (item);
|
|
|
|
|
|
|
|
return (GIMP_IS_IMAGE (image) &&
|
|
|
|
gimp_container_have (gimp_image_get_channels (image),
|
2009-08-30 01:47:52 +08:00
|
|
|
GIMP_OBJECT (item)));
|
2004-01-27 00:18:16 +08:00
|
|
|
}
|
|
|
|
|
2010-02-06 23:17:23 +08:00
|
|
|
static GimpItemTree *
|
|
|
|
gimp_channel_get_tree (GimpItem *item)
|
2009-08-02 02:22:07 +08:00
|
|
|
{
|
|
|
|
if (gimp_item_is_attached (item))
|
|
|
|
{
|
|
|
|
GimpImage *image = gimp_item_get_image (item);
|
|
|
|
|
2010-02-06 23:17:23 +08:00
|
|
|
return gimp_image_get_channel_tree (image);
|
2009-08-02 02:22:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-02-11 21:52:47 +08:00
|
|
|
static GimpItem *
|
|
|
|
gimp_channel_duplicate (GimpItem *item,
|
2008-01-08 19:46:15 +08:00
|
|
|
GType new_type)
|
2003-02-11 21:52:47 +08:00
|
|
|
{
|
2005-12-23 09:15:19 +08:00
|
|
|
GimpItem *new_item;
|
2003-02-11 21:52:47 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_DRAWABLE), NULL);
|
|
|
|
|
2008-01-08 19:46:15 +08:00
|
|
|
new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type);
|
2003-02-11 21:52:47 +08:00
|
|
|
|
2005-12-23 09:15:19 +08:00
|
|
|
if (GIMP_IS_CHANNEL (new_item))
|
|
|
|
{
|
|
|
|
GimpChannel *channel = GIMP_CHANNEL (item);
|
|
|
|
GimpChannel *new_channel = GIMP_CHANNEL (new_item);
|
|
|
|
|
|
|
|
new_channel->color = channel->color;
|
|
|
|
new_channel->show_masked = channel->show_masked;
|
|
|
|
|
|
|
|
/* selection mask variables */
|
|
|
|
new_channel->bounds_known = channel->bounds_known;
|
|
|
|
new_channel->empty = channel->empty;
|
|
|
|
new_channel->x1 = channel->x1;
|
|
|
|
new_channel->y1 = channel->y1;
|
|
|
|
new_channel->x2 = channel->x2;
|
|
|
|
new_channel->y2 = channel->y2;
|
|
|
|
}
|
2003-02-11 21:52:47 +08:00
|
|
|
|
|
|
|
return new_item;
|
|
|
|
}
|
|
|
|
|
2005-01-16 05:15:43 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_convert (GimpItem *item,
|
|
|
|
GimpImage *dest_image)
|
|
|
|
{
|
2009-09-08 23:49:48 +08:00
|
|
|
GimpChannel *channel = GIMP_CHANNEL (item);
|
|
|
|
GimpDrawable *drawable = GIMP_DRAWABLE (item);
|
2005-01-16 05:15:43 +08:00
|
|
|
|
2009-09-08 23:49:48 +08:00
|
|
|
if (! gimp_drawable_is_gray (drawable))
|
2005-01-16 05:15:43 +08:00
|
|
|
{
|
2009-09-14 01:24:19 +08:00
|
|
|
gimp_drawable_convert_type (drawable, NULL, GIMP_GRAY, FALSE);
|
2005-01-16 05:15:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (gimp_drawable_has_alpha (drawable))
|
|
|
|
{
|
|
|
|
TileManager *new_tiles;
|
|
|
|
PixelRegion srcPR;
|
|
|
|
PixelRegion destPR;
|
|
|
|
guchar bg[1] = { 0 };
|
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
new_tiles = tile_manager_new (gimp_item_get_width (item),
|
|
|
|
gimp_item_get_height (item),
|
2005-01-16 05:15:43 +08:00
|
|
|
GIMP_IMAGE_TYPE_BYTES (GIMP_GRAY_IMAGE));
|
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
|
2005-01-16 05:15:43 +08:00
|
|
|
0, 0,
|
2008-11-04 05:17:50 +08:00
|
|
|
gimp_item_get_width (item),
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_height (item),
|
2005-01-16 05:15:43 +08:00
|
|
|
FALSE);
|
|
|
|
pixel_region_init (&destPR, new_tiles,
|
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (item),
|
|
|
|
gimp_item_get_height (item),
|
2005-01-16 05:15:43 +08:00
|
|
|
TRUE);
|
|
|
|
|
|
|
|
flatten_region (&srcPR, &destPR, bg);
|
|
|
|
|
|
|
|
gimp_drawable_set_tiles_full (drawable, FALSE, NULL,
|
|
|
|
new_tiles, GIMP_GRAY_IMAGE,
|
2008-12-28 20:43:07 +08:00
|
|
|
gimp_item_get_offset_x (item),
|
|
|
|
gimp_item_get_offset_y (item));
|
2005-01-16 05:15:43 +08:00
|
|
|
tile_manager_unref (new_tiles);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (G_TYPE_FROM_INSTANCE (channel) == GIMP_TYPE_CHANNEL)
|
|
|
|
{
|
|
|
|
gint width = gimp_image_get_width (dest_image);
|
|
|
|
gint height = gimp_image_get_height (dest_image);
|
|
|
|
|
2008-11-04 05:17:50 +08:00
|
|
|
gimp_item_set_offset (item, 0, 0);
|
2005-01-16 05:15:43 +08:00
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
if (gimp_item_get_width (item) != width ||
|
|
|
|
gimp_item_get_height (item) != height)
|
2005-01-16 05:15:43 +08:00
|
|
|
{
|
|
|
|
gimp_item_resize (item, gimp_get_user_context (dest_image->gimp),
|
|
|
|
width, height, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image);
|
|
|
|
}
|
|
|
|
|
2003-05-09 21:05:37 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_translate (GimpItem *item,
|
2004-01-12 21:57:30 +08:00
|
|
|
gint off_x,
|
|
|
|
gint off_y,
|
2003-05-09 21:05:37 +08:00
|
|
|
gboolean push_undo)
|
|
|
|
{
|
2004-03-17 00:23:06 +08:00
|
|
|
GimpChannel *channel = GIMP_CHANNEL (item);
|
2003-05-09 21:05:37 +08:00
|
|
|
GimpChannel *tmp_mask = NULL;
|
|
|
|
gint width, height;
|
|
|
|
PixelRegion srcPR, destPR;
|
|
|
|
gint x1, y1, x2, y2;
|
|
|
|
|
2003-09-04 19:33:06 +08:00
|
|
|
gimp_channel_bounds (channel, &x1, &y1, &x2, &y2);
|
2003-05-09 21:05:37 +08:00
|
|
|
|
2003-09-16 19:39:29 +08:00
|
|
|
/* update the old area */
|
2004-03-17 00:23:06 +08:00
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (item), x1, y1, x2 - x1, y2 - y1);
|
2003-05-09 21:05:37 +08:00
|
|
|
|
|
|
|
if (push_undo)
|
2004-04-13 19:43:27 +08:00
|
|
|
gimp_channel_push_undo (channel, NULL);
|
2003-09-04 19:33:06 +08:00
|
|
|
else
|
To optimize duplicate and/or wrong image updates away, introduced new
2003-09-06 Michael Natterer <mitch@gimp.org>
To optimize duplicate and/or wrong image updates away, introduced
new policy that a child object must never explicitly update or
invalidate its parent object (just like the GUI is not updated
explicitly by the core):
* app/core/gimpdrawable.[ch]: added new signal
GimpDrawable::update(). Never update or invalidate the image when
the drawable is updated or invalidated.
(gimp_drawable_set_visible): don't gimp_drawable_update() the
drawable since its pixels have not changed.
* app/core/gimpimage.[ch]: connect to the "add" and "remove"
signals of the layers and channels containers. Also connect to the
"update" and "visibility_changed" signals of all drawables in
these containers (optimizes away updates issued by drawables which
are not yet added to the image and updates of the selection
mask). Also, don't propagate updates to the image if the emitting
drawable is invisible (optimizes away updates issued by invisible
drawables).
(gimp_image_add_layer,channel)
(gimp_image_remove_layer,channel): don't update the image since
that's done by our "add" and "remove" handlers now.
(gimp_image_position_layer,channel): update just the image, not
the drawable since its pixels have not changed.
(gimp_image_real_colormap_changed)
(gimp_image_set_component_visible): always call
gimp_image_update() *and* gimp_viewable_invalidate_preview() to
get everything updated, since update and invalidate of images are
not connected.
* app/core/gimpimage-undo-push.c (undo_pop_layer,channel): don't
update the drawable since (a) its pixels don't change and (b) the
image updates itself upon adding/removing now.
(undo_pop_layer_mod): replaced gimp_image_update() by
gimp_drawable_update() (just for consistency with other similar
functions).
* app/core/gimplayer.c: connect to "update" of the layer mask and
issue updates on the layer if the mask update has any effect on
the projection.
(gimp_layer_create_mask): don't set the mask's offsets here since
they may be different when we later add the mask to the layer.
* app/core/gimplayermask.c (gimp_layer_mask_set_layer): set the
mask offsets here instead.
* app/core/gimpchannel.c (gimp_channel_translate): update the
channel even if push_undo == FALSE.
* app/paint/gimppaintcore.c (gimp_paint_core_finish)
* app/tools/gimpinktool.c (ink_finish): invalidate both the
drawable and the image preview since invalidating the drawable
doesn't invalidate the image any more.
* app/text/gimptextlayer.c (gimp_text_layer_render_now): also
update the new extents of the text layer, not only the old one.
(gimp_text_layer_render_layout): don't update the drawable since
gimp_drawable_fill() already updated it.
2003-09-07 04:06:53 +08:00
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
x1 = CLAMP ((x1 + off_x), 0, gimp_item_get_width (GIMP_ITEM (channel)));
|
|
|
|
y1 = CLAMP ((y1 + off_y), 0, gimp_item_get_height (GIMP_ITEM (channel)));
|
|
|
|
x2 = CLAMP ((x2 + off_x), 0, gimp_item_get_width (GIMP_ITEM (channel)));
|
|
|
|
y2 = CLAMP ((y2 + off_y), 0, gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-16 19:39:29 +08:00
|
|
|
|
|
|
|
width = x2 - x1;
|
|
|
|
height = y2 - y1;
|
2003-05-09 21:05:37 +08:00
|
|
|
|
|
|
|
/* make sure width and height are non-zero */
|
|
|
|
if (width != 0 && height != 0)
|
|
|
|
{
|
|
|
|
/* copy the portion of the mask we will keep to a
|
|
|
|
* temporary buffer
|
|
|
|
*/
|
2003-09-04 19:33:06 +08:00
|
|
|
tmp_mask = gimp_channel_new_mask (gimp_item_get_image (item),
|
2004-01-12 21:57:30 +08:00
|
|
|
width, height);
|
2003-05-09 21:05:37 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&srcPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
x1 - off_x, y1 - off_y, width, height, FALSE);
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&destPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (tmp_mask)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0, width, height, TRUE);
|
2003-05-09 21:05:37 +08:00
|
|
|
copy_region (&srcPR, &destPR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* clear the mask */
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&srcPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)), TRUE);
|
2008-09-02 04:44:00 +08:00
|
|
|
clear_region (&srcPR);
|
2003-05-09 21:05:37 +08:00
|
|
|
|
|
|
|
if (width != 0 && height != 0)
|
|
|
|
{
|
|
|
|
/* copy the temp mask back to the mask */
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&srcPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (tmp_mask)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0, width, height, FALSE);
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&destPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
x1, y1, width, height, TRUE);
|
2003-05-09 21:05:37 +08:00
|
|
|
copy_region (&srcPR, &destPR);
|
|
|
|
|
|
|
|
/* free the temporary mask */
|
|
|
|
g_object_unref (tmp_mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* calculate new bounds */
|
|
|
|
if (width == 0 || height == 0)
|
|
|
|
{
|
2003-09-04 19:33:06 +08:00
|
|
|
channel->empty = TRUE;
|
|
|
|
channel->x1 = 0;
|
|
|
|
channel->y1 = 0;
|
2008-11-03 08:09:01 +08:00
|
|
|
channel->x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
|
|
|
channel->y2 = gimp_item_get_height (GIMP_ITEM (channel));
|
2003-05-09 21:05:37 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-09-04 19:33:06 +08:00
|
|
|
channel->x1 = x1;
|
|
|
|
channel->y1 = y1;
|
|
|
|
channel->x2 = x2;
|
|
|
|
channel->y2 = y2;
|
2003-05-09 21:05:37 +08:00
|
|
|
}
|
|
|
|
|
To optimize duplicate and/or wrong image updates away, introduced new
2003-09-06 Michael Natterer <mitch@gimp.org>
To optimize duplicate and/or wrong image updates away, introduced
new policy that a child object must never explicitly update or
invalidate its parent object (just like the GUI is not updated
explicitly by the core):
* app/core/gimpdrawable.[ch]: added new signal
GimpDrawable::update(). Never update or invalidate the image when
the drawable is updated or invalidated.
(gimp_drawable_set_visible): don't gimp_drawable_update() the
drawable since its pixels have not changed.
* app/core/gimpimage.[ch]: connect to the "add" and "remove"
signals of the layers and channels containers. Also connect to the
"update" and "visibility_changed" signals of all drawables in
these containers (optimizes away updates issued by drawables which
are not yet added to the image and updates of the selection
mask). Also, don't propagate updates to the image if the emitting
drawable is invisible (optimizes away updates issued by invisible
drawables).
(gimp_image_add_layer,channel)
(gimp_image_remove_layer,channel): don't update the image since
that's done by our "add" and "remove" handlers now.
(gimp_image_position_layer,channel): update just the image, not
the drawable since its pixels have not changed.
(gimp_image_real_colormap_changed)
(gimp_image_set_component_visible): always call
gimp_image_update() *and* gimp_viewable_invalidate_preview() to
get everything updated, since update and invalidate of images are
not connected.
* app/core/gimpimage-undo-push.c (undo_pop_layer,channel): don't
update the drawable since (a) its pixels don't change and (b) the
image updates itself upon adding/removing now.
(undo_pop_layer_mod): replaced gimp_image_update() by
gimp_drawable_update() (just for consistency with other similar
functions).
* app/core/gimplayer.c: connect to "update" of the layer mask and
issue updates on the layer if the mask update has any effect on
the projection.
(gimp_layer_create_mask): don't set the mask's offsets here since
they may be different when we later add the mask to the layer.
* app/core/gimplayermask.c (gimp_layer_mask_set_layer): set the
mask offsets here instead.
* app/core/gimpchannel.c (gimp_channel_translate): update the
channel even if push_undo == FALSE.
* app/paint/gimppaintcore.c (gimp_paint_core_finish)
* app/tools/gimpinktool.c (ink_finish): invalidate both the
drawable and the image preview since invalidating the drawable
doesn't invalidate the image any more.
* app/text/gimptextlayer.c (gimp_text_layer_render_now): also
update the new extents of the text layer, not only the old one.
(gimp_text_layer_render_layout): don't update the drawable since
gimp_drawable_fill() already updated it.
2003-09-07 04:06:53 +08:00
|
|
|
/* update the new area */
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (item),
|
|
|
|
channel->x1, channel->y1,
|
|
|
|
channel->x2 - channel->x1,
|
|
|
|
channel->y2 - channel->y1);
|
2003-05-09 21:05:37 +08:00
|
|
|
}
|
|
|
|
|
2003-05-07 19:09:00 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_scale (GimpItem *item,
|
2004-01-12 21:57:30 +08:00
|
|
|
gint new_width,
|
|
|
|
gint new_height,
|
2003-05-07 19:09:00 +08:00
|
|
|
gint new_offset_x,
|
|
|
|
gint new_offset_y,
|
2004-02-09 08:09:20 +08:00
|
|
|
GimpInterpolationType interpolation_type,
|
2004-08-11 02:47:21 +08:00
|
|
|
GimpProgress *progress)
|
2003-05-07 19:09:00 +08:00
|
|
|
{
|
2008-08-05 23:27:18 +08:00
|
|
|
GimpChannel *channel = GIMP_CHANNEL (item);
|
|
|
|
|
2003-06-02 23:19:03 +08:00
|
|
|
if (G_TYPE_FROM_INSTANCE (item) == GIMP_TYPE_CHANNEL)
|
|
|
|
{
|
|
|
|
new_offset_x = 0;
|
|
|
|
new_offset_y = 0;
|
|
|
|
}
|
|
|
|
|
2008-08-05 23:27:18 +08:00
|
|
|
/* don't waste CPU cycles scaling an empty channel */
|
|
|
|
if (channel->bounds_known && channel->empty)
|
|
|
|
{
|
2011-03-16 07:16:31 +08:00
|
|
|
GimpDrawable *drawable = GIMP_DRAWABLE (item);
|
|
|
|
TileManager *new_tiles;
|
|
|
|
|
|
|
|
new_tiles = tile_manager_new (new_width, new_height,
|
|
|
|
gimp_drawable_bytes (drawable));
|
2008-08-05 23:27:18 +08:00
|
|
|
|
|
|
|
gimp_drawable_set_tiles_full (drawable,
|
|
|
|
gimp_item_is_attached (item), NULL,
|
|
|
|
new_tiles, gimp_drawable_type (drawable),
|
|
|
|
new_offset_x, new_offset_y);
|
|
|
|
tile_manager_unref (new_tiles);
|
|
|
|
|
|
|
|
gimp_channel_clear (GIMP_CHANNEL (item), NULL, FALSE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GIMP_ITEM_CLASS (parent_class)->scale (item, new_width, new_height,
|
|
|
|
new_offset_x, new_offset_y,
|
|
|
|
interpolation_type, progress);
|
|
|
|
}
|
2003-05-07 19:09:00 +08:00
|
|
|
}
|
|
|
|
|
2003-05-07 21:01:17 +08:00
|
|
|
static void
|
2004-04-15 07:37:34 +08:00
|
|
|
gimp_channel_resize (GimpItem *item,
|
|
|
|
GimpContext *context,
|
|
|
|
gint new_width,
|
|
|
|
gint new_height,
|
|
|
|
gint offset_x,
|
|
|
|
gint offset_y)
|
2003-05-07 21:01:17 +08:00
|
|
|
{
|
2004-04-15 07:37:34 +08:00
|
|
|
GIMP_ITEM_CLASS (parent_class)->resize (item, context, new_width, new_height,
|
2003-05-07 21:01:17 +08:00
|
|
|
offset_x, offset_y);
|
|
|
|
|
2003-06-02 23:19:03 +08:00
|
|
|
if (G_TYPE_FROM_INSTANCE (item) == GIMP_TYPE_CHANNEL)
|
|
|
|
{
|
2008-11-04 05:17:50 +08:00
|
|
|
gimp_item_set_offset (item, 0, 0);
|
2003-06-02 23:19:03 +08:00
|
|
|
}
|
2003-05-07 21:01:17 +08:00
|
|
|
}
|
|
|
|
|
2002-08-20 18:22:23 +08:00
|
|
|
static void
|
2003-05-12 23:56:36 +08:00
|
|
|
gimp_channel_flip (GimpItem *item,
|
2004-04-15 07:37:34 +08:00
|
|
|
GimpContext *context,
|
2003-05-12 23:56:36 +08:00
|
|
|
GimpOrientationType flip_type,
|
2003-05-13 21:57:11 +08:00
|
|
|
gdouble axis,
|
|
|
|
gboolean clip_result)
|
2003-05-12 23:56:36 +08:00
|
|
|
{
|
2003-05-13 21:57:11 +08:00
|
|
|
if (G_TYPE_FROM_INSTANCE (item) == GIMP_TYPE_CHANNEL)
|
|
|
|
clip_result = TRUE;
|
2003-05-12 23:56:36 +08:00
|
|
|
|
2004-04-15 07:37:34 +08:00
|
|
|
GIMP_ITEM_CLASS (parent_class)->flip (item, context, flip_type, axis,
|
|
|
|
clip_result);
|
2003-05-12 23:56:36 +08:00
|
|
|
}
|
|
|
|
|
2003-05-20 18:36:29 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_rotate (GimpItem *item,
|
2004-04-15 07:37:34 +08:00
|
|
|
GimpContext *context,
|
2003-05-20 18:36:29 +08:00
|
|
|
GimpRotationType rotate_type,
|
|
|
|
gdouble center_x,
|
|
|
|
gdouble center_y,
|
|
|
|
gboolean clip_result)
|
|
|
|
{
|
2003-05-20 23:26:38 +08:00
|
|
|
/* don't default to clip_result == TRUE here */
|
2003-05-20 18:36:29 +08:00
|
|
|
|
2004-04-15 07:37:34 +08:00
|
|
|
GIMP_ITEM_CLASS (parent_class)->rotate (item, context,
|
2003-05-20 18:36:29 +08:00
|
|
|
rotate_type, center_x, center_y,
|
|
|
|
clip_result);
|
|
|
|
}
|
|
|
|
|
2003-05-12 23:56:36 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_transform (GimpItem *item,
|
2004-04-15 07:37:34 +08:00
|
|
|
GimpContext *context,
|
2003-07-07 21:50:48 +08:00
|
|
|
const GimpMatrix3 *matrix,
|
2003-05-12 23:56:36 +08:00
|
|
|
GimpTransformDirection direction,
|
|
|
|
GimpInterpolationType interpolation_type,
|
2004-03-14 01:45:58 +08:00
|
|
|
gint recursion_level,
|
2006-12-25 00:48:08 +08:00
|
|
|
GimpTransformResize clip_result,
|
2004-08-11 02:47:21 +08:00
|
|
|
GimpProgress *progress)
|
2003-05-12 23:56:36 +08:00
|
|
|
{
|
2003-05-13 21:57:11 +08:00
|
|
|
if (G_TYPE_FROM_INSTANCE (item) == GIMP_TYPE_CHANNEL)
|
|
|
|
clip_result = TRUE;
|
2003-05-12 23:56:36 +08:00
|
|
|
|
2004-04-15 07:37:34 +08:00
|
|
|
GIMP_ITEM_CLASS (parent_class)->transform (item, context, matrix, direction,
|
2004-03-14 01:45:58 +08:00
|
|
|
interpolation_type,
|
2007-09-10 23:29:48 +08:00
|
|
|
recursion_level,
|
|
|
|
clip_result,
|
|
|
|
progress);
|
2003-05-12 23:56:36 +08:00
|
|
|
}
|
|
|
|
|
2003-09-02 01:56:44 +08:00
|
|
|
static gboolean
|
2008-10-24 15:37:46 +08:00
|
|
|
gimp_channel_stroke (GimpItem *item,
|
|
|
|
GimpDrawable *drawable,
|
|
|
|
GimpStrokeOptions *stroke_options,
|
2008-10-25 19:59:03 +08:00
|
|
|
gboolean push_undo,
|
2008-10-24 15:37:46 +08:00
|
|
|
GimpProgress *progress,
|
|
|
|
GError **error)
|
2003-09-02 01:56:44 +08:00
|
|
|
{
|
2004-01-22 08:16:49 +08:00
|
|
|
GimpChannel *channel = GIMP_CHANNEL (item);
|
2003-09-30 10:44:17 +08:00
|
|
|
const BoundSeg *segs_in;
|
|
|
|
const BoundSeg *segs_out;
|
|
|
|
gint n_segs_in;
|
|
|
|
gint n_segs_out;
|
|
|
|
gboolean retval = FALSE;
|
2003-09-30 23:16:51 +08:00
|
|
|
gint offset_x, offset_y;
|
2003-09-02 01:56:44 +08:00
|
|
|
|
2003-09-30 10:44:17 +08:00
|
|
|
if (! gimp_channel_boundary (channel, &segs_in, &segs_out,
|
|
|
|
&n_segs_in, &n_segs_out,
|
2003-09-02 01:56:44 +08:00
|
|
|
0, 0, 0, 0))
|
|
|
|
{
|
2008-11-12 18:56:06 +08:00
|
|
|
g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
|
2008-11-04 20:33:09 +08:00
|
|
|
_("Cannot stroke empty channel."));
|
2003-09-02 01:56:44 +08:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2008-11-03 07:03:29 +08:00
|
|
|
gimp_item_get_offset (GIMP_ITEM (channel), &offset_x, &offset_y);
|
2003-09-30 23:59:57 +08:00
|
|
|
|
2011-03-06 04:00:28 +08:00
|
|
|
switch (gimp_stroke_options_get_method (stroke_options))
|
2003-09-30 10:44:17 +08:00
|
|
|
{
|
2004-10-22 20:32:31 +08:00
|
|
|
case GIMP_STROKE_METHOD_LIBART:
|
2003-09-30 10:44:17 +08:00
|
|
|
gimp_drawable_stroke_boundary (drawable,
|
2008-10-24 15:37:46 +08:00
|
|
|
stroke_options,
|
2003-09-30 23:16:51 +08:00
|
|
|
segs_in, n_segs_in,
|
2008-10-25 19:59:03 +08:00
|
|
|
offset_x, offset_y,
|
|
|
|
push_undo);
|
2003-09-30 10:44:17 +08:00
|
|
|
retval = TRUE;
|
2004-10-22 20:32:31 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case GIMP_STROKE_METHOD_PAINT_CORE:
|
|
|
|
{
|
2011-03-06 04:00:28 +08:00
|
|
|
GimpPaintInfo *paint_info;
|
|
|
|
GimpPaintCore *core;
|
|
|
|
GimpPaintOptions *paint_options;
|
|
|
|
gboolean emulate_dynamics;
|
2004-10-22 20:32:31 +08:00
|
|
|
|
2008-10-24 15:37:46 +08:00
|
|
|
paint_info = gimp_context_get_paint_info (GIMP_CONTEXT (stroke_options));
|
|
|
|
|
|
|
|
core = g_object_new (paint_info->paint_type, NULL);
|
2004-01-22 08:16:49 +08:00
|
|
|
|
2011-03-06 04:00:28 +08:00
|
|
|
paint_options = gimp_stroke_options_get_paint_options (stroke_options);
|
|
|
|
emulate_dynamics = gimp_stroke_options_get_emulate_dynamics (stroke_options);
|
|
|
|
|
2004-10-22 20:32:31 +08:00
|
|
|
retval = gimp_paint_core_stroke_boundary (core, drawable,
|
2011-03-06 04:00:28 +08:00
|
|
|
paint_options,
|
|
|
|
emulate_dynamics,
|
2004-10-22 20:32:31 +08:00
|
|
|
segs_in, n_segs_in,
|
2007-12-07 02:40:12 +08:00
|
|
|
offset_x, offset_y,
|
2008-10-25 19:59:03 +08:00
|
|
|
push_undo, error);
|
2003-09-02 01:56:44 +08:00
|
|
|
|
2004-10-22 20:32:31 +08:00
|
|
|
g_object_unref (core);
|
|
|
|
}
|
|
|
|
break;
|
2004-01-22 08:16:49 +08:00
|
|
|
|
2004-10-22 20:32:31 +08:00
|
|
|
default:
|
|
|
|
g_return_val_if_reached (FALSE);
|
2003-09-30 10:44:17 +08:00
|
|
|
}
|
2003-09-02 01:56:44 +08:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2010-07-21 05:09:19 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_to_selection (GimpItem *item,
|
|
|
|
GimpChannelOps op,
|
|
|
|
gboolean antialias,
|
|
|
|
gboolean feather,
|
|
|
|
gdouble feather_radius_x,
|
|
|
|
gdouble feather_radius_y)
|
|
|
|
{
|
|
|
|
GimpChannel *channel = GIMP_CHANNEL (item);
|
|
|
|
GimpImage *image = gimp_item_get_image (item);
|
|
|
|
gint off_x, off_y;
|
|
|
|
|
|
|
|
gimp_item_get_offset (item, &off_x, &off_y);
|
|
|
|
|
|
|
|
gimp_channel_select_channel (gimp_image_get_mask (image),
|
|
|
|
GIMP_ITEM_GET_CLASS (item)->to_selection_desc,
|
|
|
|
channel, off_x, off_y,
|
|
|
|
op,
|
|
|
|
feather, feather_radius_x, feather_radius_x);
|
|
|
|
}
|
|
|
|
|
2003-09-04 19:33:06 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_invalidate_boundary (GimpDrawable *drawable)
|
|
|
|
{
|
2004-03-17 00:23:06 +08:00
|
|
|
GIMP_CHANNEL (drawable)->boundary_known = FALSE;
|
2003-09-04 19:33:06 +08:00
|
|
|
}
|
|
|
|
|
2003-10-06 22:40:12 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_get_active_components (const GimpDrawable *drawable,
|
|
|
|
gboolean *active)
|
|
|
|
{
|
|
|
|
/* Make sure that the alpha channel is not valid. */
|
2008-10-19 21:47:09 +08:00
|
|
|
active[GRAY] = TRUE;
|
|
|
|
active[ALPHA_G] = FALSE;
|
2003-10-06 22:40:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_apply_region (GimpDrawable *drawable,
|
|
|
|
PixelRegion *src2PR,
|
|
|
|
gboolean push_undo,
|
|
|
|
const gchar *undo_desc,
|
|
|
|
gdouble opacity,
|
|
|
|
GimpLayerModeEffects mode,
|
|
|
|
TileManager *src1_tiles,
|
2008-11-09 03:52:18 +08:00
|
|
|
PixelRegion *destPR,
|
2003-10-06 22:40:12 +08:00
|
|
|
gint x,
|
|
|
|
gint y)
|
|
|
|
{
|
|
|
|
gimp_drawable_invalidate_boundary (drawable);
|
|
|
|
|
|
|
|
GIMP_DRAWABLE_CLASS (parent_class)->apply_region (drawable, src2PR,
|
|
|
|
push_undo, undo_desc,
|
|
|
|
opacity, mode,
|
2008-11-09 03:52:18 +08:00
|
|
|
src1_tiles, destPR,
|
2003-10-06 22:40:12 +08:00
|
|
|
x, y);
|
|
|
|
|
|
|
|
GIMP_CHANNEL (drawable)->bounds_known = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_replace_region (GimpDrawable *drawable,
|
|
|
|
PixelRegion *src2PR,
|
|
|
|
gboolean push_undo,
|
|
|
|
const gchar *undo_desc,
|
|
|
|
gdouble opacity,
|
|
|
|
PixelRegion *maskPR,
|
|
|
|
gint x,
|
|
|
|
gint y)
|
|
|
|
{
|
|
|
|
gimp_drawable_invalidate_boundary (drawable);
|
|
|
|
|
|
|
|
GIMP_DRAWABLE_CLASS (parent_class)->replace_region (drawable, src2PR,
|
|
|
|
push_undo, undo_desc,
|
|
|
|
opacity,
|
|
|
|
maskPR,
|
|
|
|
x, y);
|
|
|
|
|
|
|
|
GIMP_CHANNEL (drawable)->bounds_known = FALSE;
|
|
|
|
}
|
|
|
|
|
2004-03-13 21:56:09 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_set_tiles (GimpDrawable *drawable,
|
|
|
|
gboolean push_undo,
|
|
|
|
const gchar *undo_desc,
|
|
|
|
TileManager *tiles,
|
2004-03-16 03:34:35 +08:00
|
|
|
GimpImageType type,
|
|
|
|
gint offset_x,
|
|
|
|
gint offset_y)
|
2004-03-13 21:56:09 +08:00
|
|
|
{
|
|
|
|
GIMP_DRAWABLE_CLASS (parent_class)->set_tiles (drawable,
|
|
|
|
push_undo, undo_desc,
|
2004-03-16 03:34:35 +08:00
|
|
|
tiles, type,
|
|
|
|
offset_x, offset_y);
|
2004-03-15 23:18:25 +08:00
|
|
|
|
|
|
|
GIMP_CHANNEL (drawable)->bounds_known = FALSE;
|
2004-03-13 21:56:09 +08:00
|
|
|
}
|
|
|
|
|
2008-10-11 18:29:19 +08:00
|
|
|
static GeglNode *
|
2008-11-03 00:39:38 +08:00
|
|
|
gimp_channel_get_node (GimpItem *item)
|
2008-10-11 18:29:19 +08:00
|
|
|
{
|
2008-11-03 00:39:38 +08:00
|
|
|
GimpDrawable *drawable = GIMP_DRAWABLE (item);
|
|
|
|
GimpChannel *channel = GIMP_CHANNEL (item);
|
|
|
|
GeglNode *node;
|
|
|
|
GeglNode *source;
|
|
|
|
GeglNode *mode_node;
|
|
|
|
GeglColor *color;
|
|
|
|
|
|
|
|
node = GIMP_ITEM_CLASS (parent_class)->get_node (item);
|
2008-10-11 18:29:19 +08:00
|
|
|
|
|
|
|
source = gimp_drawable_get_source_node (drawable);
|
2008-10-15 02:32:07 +08:00
|
|
|
gegl_node_add_child (node, source);
|
2008-10-11 18:29:19 +08:00
|
|
|
|
|
|
|
color = gegl_color_new (NULL);
|
|
|
|
gegl_color_set_rgba (color,
|
|
|
|
channel->color.r,
|
|
|
|
channel->color.g,
|
|
|
|
channel->color.b,
|
|
|
|
channel->color.a);
|
|
|
|
|
2010-02-15 03:26:16 +08:00
|
|
|
g_warn_if_fail (channel->color_node == NULL);
|
|
|
|
|
2008-10-15 02:32:07 +08:00
|
|
|
channel->color_node = gegl_node_new_child (node,
|
2008-10-15 06:44:42 +08:00
|
|
|
"operation", "gegl:color",
|
2008-10-11 18:29:19 +08:00
|
|
|
"value", color,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
g_object_unref (color);
|
|
|
|
|
2010-02-15 03:26:16 +08:00
|
|
|
g_warn_if_fail (channel->mask_node == NULL);
|
|
|
|
|
2008-10-15 02:32:07 +08:00
|
|
|
channel->mask_node = gegl_node_new_child (node,
|
2008-10-15 06:44:42 +08:00
|
|
|
"operation", "gegl:opacity",
|
2008-10-11 18:29:19 +08:00
|
|
|
NULL);
|
|
|
|
gegl_node_connect_to (channel->color_node, "output",
|
|
|
|
channel->mask_node, "input");
|
|
|
|
|
2010-02-15 03:26:16 +08:00
|
|
|
g_warn_if_fail (channel->invert_node == NULL);
|
|
|
|
|
2008-10-15 02:32:07 +08:00
|
|
|
channel->invert_node = gegl_node_new_child (node,
|
2008-10-15 06:44:42 +08:00
|
|
|
"operation", "gegl:invert",
|
2008-10-11 18:29:19 +08:00
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (channel->show_masked)
|
|
|
|
{
|
|
|
|
gegl_node_connect_to (source, "output",
|
|
|
|
channel->invert_node, "input");
|
|
|
|
gegl_node_connect_to (channel->invert_node, "output",
|
|
|
|
channel->mask_node, "aux");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gegl_node_connect_to (source, "output",
|
|
|
|
channel->mask_node, "aux");
|
|
|
|
}
|
|
|
|
|
2008-10-15 02:32:07 +08:00
|
|
|
mode_node = gimp_drawable_get_mode_node (drawable);
|
2008-10-11 18:29:19 +08:00
|
|
|
|
2008-10-15 02:32:07 +08:00
|
|
|
gegl_node_connect_to (channel->mask_node, "output",
|
|
|
|
mode_node, "aux");
|
2008-10-11 18:29:19 +08:00
|
|
|
|
2008-10-15 02:32:07 +08:00
|
|
|
return node;
|
2008-10-11 18:29:19 +08:00
|
|
|
}
|
|
|
|
|
2004-03-15 22:10:30 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_swap_pixels (GimpDrawable *drawable,
|
|
|
|
TileManager *tiles,
|
|
|
|
gboolean sparse,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
gint width,
|
|
|
|
gint height)
|
|
|
|
{
|
|
|
|
gimp_drawable_invalidate_boundary (drawable);
|
|
|
|
|
|
|
|
GIMP_DRAWABLE_CLASS (parent_class)->swap_pixels (drawable, tiles, sparse,
|
|
|
|
x, y, width, height);
|
|
|
|
|
|
|
|
GIMP_CHANNEL (drawable)->bounds_known = FALSE;
|
|
|
|
}
|
|
|
|
|
2005-07-12 03:21:52 +08:00
|
|
|
static gint
|
|
|
|
gimp_channel_get_opacity_at (GimpPickable *pickable,
|
|
|
|
gint x,
|
|
|
|
gint y)
|
|
|
|
{
|
|
|
|
GimpChannel *channel = GIMP_CHANNEL (pickable);
|
|
|
|
Tile *tile;
|
|
|
|
gint val;
|
|
|
|
|
|
|
|
/* Some checks to cut back on unnecessary work */
|
|
|
|
if (channel->bounds_known)
|
|
|
|
{
|
|
|
|
if (channel->empty)
|
2006-04-12 20:49:29 +08:00
|
|
|
return 0;
|
2005-07-12 03:21:52 +08:00
|
|
|
else if (x < channel->x1 || x >= channel->x2 ||
|
|
|
|
y < channel->y1 || y >= channel->y2)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-11-03 08:09:01 +08:00
|
|
|
if (x < 0 || x >= gimp_item_get_width (GIMP_ITEM (channel)) ||
|
|
|
|
y < 0 || y >= gimp_item_get_height (GIMP_ITEM (channel)))
|
2005-07-12 03:21:52 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
tile = tile_manager_get_tile (gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
|
|
|
x, y,
|
2005-07-12 03:21:52 +08:00
|
|
|
TRUE, FALSE);
|
2007-09-13 02:29:11 +08:00
|
|
|
val = *(guchar *) (tile_data_pointer (tile, x, y));
|
2005-07-12 03:21:52 +08:00
|
|
|
tile_release (tile, FALSE);
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_channel_real_boundary (GimpChannel *channel,
|
|
|
|
const BoundSeg **segs_in,
|
|
|
|
const BoundSeg **segs_out,
|
|
|
|
gint *num_segs_in,
|
|
|
|
gint *num_segs_out,
|
|
|
|
gint x1,
|
|
|
|
gint y1,
|
|
|
|
gint x2,
|
|
|
|
gint y2)
|
2002-08-20 18:22:23 +08:00
|
|
|
{
|
2007-05-03 23:17:07 +08:00
|
|
|
gint x3, y3, x4, y4;
|
|
|
|
PixelRegion bPR;
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
if (! channel->boundary_known)
|
|
|
|
{
|
|
|
|
/* free the out of date boundary segments */
|
2007-05-03 23:17:07 +08:00
|
|
|
g_free (channel->segs_in);
|
|
|
|
g_free (channel->segs_out);
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
if (gimp_channel_bounds (channel, &x3, &y3, &x4, &y4))
|
2004-01-12 21:57:30 +08:00
|
|
|
{
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&bPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-03-17 00:23:06 +08:00
|
|
|
x3, y3, x4 - x3, y4 - y3, FALSE);
|
|
|
|
|
2005-08-20 23:46:37 +08:00
|
|
|
channel->segs_out = boundary_find (&bPR, BOUNDARY_IGNORE_BOUNDS,
|
|
|
|
x1, y1, x2, y2,
|
|
|
|
BOUNDARY_HALF_WAY,
|
|
|
|
&channel->num_segs_out);
|
2004-01-12 21:57:30 +08:00
|
|
|
x1 = MAX (x1, x3);
|
|
|
|
y1 = MAX (y1, y3);
|
|
|
|
x2 = MIN (x2, x4);
|
|
|
|
y2 = MIN (y2, y4);
|
|
|
|
|
|
|
|
if (x2 > x1 && y2 > y1)
|
|
|
|
{
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&bPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)), FALSE);
|
2004-03-17 00:23:06 +08:00
|
|
|
|
2005-08-20 23:46:37 +08:00
|
|
|
channel->segs_in = boundary_find (&bPR, BOUNDARY_WITHIN_BOUNDS,
|
|
|
|
x1, y1, x2, y2,
|
|
|
|
BOUNDARY_HALF_WAY,
|
|
|
|
&channel->num_segs_in);
|
2004-01-12 21:57:30 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
channel->segs_in = NULL;
|
|
|
|
channel->num_segs_in = 0;
|
|
|
|
}
|
|
|
|
}
|
2003-09-03 07:07:40 +08:00
|
|
|
else
|
2004-01-12 21:57:30 +08:00
|
|
|
{
|
|
|
|
channel->segs_in = NULL;
|
|
|
|
channel->segs_out = NULL;
|
|
|
|
channel->num_segs_in = 0;
|
|
|
|
channel->num_segs_out = 0;
|
|
|
|
}
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
channel->boundary_known = TRUE;
|
|
|
|
}
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
*segs_in = channel->segs_in;
|
|
|
|
*segs_out = channel->segs_out;
|
|
|
|
*num_segs_in = channel->num_segs_in;
|
|
|
|
*num_segs_out = channel->num_segs_out;
|
|
|
|
|
2007-05-03 23:17:07 +08:00
|
|
|
return (! channel->empty);
|
2002-08-20 18:22:23 +08:00
|
|
|
}
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_channel_real_bounds (GimpChannel *channel,
|
|
|
|
gint *x1,
|
|
|
|
gint *y1,
|
|
|
|
gint *x2,
|
|
|
|
gint *y2)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
PixelRegion maskPR;
|
|
|
|
guchar *data, *data1;
|
|
|
|
gint x, y;
|
|
|
|
gint ex, ey;
|
|
|
|
gint tx1, tx2, ty1, ty2;
|
|
|
|
gint minx, maxx;
|
|
|
|
gpointer pr;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
/* if the channel's bounds have already been reliably calculated... */
|
|
|
|
if (channel->bounds_known)
|
|
|
|
{
|
|
|
|
*x1 = channel->x1;
|
|
|
|
*y1 = channel->y1;
|
|
|
|
*x2 = channel->x2;
|
|
|
|
*y2 = channel->y2;
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
return ! channel->empty;
|
|
|
|
}
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
/* go through and calculate the bounds */
|
2008-11-03 08:09:01 +08:00
|
|
|
tx1 = gimp_item_get_width (GIMP_ITEM (channel));
|
|
|
|
ty1 = gimp_item_get_height (GIMP_ITEM (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
tx2 = 0;
|
|
|
|
ty2 = 0;
|
2001-01-15 12:37:01 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&maskPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)), FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
for (pr = pixel_regions_register (1, &maskPR);
|
|
|
|
pr != NULL;
|
|
|
|
pr = pixel_regions_process (pr))
|
|
|
|
{
|
|
|
|
data1 = data = maskPR.data;
|
|
|
|
ex = maskPR.x + maskPR.w;
|
|
|
|
ey = maskPR.y + maskPR.h;
|
2004-01-12 21:57:30 +08:00
|
|
|
|
|
|
|
/* only check the pixels if this tile is not fully within the
|
|
|
|
* currently computed bounds
|
|
|
|
*/
|
2003-09-03 07:07:40 +08:00
|
|
|
if (maskPR.x < tx1 || ex > tx2 ||
|
2004-01-12 21:57:30 +08:00
|
|
|
maskPR.y < ty1 || ey > ty2)
|
2003-09-03 07:07:40 +08:00
|
|
|
{
|
2004-01-12 21:57:30 +08:00
|
|
|
/* Check upper left and lower right corners to see if we can
|
|
|
|
* avoid checking the rest of the pixels in this tile
|
|
|
|
*/
|
|
|
|
if (data[0] && data[maskPR.rowstride*(maskPR.h - 1) + maskPR.w - 1])
|
2003-09-03 07:07:40 +08:00
|
|
|
{
|
|
|
|
if (maskPR.x < tx1)
|
|
|
|
tx1 = maskPR.x;
|
|
|
|
if (ex > tx2)
|
|
|
|
tx2 = ex;
|
|
|
|
if (maskPR.y < ty1)
|
|
|
|
ty1 = maskPR.y;
|
|
|
|
if (ey > ty2)
|
|
|
|
ty2 = ey;
|
|
|
|
}
|
2004-01-12 21:57:30 +08:00
|
|
|
else
|
2003-09-03 07:07:40 +08:00
|
|
|
{
|
|
|
|
for (y = maskPR.y; y < ey; y++, data1 += maskPR.rowstride)
|
|
|
|
{
|
|
|
|
for (x = maskPR.x, data = data1; x < ex; x++, data++)
|
|
|
|
{
|
|
|
|
if (*data)
|
|
|
|
{
|
|
|
|
minx = x;
|
|
|
|
maxx = x;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
for (; x < ex; x++, data++)
|
|
|
|
if (*data)
|
|
|
|
maxx = x;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
if (minx < tx1)
|
|
|
|
tx1 = minx;
|
|
|
|
if (maxx > tx2)
|
|
|
|
tx2 = maxx;
|
|
|
|
if (y < ty1)
|
|
|
|
ty1 = y;
|
|
|
|
if (y > ty2)
|
|
|
|
ty2 = y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2001-12-03 21:44:59 +08:00
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
tx2 = CLAMP (tx2 + 1, 0, gimp_item_get_width (GIMP_ITEM (channel)));
|
|
|
|
ty2 = CLAMP (ty2 + 1, 0, gimp_item_get_height (GIMP_ITEM (channel)));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
if (tx1 == gimp_item_get_width (GIMP_ITEM (channel)) &&
|
|
|
|
ty1 == gimp_item_get_height (GIMP_ITEM (channel)))
|
2003-09-03 07:07:40 +08:00
|
|
|
{
|
|
|
|
channel->empty = TRUE;
|
|
|
|
channel->x1 = 0;
|
|
|
|
channel->y1 = 0;
|
2008-11-03 08:09:01 +08:00
|
|
|
channel->x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
|
|
|
channel->y2 = gimp_item_get_height (GIMP_ITEM (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
channel->empty = FALSE;
|
|
|
|
channel->x1 = tx1;
|
|
|
|
channel->y1 = ty1;
|
|
|
|
channel->x2 = tx2;
|
|
|
|
channel->y2 = ty2;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
channel->bounds_known = TRUE;
|
|
|
|
|
|
|
|
*x1 = channel->x1;
|
|
|
|
*x2 = channel->x2;
|
|
|
|
*y1 = channel->y1;
|
|
|
|
*y2 = channel->y2;
|
|
|
|
|
|
|
|
return ! channel->empty;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
static gboolean
|
|
|
|
gimp_channel_real_is_empty (GimpChannel *channel)
|
|
|
|
{
|
|
|
|
PixelRegion maskPR;
|
|
|
|
guchar *data;
|
|
|
|
gint x, y;
|
|
|
|
gpointer pr;
|
2003-08-21 23:54:47 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
if (channel->bounds_known)
|
|
|
|
return channel->empty;
|
2003-08-21 23:54:47 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&maskPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)), FALSE);
|
2003-08-21 23:54:47 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
for (pr = pixel_regions_register (1, &maskPR);
|
|
|
|
pr != NULL;
|
|
|
|
pr = pixel_regions_process (pr))
|
|
|
|
{
|
|
|
|
/* check if any pixel in the channel is non-zero */
|
|
|
|
data = maskPR.data;
|
2003-08-21 23:54:47 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
for (y = 0; y < maskPR.h; y++)
|
2004-01-12 21:57:30 +08:00
|
|
|
for (x = 0; x < maskPR.w; x++)
|
|
|
|
if (*data++)
|
|
|
|
{
|
|
|
|
pixel_regions_process_stop (pr);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-08-21 23:54:47 +08:00
|
|
|
}
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
/* The mask is empty, meaning we can set the bounds as known */
|
|
|
|
if (channel->segs_in)
|
|
|
|
g_free (channel->segs_in);
|
|
|
|
if (channel->segs_out)
|
|
|
|
g_free (channel->segs_out);
|
|
|
|
|
|
|
|
channel->empty = TRUE;
|
|
|
|
channel->segs_in = NULL;
|
|
|
|
channel->segs_out = NULL;
|
|
|
|
channel->num_segs_in = 0;
|
|
|
|
channel->num_segs_out = 0;
|
|
|
|
channel->bounds_known = TRUE;
|
|
|
|
channel->boundary_known = TRUE;
|
|
|
|
channel->x1 = 0;
|
|
|
|
channel->y1 = 0;
|
2008-11-03 08:09:01 +08:00
|
|
|
channel->x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
|
|
|
channel->y2 = gimp_item_get_height (GIMP_ITEM (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
return TRUE;
|
2003-08-21 23:54:47 +08:00
|
|
|
}
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_real_feather (GimpChannel *channel,
|
|
|
|
gdouble radius_x,
|
|
|
|
gdouble radius_y,
|
|
|
|
gboolean push_undo)
|
2003-03-12 07:54:49 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
PixelRegion srcPR;
|
2003-03-12 07:54:49 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
if (push_undo)
|
2003-09-04 19:33:06 +08:00
|
|
|
gimp_channel_push_undo (channel,
|
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->feather_desc);
|
|
|
|
else
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
2003-03-12 07:54:49 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&srcPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)),
|
2005-07-09 19:48:02 +08:00
|
|
|
TRUE);
|
2003-09-03 07:07:40 +08:00
|
|
|
gaussian_blur_region (&srcPR, radius_x, radius_y);
|
2003-03-12 07:54:49 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
channel->bounds_known = FALSE;
|
2003-10-06 20:17:11 +08:00
|
|
|
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
2003-03-12 07:54:49 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
static void
|
|
|
|
gimp_channel_real_sharpen (GimpChannel *channel,
|
|
|
|
gboolean push_undo)
|
|
|
|
{
|
|
|
|
PixelRegion maskPR;
|
|
|
|
GimpLut *lut;
|
2003-03-12 07:54:49 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
if (push_undo)
|
2003-09-04 19:33:06 +08:00
|
|
|
gimp_channel_push_undo (channel,
|
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->sharpen_desc);
|
|
|
|
else
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&maskPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
TRUE);
|
2003-09-03 07:07:40 +08:00
|
|
|
lut = threshold_lut_new (0.5, 1);
|
|
|
|
|
2005-02-12 01:03:56 +08:00
|
|
|
pixel_regions_process_parallel ((PixelProcessorFunc) gimp_lut_process_inline,
|
2004-01-12 21:57:30 +08:00
|
|
|
lut, 1, &maskPR);
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_lut_free (lut);
|
|
|
|
|
|
|
|
channel->bounds_known = FALSE;
|
2003-10-06 20:17:11 +08:00
|
|
|
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_real_clear (GimpChannel *channel,
|
|
|
|
const gchar *undo_desc,
|
|
|
|
gboolean push_undo)
|
|
|
|
{
|
|
|
|
PixelRegion maskPR;
|
|
|
|
|
|
|
|
if (push_undo)
|
|
|
|
{
|
|
|
|
if (! undo_desc)
|
2003-09-04 19:33:06 +08:00
|
|
|
undo_desc = GIMP_CHANNEL_GET_CLASS (channel)->clear_desc;
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
gimp_channel_push_undo (channel, undo_desc);
|
|
|
|
}
|
2003-09-04 19:33:06 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
|
|
|
}
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2008-08-05 23:27:18 +08:00
|
|
|
if (channel->bounds_known && ! channel->empty)
|
2003-09-03 07:07:40 +08:00
|
|
|
{
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&maskPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
channel->x1, channel->y1,
|
2007-12-24 00:58:41 +08:00
|
|
|
channel->x2 - channel->x1,
|
|
|
|
channel->y2 - channel->y1, TRUE);
|
2008-09-02 04:44:00 +08:00
|
|
|
clear_region (&maskPR);
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* clear the mask */
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&maskPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)), TRUE);
|
2008-09-02 04:44:00 +08:00
|
|
|
clear_region (&maskPR);
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* we know the bounds */
|
|
|
|
channel->bounds_known = TRUE;
|
|
|
|
channel->empty = TRUE;
|
|
|
|
channel->x1 = 0;
|
|
|
|
channel->y1 = 0;
|
2008-11-03 08:09:01 +08:00
|
|
|
channel->x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
|
|
|
channel->y2 = gimp_item_get_height (GIMP_ITEM (channel));
|
2003-10-06 20:17:11 +08:00
|
|
|
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_real_all (GimpChannel *channel,
|
|
|
|
gboolean push_undo)
|
|
|
|
{
|
|
|
|
PixelRegion maskPR;
|
2008-09-07 14:47:17 +08:00
|
|
|
guchar bg = OPAQUE_OPACITY;
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
if (push_undo)
|
2003-09-04 19:33:06 +08:00
|
|
|
gimp_channel_push_undo (channel,
|
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->all_desc);
|
|
|
|
else
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
/* clear the channel */
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&maskPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)), TRUE);
|
2008-09-07 14:47:17 +08:00
|
|
|
color_region (&maskPR, &bg);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
/* we know the bounds */
|
|
|
|
channel->bounds_known = TRUE;
|
|
|
|
channel->empty = FALSE;
|
|
|
|
channel->x1 = 0;
|
|
|
|
channel->y1 = 0;
|
2008-11-03 08:09:01 +08:00
|
|
|
channel->x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
|
|
|
channel->y2 = gimp_item_get_height (GIMP_ITEM (channel));
|
2003-10-06 20:17:11 +08:00
|
|
|
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_real_invert (GimpChannel *channel,
|
|
|
|
gboolean push_undo)
|
|
|
|
{
|
|
|
|
if (push_undo)
|
2003-09-04 19:33:06 +08:00
|
|
|
gimp_channel_push_undo (channel,
|
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->invert_desc);
|
|
|
|
else
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
if (channel->bounds_known && channel->empty)
|
|
|
|
{
|
|
|
|
gimp_channel_all (channel, FALSE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PixelRegion maskPR;
|
|
|
|
GimpLut *lut;
|
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&maskPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2003-09-03 07:07:40 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)), TRUE);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
lut = invert_lut_new (1);
|
|
|
|
|
2005-02-12 01:03:56 +08:00
|
|
|
pixel_regions_process_parallel ((PixelProcessorFunc)
|
|
|
|
gimp_lut_process_inline,
|
|
|
|
lut, 1, &maskPR);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
gimp_lut_free (lut);
|
|
|
|
|
|
|
|
channel->bounds_known = FALSE;
|
2003-10-06 20:17:11 +08:00
|
|
|
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_real_border (GimpChannel *channel,
|
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
2006-06-06 04:19:12 +08:00
|
|
|
gboolean feather,
|
2007-03-06 04:21:23 +08:00
|
|
|
gboolean edge_lock,
|
2003-09-03 07:07:40 +08:00
|
|
|
gboolean push_undo)
|
|
|
|
{
|
|
|
|
PixelRegion bPR;
|
|
|
|
gint x1, y1, x2, y2;
|
|
|
|
|
|
|
|
if (radius_x < 0 || radius_y < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (! gimp_channel_bounds (channel, &x1, &y1, &x2, &y2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gimp_channel_is_empty (channel))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (x1 - radius_x < 0)
|
|
|
|
x1 = 0;
|
|
|
|
else
|
|
|
|
x1 -= radius_x;
|
2006-04-25 19:05:17 +08:00
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
if (x2 + radius_x > gimp_item_get_width (GIMP_ITEM (channel)))
|
|
|
|
x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
else
|
|
|
|
x2 += radius_x;
|
|
|
|
|
|
|
|
if (y1 - radius_y < 0)
|
|
|
|
y1 = 0;
|
|
|
|
else
|
|
|
|
y1 -= radius_y;
|
2006-04-25 19:05:17 +08:00
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
if (y2 + radius_y > gimp_item_get_height (GIMP_ITEM (channel)))
|
|
|
|
y2 = gimp_item_get_height (GIMP_ITEM (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
else
|
|
|
|
y2 += radius_y;
|
|
|
|
|
|
|
|
if (push_undo)
|
2003-09-04 19:33:06 +08:00
|
|
|
gimp_channel_push_undo (channel,
|
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->border_desc);
|
|
|
|
else
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&bPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2006-04-25 19:05:17 +08:00
|
|
|
x1, y1, x2 - x1, y2 - y1, TRUE);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2007-03-06 04:21:23 +08:00
|
|
|
border_region (&bPR, radius_x, radius_y, feather, edge_lock);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
channel->bounds_known = FALSE;
|
2003-10-06 20:17:11 +08:00
|
|
|
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_real_grow (GimpChannel *channel,
|
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
|
|
|
gboolean push_undo)
|
|
|
|
{
|
|
|
|
PixelRegion bPR;
|
|
|
|
gint x1, y1, x2, y2;
|
|
|
|
|
|
|
|
if (radius_x == 0 && radius_y == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (radius_x <= 0 && radius_y <= 0)
|
|
|
|
{
|
|
|
|
gimp_channel_shrink (channel, -radius_x, -radius_y, FALSE, push_undo);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (radius_x < 0 || radius_y < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (! gimp_channel_bounds (channel, &x1, &y1, &x2, &y2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gimp_channel_is_empty (channel))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (x1 - radius_x > 0)
|
|
|
|
x1 = x1 - radius_x;
|
|
|
|
else
|
|
|
|
x1 = 0;
|
2007-12-24 00:58:41 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
if (y1 - radius_y > 0)
|
|
|
|
y1 = y1 - radius_y;
|
|
|
|
else
|
|
|
|
y1 = 0;
|
2007-12-24 00:58:41 +08:00
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
if (x2 + radius_x < gimp_item_get_width (GIMP_ITEM (channel)))
|
2003-09-03 07:07:40 +08:00
|
|
|
x2 = x2 + radius_x;
|
|
|
|
else
|
2008-11-03 08:09:01 +08:00
|
|
|
x2 = gimp_item_get_width (GIMP_ITEM (channel));
|
2007-12-24 00:58:41 +08:00
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
if (y2 + radius_y < gimp_item_get_height (GIMP_ITEM (channel)))
|
2003-09-03 07:07:40 +08:00
|
|
|
y2 = y2 + radius_y;
|
|
|
|
else
|
2008-11-03 08:09:01 +08:00
|
|
|
y2 = gimp_item_get_height (GIMP_ITEM (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
if (push_undo)
|
2003-09-04 19:33:06 +08:00
|
|
|
gimp_channel_push_undo (channel,
|
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->grow_desc);
|
|
|
|
else
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
/* need full extents for grow, not! */
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&bPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
x1, y1, (x2 - x1), (y2 - y1), TRUE);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
fatten_region (&bPR, radius_x, radius_y);
|
|
|
|
|
|
|
|
channel->bounds_known = FALSE;
|
2003-10-06 20:17:11 +08:00
|
|
|
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_channel_real_shrink (GimpChannel *channel,
|
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
|
|
|
gboolean edge_lock,
|
|
|
|
gboolean push_undo)
|
|
|
|
{
|
|
|
|
PixelRegion bPR;
|
|
|
|
gint x1, y1, x2, y2;
|
|
|
|
|
|
|
|
if (radius_x == 0 && radius_y == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (radius_x <= 0 && radius_y <= 0)
|
|
|
|
{
|
|
|
|
gimp_channel_grow (channel, -radius_x, -radius_y, push_undo);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (radius_x < 0 || radius_y < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (! gimp_channel_bounds (channel, &x1, &y1, &x2, &y2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (gimp_channel_is_empty (channel))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (x1 > 0)
|
|
|
|
x1--;
|
|
|
|
if (y1 > 0)
|
|
|
|
y1--;
|
2008-11-03 08:09:01 +08:00
|
|
|
if (x2 < gimp_item_get_width (GIMP_ITEM (channel)))
|
2003-09-03 07:07:40 +08:00
|
|
|
x2++;
|
2008-11-03 08:09:01 +08:00
|
|
|
if (y2 < gimp_item_get_height (GIMP_ITEM (channel)))
|
2003-09-03 07:07:40 +08:00
|
|
|
y2++;
|
|
|
|
|
|
|
|
if (push_undo)
|
2003-09-04 19:33:06 +08:00
|
|
|
gimp_channel_push_undo (channel,
|
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->shrink_desc);
|
|
|
|
else
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&bPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2004-01-12 21:57:30 +08:00
|
|
|
x1, y1, (x2 - x1), (y2 - y1), TRUE);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
thin_region (&bPR, radius_x, radius_y, edge_lock);
|
|
|
|
|
|
|
|
channel->bounds_known = FALSE;
|
2003-10-06 20:17:11 +08:00
|
|
|
|
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel), 0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2007-06-21 22:36:58 +08:00
|
|
|
gimp_channel_validate_tile (TileManager *tm,
|
|
|
|
Tile *tile)
|
2003-09-03 07:07:40 +08:00
|
|
|
{
|
|
|
|
/* Set the contents of the tile to empty */
|
|
|
|
memset (tile_data_pointer (tile, 0, 0),
|
2004-01-12 21:57:30 +08:00
|
|
|
TRANSPARENT_OPACITY, tile_size (tile));
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* public functions */
|
|
|
|
|
|
|
|
GimpChannel *
|
2006-03-29 01:08:36 +08:00
|
|
|
gimp_channel_new (GimpImage *image,
|
2004-01-12 21:57:30 +08:00
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
const gchar *name,
|
|
|
|
const GimpRGB *color)
|
2003-09-03 07:07:40 +08:00
|
|
|
{
|
|
|
|
GimpChannel *channel;
|
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2011-02-01 19:47:24 +08:00
|
|
|
channel = GIMP_CHANNEL (gimp_drawable_new (GIMP_TYPE_CHANNEL,
|
|
|
|
image, name,
|
|
|
|
0, 0, width, height,
|
|
|
|
GIMP_GRAY_IMAGE));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2005-01-16 00:59:34 +08:00
|
|
|
if (color)
|
|
|
|
channel->color = *color;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
channel->show_masked = TRUE;
|
|
|
|
|
|
|
|
/* selection mask variables */
|
|
|
|
channel->x2 = width;
|
|
|
|
channel->y2 = height;
|
|
|
|
|
|
|
|
return channel;
|
|
|
|
}
|
|
|
|
|
|
|
|
GimpChannel *
|
2006-03-29 01:08:36 +08:00
|
|
|
gimp_channel_new_from_alpha (GimpImage *image,
|
2004-03-17 00:23:06 +08:00
|
|
|
GimpDrawable *drawable,
|
2003-09-03 07:07:40 +08:00
|
|
|
const gchar *name,
|
|
|
|
const GimpRGB *color)
|
|
|
|
{
|
|
|
|
GimpChannel *channel;
|
|
|
|
gint width;
|
|
|
|
gint height;
|
2003-10-07 00:43:05 +08:00
|
|
|
PixelRegion srcPR, destPR;
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2004-03-17 00:23:06 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
|
|
|
|
g_return_val_if_fail (gimp_drawable_has_alpha (drawable), NULL);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2008-11-03 08:09:01 +08:00
|
|
|
width = gimp_item_get_width (GIMP_ITEM (drawable));
|
|
|
|
height = gimp_item_get_height (GIMP_ITEM (drawable));
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
channel = gimp_channel_new (image, width, height, name, color);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
gimp_channel_clear (channel, NULL, FALSE);
|
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&srcPR,
|
|
|
|
gimp_drawable_get_tiles (drawable),
|
2003-10-07 00:43:05 +08:00
|
|
|
0, 0, width, height, FALSE);
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&destPR,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2003-10-07 00:43:05 +08:00
|
|
|
0, 0, width, height, TRUE);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2003-10-07 00:43:05 +08:00
|
|
|
extract_alpha_region (&srcPR, NULL, &destPR);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2003-10-07 00:43:05 +08:00
|
|
|
channel->bounds_known = FALSE;
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
return channel;
|
|
|
|
}
|
|
|
|
|
|
|
|
GimpChannel *
|
2006-03-29 01:08:36 +08:00
|
|
|
gimp_channel_new_from_component (GimpImage *image,
|
2003-09-03 07:07:40 +08:00
|
|
|
GimpChannelType type,
|
|
|
|
const gchar *name,
|
|
|
|
const GimpRGB *color)
|
|
|
|
{
|
2010-02-04 04:46:09 +08:00
|
|
|
GimpProjection *projection;
|
|
|
|
GimpChannel *channel;
|
|
|
|
TileManager *proj_tiles;
|
|
|
|
PixelRegion src;
|
|
|
|
PixelRegion dest;
|
|
|
|
gint width;
|
|
|
|
gint height;
|
|
|
|
gint pixel;
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
pixel = gimp_image_get_component_index (image, type);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
|
|
|
g_return_val_if_fail (pixel != -1, NULL);
|
|
|
|
|
2010-02-04 04:46:09 +08:00
|
|
|
projection = gimp_image_get_projection (image);
|
|
|
|
|
|
|
|
gimp_pickable_flush (GIMP_PICKABLE (projection));
|
2006-03-03 03:30:59 +08:00
|
|
|
|
2010-02-04 04:46:09 +08:00
|
|
|
proj_tiles = gimp_pickable_get_tiles (GIMP_PICKABLE (projection));
|
|
|
|
width = tile_manager_width (proj_tiles);
|
|
|
|
height = tile_manager_height (proj_tiles);
|
2003-09-03 07:07:40 +08:00
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
channel = gimp_channel_new (image, width, height, name, color);
|
2003-03-12 07:54:49 +08:00
|
|
|
|
2010-02-04 04:46:09 +08:00
|
|
|
pixel_region_init (&src, proj_tiles,
|
2003-03-12 07:54:49 +08:00
|
|
|
0, 0, width, height, FALSE);
|
2007-12-24 00:58:41 +08:00
|
|
|
pixel_region_init (&dest,
|
|
|
|
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
|
2003-03-12 07:54:49 +08:00
|
|
|
0, 0, width, height, TRUE);
|
|
|
|
|
|
|
|
copy_component (&src, &dest, pixel);
|
|
|
|
|
|
|
|
return channel;
|
|
|
|
}
|
|
|
|
|
2010-02-07 19:03:07 +08:00
|
|
|
GimpChannel *
|
|
|
|
gimp_channel_get_parent (GimpChannel *channel)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), NULL);
|
|
|
|
|
|
|
|
return GIMP_CHANNEL (gimp_viewable_get_parent (GIMP_VIEWABLE (channel)));
|
|
|
|
}
|
|
|
|
|
2003-08-30 22:25:05 +08:00
|
|
|
void
|
2001-01-29 10:45:02 +08:00
|
|
|
gimp_channel_set_color (GimpChannel *channel,
|
2004-01-12 21:57:30 +08:00
|
|
|
const GimpRGB *color,
|
2003-03-17 10:25:39 +08:00
|
|
|
gboolean push_undo)
|
1999-07-07 11:18:54 +08:00
|
|
|
{
|
2001-01-15 12:37:01 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
|
|
|
g_return_if_fail (color != NULL);
|
1999-08-22 19:45:31 +08:00
|
|
|
|
2001-07-08 06:49:01 +08:00
|
|
|
if (gimp_rgba_distance (&channel->color, color) > 0.0001)
|
|
|
|
{
|
2004-11-16 21:41:55 +08:00
|
|
|
if (push_undo && gimp_item_is_attached (GIMP_ITEM (channel)))
|
2003-03-17 10:25:39 +08:00
|
|
|
{
|
2006-03-29 01:08:36 +08:00
|
|
|
GimpImage *image = gimp_item_get_image (GIMP_ITEM (channel));
|
2003-03-17 10:25:39 +08:00
|
|
|
|
2010-06-08 19:24:11 +08:00
|
|
|
gimp_image_undo_push_channel_color (image, C_("undo-type", "Set Channel Color"),
|
2004-11-16 21:41:55 +08:00
|
|
|
channel);
|
2003-03-17 10:25:39 +08:00
|
|
|
}
|
|
|
|
|
2001-07-08 06:49:01 +08:00
|
|
|
channel->color = *color;
|
|
|
|
|
2008-10-11 18:29:19 +08:00
|
|
|
if (channel->color_node)
|
|
|
|
{
|
|
|
|
GeglColor *gegl_color;
|
|
|
|
|
|
|
|
gegl_color = gegl_color_new (NULL);
|
|
|
|
gegl_color_set_rgba (gegl_color,
|
|
|
|
channel->color.r,
|
|
|
|
channel->color.g,
|
|
|
|
channel->color.b,
|
|
|
|
channel->color.a);
|
|
|
|
|
|
|
|
gegl_node_set (channel->color_node,
|
|
|
|
"value", gegl_color,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
g_object_unref (gegl_color);
|
|
|
|
}
|
|
|
|
|
2001-07-08 06:49:01 +08:00
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2004-07-05 19:18:34 +08:00
|
|
|
|
|
|
|
g_signal_emit (channel, channel_signals[COLOR_CHANGED], 0);
|
2001-07-08 06:49:01 +08:00
|
|
|
}
|
1999-08-22 19:45:31 +08:00
|
|
|
}
|
1999-07-07 11:18:54 +08:00
|
|
|
|
2002-03-09 00:34:42 +08:00
|
|
|
void
|
|
|
|
gimp_channel_get_color (const GimpChannel *channel,
|
|
|
|
GimpRGB *color)
|
1999-08-08 04:55:26 +08:00
|
|
|
{
|
2002-03-09 00:34:42 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
|
|
|
g_return_if_fail (color != NULL);
|
2001-01-15 12:37:01 +08:00
|
|
|
|
2002-03-09 00:34:42 +08:00
|
|
|
*color = channel->color;
|
1999-08-08 04:55:26 +08:00
|
|
|
}
|
2001-01-29 21:51:23 +08:00
|
|
|
|
2002-03-04 01:38:12 +08:00
|
|
|
gdouble
|
2001-01-29 10:45:02 +08:00
|
|
|
gimp_channel_get_opacity (const GimpChannel *channel)
|
2001-01-15 12:37:01 +08:00
|
|
|
{
|
2002-08-30 00:48:17 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), GIMP_OPACITY_TRANSPARENT);
|
2001-01-15 12:37:01 +08:00
|
|
|
|
2002-03-04 01:38:12 +08:00
|
|
|
return channel->color.a;
|
1999-08-08 04:55:26 +08:00
|
|
|
}
|
|
|
|
|
2002-08-20 18:22:23 +08:00
|
|
|
void
|
2001-01-29 10:45:02 +08:00
|
|
|
gimp_channel_set_opacity (GimpChannel *channel,
|
2004-01-12 21:57:30 +08:00
|
|
|
gdouble opacity,
|
Made drawable/layer properties (visibility, opacity etc.) undoable (fixes
2003-03-17 Michael Natterer <mitch@gimp.org>
Made drawable/layer properties (visibility, opacity etc.)
undoable (fixes bug #73893).
* app/core/core-enums.[ch]: added undo types/groups for
visibility, mode, opacity, linked and preserve_trans.
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpitemundo.[ch]: new GimpUndo subclass which holds a
ref'ed GimpItem pointer so (1) this doesn't need to be done by all
undo steps related to an item and (2) the item the undo step is
for can be determined from outside the undo system.
* app/core/gimpimage-undo.[ch]: added gimp_image_undo_push_item()
which returns a new GimpItemUndo.
* app/core/gimpimage-undo-push.[ch]: use it for all item related
undo steps. Removed lots of GimpItem, GimpLayer, GimpDrawable
and GimpVectors pointers from the private undo structs. Added
undo push functions for the new undo types added above.
* app/core/gimpdrawable.[ch] (gimp_drawable_set_visible): added
"gboolean push_undo" parameter.
* app/core/gimplayer.[ch] (gimp_layer_set_opacity, _mode,
_preserve_trans, _linked): added "gboolean push_undo" parameters.
* app/core/gimpimage-mask.c
* app/core/gimpimage-merge.c
* app/core/gimplayer-floating-sel.c
* app/tools/gimpmovetool.c
* app/xcf/xcf-load.c
* app/widgets/gimpdrawablelistitem.c
* app/widgets/gimplayerlistitem.c
* app/widgets/gimplayerlistview.c: changed accordingly.
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/layer.pdb: ditto. Added '$undo' paramaters to
the foo_accessors() functions. Removed $func from foo_accesors()
because we don't manipulate items without using getters/setters
any longer.
* app/pdb/channel_cmds.c
* app/pdb/layer_cmds.c: regenerated.
* app/widgets/gimpcellrenderertoggle.[ch]: added "clicked" signal
which carries an additional "GdkModifierType state" parameter as
in GimpCellRendererViewable .
* app/widgets/gimpcontainertreeview.c: emit "clicked" from
the toggle renderer, not "toggled" so the callbacks get the
modifier state.
* app/widgets/gimpdrawabletreeview.c: resurrected the "exclusive
visible by <shift>+click" feature as in 1.2.
* app/widgets/gimplayertreeview.c: compress layer opacity undos by
looking at the top of the undo stack and not pushing an undo if
there already is a GIMP_UNDO_DRAWABLE_OPACITY for the active
layer.
2003-03-18 02:02:41 +08:00
|
|
|
gboolean push_undo)
|
1999-07-07 11:18:54 +08:00
|
|
|
{
|
2001-01-15 12:37:01 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
|
|
|
|
2002-03-04 01:38:12 +08:00
|
|
|
opacity = CLAMP (opacity, GIMP_OPACITY_TRANSPARENT, GIMP_OPACITY_OPAQUE);
|
2001-01-15 12:37:01 +08:00
|
|
|
|
Made drawable/layer properties (visibility, opacity etc.) undoable (fixes
2003-03-17 Michael Natterer <mitch@gimp.org>
Made drawable/layer properties (visibility, opacity etc.)
undoable (fixes bug #73893).
* app/core/core-enums.[ch]: added undo types/groups for
visibility, mode, opacity, linked and preserve_trans.
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpitemundo.[ch]: new GimpUndo subclass which holds a
ref'ed GimpItem pointer so (1) this doesn't need to be done by all
undo steps related to an item and (2) the item the undo step is
for can be determined from outside the undo system.
* app/core/gimpimage-undo.[ch]: added gimp_image_undo_push_item()
which returns a new GimpItemUndo.
* app/core/gimpimage-undo-push.[ch]: use it for all item related
undo steps. Removed lots of GimpItem, GimpLayer, GimpDrawable
and GimpVectors pointers from the private undo structs. Added
undo push functions for the new undo types added above.
* app/core/gimpdrawable.[ch] (gimp_drawable_set_visible): added
"gboolean push_undo" parameter.
* app/core/gimplayer.[ch] (gimp_layer_set_opacity, _mode,
_preserve_trans, _linked): added "gboolean push_undo" parameters.
* app/core/gimpimage-mask.c
* app/core/gimpimage-merge.c
* app/core/gimplayer-floating-sel.c
* app/tools/gimpmovetool.c
* app/xcf/xcf-load.c
* app/widgets/gimpdrawablelistitem.c
* app/widgets/gimplayerlistitem.c
* app/widgets/gimplayerlistview.c: changed accordingly.
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/layer.pdb: ditto. Added '$undo' paramaters to
the foo_accessors() functions. Removed $func from foo_accesors()
because we don't manipulate items without using getters/setters
any longer.
* app/pdb/channel_cmds.c
* app/pdb/layer_cmds.c: regenerated.
* app/widgets/gimpcellrenderertoggle.[ch]: added "clicked" signal
which carries an additional "GdkModifierType state" parameter as
in GimpCellRendererViewable .
* app/widgets/gimpcontainertreeview.c: emit "clicked" from
the toggle renderer, not "toggled" so the callbacks get the
modifier state.
* app/widgets/gimpdrawabletreeview.c: resurrected the "exclusive
visible by <shift>+click" feature as in 1.2.
* app/widgets/gimplayertreeview.c: compress layer opacity undos by
looking at the top of the undo stack and not pushing an undo if
there already is a GIMP_UNDO_DRAWABLE_OPACITY for the active
layer.
2003-03-18 02:02:41 +08:00
|
|
|
if (channel->color.a != opacity)
|
|
|
|
{
|
2004-11-16 21:41:55 +08:00
|
|
|
if (push_undo && gimp_item_is_attached (GIMP_ITEM (channel)))
|
Made drawable/layer properties (visibility, opacity etc.) undoable (fixes
2003-03-17 Michael Natterer <mitch@gimp.org>
Made drawable/layer properties (visibility, opacity etc.)
undoable (fixes bug #73893).
* app/core/core-enums.[ch]: added undo types/groups for
visibility, mode, opacity, linked and preserve_trans.
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpitemundo.[ch]: new GimpUndo subclass which holds a
ref'ed GimpItem pointer so (1) this doesn't need to be done by all
undo steps related to an item and (2) the item the undo step is
for can be determined from outside the undo system.
* app/core/gimpimage-undo.[ch]: added gimp_image_undo_push_item()
which returns a new GimpItemUndo.
* app/core/gimpimage-undo-push.[ch]: use it for all item related
undo steps. Removed lots of GimpItem, GimpLayer, GimpDrawable
and GimpVectors pointers from the private undo structs. Added
undo push functions for the new undo types added above.
* app/core/gimpdrawable.[ch] (gimp_drawable_set_visible): added
"gboolean push_undo" parameter.
* app/core/gimplayer.[ch] (gimp_layer_set_opacity, _mode,
_preserve_trans, _linked): added "gboolean push_undo" parameters.
* app/core/gimpimage-mask.c
* app/core/gimpimage-merge.c
* app/core/gimplayer-floating-sel.c
* app/tools/gimpmovetool.c
* app/xcf/xcf-load.c
* app/widgets/gimpdrawablelistitem.c
* app/widgets/gimplayerlistitem.c
* app/widgets/gimplayerlistview.c: changed accordingly.
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/layer.pdb: ditto. Added '$undo' paramaters to
the foo_accessors() functions. Removed $func from foo_accesors()
because we don't manipulate items without using getters/setters
any longer.
* app/pdb/channel_cmds.c
* app/pdb/layer_cmds.c: regenerated.
* app/widgets/gimpcellrenderertoggle.[ch]: added "clicked" signal
which carries an additional "GdkModifierType state" parameter as
in GimpCellRendererViewable .
* app/widgets/gimpcontainertreeview.c: emit "clicked" from
the toggle renderer, not "toggled" so the callbacks get the
modifier state.
* app/widgets/gimpdrawabletreeview.c: resurrected the "exclusive
visible by <shift>+click" feature as in 1.2.
* app/widgets/gimplayertreeview.c: compress layer opacity undos by
looking at the top of the undo stack and not pushing an undo if
there already is a GIMP_UNDO_DRAWABLE_OPACITY for the active
layer.
2003-03-18 02:02:41 +08:00
|
|
|
{
|
2006-03-29 01:08:36 +08:00
|
|
|
GimpImage *image = gimp_item_get_image (GIMP_ITEM (channel));
|
Made drawable/layer properties (visibility, opacity etc.) undoable (fixes
2003-03-17 Michael Natterer <mitch@gimp.org>
Made drawable/layer properties (visibility, opacity etc.)
undoable (fixes bug #73893).
* app/core/core-enums.[ch]: added undo types/groups for
visibility, mode, opacity, linked and preserve_trans.
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpitemundo.[ch]: new GimpUndo subclass which holds a
ref'ed GimpItem pointer so (1) this doesn't need to be done by all
undo steps related to an item and (2) the item the undo step is
for can be determined from outside the undo system.
* app/core/gimpimage-undo.[ch]: added gimp_image_undo_push_item()
which returns a new GimpItemUndo.
* app/core/gimpimage-undo-push.[ch]: use it for all item related
undo steps. Removed lots of GimpItem, GimpLayer, GimpDrawable
and GimpVectors pointers from the private undo structs. Added
undo push functions for the new undo types added above.
* app/core/gimpdrawable.[ch] (gimp_drawable_set_visible): added
"gboolean push_undo" parameter.
* app/core/gimplayer.[ch] (gimp_layer_set_opacity, _mode,
_preserve_trans, _linked): added "gboolean push_undo" parameters.
* app/core/gimpimage-mask.c
* app/core/gimpimage-merge.c
* app/core/gimplayer-floating-sel.c
* app/tools/gimpmovetool.c
* app/xcf/xcf-load.c
* app/widgets/gimpdrawablelistitem.c
* app/widgets/gimplayerlistitem.c
* app/widgets/gimplayerlistview.c: changed accordingly.
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/layer.pdb: ditto. Added '$undo' paramaters to
the foo_accessors() functions. Removed $func from foo_accesors()
because we don't manipulate items without using getters/setters
any longer.
* app/pdb/channel_cmds.c
* app/pdb/layer_cmds.c: regenerated.
* app/widgets/gimpcellrenderertoggle.[ch]: added "clicked" signal
which carries an additional "GdkModifierType state" parameter as
in GimpCellRendererViewable .
* app/widgets/gimpcontainertreeview.c: emit "clicked" from
the toggle renderer, not "toggled" so the callbacks get the
modifier state.
* app/widgets/gimpdrawabletreeview.c: resurrected the "exclusive
visible by <shift>+click" feature as in 1.2.
* app/widgets/gimplayertreeview.c: compress layer opacity undos by
looking at the top of the undo stack and not pushing an undo if
there already is a GIMP_UNDO_DRAWABLE_OPACITY for the active
layer.
2003-03-18 02:02:41 +08:00
|
|
|
|
2010-06-08 19:24:11 +08:00
|
|
|
gimp_image_undo_push_channel_color (image, C_("undo-type", "Set Channel Opacity"),
|
2004-11-16 21:41:55 +08:00
|
|
|
channel);
|
Made drawable/layer properties (visibility, opacity etc.) undoable (fixes
2003-03-17 Michael Natterer <mitch@gimp.org>
Made drawable/layer properties (visibility, opacity etc.)
undoable (fixes bug #73893).
* app/core/core-enums.[ch]: added undo types/groups for
visibility, mode, opacity, linked and preserve_trans.
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpitemundo.[ch]: new GimpUndo subclass which holds a
ref'ed GimpItem pointer so (1) this doesn't need to be done by all
undo steps related to an item and (2) the item the undo step is
for can be determined from outside the undo system.
* app/core/gimpimage-undo.[ch]: added gimp_image_undo_push_item()
which returns a new GimpItemUndo.
* app/core/gimpimage-undo-push.[ch]: use it for all item related
undo steps. Removed lots of GimpItem, GimpLayer, GimpDrawable
and GimpVectors pointers from the private undo structs. Added
undo push functions for the new undo types added above.
* app/core/gimpdrawable.[ch] (gimp_drawable_set_visible): added
"gboolean push_undo" parameter.
* app/core/gimplayer.[ch] (gimp_layer_set_opacity, _mode,
_preserve_trans, _linked): added "gboolean push_undo" parameters.
* app/core/gimpimage-mask.c
* app/core/gimpimage-merge.c
* app/core/gimplayer-floating-sel.c
* app/tools/gimpmovetool.c
* app/xcf/xcf-load.c
* app/widgets/gimpdrawablelistitem.c
* app/widgets/gimplayerlistitem.c
* app/widgets/gimplayerlistview.c: changed accordingly.
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/layer.pdb: ditto. Added '$undo' paramaters to
the foo_accessors() functions. Removed $func from foo_accesors()
because we don't manipulate items without using getters/setters
any longer.
* app/pdb/channel_cmds.c
* app/pdb/layer_cmds.c: regenerated.
* app/widgets/gimpcellrenderertoggle.[ch]: added "clicked" signal
which carries an additional "GdkModifierType state" parameter as
in GimpCellRendererViewable .
* app/widgets/gimpcontainertreeview.c: emit "clicked" from
the toggle renderer, not "toggled" so the callbacks get the
modifier state.
* app/widgets/gimpdrawabletreeview.c: resurrected the "exclusive
visible by <shift>+click" feature as in 1.2.
* app/widgets/gimplayertreeview.c: compress layer opacity undos by
looking at the top of the undo stack and not pushing an undo if
there already is a GIMP_UNDO_DRAWABLE_OPACITY for the active
layer.
2003-03-18 02:02:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
channel->color.a = opacity;
|
|
|
|
|
2008-10-11 18:29:19 +08:00
|
|
|
if (channel->color_node)
|
|
|
|
{
|
|
|
|
GeglColor *gegl_color;
|
|
|
|
|
|
|
|
gegl_color = gegl_color_new (NULL);
|
|
|
|
gegl_color_set_rgba (gegl_color,
|
|
|
|
channel->color.r,
|
|
|
|
channel->color.g,
|
|
|
|
channel->color.b,
|
|
|
|
channel->color.a);
|
|
|
|
|
|
|
|
gegl_node_set (channel->color_node,
|
|
|
|
"value", gegl_color,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
g_object_unref (gegl_color);
|
|
|
|
}
|
|
|
|
|
Made drawable/layer properties (visibility, opacity etc.) undoable (fixes
2003-03-17 Michael Natterer <mitch@gimp.org>
Made drawable/layer properties (visibility, opacity etc.)
undoable (fixes bug #73893).
* app/core/core-enums.[ch]: added undo types/groups for
visibility, mode, opacity, linked and preserve_trans.
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpitemundo.[ch]: new GimpUndo subclass which holds a
ref'ed GimpItem pointer so (1) this doesn't need to be done by all
undo steps related to an item and (2) the item the undo step is
for can be determined from outside the undo system.
* app/core/gimpimage-undo.[ch]: added gimp_image_undo_push_item()
which returns a new GimpItemUndo.
* app/core/gimpimage-undo-push.[ch]: use it for all item related
undo steps. Removed lots of GimpItem, GimpLayer, GimpDrawable
and GimpVectors pointers from the private undo structs. Added
undo push functions for the new undo types added above.
* app/core/gimpdrawable.[ch] (gimp_drawable_set_visible): added
"gboolean push_undo" parameter.
* app/core/gimplayer.[ch] (gimp_layer_set_opacity, _mode,
_preserve_trans, _linked): added "gboolean push_undo" parameters.
* app/core/gimpimage-mask.c
* app/core/gimpimage-merge.c
* app/core/gimplayer-floating-sel.c
* app/tools/gimpmovetool.c
* app/xcf/xcf-load.c
* app/widgets/gimpdrawablelistitem.c
* app/widgets/gimplayerlistitem.c
* app/widgets/gimplayerlistview.c: changed accordingly.
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/layer.pdb: ditto. Added '$undo' paramaters to
the foo_accessors() functions. Removed $func from foo_accesors()
because we don't manipulate items without using getters/setters
any longer.
* app/pdb/channel_cmds.c
* app/pdb/layer_cmds.c: regenerated.
* app/widgets/gimpcellrenderertoggle.[ch]: added "clicked" signal
which carries an additional "GdkModifierType state" parameter as
in GimpCellRendererViewable .
* app/widgets/gimpcontainertreeview.c: emit "clicked" from
the toggle renderer, not "toggled" so the callbacks get the
modifier state.
* app/widgets/gimpdrawabletreeview.c: resurrected the "exclusive
visible by <shift>+click" feature as in 1.2.
* app/widgets/gimplayertreeview.c: compress layer opacity undos by
looking at the top of the undo stack and not pushing an undo if
there already is a GIMP_UNDO_DRAWABLE_OPACITY for the active
layer.
2003-03-18 02:02:41 +08:00
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2004-07-05 19:18:34 +08:00
|
|
|
|
|
|
|
g_signal_emit (channel, channel_signals[COLOR_CHANGED], 0);
|
Made drawable/layer properties (visibility, opacity etc.) undoable (fixes
2003-03-17 Michael Natterer <mitch@gimp.org>
Made drawable/layer properties (visibility, opacity etc.)
undoable (fixes bug #73893).
* app/core/core-enums.[ch]: added undo types/groups for
visibility, mode, opacity, linked and preserve_trans.
* app/core/Makefile.am
* app/core/core-types.h
* app/core/gimpitemundo.[ch]: new GimpUndo subclass which holds a
ref'ed GimpItem pointer so (1) this doesn't need to be done by all
undo steps related to an item and (2) the item the undo step is
for can be determined from outside the undo system.
* app/core/gimpimage-undo.[ch]: added gimp_image_undo_push_item()
which returns a new GimpItemUndo.
* app/core/gimpimage-undo-push.[ch]: use it for all item related
undo steps. Removed lots of GimpItem, GimpLayer, GimpDrawable
and GimpVectors pointers from the private undo structs. Added
undo push functions for the new undo types added above.
* app/core/gimpdrawable.[ch] (gimp_drawable_set_visible): added
"gboolean push_undo" parameter.
* app/core/gimplayer.[ch] (gimp_layer_set_opacity, _mode,
_preserve_trans, _linked): added "gboolean push_undo" parameters.
* app/core/gimpimage-mask.c
* app/core/gimpimage-merge.c
* app/core/gimplayer-floating-sel.c
* app/tools/gimpmovetool.c
* app/xcf/xcf-load.c
* app/widgets/gimpdrawablelistitem.c
* app/widgets/gimplayerlistitem.c
* app/widgets/gimplayerlistview.c: changed accordingly.
* tools/pdbgen/pdb/channel.pdb
* tools/pdbgen/pdb/layer.pdb: ditto. Added '$undo' paramaters to
the foo_accessors() functions. Removed $func from foo_accesors()
because we don't manipulate items without using getters/setters
any longer.
* app/pdb/channel_cmds.c
* app/pdb/layer_cmds.c: regenerated.
* app/widgets/gimpcellrenderertoggle.[ch]: added "clicked" signal
which carries an additional "GdkModifierType state" parameter as
in GimpCellRendererViewable .
* app/widgets/gimpcontainertreeview.c: emit "clicked" from
the toggle renderer, not "toggled" so the callbacks get the
modifier state.
* app/widgets/gimpdrawabletreeview.c: resurrected the "exclusive
visible by <shift>+click" feature as in 1.2.
* app/widgets/gimplayertreeview.c: compress layer opacity undos by
looking at the top of the undo stack and not pushing an undo if
there already is a GIMP_UNDO_DRAWABLE_OPACITY for the active
layer.
2003-03-18 02:02:41 +08:00
|
|
|
}
|
1999-07-07 11:18:54 +08:00
|
|
|
}
|
|
|
|
|
2002-08-20 18:22:23 +08:00
|
|
|
gboolean
|
|
|
|
gimp_channel_get_show_masked (GimpChannel *channel)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
|
|
|
|
|
|
|
|
return channel->show_masked;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_channel_set_show_masked (GimpChannel *channel,
|
|
|
|
gboolean show_masked)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
|
|
|
|
|
|
|
if (show_masked != channel->show_masked)
|
|
|
|
{
|
|
|
|
channel->show_masked = show_masked ? TRUE : FALSE;
|
|
|
|
|
2008-10-11 18:29:19 +08:00
|
|
|
if (channel->invert_node)
|
|
|
|
{
|
|
|
|
GeglNode *source;
|
|
|
|
|
|
|
|
source = gimp_drawable_get_source_node (GIMP_DRAWABLE (channel));
|
|
|
|
|
|
|
|
if (channel->show_masked)
|
|
|
|
{
|
|
|
|
gegl_node_connect_to (source, "output",
|
|
|
|
channel->invert_node, "input");
|
|
|
|
gegl_node_connect_to (channel->invert_node, "output",
|
|
|
|
channel->mask_node, "aux");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gegl_node_disconnect (channel->invert_node, "input");
|
|
|
|
|
|
|
|
gegl_node_connect_to (source, "output",
|
|
|
|
channel->mask_node, "aux");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-20 18:22:23 +08:00
|
|
|
gimp_drawable_update (GIMP_DRAWABLE (channel),
|
2004-01-12 21:57:30 +08:00
|
|
|
0, 0,
|
2008-11-03 08:09:01 +08:00
|
|
|
gimp_item_get_width (GIMP_ITEM (channel)),
|
|
|
|
gimp_item_get_height (GIMP_ITEM (channel)));
|
2002-08-20 18:22:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-09-04 19:33:06 +08:00
|
|
|
void
|
|
|
|
gimp_channel_push_undo (GimpChannel *channel,
|
|
|
|
const gchar *undo_desc)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
2004-11-16 21:41:55 +08:00
|
|
|
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)));
|
2003-09-04 19:33:06 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
gimp_image_undo_push_mask (gimp_item_get_image (GIMP_ITEM (channel)),
|
|
|
|
undo_desc, channel);
|
2003-09-04 19:33:06 +08:00
|
|
|
|
|
|
|
gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (channel));
|
|
|
|
}
|
|
|
|
|
2001-01-30 01:54:02 +08:00
|
|
|
|
1999-08-22 19:45:31 +08:00
|
|
|
/******************************/
|
|
|
|
/* selection mask functions */
|
|
|
|
/******************************/
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-29 10:45:02 +08:00
|
|
|
GimpChannel *
|
2006-03-29 01:08:36 +08:00
|
|
|
gimp_channel_new_mask (GimpImage *image,
|
2004-01-12 21:57:30 +08:00
|
|
|
gint width,
|
|
|
|
gint height)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-01-29 10:45:02 +08:00
|
|
|
GimpChannel *new_channel;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
2001-08-11 22:39:19 +08:00
|
|
|
|
2006-03-29 01:08:36 +08:00
|
|
|
new_channel = gimp_channel_new (image, width, height,
|
2005-01-16 00:59:34 +08:00
|
|
|
_("Selection Mask"), NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2007-12-24 00:58:41 +08:00
|
|
|
tile_manager_set_validate_proc (gimp_drawable_get_tiles (GIMP_DRAWABLE (new_channel)),
|
2007-06-21 22:36:58 +08:00
|
|
|
(TileValidateProc) gimp_channel_validate_tile,
|
|
|
|
NULL);
|
1999-04-09 14:00:11 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
return new_channel;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
1999-08-22 19:45:31 +08:00
|
|
|
gboolean
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_boundary (GimpChannel *channel,
|
2004-01-12 21:57:30 +08:00
|
|
|
const BoundSeg **segs_in,
|
|
|
|
const BoundSeg **segs_out,
|
|
|
|
gint *num_segs_in,
|
|
|
|
gint *num_segs_out,
|
|
|
|
gint x1,
|
|
|
|
gint y1,
|
|
|
|
gint x2,
|
|
|
|
gint y2)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
|
|
|
|
g_return_val_if_fail (segs_in != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (segs_out != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (num_segs_in != NULL, FALSE);
|
|
|
|
g_return_val_if_fail (num_segs_out != NULL, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
return GIMP_CHANNEL_GET_CLASS (channel)->boundary (channel,
|
|
|
|
segs_in, segs_out,
|
|
|
|
num_segs_in, num_segs_out,
|
|
|
|
x1, y1,
|
|
|
|
x2, y2);
|
|
|
|
}
|
2001-08-11 22:39:19 +08:00
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
gboolean
|
|
|
|
gimp_channel_bounds (GimpChannel *channel,
|
2004-01-12 21:57:30 +08:00
|
|
|
gint *x1,
|
|
|
|
gint *y1,
|
|
|
|
gint *x2,
|
|
|
|
gint *y2)
|
2003-09-03 07:07:40 +08:00
|
|
|
{
|
2006-08-04 02:17:42 +08:00
|
|
|
gint tmp_x1, tmp_y1, tmp_x2, tmp_y2;
|
|
|
|
gboolean retval;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2006-08-04 02:17:42 +08:00
|
|
|
retval = GIMP_CHANNEL_GET_CLASS (channel)->bounds (channel,
|
|
|
|
&tmp_x1, &tmp_y1,
|
|
|
|
&tmp_x2, &tmp_y2);
|
|
|
|
|
|
|
|
if (x1) *x1 = tmp_x1;
|
|
|
|
if (y1) *y1 = tmp_y1;
|
|
|
|
if (x2) *x2 = tmp_x2;
|
|
|
|
if (y2) *y2 = tmp_y2;
|
|
|
|
|
|
|
|
return retval;
|
2003-09-03 07:07:40 +08:00
|
|
|
}
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2003-09-04 21:45:31 +08:00
|
|
|
gboolean
|
|
|
|
gimp_channel_is_empty (GimpChannel *channel)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GIMP_IS_CHANNEL (channel), FALSE);
|
|
|
|
|
|
|
|
return GIMP_CHANNEL_GET_CLASS (channel)->is_empty (channel);
|
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
void
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_feather (GimpChannel *channel,
|
2004-01-12 21:57:30 +08:00
|
|
|
gdouble radius_x,
|
|
|
|
gdouble radius_y,
|
2001-10-22 20:13:44 +08:00
|
|
|
gboolean push_undo)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
if (! gimp_item_is_attached (GIMP_ITEM (channel)))
|
|
|
|
push_undo = FALSE;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->feather (channel, radius_x, radius_y,
|
|
|
|
push_undo);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2002-03-09 00:34:42 +08:00
|
|
|
void
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_sharpen (GimpChannel *channel,
|
2002-08-20 18:22:23 +08:00
|
|
|
gboolean push_undo)
|
2002-03-09 00:34:42 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
2002-09-24 23:57:27 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
if (! gimp_item_is_attached (GIMP_ITEM (channel)))
|
|
|
|
push_undo = FALSE;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->sharpen (channel, push_undo);
|
2002-03-09 00:34:42 +08:00
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
void
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_clear (GimpChannel *channel,
|
|
|
|
const gchar *undo_desc,
|
2002-08-20 18:22:23 +08:00
|
|
|
gboolean push_undo)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
if (! gimp_item_is_attached (GIMP_ITEM (channel)))
|
|
|
|
push_undo = FALSE;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->clear (channel, undo_desc, push_undo);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_all (GimpChannel *channel,
|
2002-08-20 18:22:23 +08:00
|
|
|
gboolean push_undo)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
if (! gimp_item_is_attached (GIMP_ITEM (channel)))
|
|
|
|
push_undo = FALSE;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->all (channel, push_undo);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_invert (GimpChannel *channel,
|
2002-06-07 03:07:59 +08:00
|
|
|
gboolean push_undo)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
2002-08-20 18:22:23 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
if (! gimp_item_is_attached (GIMP_ITEM (channel)))
|
|
|
|
push_undo = FALSE;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->invert (channel, push_undo);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_border (GimpChannel *channel,
|
2004-01-12 21:57:30 +08:00
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
2006-06-06 04:19:12 +08:00
|
|
|
gboolean feather,
|
2007-03-06 04:21:23 +08:00
|
|
|
gboolean edge_lock,
|
2002-08-20 18:22:23 +08:00
|
|
|
gboolean push_undo)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
if (! gimp_item_is_attached (GIMP_ITEM (channel)))
|
|
|
|
push_undo = FALSE;
|
|
|
|
|
2006-06-06 04:19:12 +08:00
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->border (channel,
|
2007-03-06 04:21:23 +08:00
|
|
|
radius_x, radius_y, feather, edge_lock,
|
|
|
|
push_undo);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_grow (GimpChannel *channel,
|
2004-01-12 21:57:30 +08:00
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
2002-08-20 18:22:23 +08:00
|
|
|
gboolean push_undo)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
1999-05-07 07:10:29 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
if (! gimp_item_is_attached (GIMP_ITEM (channel)))
|
|
|
|
push_undo = FALSE;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->grow (channel, radius_x, radius_y,
|
|
|
|
push_undo);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2003-09-03 07:07:40 +08:00
|
|
|
gimp_channel_shrink (GimpChannel *channel,
|
2004-01-12 21:57:30 +08:00
|
|
|
gint radius_x,
|
|
|
|
gint radius_y,
|
|
|
|
gboolean edge_lock,
|
2002-08-20 18:22:23 +08:00
|
|
|
gboolean push_undo)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2003-09-03 07:07:40 +08:00
|
|
|
g_return_if_fail (GIMP_IS_CHANNEL (channel));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2004-11-16 21:41:55 +08:00
|
|
|
if (! gimp_item_is_attached (GIMP_ITEM (channel)))
|
|
|
|
push_undo = FALSE;
|
|
|
|
|
2003-09-03 07:07:40 +08:00
|
|
|
GIMP_CHANNEL_GET_CLASS (channel)->shrink (channel, radius_x, radius_y,
|
|
|
|
edge_lock, push_undo);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|