mirror of https://github.com/GNOME/gimp.git
made all functions which push an undo step virtual and added them all as
2003-09-03 Michael Natterer <mitch@gimp.org> * app/core/gimpchannel.[ch]: made all functions which push an undo step virtual and added them all as default implementations. * app/core/Makefile.am * app/core/core-types.h * app/core/gimpselection.[ch]: new object which is a GimpChannel subclass and implements all of its virtual functions, pushes an image_mask undo and chains up with "push_undo = FALSE". * app/core/gimpimage-mask.[ch]: made most functions simple wrappers like gimp_channel_invert(gimp_image_get_mask(gimage)); so the API stays the same for now. * app/core/gimpimage.[ch]: create a GimpSelection object as gimage->selection_mask. Removed "gboolean mask_stroking" since it is in GimpSelection now. * app/xcf/xcf-load.c (xcf_load_channel_props): added an evil hack which turns a GimpChannel into a GimpSelection once we figured the loaded channel is the selection. * app/core/gimplayer.c (gimp_layer_create_mask): gimp_channel_clear() takes an additional "const gchar *undo_desc" parameter now. * app/core/gimpscanconvert.c (gimp_scan_convert_to_channel): set mask->bounds_known to FALSE before returning the new channel * app/tools/gimpiscissorstool.c (iscissors_convert): no need to call gimp_channel_invalidate_boundary() on the channel returned by the above function. * app/core/gimpchannel.[ch]: removed gimp_channel_invalidate_boundary() since it is no longer needed.
This commit is contained in:
parent
443a5f3fd2
commit
420d17d286
37
ChangeLog
37
ChangeLog
|
@ -1,3 +1,40 @@
|
|||
2003-09-03 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/core/gimpchannel.[ch]: made all functions which push an
|
||||
undo step virtual and added them all as default implementations.
|
||||
|
||||
* app/core/Makefile.am
|
||||
* app/core/core-types.h
|
||||
* app/core/gimpselection.[ch]: new object which is a GimpChannel
|
||||
subclass and implements all of its virtual functions, pushes
|
||||
an image_mask undo and chains up with "push_undo = FALSE".
|
||||
|
||||
* app/core/gimpimage-mask.[ch]: made most functions simple
|
||||
wrappers like gimp_channel_invert(gimp_image_get_mask(gimage));
|
||||
so the API stays the same for now.
|
||||
|
||||
* app/core/gimpimage.[ch]: create a GimpSelection object
|
||||
as gimage->selection_mask. Removed "gboolean mask_stroking"
|
||||
since it is in GimpSelection now.
|
||||
|
||||
* app/xcf/xcf-load.c (xcf_load_channel_props): added an evil hack
|
||||
which turns a GimpChannel into a GimpSelection once we figured the
|
||||
loaded channel is the selection.
|
||||
|
||||
* app/core/gimplayer.c (gimp_layer_create_mask):
|
||||
gimp_channel_clear() takes an additional "const gchar *undo_desc"
|
||||
parameter now.
|
||||
|
||||
* app/core/gimpscanconvert.c (gimp_scan_convert_to_channel): set
|
||||
mask->bounds_known to FALSE before returning the new channel
|
||||
|
||||
* app/tools/gimpiscissorstool.c (iscissors_convert): no need to
|
||||
call gimp_channel_invalidate_boundary() on the channel returned by
|
||||
the above function.
|
||||
|
||||
* app/core/gimpchannel.[ch]: removed
|
||||
gimp_channel_invalidate_boundary() since it is no longer needed.
|
||||
|
||||
2003-09-03 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* libgimpcolor/gimpcolorspace.[ch] (gimp_rgb_to_cmyk_int): made
|
||||
|
|
|
@ -172,6 +172,8 @@ libappcore_a_sources = \
|
|||
gimppreviewcache.h \
|
||||
gimpscanconvert.c \
|
||||
gimpscanconvert.h \
|
||||
gimpselection.c \
|
||||
gimpselection.h \
|
||||
gimptemplate.c \
|
||||
gimptemplate.h \
|
||||
gimptoolinfo.c \
|
||||
|
|
|
@ -80,6 +80,7 @@ typedef struct _GimpGrid GimpGrid;
|
|||
typedef struct _GimpDrawable GimpDrawable;
|
||||
|
||||
typedef struct _GimpChannel GimpChannel;
|
||||
typedef struct _GimpSelection GimpSelection;
|
||||
|
||||
typedef struct _GimpLayer GimpLayer;
|
||||
typedef struct _GimpLayerMask GimpLayerMask;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -59,131 +59,175 @@ struct _GimpChannel
|
|||
struct _GimpChannelClass
|
||||
{
|
||||
GimpDrawableClass parent_class;
|
||||
|
||||
gboolean (* 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);
|
||||
gboolean (* bounds) (GimpChannel *channel,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
gint (* value) (GimpChannel *channel,
|
||||
gint x,
|
||||
gint y);
|
||||
gboolean (* is_empty) (GimpChannel *channel);
|
||||
void (* feather) (GimpChannel *channel,
|
||||
gdouble radius_x,
|
||||
gdouble radius_y,
|
||||
gboolean push_undo);
|
||||
void (* sharpen) (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
void (* clear) (GimpChannel *channel,
|
||||
const gchar *undo_desc,
|
||||
gboolean push_undo);
|
||||
void (* all) (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
void (* invert) (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
void (* border) (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void (* grow) (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void (* shrink) (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean edge_lock,
|
||||
gboolean push_undo);
|
||||
};
|
||||
|
||||
|
||||
/* function declarations */
|
||||
|
||||
GType gimp_channel_get_type (void) G_GNUC_CONST;
|
||||
GType gimp_channel_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpChannel * gimp_channel_new (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
GimpChannel * gimp_channel_new (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
|
||||
GimpChannel * gimp_channel_new_from_alpha (GimpImage *gimage,
|
||||
GimpLayer *layer,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
GimpChannel * gimp_channel_new_from_component (GimpImage *gimage,
|
||||
GimpChannelType type,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
GimpChannel * gimp_channel_new_from_alpha (GimpImage *gimage,
|
||||
GimpLayer *layer,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
GimpChannel * gimp_channel_new_from_component (GimpImage *gimage,
|
||||
GimpChannelType type,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
|
||||
gdouble gimp_channel_get_opacity (const GimpChannel *channel);
|
||||
void gimp_channel_set_opacity (GimpChannel *channel,
|
||||
gdouble opacity,
|
||||
gboolean push_undo);
|
||||
gdouble gimp_channel_get_opacity (const GimpChannel *channel);
|
||||
void gimp_channel_set_opacity (GimpChannel *channel,
|
||||
gdouble opacity,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_get_color (const GimpChannel *channel,
|
||||
GimpRGB *color);
|
||||
void gimp_channel_set_color (GimpChannel *channel,
|
||||
const GimpRGB *color,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_get_color (const GimpChannel *channel,
|
||||
GimpRGB *color);
|
||||
void gimp_channel_set_color (GimpChannel *channel,
|
||||
const GimpRGB *color,
|
||||
gboolean push_undo);
|
||||
|
||||
gboolean gimp_channel_get_show_masked (GimpChannel *channel);
|
||||
void gimp_channel_set_show_masked (GimpChannel *channel,
|
||||
gboolean show_masked);
|
||||
gboolean gimp_channel_get_show_masked (GimpChannel *channel);
|
||||
void gimp_channel_set_show_masked (GimpChannel *channel,
|
||||
gboolean show_masked);
|
||||
|
||||
|
||||
/* selection mask functions */
|
||||
|
||||
GimpChannel * gimp_channel_new_mask (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height);
|
||||
GimpChannel * gimp_channel_new_mask (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
gboolean gimp_channel_boundary (GimpChannel *mask,
|
||||
const BoundSeg **segs_in,
|
||||
const BoundSeg **segs_out,
|
||||
gint *num_segs_in,
|
||||
gint *num_segs_out,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2);
|
||||
gboolean gimp_channel_bounds (GimpChannel *mask,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
gint gimp_channel_value (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y);
|
||||
gboolean gimp_channel_is_empty (GimpChannel *mask);
|
||||
gboolean gimp_channel_boundary (GimpChannel *mask,
|
||||
const BoundSeg **segs_in,
|
||||
const BoundSeg **segs_out,
|
||||
gint *num_segs_in,
|
||||
gint *num_segs_out,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2);
|
||||
gboolean gimp_channel_bounds (GimpChannel *mask,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
gint gimp_channel_value (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y);
|
||||
gboolean gimp_channel_is_empty (GimpChannel *mask);
|
||||
|
||||
void gimp_channel_add_segment (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint value);
|
||||
void gimp_channel_sub_segment (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint value);
|
||||
void gimp_channel_combine_rect (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
void gimp_channel_combine_ellipse (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h,
|
||||
gboolean antialias);
|
||||
void gimp_channel_combine_mask (GimpChannel *mask,
|
||||
GimpChannel *add_on,
|
||||
GimpChannelOps op,
|
||||
gint off_x,
|
||||
gint off_y);
|
||||
void gimp_channel_add_segment (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint value);
|
||||
void gimp_channel_sub_segment (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint value);
|
||||
void gimp_channel_combine_rect (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
void gimp_channel_combine_ellipse (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h,
|
||||
gboolean antialias);
|
||||
void gimp_channel_combine_mask (GimpChannel *mask,
|
||||
GimpChannel *add_on,
|
||||
GimpChannelOps op,
|
||||
gint off_x,
|
||||
gint off_y);
|
||||
|
||||
void gimp_channel_feather (GimpChannel *mask,
|
||||
gdouble radius_x,
|
||||
gdouble radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_sharpen (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_feather (GimpChannel *mask,
|
||||
gdouble radius_x,
|
||||
gdouble radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_sharpen (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_clear (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_all (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_invert (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_clear (GimpChannel *mask,
|
||||
const gchar *undo_desc,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_all (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_invert (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_border (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_grow (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_shrink (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean edge_lock,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_border (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_grow (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_shrink (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean edge_lock,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_load (GimpChannel *mask,
|
||||
GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_invalidate_bounds (GimpChannel *channel);
|
||||
void gimp_channel_load (GimpChannel *mask,
|
||||
GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
|
||||
|
||||
#endif /* __GIMP_CHANNEL_H__ */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -59,131 +59,175 @@ struct _GimpChannel
|
|||
struct _GimpChannelClass
|
||||
{
|
||||
GimpDrawableClass parent_class;
|
||||
|
||||
gboolean (* 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);
|
||||
gboolean (* bounds) (GimpChannel *channel,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
gint (* value) (GimpChannel *channel,
|
||||
gint x,
|
||||
gint y);
|
||||
gboolean (* is_empty) (GimpChannel *channel);
|
||||
void (* feather) (GimpChannel *channel,
|
||||
gdouble radius_x,
|
||||
gdouble radius_y,
|
||||
gboolean push_undo);
|
||||
void (* sharpen) (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
void (* clear) (GimpChannel *channel,
|
||||
const gchar *undo_desc,
|
||||
gboolean push_undo);
|
||||
void (* all) (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
void (* invert) (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
void (* border) (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void (* grow) (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void (* shrink) (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean edge_lock,
|
||||
gboolean push_undo);
|
||||
};
|
||||
|
||||
|
||||
/* function declarations */
|
||||
|
||||
GType gimp_channel_get_type (void) G_GNUC_CONST;
|
||||
GType gimp_channel_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpChannel * gimp_channel_new (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
GimpChannel * gimp_channel_new (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
|
||||
GimpChannel * gimp_channel_new_from_alpha (GimpImage *gimage,
|
||||
GimpLayer *layer,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
GimpChannel * gimp_channel_new_from_component (GimpImage *gimage,
|
||||
GimpChannelType type,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
GimpChannel * gimp_channel_new_from_alpha (GimpImage *gimage,
|
||||
GimpLayer *layer,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
GimpChannel * gimp_channel_new_from_component (GimpImage *gimage,
|
||||
GimpChannelType type,
|
||||
const gchar *name,
|
||||
const GimpRGB *color);
|
||||
|
||||
gdouble gimp_channel_get_opacity (const GimpChannel *channel);
|
||||
void gimp_channel_set_opacity (GimpChannel *channel,
|
||||
gdouble opacity,
|
||||
gboolean push_undo);
|
||||
gdouble gimp_channel_get_opacity (const GimpChannel *channel);
|
||||
void gimp_channel_set_opacity (GimpChannel *channel,
|
||||
gdouble opacity,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_get_color (const GimpChannel *channel,
|
||||
GimpRGB *color);
|
||||
void gimp_channel_set_color (GimpChannel *channel,
|
||||
const GimpRGB *color,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_get_color (const GimpChannel *channel,
|
||||
GimpRGB *color);
|
||||
void gimp_channel_set_color (GimpChannel *channel,
|
||||
const GimpRGB *color,
|
||||
gboolean push_undo);
|
||||
|
||||
gboolean gimp_channel_get_show_masked (GimpChannel *channel);
|
||||
void gimp_channel_set_show_masked (GimpChannel *channel,
|
||||
gboolean show_masked);
|
||||
gboolean gimp_channel_get_show_masked (GimpChannel *channel);
|
||||
void gimp_channel_set_show_masked (GimpChannel *channel,
|
||||
gboolean show_masked);
|
||||
|
||||
|
||||
/* selection mask functions */
|
||||
|
||||
GimpChannel * gimp_channel_new_mask (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height);
|
||||
GimpChannel * gimp_channel_new_mask (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
gboolean gimp_channel_boundary (GimpChannel *mask,
|
||||
const BoundSeg **segs_in,
|
||||
const BoundSeg **segs_out,
|
||||
gint *num_segs_in,
|
||||
gint *num_segs_out,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2);
|
||||
gboolean gimp_channel_bounds (GimpChannel *mask,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
gint gimp_channel_value (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y);
|
||||
gboolean gimp_channel_is_empty (GimpChannel *mask);
|
||||
gboolean gimp_channel_boundary (GimpChannel *mask,
|
||||
const BoundSeg **segs_in,
|
||||
const BoundSeg **segs_out,
|
||||
gint *num_segs_in,
|
||||
gint *num_segs_out,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2);
|
||||
gboolean gimp_channel_bounds (GimpChannel *mask,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
gint gimp_channel_value (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y);
|
||||
gboolean gimp_channel_is_empty (GimpChannel *mask);
|
||||
|
||||
void gimp_channel_add_segment (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint value);
|
||||
void gimp_channel_sub_segment (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint value);
|
||||
void gimp_channel_combine_rect (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
void gimp_channel_combine_ellipse (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h,
|
||||
gboolean antialias);
|
||||
void gimp_channel_combine_mask (GimpChannel *mask,
|
||||
GimpChannel *add_on,
|
||||
GimpChannelOps op,
|
||||
gint off_x,
|
||||
gint off_y);
|
||||
void gimp_channel_add_segment (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint value);
|
||||
void gimp_channel_sub_segment (GimpChannel *mask,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint value);
|
||||
void gimp_channel_combine_rect (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
void gimp_channel_combine_ellipse (GimpChannel *mask,
|
||||
GimpChannelOps op,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h,
|
||||
gboolean antialias);
|
||||
void gimp_channel_combine_mask (GimpChannel *mask,
|
||||
GimpChannel *add_on,
|
||||
GimpChannelOps op,
|
||||
gint off_x,
|
||||
gint off_y);
|
||||
|
||||
void gimp_channel_feather (GimpChannel *mask,
|
||||
gdouble radius_x,
|
||||
gdouble radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_sharpen (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_feather (GimpChannel *mask,
|
||||
gdouble radius_x,
|
||||
gdouble radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_sharpen (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_clear (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_all (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_invert (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_clear (GimpChannel *mask,
|
||||
const gchar *undo_desc,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_all (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_invert (GimpChannel *mask,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_border (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_grow (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_shrink (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean edge_lock,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_border (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_grow (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
void gimp_channel_shrink (GimpChannel *mask,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean edge_lock,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_load (GimpChannel *mask,
|
||||
GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_channel_invalidate_bounds (GimpChannel *channel);
|
||||
void gimp_channel_load (GimpChannel *mask,
|
||||
GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
|
||||
|
||||
#endif /* __GIMP_CHANNEL_H__ */
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
#include "paint-funcs/paint-funcs.h"
|
||||
|
||||
#include "paint/gimppaintcore-stroke.h"
|
||||
|
||||
#include "gimp.h"
|
||||
#include "gimpchannel.h"
|
||||
#include "gimpcontainer.h"
|
||||
|
@ -41,7 +39,7 @@
|
|||
#include "gimplayer.h"
|
||||
#include "gimplayer-floating-sel.h"
|
||||
#include "gimplayermask.h"
|
||||
#include "gimppaintinfo.h"
|
||||
#include "gimpselection.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
@ -55,83 +53,14 @@ gimp_image_mask_boundary (GimpImage *gimage,
|
|||
gint *num_segs_in,
|
||||
gint *num_segs_out)
|
||||
{
|
||||
GimpDrawable *drawable;
|
||||
GimpLayer *layer;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), 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);
|
||||
|
||||
if ((layer = gimp_image_floating_sel (gimage)))
|
||||
{
|
||||
/* If there is a floating selection, then
|
||||
* we need to do some slightly different boundaries.
|
||||
* Instead of inside and outside boundaries being defined
|
||||
* by the extents of the layer, the inside boundary (the one
|
||||
* that actually marches and is black/white) is the boundary of
|
||||
* the floating selection. The outside boundary (doesn't move,
|
||||
* is black/gray) is defined as the normal selection mask
|
||||
*/
|
||||
|
||||
/* Find the selection mask boundary */
|
||||
gimp_channel_boundary (gimp_image_get_mask (gimage),
|
||||
segs_in, segs_out,
|
||||
num_segs_in, num_segs_out,
|
||||
0, 0, 0, 0);
|
||||
|
||||
/* Find the floating selection boundary */
|
||||
*segs_in = floating_sel_boundary (layer, num_segs_in);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if ((drawable = gimp_image_active_drawable (gimage)) &&
|
||||
GIMP_IS_CHANNEL (drawable))
|
||||
{
|
||||
/* Otherwise, return the boundary...if a channel is active */
|
||||
|
||||
return gimp_channel_boundary (gimp_image_get_mask (gimage),
|
||||
segs_in, segs_out,
|
||||
num_segs_in, num_segs_out,
|
||||
0, 0, gimage->width, gimage->height);
|
||||
}
|
||||
else if ((layer = gimp_image_get_active_layer (gimage)))
|
||||
{
|
||||
/* If a layer is active, we return multiple boundaries based
|
||||
* on the extents
|
||||
*/
|
||||
|
||||
gint x1, y1;
|
||||
gint x2, y2;
|
||||
gint off_x, off_y;
|
||||
|
||||
gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);
|
||||
|
||||
x1 = CLAMP (off_x, 0, gimage->width);
|
||||
y1 = CLAMP (off_y, 0, gimage->height);
|
||||
x2 = CLAMP (off_x + gimp_item_width (GIMP_ITEM (layer)), 0,
|
||||
gimage->width);
|
||||
y2 = CLAMP (off_y + gimp_item_height (GIMP_ITEM (layer)), 0,
|
||||
gimage->height);
|
||||
|
||||
return gimp_channel_boundary (gimp_image_get_mask (gimage),
|
||||
segs_in, segs_out,
|
||||
num_segs_in, num_segs_out,
|
||||
x1, y1, x2, y2);
|
||||
}
|
||||
else
|
||||
{
|
||||
*segs_in = NULL;
|
||||
*segs_out = NULL;
|
||||
*num_segs_in = 0;
|
||||
*num_segs_out = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
return gimp_channel_boundary (gimp_image_get_mask (gimage),
|
||||
segs_in, segs_out,
|
||||
num_segs_in, num_segs_out,
|
||||
0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
gimp_image_mask_bounds (GimpImage *gimage,
|
||||
gint *x1,
|
||||
|
@ -139,61 +68,160 @@ gimp_image_mask_bounds (GimpImage *gimage,
|
|||
gint *x2,
|
||||
gint *y2)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
|
||||
return gimp_channel_bounds (gimp_image_get_mask (gimage), x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gimp_image_mask_invalidate (GimpImage *gimage)
|
||||
{
|
||||
GimpLayer *layer;
|
||||
GimpChannel *mask;
|
||||
|
||||
/* Turn the current selection off */
|
||||
gimp_image_selection_control (gimage, GIMP_SELECTION_OFF);
|
||||
|
||||
mask = gimp_image_get_mask (gimage);
|
||||
mask->boundary_known = FALSE;
|
||||
|
||||
/* If there is a floating selection, update it's area...
|
||||
* we need to do this since this selection mask can act as an additional
|
||||
* mask in the composition of the floating selection
|
||||
*/
|
||||
layer = gimp_image_get_active_layer (gimage);
|
||||
|
||||
if (layer && gimp_layer_is_floating_sel (layer))
|
||||
gimp_drawable_update (GIMP_DRAWABLE (layer),
|
||||
0, 0,
|
||||
GIMP_ITEM (layer)->width,
|
||||
GIMP_ITEM (layer)->height);
|
||||
|
||||
/* invalidate the preview */
|
||||
GIMP_DRAWABLE (mask)->preview_valid = FALSE;
|
||||
}
|
||||
|
||||
|
||||
gint
|
||||
gimp_image_mask_value (GimpImage *gimage,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), 0);
|
||||
|
||||
return gimp_channel_value (gimp_image_get_mask (gimage), x, y);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
gimp_image_mask_is_empty (GimpImage *gimage)
|
||||
{
|
||||
/* in order to allow stroking of selections, we need to pretend here
|
||||
* that the selection mask is empty so that it doesn't mask the paint
|
||||
* during the stroke operation.
|
||||
*/
|
||||
if (gimage->mask_stroking)
|
||||
return TRUE;
|
||||
else
|
||||
return gimp_channel_is_empty (gimp_image_get_mask (gimage));
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
|
||||
return gimp_channel_is_empty (gimp_image_get_mask (gimage));
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_feather (GimpImage *gimage,
|
||||
gdouble feather_radius_x,
|
||||
gdouble feather_radius_y)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_channel_feather (gimp_image_get_mask (gimage),
|
||||
feather_radius_x,
|
||||
feather_radius_y,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_sharpen (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_channel_sharpen (gimp_image_get_mask (gimage), TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_clear (GimpImage *gimage,
|
||||
const gchar *undo_desc)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_channel_clear (gimp_image_get_mask (gimage), undo_desc, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_all (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_channel_all (gimp_image_get_mask (gimage), TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_invert (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_channel_invert (gimp_image_get_mask (gimage), TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_border (GimpImage *gimage,
|
||||
gint border_radius_x,
|
||||
gint border_radius_y)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_channel_border (gimp_image_get_mask (gimage),
|
||||
border_radius_x,
|
||||
border_radius_y,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_grow (GimpImage *gimage,
|
||||
gint grow_pixels_x,
|
||||
gint grow_pixels_y)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_channel_grow (gimp_image_get_mask (gimage),
|
||||
grow_pixels_x,
|
||||
grow_pixels_y,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_shrink (GimpImage *gimage,
|
||||
gint shrink_pixels_x,
|
||||
gint shrink_pixels_y,
|
||||
gboolean edge_lock)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_channel_shrink (gimp_image_get_mask (gimage),
|
||||
shrink_pixels_x,
|
||||
shrink_pixels_y,
|
||||
edge_lock,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_translate (GimpImage *gimage,
|
||||
gint off_x,
|
||||
gint off_y,
|
||||
gboolean push_undo)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_item_translate (GIMP_ITEM (gimp_image_get_mask (gimage)),
|
||||
off_x, off_y, TRUE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_image_mask_stroke (GimpImage *gimage,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintInfo *paint_info)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
|
||||
return gimp_item_stroke (GIMP_ITEM (gimp_image_get_mask (gimage)),
|
||||
drawable, paint_info);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_push_undo (GimpImage *gimage,
|
||||
const gchar *undo_desc)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_selection_push_undo (GIMP_SELECTION (gimp_image_get_mask (gimage)),
|
||||
undo_desc);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_invalidate (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_selection_invalidate (GIMP_SELECTION (gimp_image_get_mask (gimage)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TileManager *
|
||||
gimp_image_mask_extract (GimpImage *gimage,
|
||||
|
@ -421,163 +449,6 @@ gimp_image_mask_float (GimpImage *gimage,
|
|||
return layer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gimp_image_mask_push_undo (GimpImage *gimage,
|
||||
const gchar *undo_desc)
|
||||
{
|
||||
GimpChannel *mask;
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
mask = gimp_image_get_mask (gimage);
|
||||
|
||||
gimp_image_undo_push_mask (gimage, undo_desc, mask);
|
||||
|
||||
gimp_image_mask_invalidate (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_feather (GimpImage *gimage,
|
||||
gdouble feather_radius_x,
|
||||
gdouble feather_radius_y)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_image_mask_push_undo (gimage, _("Feather Selection"));
|
||||
|
||||
gimp_channel_feather (gimp_image_get_mask (gimage),
|
||||
feather_radius_x,
|
||||
feather_radius_y,
|
||||
FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_sharpen (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_image_mask_push_undo (gimage, _("Sharpen Selection"));
|
||||
|
||||
gimp_channel_sharpen (gimp_image_get_mask (gimage), FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_clear (GimpImage *gimage,
|
||||
const gchar *undo_desc)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
if (! undo_desc)
|
||||
undo_desc = _("Select None");
|
||||
|
||||
gimp_image_mask_push_undo (gimage, undo_desc);
|
||||
|
||||
gimp_channel_clear (gimp_image_get_mask (gimage), FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_all (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_image_mask_push_undo (gimage, _("Select All"));
|
||||
|
||||
gimp_channel_all (gimp_image_get_mask (gimage), FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_invert (GimpImage *gimage)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_image_mask_push_undo (gimage, _("Invert Selection"));
|
||||
|
||||
gimp_channel_invert (gimp_image_get_mask (gimage), FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_border (GimpImage *gimage,
|
||||
gint border_radius_x,
|
||||
gint border_radius_y)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_image_mask_push_undo (gimage, _("Border Selection"));
|
||||
|
||||
gimp_channel_border (gimp_image_get_mask (gimage),
|
||||
border_radius_x,
|
||||
border_radius_y,
|
||||
FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_grow (GimpImage *gimage,
|
||||
gint grow_pixels_x,
|
||||
gint grow_pixels_y)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_image_mask_push_undo (gimage, _("Grow Selection"));
|
||||
|
||||
gimp_channel_grow (gimp_image_get_mask (gimage),
|
||||
grow_pixels_x,
|
||||
grow_pixels_y,
|
||||
FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_shrink (GimpImage *gimage,
|
||||
gint shrink_pixels_x,
|
||||
gint shrink_pixels_y,
|
||||
gboolean edge_lock)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_image_mask_push_undo (gimage, _("Shrink Selection"));
|
||||
|
||||
gimp_channel_shrink (gimp_image_get_mask (gimage),
|
||||
shrink_pixels_x,
|
||||
shrink_pixels_y,
|
||||
edge_lock,
|
||||
FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_translate (GimpImage *gimage,
|
||||
gint off_x,
|
||||
gint off_y,
|
||||
gboolean push_undo)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
if (push_undo)
|
||||
gimp_image_mask_push_undo (gimage, _("Move Selection"));
|
||||
else
|
||||
gimp_image_mask_invalidate (gimage);
|
||||
|
||||
gimp_item_translate (GIMP_ITEM (gimp_image_get_mask (gimage)),
|
||||
off_x, off_y, FALSE);
|
||||
|
||||
gimp_image_mask_changed (gimage);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_image_mask_load (GimpImage *gimage,
|
||||
GimpChannel *channel)
|
||||
|
@ -604,7 +475,7 @@ gimp_image_mask_save (GimpImage *gimage)
|
|||
mask = gimp_image_get_mask (gimage);
|
||||
|
||||
new_channel = GIMP_CHANNEL (gimp_item_duplicate (GIMP_ITEM (mask),
|
||||
G_TYPE_FROM_INSTANCE (mask),
|
||||
GIMP_TYPE_CHANNEL,
|
||||
FALSE));
|
||||
|
||||
/* saved selections are not visible by default */
|
||||
|
@ -614,47 +485,3 @@ gimp_image_mask_save (GimpImage *gimage)
|
|||
|
||||
return new_channel;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_image_mask_stroke (GimpImage *gimage,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintInfo *paint_info)
|
||||
{
|
||||
const BoundSeg *bs_in;
|
||||
const BoundSeg *bs_out;
|
||||
gint num_segs_in;
|
||||
gint num_segs_out;
|
||||
GimpPaintCore *core;
|
||||
gboolean retval;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_PAINT_INFO (paint_info), FALSE);
|
||||
|
||||
if (! gimp_image_mask_boundary (gimage, &bs_in, &bs_out,
|
||||
&num_segs_in, &num_segs_out))
|
||||
{
|
||||
g_message (_("No selection to stroke."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gimage->mask_stroking = TRUE;
|
||||
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_PAINT,
|
||||
_("Stroke Selection"));
|
||||
|
||||
core = g_object_new (paint_info->paint_type, NULL);
|
||||
|
||||
retval = gimp_paint_core_stroke_boundary (core, drawable,
|
||||
paint_info->paint_options,
|
||||
bs_in, num_segs_in,
|
||||
0, 0);
|
||||
|
||||
g_object_unref (core);
|
||||
|
||||
gimp_image_undo_group_end (gimage);
|
||||
|
||||
gimage->mask_stroking = FALSE;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -20,26 +20,63 @@
|
|||
#define __GIMP_IMAGE_MASK_H__
|
||||
|
||||
|
||||
/* pure wrappers around the resp. GimpChannel::foo() functions: */
|
||||
|
||||
gboolean gimp_image_mask_boundary (GimpImage *gimage,
|
||||
const BoundSeg **segs_in,
|
||||
const BoundSeg **segs_out,
|
||||
gint *num_segs_in,
|
||||
gint *num_segs_out);
|
||||
|
||||
gboolean gimp_image_mask_bounds (GimpImage *gimage,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
|
||||
void gimp_image_mask_invalidate (GimpImage *gimage);
|
||||
|
||||
gint gimp_image_mask_value (GimpImage *gimage,
|
||||
gint x,
|
||||
gint y);
|
||||
|
||||
gboolean gimp_image_mask_is_empty (GimpImage *gimage);
|
||||
|
||||
void gimp_image_mask_feather (GimpImage *gimage,
|
||||
gdouble feather_radius_x,
|
||||
gdouble feather_radius_y);
|
||||
void gimp_image_mask_sharpen (GimpImage *gimage);
|
||||
void gimp_image_mask_clear (GimpImage *gimage,
|
||||
const gchar *undo_name);
|
||||
void gimp_image_mask_all (GimpImage *gimage);
|
||||
void gimp_image_mask_invert (GimpImage *gimage);
|
||||
void gimp_image_mask_border (GimpImage *gimage,
|
||||
gint border_radius_x,
|
||||
gint border_radius_y);
|
||||
void gimp_image_mask_grow (GimpImage *gimage,
|
||||
gint grow_pixels_x,
|
||||
gint grow_pixels_y);
|
||||
void gimp_image_mask_shrink (GimpImage *gimage,
|
||||
gint shrink_pixels_x,
|
||||
gint shrink_pixels_y,
|
||||
gboolean edge_lock);
|
||||
|
||||
|
||||
/* pure wrappers around the resp. GimpItem::foo() functions: */
|
||||
|
||||
void gimp_image_mask_translate (GimpImage *gimage,
|
||||
gint off_x,
|
||||
gint off_y,
|
||||
gboolean push_undo);
|
||||
gboolean gimp_image_mask_stroke (GimpImage *gimage,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintInfo *paint_info);
|
||||
|
||||
|
||||
/* pure wrappers around the resp. GimpSelection functions: */
|
||||
|
||||
void gimp_image_mask_push_undo (GimpImage *gimage,
|
||||
const gchar *undo_desc);
|
||||
void gimp_image_mask_invalidate (GimpImage *gimage);
|
||||
|
||||
|
||||
/* really implemented here: */
|
||||
|
||||
TileManager * gimp_image_mask_extract (GimpImage *gimage,
|
||||
GimpDrawable *drawable,
|
||||
gboolean cut_image,
|
||||
|
@ -52,44 +89,9 @@ GimpLayer * gimp_image_mask_float (GimpImage *gimage,
|
|||
gint off_x,
|
||||
gint off_y);
|
||||
|
||||
void gimp_image_mask_push_undo (GimpImage *gimage,
|
||||
const gchar *undo_desc);
|
||||
|
||||
void gimp_image_mask_feather (GimpImage *gimage,
|
||||
gdouble feather_radius_x,
|
||||
gdouble feather_radius_y);
|
||||
void gimp_image_mask_sharpen (GimpImage *gimage);
|
||||
|
||||
void gimp_image_mask_clear (GimpImage *gimage,
|
||||
const gchar *undo_name);
|
||||
void gimp_image_mask_all (GimpImage *gimage);
|
||||
void gimp_image_mask_invert (GimpImage *gimage);
|
||||
|
||||
void gimp_image_mask_border (GimpImage *gimage,
|
||||
gint border_radius_x,
|
||||
gint border_radius_y);
|
||||
|
||||
void gimp_image_mask_grow (GimpImage *gimage,
|
||||
gint grow_pixels_x,
|
||||
gint grow_pixels_y);
|
||||
|
||||
void gimp_image_mask_shrink (GimpImage *gimage,
|
||||
gint shrink_pixels_x,
|
||||
gint shrink_pixels_y,
|
||||
gboolean edge_lock);
|
||||
|
||||
void gimp_image_mask_translate (GimpImage *gimage,
|
||||
gint off_x,
|
||||
gint off_y,
|
||||
gboolean push_undo);
|
||||
|
||||
void gimp_image_mask_load (GimpImage *gimage,
|
||||
GimpChannel *channel);
|
||||
GimpChannel * gimp_image_mask_save (GimpImage *gimage);
|
||||
|
||||
gboolean gimp_image_mask_stroke (GimpImage *gimage,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintInfo *paint_info);
|
||||
|
||||
|
||||
#endif /* __GIMP_IMAGE_MASK_H__ */
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "gimplist.h"
|
||||
#include "gimpmarshal.h"
|
||||
#include "gimpparasitelist.h"
|
||||
#include "gimpselection.h"
|
||||
#include "gimpundostack.h"
|
||||
|
||||
#include "file/file-utils.h"
|
||||
|
@ -483,7 +484,6 @@ gimp_image_init (GimpImage *gimage)
|
|||
|
||||
gimage->floating_sel = NULL;
|
||||
gimage->selection_mask = NULL;
|
||||
gimage->mask_stroking = FALSE;
|
||||
|
||||
gimage->parasites = gimp_parasite_list_new ();
|
||||
|
||||
|
@ -851,9 +851,9 @@ gimp_image_new (Gimp *gimp,
|
|||
}
|
||||
|
||||
/* create the selection mask */
|
||||
gimage->selection_mask = gimp_channel_new_mask (gimage,
|
||||
gimage->width,
|
||||
gimage->height);
|
||||
gimage->selection_mask = gimp_selection_new (gimage,
|
||||
gimage->width,
|
||||
gimage->height);
|
||||
|
||||
g_signal_connect_object (gimp->config, "notify::transparency-type",
|
||||
G_CALLBACK (gimp_image_invalidate_layer_previews),
|
||||
|
|
|
@ -138,7 +138,6 @@ struct _GimpImage
|
|||
|
||||
GimpLayer *floating_sel; /* the FS layer */
|
||||
GimpChannel *selection_mask; /* the selection mask channel */
|
||||
gboolean mask_stroking; /* is a stroke being done */
|
||||
|
||||
GimpParasiteList *parasites; /* Plug-in parasite data */
|
||||
|
||||
|
|
|
@ -925,7 +925,7 @@ gimp_layer_create_mask (const GimpLayer *layer,
|
|||
return mask;
|
||||
|
||||
case GIMP_ADD_BLACK_MASK:
|
||||
gimp_channel_clear (GIMP_CHANNEL (mask), FALSE);
|
||||
gimp_channel_clear (GIMP_CHANNEL (mask), NULL, FALSE);
|
||||
return mask;
|
||||
|
||||
default:
|
||||
|
@ -973,7 +973,7 @@ gimp_layer_create_mask (const GimpLayer *layer,
|
|||
|
||||
if (copy_width < item->width || copy_height < item->height ||
|
||||
selection_empty)
|
||||
gimp_channel_clear (GIMP_CHANNEL (mask), FALSE);
|
||||
gimp_channel_clear (GIMP_CHANNEL (mask), NULL, FALSE);
|
||||
|
||||
if ((copy_width || copy_height) && ! selection_empty)
|
||||
{
|
||||
|
|
|
@ -255,5 +255,7 @@ gimp_scan_convert_to_channel (GimpScanConvert *sc,
|
|||
art_free (svp);
|
||||
art_free (pert_vpath);
|
||||
|
||||
mask->bounds_known = FALSE;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,586 @@
|
|||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "core-types.h"
|
||||
|
||||
#include "base/tile.h"
|
||||
#include "base/tile-manager.h"
|
||||
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimpimage-undo-push.h"
|
||||
#include "gimplayer.h"
|
||||
#include "gimplayer-floating-sel.h"
|
||||
#include "gimpselection.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
static void gimp_selection_class_init (GimpSelectionClass *klass);
|
||||
static void gimp_selection_init (GimpSelection *selection);
|
||||
|
||||
static void gimp_selection_translate (GimpItem *item,
|
||||
gint offset_x,
|
||||
gint offset_y,
|
||||
gboolean push_undo);
|
||||
static gboolean gimp_selection_stroke (GimpItem *item,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintInfo *paint_info);
|
||||
|
||||
static gboolean gimp_selection_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_selection_bounds (GimpChannel *channel,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2);
|
||||
static gint gimp_selection_value (GimpChannel *channel,
|
||||
gint x,
|
||||
gint y);
|
||||
static gboolean gimp_selection_is_empty (GimpChannel *channel);
|
||||
static void gimp_selection_feather (GimpChannel *channel,
|
||||
gdouble radius_x,
|
||||
gdouble radius_y,
|
||||
gboolean push_undo);
|
||||
static void gimp_selection_sharpen (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
static void gimp_selection_clear (GimpChannel *channel,
|
||||
const gchar *undo_desc,
|
||||
gboolean push_undo);
|
||||
static void gimp_selection_all (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
static void gimp_selection_invert (GimpChannel *channel,
|
||||
gboolean push_undo);
|
||||
static void gimp_selection_border (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
static void gimp_selection_grow (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo);
|
||||
static void gimp_selection_shrink (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean edge_lock,
|
||||
gboolean push_undo);
|
||||
|
||||
static void gimp_selection_changed (GimpSelection *selection);
|
||||
static void gimp_selection_validate (TileManager *tm,
|
||||
Tile *tile);
|
||||
|
||||
|
||||
static GimpChannelClass *parent_class = NULL;
|
||||
|
||||
|
||||
GType
|
||||
gimp_selection_get_type (void)
|
||||
{
|
||||
static GType selection_type = 0;
|
||||
|
||||
if (! selection_type)
|
||||
{
|
||||
static const GTypeInfo selection_info =
|
||||
{
|
||||
sizeof (GimpSelectionClass),
|
||||
(GBaseInitFunc) NULL,
|
||||
(GBaseFinalizeFunc) NULL,
|
||||
(GClassInitFunc) gimp_selection_class_init,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
sizeof (GimpSelection),
|
||||
0, /* n_preallocs */
|
||||
(GInstanceInitFunc) gimp_selection_init,
|
||||
};
|
||||
|
||||
selection_type = g_type_register_static (GIMP_TYPE_CHANNEL,
|
||||
"GimpSelection",
|
||||
&selection_info, 0);
|
||||
}
|
||||
|
||||
return selection_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_class_init (GimpSelectionClass *klass)
|
||||
{
|
||||
GimpItemClass *item_class;
|
||||
GimpChannelClass *channel_class;
|
||||
|
||||
item_class = GIMP_ITEM_CLASS (klass);
|
||||
channel_class = GIMP_CHANNEL_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
item_class->translate = gimp_selection_translate;
|
||||
item_class->stroke = gimp_selection_stroke;
|
||||
|
||||
channel_class->boundary = gimp_selection_boundary;
|
||||
channel_class->bounds = gimp_selection_bounds;
|
||||
channel_class->value = gimp_selection_value;
|
||||
channel_class->is_empty = gimp_selection_is_empty;
|
||||
channel_class->feather = gimp_selection_feather;
|
||||
channel_class->sharpen = gimp_selection_sharpen;
|
||||
channel_class->clear = gimp_selection_clear;
|
||||
channel_class->all = gimp_selection_all;
|
||||
channel_class->invert = gimp_selection_invert;
|
||||
channel_class->border = gimp_selection_border;
|
||||
channel_class->grow = gimp_selection_grow;
|
||||
channel_class->shrink = gimp_selection_shrink;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_init (GimpSelection *selection)
|
||||
{
|
||||
selection->stroking = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_translate (GimpItem *item,
|
||||
gint offset_x,
|
||||
gint offset_y,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (item);
|
||||
|
||||
if (push_undo)
|
||||
gimp_selection_push_undo (selection, _("Move Selection"));
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_ITEM_CLASS (parent_class)->translate (item, offset_x, offset_y, FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_selection_stroke (GimpItem *item,
|
||||
GimpDrawable *drawable,
|
||||
GimpPaintInfo *paint_info)
|
||||
{
|
||||
GimpSelection *selection;
|
||||
GimpImage *gimage;
|
||||
const BoundSeg *dummy_in;
|
||||
const BoundSeg *dummy_out;
|
||||
gint num_dummy_in;
|
||||
gint num_dummy_out;
|
||||
gboolean retval;
|
||||
|
||||
selection = GIMP_SELECTION (item);
|
||||
|
||||
if (! gimp_channel_boundary (GIMP_CHANNEL (selection),
|
||||
&dummy_in, &dummy_out,
|
||||
&num_dummy_in, &num_dummy_out,
|
||||
0, 0, 0, 0))
|
||||
{
|
||||
g_message (_("No selection to stroke."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gimage = gimp_item_get_image (item);
|
||||
|
||||
selection->stroking = TRUE;
|
||||
|
||||
gimp_image_undo_group_start (gimage, GIMP_UNDO_GROUP_PAINT,
|
||||
_("Stroke Selection"));
|
||||
|
||||
retval = GIMP_ITEM_CLASS (parent_class)->stroke (item, drawable, paint_info);
|
||||
|
||||
gimp_image_undo_group_end (gimage);
|
||||
|
||||
selection->stroking = FALSE;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_selection_boundary (GimpChannel *channel,
|
||||
const BoundSeg **segs_in,
|
||||
const BoundSeg **segs_out,
|
||||
gint *num_segs_in,
|
||||
gint *num_segs_out,
|
||||
gint unused1,
|
||||
gint unused2,
|
||||
gint unused3,
|
||||
gint unused4)
|
||||
{
|
||||
GimpImage *gimage;
|
||||
GimpDrawable *drawable;
|
||||
GimpLayer *layer;
|
||||
|
||||
gimage = gimp_item_get_image (GIMP_ITEM (channel));
|
||||
|
||||
if ((layer = gimp_image_floating_sel (gimage)))
|
||||
{
|
||||
/* If there is a floating selection, then
|
||||
* we need to do some slightly different boundaries.
|
||||
* Instead of inside and outside boundaries being defined
|
||||
* by the extents of the layer, the inside boundary (the one
|
||||
* that actually marches and is black/white) is the boundary of
|
||||
* the floating selection. The outside boundary (doesn't move,
|
||||
* is black/gray) is defined as the normal selection mask
|
||||
*/
|
||||
|
||||
/* Find the selection mask boundary */
|
||||
GIMP_CHANNEL_CLASS (parent_class)->boundary (channel,
|
||||
segs_in, segs_out,
|
||||
num_segs_in, num_segs_out,
|
||||
0, 0, 0, 0);
|
||||
|
||||
/* Find the floating selection boundary */
|
||||
*segs_in = floating_sel_boundary (layer, num_segs_in);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if ((drawable = gimp_image_active_drawable (gimage)) &&
|
||||
GIMP_IS_CHANNEL (drawable))
|
||||
{
|
||||
/* Otherwise, return the boundary...if a channel is active */
|
||||
|
||||
return GIMP_CHANNEL_CLASS (parent_class)->boundary (channel,
|
||||
segs_in, segs_out,
|
||||
num_segs_in,
|
||||
num_segs_out,
|
||||
0, 0,
|
||||
gimage->width,
|
||||
gimage->height);
|
||||
}
|
||||
else if ((layer = gimp_image_get_active_layer (gimage)))
|
||||
{
|
||||
/* If a layer is active, we return multiple boundaries based
|
||||
* on the extents
|
||||
*/
|
||||
|
||||
gint x1, y1;
|
||||
gint x2, y2;
|
||||
gint off_x, off_y;
|
||||
|
||||
gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y);
|
||||
|
||||
x1 = CLAMP (off_x, 0, gimage->width);
|
||||
y1 = CLAMP (off_y, 0, gimage->height);
|
||||
x2 = CLAMP (off_x + gimp_item_width (GIMP_ITEM (layer)), 0,
|
||||
gimage->width);
|
||||
y2 = CLAMP (off_y + gimp_item_height (GIMP_ITEM (layer)), 0,
|
||||
gimage->height);
|
||||
|
||||
return GIMP_CHANNEL_CLASS (parent_class)->boundary (channel,
|
||||
segs_in, segs_out,
|
||||
num_segs_in,
|
||||
num_segs_out,
|
||||
x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
*segs_in = NULL;
|
||||
*segs_out = NULL;
|
||||
*num_segs_in = 0;
|
||||
*num_segs_out = 0;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_selection_bounds (GimpChannel *channel,
|
||||
gint *x1,
|
||||
gint *y1,
|
||||
gint *x2,
|
||||
gint *y2)
|
||||
{
|
||||
return GIMP_CHANNEL_CLASS (parent_class)->bounds (channel, x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_selection_value (GimpChannel *channel,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
return GIMP_CHANNEL_CLASS (parent_class)->value (channel, x, y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_selection_is_empty (GimpChannel *channel)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
/* in order to allow stroking of selections, we need to pretend here
|
||||
* that the selection mask is empty so that it doesn't mask the paint
|
||||
* during the stroke operation.
|
||||
*/
|
||||
if (selection->stroking)
|
||||
return TRUE;
|
||||
|
||||
return GIMP_CHANNEL_CLASS (parent_class)->is_empty (channel);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_feather (GimpChannel *channel,
|
||||
gdouble radius_x,
|
||||
gdouble radius_y,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
if (push_undo)
|
||||
gimp_selection_push_undo (selection, _("Feather Selection"));
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_CHANNEL_CLASS (parent_class)->feather (channel, radius_x, radius_y,
|
||||
FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_sharpen (GimpChannel *channel,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
if (push_undo)
|
||||
gimp_selection_push_undo (selection, _("Sharpen Selection"));
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_CHANNEL_CLASS (parent_class)->sharpen (channel, FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_clear (GimpChannel *channel,
|
||||
const gchar *undo_desc,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
if (push_undo)
|
||||
{
|
||||
if (! undo_desc)
|
||||
undo_desc = _("Select None");
|
||||
|
||||
gimp_selection_push_undo (selection, undo_desc);
|
||||
}
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_CHANNEL_CLASS (parent_class)->clear (channel, NULL, FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_all (GimpChannel *channel,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
if (push_undo)
|
||||
gimp_selection_push_undo (selection, _("Select All"));
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_CHANNEL_CLASS (parent_class)->all (channel, FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_invert (GimpChannel *channel,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
if (push_undo)
|
||||
gimp_selection_push_undo (selection, _("Invert Selection"));
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_CHANNEL_CLASS (parent_class)->invert (channel, FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_border (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
if (push_undo)
|
||||
gimp_selection_push_undo (selection, _("Border Selection"));
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_CHANNEL_CLASS (parent_class)->border (channel, radius_x, radius_y,
|
||||
FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_grow (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
if (push_undo)
|
||||
gimp_selection_push_undo (selection, _("Grow Selection"));
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_CHANNEL_CLASS (parent_class)->grow (channel, radius_x, radius_y,
|
||||
FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_shrink (GimpChannel *channel,
|
||||
gint radius_x,
|
||||
gint radius_y,
|
||||
gboolean edge_lock,
|
||||
gboolean push_undo)
|
||||
{
|
||||
GimpSelection *selection = GIMP_SELECTION (channel);
|
||||
|
||||
if (push_undo)
|
||||
gimp_selection_push_undo (selection, _("Shrink Selection"));
|
||||
else
|
||||
gimp_selection_invalidate (selection);
|
||||
|
||||
GIMP_CHANNEL_CLASS (parent_class)->shrink (channel, radius_x, radius_y,
|
||||
edge_lock, FALSE);
|
||||
|
||||
gimp_selection_changed (selection);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_changed (GimpSelection *selection)
|
||||
{
|
||||
gimp_image_mask_changed (gimp_item_get_image (GIMP_ITEM (selection)));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_selection_validate (TileManager *tm,
|
||||
Tile *tile)
|
||||
{
|
||||
/* Set the contents of the tile to empty */
|
||||
memset (tile_data_pointer (tile, 0, 0),
|
||||
TRANSPARENT_OPACITY, tile_size (tile));
|
||||
}
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
GimpChannel *
|
||||
gimp_selection_new (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GimpRGB black = { 0.0, 0.0, 0.0, 0.5 };
|
||||
GimpChannel *channel;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (gimage), NULL);
|
||||
|
||||
channel = g_object_new (GIMP_TYPE_SELECTION, NULL);
|
||||
|
||||
gimp_drawable_configure (GIMP_DRAWABLE (channel),
|
||||
gimage,
|
||||
0, 0, width, height,
|
||||
GIMP_GRAY_IMAGE,
|
||||
_("Selection Mask"));
|
||||
|
||||
channel->color = black;
|
||||
channel->show_masked = TRUE;
|
||||
channel->x2 = width;
|
||||
channel->y2 = height;
|
||||
|
||||
/* Set the validate procedure */
|
||||
tile_manager_set_validate_proc (GIMP_DRAWABLE (channel)->tiles,
|
||||
gimp_selection_validate);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_selection_push_undo (GimpSelection *selection,
|
||||
const gchar *undo_desc)
|
||||
{
|
||||
GimpImage *gimage;
|
||||
|
||||
g_return_if_fail (GIMP_IS_SELECTION (selection));
|
||||
|
||||
gimage = gimp_item_get_image (GIMP_ITEM (selection));
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
gimp_image_undo_push_mask (gimage, undo_desc, GIMP_CHANNEL (selection));
|
||||
|
||||
gimp_selection_invalidate (selection);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_selection_invalidate (GimpSelection *selection)
|
||||
{
|
||||
GimpLayer *layer;
|
||||
GimpImage *gimage;
|
||||
|
||||
g_return_if_fail (GIMP_IS_SELECTION (selection));
|
||||
|
||||
gimage = gimp_item_get_image (GIMP_ITEM (selection));
|
||||
|
||||
g_return_if_fail (GIMP_IS_IMAGE (gimage));
|
||||
|
||||
/* Turn the current selection off */
|
||||
gimp_image_selection_control (gimage, GIMP_SELECTION_OFF);
|
||||
|
||||
GIMP_CHANNEL (selection)->boundary_known = FALSE;
|
||||
|
||||
/* If there is a floating selection, update it's area...
|
||||
* we need to do this since this selection mask can act as an additional
|
||||
* mask in the composition of the floating selection
|
||||
*/
|
||||
layer = gimp_image_get_active_layer (gimage);
|
||||
|
||||
if (layer && gimp_layer_is_floating_sel (layer))
|
||||
gimp_drawable_update (GIMP_DRAWABLE (layer),
|
||||
0, 0,
|
||||
GIMP_ITEM (layer)->width,
|
||||
GIMP_ITEM (layer)->height);
|
||||
|
||||
/* invalidate the preview */
|
||||
GIMP_DRAWABLE (selection)->preview_valid = FALSE;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/* The GIMP -- an image manipulation program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_SELECTION_H__
|
||||
#define __GIMP_SELECTION_H__
|
||||
|
||||
|
||||
#include "gimpchannel.h"
|
||||
|
||||
|
||||
#define GIMP_TYPE_SELECTION (gimp_selection_get_type ())
|
||||
#define GIMP_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SELECTION, GimpSelection))
|
||||
#define GIMP_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SELECTION, GimpSelectionClass))
|
||||
#define GIMP_IS_SELECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SELECTION))
|
||||
#define GIMP_IS_SELECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SELECTION))
|
||||
#define GIMP_SELECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SELECTION, GimpSelectionClass))
|
||||
|
||||
|
||||
typedef struct _GimpSelectionClass GimpSelectionClass;
|
||||
|
||||
struct _GimpSelection
|
||||
{
|
||||
GimpChannel parent_instance;
|
||||
|
||||
gboolean stroking;
|
||||
};
|
||||
|
||||
struct _GimpSelectionClass
|
||||
{
|
||||
GimpChannelClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType gimp_selection_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpChannel * gimp_selection_new (GimpImage *gimage,
|
||||
gint width,
|
||||
gint height);
|
||||
void gimp_selection_push_undo (GimpSelection *selection,
|
||||
const gchar *undo_desc);
|
||||
void gimp_selection_invalidate (GimpSelection *selection);
|
||||
|
||||
|
||||
#endif /* __GIMP_SELECTION_H__ */
|
|
@ -568,8 +568,6 @@ iscissors_convert (GimpIscissorsTool *iscissors,
|
|||
|
||||
iscissors->mask = gimp_scan_convert_to_channel (sc, gdisp->gimage);
|
||||
gimp_scan_convert_free (sc);
|
||||
|
||||
gimp_channel_invalidate_bounds (iscissors->mask);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "config/gimpcoreconfig.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpchannel.h"
|
||||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpdrawable.h"
|
||||
#include "core/gimpimage.h"
|
||||
|
@ -45,6 +44,7 @@
|
|||
#include "core/gimplayer-floating-sel.h"
|
||||
#include "core/gimplayermask.h"
|
||||
#include "core/gimpparasitelist.h"
|
||||
#include "core/gimpselection.h"
|
||||
#include "core/gimpunit.h"
|
||||
|
||||
#include "text/gimptextlayer.h"
|
||||
|
@ -61,46 +61,46 @@
|
|||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
static gboolean xcf_load_image_props (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static gboolean xcf_load_layer_props (XcfInfo *info,
|
||||
GimpImage *gimage,
|
||||
GimpLayer *layer,
|
||||
gboolean *apply_mask,
|
||||
gboolean *edit_mask,
|
||||
gboolean *show_mask);
|
||||
static gboolean xcf_load_channel_props (XcfInfo *info,
|
||||
GimpImage *gimage,
|
||||
GimpChannel *channel);
|
||||
static gboolean xcf_load_prop (XcfInfo *info,
|
||||
PropType *prop_type,
|
||||
guint32 *prop_size);
|
||||
static GimpLayer * xcf_load_layer (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static GimpChannel * xcf_load_channel (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static GimpLayerMask * xcf_load_layer_mask (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static gboolean xcf_load_hierarchy (XcfInfo *info,
|
||||
TileManager *tiles);
|
||||
static gboolean xcf_load_level (XcfInfo *info,
|
||||
TileManager *tiles);
|
||||
static gboolean xcf_load_tile (XcfInfo *info,
|
||||
Tile *tile);
|
||||
static gboolean xcf_load_tile_rle (XcfInfo *info,
|
||||
Tile *tile,
|
||||
gint data_length);
|
||||
static GimpParasite * xcf_load_parasite (XcfInfo *info);
|
||||
static gboolean xcf_load_old_paths (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static gboolean xcf_load_old_path (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static gboolean xcf_load_image_props (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static gboolean xcf_load_layer_props (XcfInfo *info,
|
||||
GimpImage *gimage,
|
||||
GimpLayer *layer,
|
||||
gboolean *apply_mask,
|
||||
gboolean *edit_mask,
|
||||
gboolean *show_mask);
|
||||
static gboolean xcf_load_channel_props (XcfInfo *info,
|
||||
GimpImage *gimage,
|
||||
GimpChannel **channel);
|
||||
static gboolean xcf_load_prop (XcfInfo *info,
|
||||
PropType *prop_type,
|
||||
guint32 *prop_size);
|
||||
static GimpLayer * xcf_load_layer (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static GimpChannel * xcf_load_channel (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static GimpLayerMask * xcf_load_layer_mask (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static gboolean xcf_load_hierarchy (XcfInfo *info,
|
||||
TileManager *tiles);
|
||||
static gboolean xcf_load_level (XcfInfo *info,
|
||||
TileManager *tiles);
|
||||
static gboolean xcf_load_tile (XcfInfo *info,
|
||||
Tile *tile);
|
||||
static gboolean xcf_load_tile_rle (XcfInfo *info,
|
||||
Tile *tile,
|
||||
gint data_length);
|
||||
static GimpParasite * xcf_load_parasite (XcfInfo *info);
|
||||
static gboolean xcf_load_old_paths (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
static gboolean xcf_load_old_path (XcfInfo *info,
|
||||
GimpImage *gimage);
|
||||
|
||||
#ifdef SWAP_FROM_FILE
|
||||
static gboolean xcf_swap_func (gint fd,
|
||||
Tile *tile,
|
||||
gint cmd,
|
||||
gpointer user_data);
|
||||
static gboolean xcf_swap_func (gint fd,
|
||||
Tile *tile,
|
||||
gint cmd,
|
||||
gpointer user_data);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -624,9 +624,9 @@ xcf_load_layer_props (XcfInfo *info,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
xcf_load_channel_props (XcfInfo *info,
|
||||
GimpImage *gimage,
|
||||
GimpChannel *channel)
|
||||
xcf_load_channel_props (XcfInfo *info,
|
||||
GimpImage *gimage,
|
||||
GimpChannel **channel)
|
||||
{
|
||||
PropType prop_type;
|
||||
guint32 prop_size;
|
||||
|
@ -641,20 +641,29 @@ xcf_load_channel_props (XcfInfo *info,
|
|||
case PROP_END:
|
||||
return TRUE;
|
||||
case PROP_ACTIVE_CHANNEL:
|
||||
info->active_channel = channel;
|
||||
info->active_channel = *channel;
|
||||
break;
|
||||
case PROP_SELECTION:
|
||||
g_object_unref (gimage->selection_mask);
|
||||
gimage->selection_mask = channel;
|
||||
channel->boundary_known = FALSE;
|
||||
channel->bounds_known = FALSE;
|
||||
gimage->selection_mask =
|
||||
gimp_selection_new (gimage,
|
||||
gimp_item_width (GIMP_ITEM (*channel)),
|
||||
gimp_item_height (GIMP_ITEM (*channel)));
|
||||
tile_manager_unref (GIMP_DRAWABLE (gimage->selection_mask)->tiles);
|
||||
GIMP_DRAWABLE (gimage->selection_mask)->tiles =
|
||||
GIMP_DRAWABLE (*channel)->tiles;
|
||||
GIMP_DRAWABLE (*channel)->tiles = NULL;
|
||||
g_object_unref (*channel);
|
||||
*channel = gimage->selection_mask;
|
||||
(*channel)->boundary_known = FALSE;
|
||||
(*channel)->bounds_known = FALSE;
|
||||
break;
|
||||
case PROP_OPACITY:
|
||||
{
|
||||
guint32 opacity;
|
||||
|
||||
info->cp += xcf_read_int32 (info->fp, &opacity, 1);
|
||||
channel->color.a = opacity / 255.0;
|
||||
(*channel)->color.a = opacity / 255.0;
|
||||
}
|
||||
break;
|
||||
case PROP_VISIBLE:
|
||||
|
@ -662,7 +671,7 @@ xcf_load_channel_props (XcfInfo *info,
|
|||
gboolean visible;
|
||||
|
||||
info->cp += xcf_read_int32 (info->fp, (guint32 *) &visible, 1);
|
||||
gimp_drawable_set_visible (GIMP_DRAWABLE (channel),
|
||||
gimp_drawable_set_visible (GIMP_DRAWABLE (*channel),
|
||||
visible ? TRUE : FALSE, FALSE);
|
||||
}
|
||||
break;
|
||||
|
@ -671,13 +680,17 @@ xcf_load_channel_props (XcfInfo *info,
|
|||
gboolean linked;
|
||||
|
||||
info->cp += xcf_read_int32 (info->fp, (guint32 *) &linked, 1);
|
||||
gimp_item_set_linked (GIMP_ITEM (channel),
|
||||
gimp_item_set_linked (GIMP_ITEM (*channel),
|
||||
linked ? TRUE : FALSE, FALSE);
|
||||
}
|
||||
break;
|
||||
case PROP_SHOW_MASKED:
|
||||
info->cp +=
|
||||
xcf_read_int32 (info->fp, (guint32 *) &channel->show_masked, 1);
|
||||
{
|
||||
gboolean show_masked;
|
||||
|
||||
info->cp += xcf_read_int32 (info->fp, (guint32 *) &show_masked, 1);
|
||||
gimp_channel_set_show_masked (*channel, show_masked);
|
||||
}
|
||||
break;
|
||||
case PROP_COLOR:
|
||||
{
|
||||
|
@ -685,13 +698,12 @@ xcf_load_channel_props (XcfInfo *info,
|
|||
|
||||
info->cp += xcf_read_int8 (info->fp, (guint8 *) col, 3);
|
||||
|
||||
gimp_rgb_set_uchar (&channel->color, col[0], col[1], col[2]);
|
||||
|
||||
gimp_rgb_set_uchar (&(*channel)->color, col[0], col[1], col[2]);
|
||||
}
|
||||
break;
|
||||
case PROP_TATTOO:
|
||||
info->cp +=
|
||||
xcf_read_int32 (info->fp, &GIMP_ITEM (channel)->tattoo, 1);
|
||||
xcf_read_int32 (info->fp, &GIMP_ITEM (*channel)->tattoo, 1);
|
||||
break;
|
||||
case PROP_PARASITES:
|
||||
{
|
||||
|
@ -701,7 +713,7 @@ xcf_load_channel_props (XcfInfo *info,
|
|||
while ((info->cp - base) < prop_size)
|
||||
{
|
||||
p = xcf_load_parasite (info);
|
||||
gimp_item_parasite_attach (GIMP_ITEM (channel), p);
|
||||
gimp_item_parasite_attach (GIMP_ITEM (*channel), p);
|
||||
gimp_parasite_free (p);
|
||||
}
|
||||
if (info->cp - base != prop_size)
|
||||
|
@ -896,7 +908,7 @@ xcf_load_channel (XcfInfo *info,
|
|||
return NULL;
|
||||
|
||||
/* read in the channel properties */
|
||||
if (!xcf_load_channel_props (info, gimage, channel))
|
||||
if (!xcf_load_channel_props (info, gimage, &channel))
|
||||
goto error;
|
||||
|
||||
/* read the hierarchy and layer mask offsets */
|
||||
|
@ -958,7 +970,7 @@ xcf_load_layer_mask (XcfInfo *info,
|
|||
return NULL;
|
||||
|
||||
/* read in the layer_mask properties */
|
||||
if (!xcf_load_channel_props (info, gimage, GIMP_CHANNEL (layer_mask)))
|
||||
if (!xcf_load_channel_props (info, gimage, (GimpChannel **) &layer_mask))
|
||||
goto error;
|
||||
|
||||
/* read the hierarchy and layer mask offsets */
|
||||
|
|
Loading…
Reference in New Issue