enabled the (commented out) signal "invalidate_preview".

2000-05-12  Sven Neumann  <sven@gimp.org>

* gimpdrawable.c: enabled the (commented out) signal
  "invalidate_preview".

* app/layers_dialog.c: connect to the "invalidate_preview"
  signal to catch changes that need to be shown in the layer
  previews. Synthetize an expose event when a layer changes.

  Expose events are optimzed away by GTK+ if the widget is not
  visible. Therefore, previews not visible in the layers_dialog
  are not redrawn when they invalidate. Later the preview gets
  validated by the image_preview in lc_dialog but is never
  propagated to the layer_pixmap. We work around this by using an
  additional flag "layer_pixmap_valid" so that the pixmap gets
  updated once the preview scrolls into sight.

  Fixes bugs #10549, #10300 and #8787.

* app/channel.[ch]
* app/layer.[ch]: code review and indentation


--Sven
This commit is contained in:
Sven Neumann 2000-05-12 17:07:54 +00:00 committed by Sven Neumann
parent 5b98ce93c1
commit b101e7bc85
19 changed files with 1681 additions and 950 deletions

View File

@ -1,3 +1,32 @@
2000-05-12 Sven Neumann <sven@gimp.org>
* gimpdrawable.c: enabled the (commented out) signal
"invalidate_preview".
* app/layers_dialog.c: connect to the "invalidate_preview"
signal to catch changes that need to be shown in the layer
previews. Synthetize an expose event when a layer changes.
Expose events are optimzed away by GTK+ if the widget is not
visible. Therefore, previews not visible in the layers_dialog
are not redrawn when they invalidate. Later the preview gets
validated by the image_preview in lc_dialog but is never
propagated to the layer_pixmap. We work around this by using an
additional flag "layer_pixmap_valid" so that the pixmap gets
updated once the preview scrolls into sight.
We should probably do the same for all drawables (masks,
channels), but it is much more difficult to change one of these
when it's not visible.
In other words: This is an awful hack but otherwise I would have
had to rewrite it all....
Fixes bugs #10549, #10300 and #8787.
* app/channel.[ch]
* app/layer.[ch]: code review and indentation
2000-05-12 Michael Natterer <mitch@gimp.org>
* libgimp/gimp.c (gimp_plugin_io_error_handler): fixed a

View File

@ -238,7 +238,7 @@ channel_get_name (Channel *channel)
void
channel_set_color (Channel *channel,
guchar *color)
guchar *color)
{
gint i;
@ -315,7 +315,7 @@ gimp_channel_destroy (GtkObject *object)
* particular layer. */
void
channel_removed (Channel *channel,
gpointer image)
gpointer data)
{
g_return_if_fail (channel != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (channel));
@ -592,9 +592,10 @@ channel_get_tattoo (const Channel *channel)
}
void
channel_set_tattoo (const Channel *channel, Tattoo val)
channel_set_tattoo (const Channel *channel,
Tattoo value)
{
gimp_drawable_set_tattoo(GIMP_DRAWABLE (channel),val);
gimp_drawable_set_tattoo (GIMP_DRAWABLE (channel), value);
}
/******************************/
@ -602,7 +603,7 @@ channel_set_tattoo (const Channel *channel, Tattoo val)
/******************************/
Channel *
channel_new_mask (GimpImage* gimage,
channel_new_mask (GimpImage *gimage,
gint width,
gint height)
{
@ -731,9 +732,9 @@ channel_bounds (Channel *mask,
guchar *data, *data1;
gint x, y;
gint ex, ey;
void *pr;
gint tx1, tx2, ty1, ty2;
gint minx, maxx;
gpointer pr;
/* if the mask's bounds have already been reliably calculated... */
if (mask->bounds_known)
@ -840,7 +841,7 @@ channel_is_empty (Channel *mask)
PixelRegion maskPR;
guchar * data;
gint x, y;
void * pr;
gpointer pr;
if (mask->bounds_known)
return mask->empty;
@ -896,7 +897,7 @@ channel_add_segment (Channel *mask,
guchar *data;
gint val;
gint x2;
void * pr;
gpointer pr;
/* check horizontal extents... */
x2 = x + width;
@ -939,7 +940,7 @@ channel_sub_segment (Channel *mask,
guchar *data;
gint val;
gint x2;
void * pr;
gpointer pr;
/* check horizontal extents... */
x2 = x + width;
@ -1037,7 +1038,7 @@ channel_combine_ellipse (Channel *mask,
gint y,
gint w,
gint h,
gboolean aa /* antialias selection? */)
gboolean antialias)
{
gint i, j;
gint x0, x1, x2;
@ -1066,7 +1067,7 @@ channel_combine_ellipse (Channel *mask,
if (i >= 0 && i < GIMP_DRAWABLE (mask)->height)
{
/* Non-antialiased code */
if (!aa)
if (!antialias)
{
y_sqr = (i + 0.5 - cy) * (i + 0.5 - cy);
rad = sqrt (a_sqr - a_sqr * y_sqr / (double) b_sqr);
@ -1754,3 +1755,4 @@ channel_invalidate_bounds (Channel *channel)
{
channel->bounds_known = FALSE;
}

View File

@ -71,80 +71,138 @@ struct _MaskUndo
/* function declarations */
Channel * channel_new (GimpImage*,
gint, gint, gchar *, gint, guchar *);
Channel * channel_copy (Channel *);
Channel * channel_ref (Channel *);
void channel_unref (Channel *);
Channel * channel_new (GimpImage *gimage,
gint width,
gint height,
gchar *name,
gint opacity,
guchar *col);
Channel * channel_copy (Channel *channel);
Channel * channel_ref (Channel *channel);
void channel_unref (Channel *channel);
gchar * channel_get_name (Channel *);
void channel_set_name (Channel *, gchar *);
gchar * channel_get_name (Channel *channel);
void channel_set_name (Channel *channel,
gchar *name);
gint channel_get_opacity (Channel *);
void channel_set_opacity (Channel *, gint);
gint channel_get_opacity (Channel *channel);
void channel_set_opacity (Channel *channel,
gint opacity);
guchar * channel_get_color (Channel *);
void channel_set_color (Channel *, guchar *);
guchar * channel_get_color (Channel *channel);
void channel_set_color (Channel *channel,
guchar *color);
Channel * channel_get_ID (gint);
void channel_delete (Channel *);
void channel_removed (Channel *, gpointer);
void channel_scale (Channel *, gint, gint);
void channel_resize (Channel *, gint, gint, gint, gint);
void channel_update (Channel *);
Channel * channel_get_ID (gint ID);
void channel_delete (Channel *channel);
void channel_removed (Channel *channel,
gpointer data);
void channel_scale (Channel *channel,
gint new_width,
gint new_height);
void channel_resize (Channel *channel,
gint new_width,
gint new_height,
gint offx,
gint offy);
void channel_update (Channel *channel);
/* access functions */
gboolean channel_toggle_visibility (Channel *);
TempBuf * channel_preview (Channel *, gint, gint);
gboolean channel_toggle_visibility (Channel *channel);
TempBuf * channel_preview (Channel *channel,
gint width,
gint height);
void channel_invalidate_previews (GimpImage*);
Tattoo channel_get_tattoo (const Channel *);
void channel_set_tattoo (const Channel *,Tattoo);
void channel_invalidate_previews (GimpImage *gimage);
Tattoo channel_get_tattoo (const Channel *channel);
void channel_set_tattoo (const Channel *channel,
Tattoo value);
/* selection mask functions */
Channel * channel_new_mask (GimpImage *, gint, gint);
gboolean channel_boundary (Channel *, BoundSeg **, BoundSeg **,
gint *, gint *, gint, gint, gint, gint);
gboolean channel_bounds (Channel *,
gint *, gint *, gint *, gint *);
gint channel_value (Channel *, gint, gint);
gboolean channel_is_empty (Channel *);
void channel_add_segment (Channel *, gint, gint, gint, gint);
void channel_sub_segment (Channel *, gint, gint, gint, gint);
void channel_inter_segment (Channel *, gint, gint, gint, gint);
void channel_combine_rect (Channel *,
ChannelOps, gint, gint, gint, gint);
void channel_combine_ellipse (Channel *,
ChannelOps,
gint, gint, gint, gint, gboolean);
void channel_combine_mask (Channel *, Channel *,
ChannelOps, gint, gint);
void channel_feather (Channel *, Channel *,
gdouble, gdouble,
ChannelOps, gint, gint);
void channel_push_undo (Channel *);
void channel_clear (Channel *);
void channel_invert (Channel *);
void channel_sharpen (Channel *);
void channel_all (Channel *);
Channel * channel_new_mask (GimpImage *gimage,
gint width,
gint height);
gboolean channel_boundary (Channel *mask,
BoundSeg **segs_in,
BoundSeg **segs_out,
gint *num_segs_in,
gint *num_segs_out,
gint x1,
gint y1,
gint x2,
gint y2);
gboolean channel_bounds (Channel *mask,
gint *x1,
gint *y1,
gint *x2,
gint *y2);
gint channel_value (Channel *mask,
gint x,
gint y);
gboolean channel_is_empty (Channel *mask);
void channel_add_segment (Channel *mask,
gint x,
gint y,
gint width,
gint value);
void channel_sub_segment (Channel *mask,
gint x,
gint y,
gint width,
gint value);
void channel_combine_rect (Channel *mask,
ChannelOps op,
gint x,
gint y,
gint w,
gint h);
void channel_combine_ellipse (Channel *mask,
ChannelOps op,
gint x,
gint y,
gint w,
gint h,
gboolean antialias);
void channel_combine_mask (Channel *mask,
Channel *add_on,
ChannelOps op,
gint off_x,
gint off_y);
void channel_feather (Channel *input,
Channel *output,
gdouble radius_x,
gdouble radius_y,
ChannelOps op,
gint off_x,
gint off_y);
void channel_border (Channel * channel,
gint radius_x,
gint radius_y);
void channel_grow (Channel * channel,
gint radius_x,
gint radius_y);
void channel_shrink (Channel * channel,
gint radius_x,
gint radius_y,
gboolean edge_lock);
void channel_push_undo (Channel *mask);
void channel_clear (Channel *mask);
void channel_invert (Channel *mask);
void channel_sharpen (Channel *mask);
void channel_all (Channel *mask);
void channel_translate (Channel *, gint, gint);
void channel_load (Channel *, Channel *);
void channel_border (Channel *mask,
gint radius_x,
gint radius_y);
void channel_grow (Channel *mask,
gint radius_x,
gint radius_y);
void channel_shrink (Channel *mask,
gint radius_x,
gint radius_y,
gboolean edge_lock);
void channel_invalidate_bounds (Channel *);
void channel_translate (Channel *mask,
gint off_x,
gint off_y);
void channel_load (Channel *mask,
Channel *channel);
void channel_invalidate_bounds (Channel *channel);
#define drawable_channel GIMP_IS_CHANNEL

View File

@ -238,7 +238,7 @@ channel_get_name (Channel *channel)
void
channel_set_color (Channel *channel,
guchar *color)
guchar *color)
{
gint i;
@ -315,7 +315,7 @@ gimp_channel_destroy (GtkObject *object)
* particular layer. */
void
channel_removed (Channel *channel,
gpointer image)
gpointer data)
{
g_return_if_fail (channel != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (channel));
@ -592,9 +592,10 @@ channel_get_tattoo (const Channel *channel)
}
void
channel_set_tattoo (const Channel *channel, Tattoo val)
channel_set_tattoo (const Channel *channel,
Tattoo value)
{
gimp_drawable_set_tattoo(GIMP_DRAWABLE (channel),val);
gimp_drawable_set_tattoo (GIMP_DRAWABLE (channel), value);
}
/******************************/
@ -602,7 +603,7 @@ channel_set_tattoo (const Channel *channel, Tattoo val)
/******************************/
Channel *
channel_new_mask (GimpImage* gimage,
channel_new_mask (GimpImage *gimage,
gint width,
gint height)
{
@ -731,9 +732,9 @@ channel_bounds (Channel *mask,
guchar *data, *data1;
gint x, y;
gint ex, ey;
void *pr;
gint tx1, tx2, ty1, ty2;
gint minx, maxx;
gpointer pr;
/* if the mask's bounds have already been reliably calculated... */
if (mask->bounds_known)
@ -840,7 +841,7 @@ channel_is_empty (Channel *mask)
PixelRegion maskPR;
guchar * data;
gint x, y;
void * pr;
gpointer pr;
if (mask->bounds_known)
return mask->empty;
@ -896,7 +897,7 @@ channel_add_segment (Channel *mask,
guchar *data;
gint val;
gint x2;
void * pr;
gpointer pr;
/* check horizontal extents... */
x2 = x + width;
@ -939,7 +940,7 @@ channel_sub_segment (Channel *mask,
guchar *data;
gint val;
gint x2;
void * pr;
gpointer pr;
/* check horizontal extents... */
x2 = x + width;
@ -1037,7 +1038,7 @@ channel_combine_ellipse (Channel *mask,
gint y,
gint w,
gint h,
gboolean aa /* antialias selection? */)
gboolean antialias)
{
gint i, j;
gint x0, x1, x2;
@ -1066,7 +1067,7 @@ channel_combine_ellipse (Channel *mask,
if (i >= 0 && i < GIMP_DRAWABLE (mask)->height)
{
/* Non-antialiased code */
if (!aa)
if (!antialias)
{
y_sqr = (i + 0.5 - cy) * (i + 0.5 - cy);
rad = sqrt (a_sqr - a_sqr * y_sqr / (double) b_sqr);
@ -1754,3 +1755,4 @@ channel_invalidate_bounds (Channel *channel)
{
channel->bounds_known = FALSE;
}

View File

@ -71,80 +71,138 @@ struct _MaskUndo
/* function declarations */
Channel * channel_new (GimpImage*,
gint, gint, gchar *, gint, guchar *);
Channel * channel_copy (Channel *);
Channel * channel_ref (Channel *);
void channel_unref (Channel *);
Channel * channel_new (GimpImage *gimage,
gint width,
gint height,
gchar *name,
gint opacity,
guchar *col);
Channel * channel_copy (Channel *channel);
Channel * channel_ref (Channel *channel);
void channel_unref (Channel *channel);
gchar * channel_get_name (Channel *);
void channel_set_name (Channel *, gchar *);
gchar * channel_get_name (Channel *channel);
void channel_set_name (Channel *channel,
gchar *name);
gint channel_get_opacity (Channel *);
void channel_set_opacity (Channel *, gint);
gint channel_get_opacity (Channel *channel);
void channel_set_opacity (Channel *channel,
gint opacity);
guchar * channel_get_color (Channel *);
void channel_set_color (Channel *, guchar *);
guchar * channel_get_color (Channel *channel);
void channel_set_color (Channel *channel,
guchar *color);
Channel * channel_get_ID (gint);
void channel_delete (Channel *);
void channel_removed (Channel *, gpointer);
void channel_scale (Channel *, gint, gint);
void channel_resize (Channel *, gint, gint, gint, gint);
void channel_update (Channel *);
Channel * channel_get_ID (gint ID);
void channel_delete (Channel *channel);
void channel_removed (Channel *channel,
gpointer data);
void channel_scale (Channel *channel,
gint new_width,
gint new_height);
void channel_resize (Channel *channel,
gint new_width,
gint new_height,
gint offx,
gint offy);
void channel_update (Channel *channel);
/* access functions */
gboolean channel_toggle_visibility (Channel *);
TempBuf * channel_preview (Channel *, gint, gint);
gboolean channel_toggle_visibility (Channel *channel);
TempBuf * channel_preview (Channel *channel,
gint width,
gint height);
void channel_invalidate_previews (GimpImage*);
Tattoo channel_get_tattoo (const Channel *);
void channel_set_tattoo (const Channel *,Tattoo);
void channel_invalidate_previews (GimpImage *gimage);
Tattoo channel_get_tattoo (const Channel *channel);
void channel_set_tattoo (const Channel *channel,
Tattoo value);
/* selection mask functions */
Channel * channel_new_mask (GimpImage *, gint, gint);
gboolean channel_boundary (Channel *, BoundSeg **, BoundSeg **,
gint *, gint *, gint, gint, gint, gint);
gboolean channel_bounds (Channel *,
gint *, gint *, gint *, gint *);
gint channel_value (Channel *, gint, gint);
gboolean channel_is_empty (Channel *);
void channel_add_segment (Channel *, gint, gint, gint, gint);
void channel_sub_segment (Channel *, gint, gint, gint, gint);
void channel_inter_segment (Channel *, gint, gint, gint, gint);
void channel_combine_rect (Channel *,
ChannelOps, gint, gint, gint, gint);
void channel_combine_ellipse (Channel *,
ChannelOps,
gint, gint, gint, gint, gboolean);
void channel_combine_mask (Channel *, Channel *,
ChannelOps, gint, gint);
void channel_feather (Channel *, Channel *,
gdouble, gdouble,
ChannelOps, gint, gint);
void channel_push_undo (Channel *);
void channel_clear (Channel *);
void channel_invert (Channel *);
void channel_sharpen (Channel *);
void channel_all (Channel *);
Channel * channel_new_mask (GimpImage *gimage,
gint width,
gint height);
gboolean channel_boundary (Channel *mask,
BoundSeg **segs_in,
BoundSeg **segs_out,
gint *num_segs_in,
gint *num_segs_out,
gint x1,
gint y1,
gint x2,
gint y2);
gboolean channel_bounds (Channel *mask,
gint *x1,
gint *y1,
gint *x2,
gint *y2);
gint channel_value (Channel *mask,
gint x,
gint y);
gboolean channel_is_empty (Channel *mask);
void channel_add_segment (Channel *mask,
gint x,
gint y,
gint width,
gint value);
void channel_sub_segment (Channel *mask,
gint x,
gint y,
gint width,
gint value);
void channel_combine_rect (Channel *mask,
ChannelOps op,
gint x,
gint y,
gint w,
gint h);
void channel_combine_ellipse (Channel *mask,
ChannelOps op,
gint x,
gint y,
gint w,
gint h,
gboolean antialias);
void channel_combine_mask (Channel *mask,
Channel *add_on,
ChannelOps op,
gint off_x,
gint off_y);
void channel_feather (Channel *input,
Channel *output,
gdouble radius_x,
gdouble radius_y,
ChannelOps op,
gint off_x,
gint off_y);
void channel_border (Channel * channel,
gint radius_x,
gint radius_y);
void channel_grow (Channel * channel,
gint radius_x,
gint radius_y);
void channel_shrink (Channel * channel,
gint radius_x,
gint radius_y,
gboolean edge_lock);
void channel_push_undo (Channel *mask);
void channel_clear (Channel *mask);
void channel_invert (Channel *mask);
void channel_sharpen (Channel *mask);
void channel_all (Channel *mask);
void channel_translate (Channel *, gint, gint);
void channel_load (Channel *, Channel *);
void channel_border (Channel *mask,
gint radius_x,
gint radius_y);
void channel_grow (Channel *mask,
gint radius_x,
gint radius_y);
void channel_shrink (Channel *mask,
gint radius_x,
gint radius_y,
gboolean edge_lock);
void channel_invalidate_bounds (Channel *);
void channel_translate (Channel *mask,
gint off_x,
gint off_y);
void channel_load (Channel *mask,
Channel *channel);
void channel_invalidate_bounds (Channel *channel);
#define drawable_channel GIMP_IS_CHANNEL

View File

@ -238,7 +238,7 @@ channel_get_name (Channel *channel)
void
channel_set_color (Channel *channel,
guchar *color)
guchar *color)
{
gint i;
@ -315,7 +315,7 @@ gimp_channel_destroy (GtkObject *object)
* particular layer. */
void
channel_removed (Channel *channel,
gpointer image)
gpointer data)
{
g_return_if_fail (channel != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (channel));
@ -592,9 +592,10 @@ channel_get_tattoo (const Channel *channel)
}
void
channel_set_tattoo (const Channel *channel, Tattoo val)
channel_set_tattoo (const Channel *channel,
Tattoo value)
{
gimp_drawable_set_tattoo(GIMP_DRAWABLE (channel),val);
gimp_drawable_set_tattoo (GIMP_DRAWABLE (channel), value);
}
/******************************/
@ -602,7 +603,7 @@ channel_set_tattoo (const Channel *channel, Tattoo val)
/******************************/
Channel *
channel_new_mask (GimpImage* gimage,
channel_new_mask (GimpImage *gimage,
gint width,
gint height)
{
@ -731,9 +732,9 @@ channel_bounds (Channel *mask,
guchar *data, *data1;
gint x, y;
gint ex, ey;
void *pr;
gint tx1, tx2, ty1, ty2;
gint minx, maxx;
gpointer pr;
/* if the mask's bounds have already been reliably calculated... */
if (mask->bounds_known)
@ -840,7 +841,7 @@ channel_is_empty (Channel *mask)
PixelRegion maskPR;
guchar * data;
gint x, y;
void * pr;
gpointer pr;
if (mask->bounds_known)
return mask->empty;
@ -896,7 +897,7 @@ channel_add_segment (Channel *mask,
guchar *data;
gint val;
gint x2;
void * pr;
gpointer pr;
/* check horizontal extents... */
x2 = x + width;
@ -939,7 +940,7 @@ channel_sub_segment (Channel *mask,
guchar *data;
gint val;
gint x2;
void * pr;
gpointer pr;
/* check horizontal extents... */
x2 = x + width;
@ -1037,7 +1038,7 @@ channel_combine_ellipse (Channel *mask,
gint y,
gint w,
gint h,
gboolean aa /* antialias selection? */)
gboolean antialias)
{
gint i, j;
gint x0, x1, x2;
@ -1066,7 +1067,7 @@ channel_combine_ellipse (Channel *mask,
if (i >= 0 && i < GIMP_DRAWABLE (mask)->height)
{
/* Non-antialiased code */
if (!aa)
if (!antialias)
{
y_sqr = (i + 0.5 - cy) * (i + 0.5 - cy);
rad = sqrt (a_sqr - a_sqr * y_sqr / (double) b_sqr);
@ -1754,3 +1755,4 @@ channel_invalidate_bounds (Channel *channel)
{
channel->bounds_known = FALSE;
}

View File

@ -71,80 +71,138 @@ struct _MaskUndo
/* function declarations */
Channel * channel_new (GimpImage*,
gint, gint, gchar *, gint, guchar *);
Channel * channel_copy (Channel *);
Channel * channel_ref (Channel *);
void channel_unref (Channel *);
Channel * channel_new (GimpImage *gimage,
gint width,
gint height,
gchar *name,
gint opacity,
guchar *col);
Channel * channel_copy (Channel *channel);
Channel * channel_ref (Channel *channel);
void channel_unref (Channel *channel);
gchar * channel_get_name (Channel *);
void channel_set_name (Channel *, gchar *);
gchar * channel_get_name (Channel *channel);
void channel_set_name (Channel *channel,
gchar *name);
gint channel_get_opacity (Channel *);
void channel_set_opacity (Channel *, gint);
gint channel_get_opacity (Channel *channel);
void channel_set_opacity (Channel *channel,
gint opacity);
guchar * channel_get_color (Channel *);
void channel_set_color (Channel *, guchar *);
guchar * channel_get_color (Channel *channel);
void channel_set_color (Channel *channel,
guchar *color);
Channel * channel_get_ID (gint);
void channel_delete (Channel *);
void channel_removed (Channel *, gpointer);
void channel_scale (Channel *, gint, gint);
void channel_resize (Channel *, gint, gint, gint, gint);
void channel_update (Channel *);
Channel * channel_get_ID (gint ID);
void channel_delete (Channel *channel);
void channel_removed (Channel *channel,
gpointer data);
void channel_scale (Channel *channel,
gint new_width,
gint new_height);
void channel_resize (Channel *channel,
gint new_width,
gint new_height,
gint offx,
gint offy);
void channel_update (Channel *channel);
/* access functions */
gboolean channel_toggle_visibility (Channel *);
TempBuf * channel_preview (Channel *, gint, gint);
gboolean channel_toggle_visibility (Channel *channel);
TempBuf * channel_preview (Channel *channel,
gint width,
gint height);
void channel_invalidate_previews (GimpImage*);
Tattoo channel_get_tattoo (const Channel *);
void channel_set_tattoo (const Channel *,Tattoo);
void channel_invalidate_previews (GimpImage *gimage);
Tattoo channel_get_tattoo (const Channel *channel);
void channel_set_tattoo (const Channel *channel,
Tattoo value);
/* selection mask functions */
Channel * channel_new_mask (GimpImage *, gint, gint);
gboolean channel_boundary (Channel *, BoundSeg **, BoundSeg **,
gint *, gint *, gint, gint, gint, gint);
gboolean channel_bounds (Channel *,
gint *, gint *, gint *, gint *);
gint channel_value (Channel *, gint, gint);
gboolean channel_is_empty (Channel *);
void channel_add_segment (Channel *, gint, gint, gint, gint);
void channel_sub_segment (Channel *, gint, gint, gint, gint);
void channel_inter_segment (Channel *, gint, gint, gint, gint);
void channel_combine_rect (Channel *,
ChannelOps, gint, gint, gint, gint);
void channel_combine_ellipse (Channel *,
ChannelOps,
gint, gint, gint, gint, gboolean);
void channel_combine_mask (Channel *, Channel *,
ChannelOps, gint, gint);
void channel_feather (Channel *, Channel *,
gdouble, gdouble,
ChannelOps, gint, gint);
void channel_push_undo (Channel *);
void channel_clear (Channel *);
void channel_invert (Channel *);
void channel_sharpen (Channel *);
void channel_all (Channel *);
Channel * channel_new_mask (GimpImage *gimage,
gint width,
gint height);
gboolean channel_boundary (Channel *mask,
BoundSeg **segs_in,
BoundSeg **segs_out,
gint *num_segs_in,
gint *num_segs_out,
gint x1,
gint y1,
gint x2,
gint y2);
gboolean channel_bounds (Channel *mask,
gint *x1,
gint *y1,
gint *x2,
gint *y2);
gint channel_value (Channel *mask,
gint x,
gint y);
gboolean channel_is_empty (Channel *mask);
void channel_add_segment (Channel *mask,
gint x,
gint y,
gint width,
gint value);
void channel_sub_segment (Channel *mask,
gint x,
gint y,
gint width,
gint value);
void channel_combine_rect (Channel *mask,
ChannelOps op,
gint x,
gint y,
gint w,
gint h);
void channel_combine_ellipse (Channel *mask,
ChannelOps op,
gint x,
gint y,
gint w,
gint h,
gboolean antialias);
void channel_combine_mask (Channel *mask,
Channel *add_on,
ChannelOps op,
gint off_x,
gint off_y);
void channel_feather (Channel *input,
Channel *output,
gdouble radius_x,
gdouble radius_y,
ChannelOps op,
gint off_x,
gint off_y);
void channel_border (Channel * channel,
gint radius_x,
gint radius_y);
void channel_grow (Channel * channel,
gint radius_x,
gint radius_y);
void channel_shrink (Channel * channel,
gint radius_x,
gint radius_y,
gboolean edge_lock);
void channel_push_undo (Channel *mask);
void channel_clear (Channel *mask);
void channel_invert (Channel *mask);
void channel_sharpen (Channel *mask);
void channel_all (Channel *mask);
void channel_translate (Channel *, gint, gint);
void channel_load (Channel *, Channel *);
void channel_border (Channel *mask,
gint radius_x,
gint radius_y);
void channel_grow (Channel *mask,
gint radius_x,
gint radius_y);
void channel_shrink (Channel *mask,
gint radius_x,
gint radius_y,
gboolean edge_lock);
void channel_invalidate_bounds (Channel *);
void channel_translate (Channel *mask,
gint off_x,
gint off_y);
void channel_load (Channel *mask,
Channel *channel);
void channel_invalidate_bounds (Channel *channel);
#define drawable_channel GIMP_IS_CHANNEL

View File

@ -217,10 +217,8 @@ gimp_drawable_invalidate_preview (GimpDrawable *drawable)
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
drawable->preview_valid = FALSE;
#if 0
gtk_signal_emit (GTK_OBJECT (drawable),
gimp_drawable_signals[INVALIDATE_PREVIEW]);
#endif
gimage = gimp_drawable_gimage (drawable);
if (gimage)
{

View File

@ -53,7 +53,7 @@ enum {
static void gimp_layer_class_init (GimpLayerClass *klass);
static void gimp_layer_init (GimpLayer *layer);
static void gimp_layer_destroy (GtkObject *object);
static void layer_invalidate_preview (GtkObject *);
static void layer_invalidate_preview (GtkObject *object);
static void gimp_layer_mask_class_init (GimpLayerMaskClass *klass);
static void gimp_layer_mask_init (GimpLayerMask *layermask);
@ -138,7 +138,8 @@ gimp_layer_mask_get_type (void)
(GtkClassInitFunc) NULL,
};
layer_mask_type = gtk_type_unique (gimp_channel_get_type (), &layer_mask_info);
layer_mask_type = gtk_type_unique (gimp_channel_get_type (),
&layer_mask_info);
}
return layer_mask_type;
@ -166,11 +167,16 @@ gimp_layer_mask_init (GimpLayerMask *layermask)
/* static functions */
static void transform_color (GImage *, PixelRegion *,
PixelRegion *, GimpDrawable *,
GimpImageBaseType);
static void layer_preview_scale (int, unsigned char *, PixelRegion *,
PixelRegion *, int);
static void transform_color (GImage *gimage,
PixelRegion *layerPR,
PixelRegion *bufPR,
GimpDrawable *drawable,
GimpImageBaseType type);
static void layer_preview_scale (GimpImageBaseType type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample);
/*
* Static variables
@ -207,7 +213,9 @@ transform_color (GImage *gimage,
unsigned char * s, * d;
void * pr;
for (pr = pixel_regions_register (2, layerPR, bufPR); pr != NULL; pr = pixel_regions_process (pr))
for (pr = pixel_regions_register (2, layerPR, bufPR);
pr != NULL;
pr = pixel_regions_process (pr))
{
h = layerPR->h;
s = bufPR->data;
@ -361,24 +369,37 @@ layer_copy (Layer *layer,
/* copy the contents across layers */
if (new_type == GIMP_DRAWABLE (layer)->type)
{
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
copy_region (&srcPR, &destPR);
}
else
{
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
add_alpha_region (&srcPR, &destPR);
}
/* duplicate the layer mask if necessary */
if (layer->mask)
{
new_layer->mask = layer_mask_ref (layer_mask_copy (layer->mask));
new_layer->mask = layer_mask_ref (layer_mask_copy (layer->mask));
new_layer->apply_mask = layer->apply_mask;
new_layer->edit_mask = layer->edit_mask;
new_layer->show_mask = layer->show_mask;
layer_mask_set_layer (new_layer->mask, new_layer);
}
@ -428,8 +449,14 @@ layer_new_from_tiles (GimpImage *gimage,
}
/* Configure the pixel regions */
pixel_region_init (&layerPR, GIMP_DRAWABLE (new_layer)->tiles, 0, 0, GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height, TRUE);
pixel_region_init (&bufPR, tiles, 0, 0, GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height, FALSE);
pixel_region_init (&layerPR, GIMP_DRAWABLE (new_layer)->tiles,
0, 0,
GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height,
TRUE);
pixel_region_init (&bufPR, tiles,
0, 0,
GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height,
FALSE);
if ((tiles->bpp == 4 && GIMP_DRAWABLE (new_layer)->type == RGBA_GIMAGE) ||
(tiles->bpp == 2 && GIMP_DRAWABLE (new_layer)->type == GRAYA_GIMAGE))
@ -486,7 +513,10 @@ layer_create_mask (Layer *layer,
GIMP_DRAWABLE (mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x;
GIMP_DRAWABLE (mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y;
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles, 0, 0, GIMP_DRAWABLE (mask)->width, GIMP_DRAWABLE (mask)->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles,
0, 0,
GIMP_DRAWABLE (mask)->width, GIMP_DRAWABLE (mask)->height,
TRUE);
switch (add_mask_type)
{
@ -500,7 +530,10 @@ layer_create_mask (Layer *layer,
/* Extract the layer's alpha channel */
if (layer_has_alpha (layer))
{
pixel_region_init (&layerPR, GIMP_DRAWABLE (layer)->tiles, 0, 0, GIMP_DRAWABLE (layer)->width, GIMP_DRAWABLE (layer)->height, FALSE);
pixel_region_init (&layerPR, GIMP_DRAWABLE (layer)->tiles,
0, 0,
GIMP_DRAWABLE (layer)->width, GIMP_DRAWABLE (layer)->height,
FALSE);
extract_alpha_region (&layerPR, NULL, &maskPR);
}
break;
@ -563,7 +596,7 @@ gimp_layer_destroy (GtkObject *object)
* particular layer. */
void
layer_removed (Layer *layer,
gpointer image)
gpointer data)
{
g_return_if_fail (layer != NULL);
g_return_if_fail (GIMP_IS_LAYER (layer));
@ -596,8 +629,14 @@ layer_apply_mask (Layer *layer,
NULL, FALSE);
/* Combine the current layer's alpha channel and the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(layer->mask)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(layer->mask)->tiles,
0, 0, GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height,
FALSE);
apply_mask_to_region (&srcPR, &maskPR, OPAQUE_OPACITY);
GIMP_DRAWABLE (layer)->preview_valid = FALSE;
@ -654,7 +693,7 @@ layer_translate_lowlevel (Layer *layer,
if (!temporary)
{
/* invalidate the mask preview */
drawable_invalidate_preview (GIMP_DRAWABLE(layer->mask));
drawable_invalidate_preview (GIMP_DRAWABLE (layer->mask));
}
}
}
@ -703,11 +742,19 @@ layer_add_alpha (Layer *layer)
}
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, (GIMP_DRAWABLE(layer)->bytes + 1));
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height,
GIMP_DRAWABLE(layer)->bytes + 1);
pixel_region_init (&destPR, new_tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
/* Add an alpha channel */
add_alpha_region (&srcPR, &destPR);
@ -727,11 +774,11 @@ layer_add_alpha (Layer *layer)
}
static void
layer_scale_lowlevel(Layer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y)
layer_scale_lowlevel (Layer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y)
{
PixelRegion srcPR, destPR;
TileManager *new_tiles;
@ -742,19 +789,25 @@ layer_scale_lowlevel(Layer *layer,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, GIMP_DRAWABLE(layer)->bytes);
pixel_region_init (&destPR, new_tiles, 0, 0, new_width, new_height, TRUE);
pixel_region_init (&destPR, new_tiles,
0, 0,
new_width, new_height,
TRUE);
/* Scale the layer -
* If the layer is of type INDEXED, then we don't use pixel-value
* resampling because that doesn't necessarily make sense for INDEXED
* images.
*/
if ((GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) || (GIMP_DRAWABLE(layer)->type == INDEXEDA_GIMAGE))
if ((GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) ||
(GIMP_DRAWABLE(layer)->type == INDEXEDA_GIMAGE))
scale_region_no_resample (&srcPR, &destPR);
else
scale_region (&srcPR, &destPR);
@ -868,7 +921,7 @@ layer_scale_by_factors (Layer *layer,
/**
* layer_scale:
* @layer: The layer to be transformed by width & height scale factors
* @layer: The layer to be transformed by width & height scale factors
* @new_width: The width that layer will acquire
* @new_height: The height that the layer will acquire
* @local_origin: sets fixed point of the scaling transform. See below.
@ -973,11 +1026,17 @@ layer_resize (Layer *layer,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, x1, y1, w, h, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
x1, y1,
w, h,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, GIMP_DRAWABLE(layer)->bytes);
pixel_region_init (&destPR, new_tiles, 0, 0, new_width, new_height, TRUE);
pixel_region_init (&destPR, new_tiles,
0, 0,
new_width, new_height,
TRUE);
/* fill with the fill color */
if (layer_has_alpha (layer))
@ -992,7 +1051,10 @@ layer_resize (Layer *layer,
gimage_get_background (GIMP_DRAWABLE(layer)->gimage, GIMP_DRAWABLE(layer), bg);
color_region (&destPR, bg);
}
pixel_region_init (&destPR, new_tiles, x2, y2, w, h, TRUE);
pixel_region_init (&destPR, new_tiles,
x2, y2,
w, h,
TRUE);
/* copy from the old to the new */
if (w && h)
@ -1243,18 +1305,17 @@ layer_preview_private (Layer *layer,
GImage *gimage;
TempBuf *preview_buf;
PixelRegion srcPR, destPR;
int type;
int bytes;
int subsample;
GimpImageBaseType type;
gint bytes;
gint subsample;
TempBuf *ret_buf;
type = 0;
type = RGB;
bytes = 0;
/* The easy way */
if (GIMP_DRAWABLE(layer)->preview_valid &&
(ret_buf = gimp_preview_cache_get(&(GIMP_DRAWABLE(layer)->preview_cache),
w,h)))
(ret_buf = gimp_preview_cache_get (&(GIMP_DRAWABLE(layer)->preview_cache), w,h)))
return ret_buf;
/* The hard way */
else
@ -1263,15 +1324,15 @@ layer_preview_private (Layer *layer,
switch (GIMP_DRAWABLE(layer)->type)
{
case RGB_GIMAGE: case RGBA_GIMAGE:
type = 0;
type = RGB;
bytes = GIMP_DRAWABLE(layer)->bytes;
break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
type = 1;
type = GRAY;
bytes = GIMP_DRAWABLE(layer)->bytes;
break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
type = 2;
type = INDEXED;
bytes = (GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) ? 3 : 4;
break;
}
@ -1285,49 +1346,54 @@ layer_preview_private (Layer *layer,
(h * (subsample + 1) * 2 < GIMP_DRAWABLE(layer)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
preview_buf = temp_buf_new (w, h, bytes, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.rowstride = w * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
destPR.data = temp_buf_data (preview_buf);
layer_preview_scale (type, gimage->cmap, &srcPR, &destPR, subsample);
if (!GIMP_DRAWABLE(layer)->preview_valid)
gimp_preview_cache_invalidate(&(GIMP_DRAWABLE(layer)->preview_cache));
if (!GIMP_DRAWABLE (layer)->preview_valid)
gimp_preview_cache_invalidate (&(GIMP_DRAWABLE (layer)->preview_cache));
GIMP_DRAWABLE(layer)->preview_valid = TRUE;
GIMP_DRAWABLE (layer)->preview_valid = TRUE;
gimp_preview_cache_add (&(GIMP_DRAWABLE (layer)->preview_cache), preview_buf);
gimp_preview_cache_add(&(GIMP_DRAWABLE(layer)->preview_cache),preview_buf);
return preview_buf;
}
}
TempBuf *
layer_preview (Layer *layer,
gint w,
gint h)
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(layer)->preview_valid &&
w <= PREVIEW_CACHE_PRIME_WIDTH &&
h <= PREVIEW_CACHE_PRIME_HEIGHT)
if (!GIMP_DRAWABLE(layer)->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = layer_preview_private(layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
TempBuf * tb = layer_preview_private (layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(w == PREVIEW_CACHE_PRIME_WIDTH &&
h == PREVIEW_CACHE_PRIME_HEIGHT)
if (width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return layer_preview_private(layer,w,h);
return layer_preview_private (layer, width, height);
}
static TempBuf *
@ -1338,7 +1404,7 @@ layer_mask_preview_private (Layer *layer,
TempBuf *preview_buf;
LayerMask *mask;
PixelRegion srcPR, destPR;
int subsample;
gint subsample;
TempBuf *ret_buf;
mask = layer->mask;
@ -1347,8 +1413,7 @@ layer_mask_preview_private (Layer *layer,
/* The easy way */
if (GIMP_DRAWABLE(mask)->preview_valid &&
(ret_buf = gimp_preview_cache_get(&(GIMP_DRAWABLE(mask)->preview_cache),
w,h)))
(ret_buf = gimp_preview_cache_get (&(GIMP_DRAWABLE(mask)->preview_cache), w, h)))
return ret_buf;
/* The hard way */
else
@ -1361,18 +1426,22 @@ layer_mask_preview_private (Layer *layer,
(h * (subsample + 1) * 2 < GIMP_DRAWABLE(layer)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles,
0, 0,
GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height,
FALSE);
preview_buf = temp_buf_new (w, h, 1, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.rowstride = w * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
destPR.data = temp_buf_data (preview_buf);
layer_preview_scale (1 /* GRAY */, NULL, &srcPR, &destPR, subsample);
if(!GIMP_DRAWABLE (mask)->preview_valid)
if (!GIMP_DRAWABLE (mask)->preview_valid)
gimp_preview_cache_invalidate (&(GIMP_DRAWABLE (mask)->preview_cache));
GIMP_DRAWABLE (mask)->preview_valid = TRUE;
@ -1385,26 +1454,26 @@ layer_mask_preview_private (Layer *layer,
TempBuf *
layer_mask_preview (Layer *layer,
gint w,
gint h)
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(layer->mask)->preview_valid &&
w <= PREVIEW_CACHE_PRIME_WIDTH &&
h <= PREVIEW_CACHE_PRIME_HEIGHT)
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = layer_mask_preview_private(layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(w == PREVIEW_CACHE_PRIME_WIDTH &&
h == PREVIEW_CACHE_PRIME_HEIGHT)
if (width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return layer_mask_preview_private(layer,w,h);
return layer_mask_preview_private (layer, width, height);
}
@ -1415,14 +1484,15 @@ layer_get_tattoo (const Layer *layer)
}
void
layer_set_tattoo (const Layer *layer , Tattoo val)
layer_set_tattoo (const Layer *layer,
Tattoo value)
{
gimp_drawable_set_tattoo(GIMP_DRAWABLE (layer),val);
gimp_drawable_set_tattoo (GIMP_DRAWABLE (layer), value);
}
void
layer_invalidate_previews (GimpImage* gimage)
layer_invalidate_previews (GimpImage *gimage)
{
GSList * tmp;
Layer * layer;
@ -1440,54 +1510,54 @@ layer_invalidate_previews (GimpImage* gimage)
}
static void
layer_preview_scale (gint type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
layer_preview_scale (GimpImageBaseType type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
{
#define EPSILON 0.000001
unsigned char * src, * s;
unsigned char * dest, * d;
double * row, * r;
int destwidth;
int src_row, src_col;
int bytes, b;
int width, height;
int orig_width, orig_height;
double x_rat, y_rat;
double x_cum, y_cum;
double x_last, y_last;
double * x_frac, y_frac, tot_frac;
int i, j;
int frac;
int advance_dest;
unsigned char rgb[MAX_CHANNELS];
guchar *src, *s;
guchar *dest, *d;
gdouble *row, *r;
gint destwidth;
gint src_row, src_col;
gint bytes, b;
gint width, height;
gint orig_width, orig_height;
gdouble x_rat, y_rat;
gdouble x_cum, y_cum;
gdouble x_last, y_last;
gdouble * x_frac, y_frac, tot_frac;
gint i, j;
gint frac;
gboolean advance_dest;
guchar rgb[MAX_CHANNELS];
orig_width = srcPR->w / subsample;
orig_width = srcPR->w / subsample;
orig_height = srcPR->h / subsample;
width = destPR->w;
width = destPR->w;
height = destPR->h;
/* Some calculations... */
bytes = destPR->bytes;
bytes = destPR->bytes;
destwidth = destPR->rowstride;
/* the data pointers... */
src = (unsigned char *) g_malloc (orig_width * bytes);
src = g_new (guchar, orig_width * bytes);
dest = destPR->data;
/* find the ratios of old x to new x and old y to new y */
x_rat = (double) orig_width / (double) width;
y_rat = (double) orig_height / (double) height;
x_rat = (gdouble) orig_width / (gdouble) width;
y_rat = (gdouble) orig_height / (gdouble) height;
/* allocate an array to help with the calculations */
row = (double *) g_malloc (sizeof (double) * width * bytes);
x_frac = (double *) g_malloc (sizeof (double) * (width + orig_width));
row = g_new (gdouble, width * bytes);
x_frac = g_new (gdouble, width + orig_width);
/* initialize the pre-calculated pixel fraction array */
src_col = 0;
x_cum = (double) src_col;
x_cum = (gdouble) src_col;
x_last = x_cum;
for (i = 0; i < width + orig_width; i++)
@ -1506,7 +1576,7 @@ layer_preview_scale (gint type,
}
/* clear the "row" array */
memset (row, 0, sizeof (double) * width * bytes);
memset (row, 0, sizeof (gdouble) * width * bytes);
/* counters... */
src_row = 0;
@ -1519,7 +1589,7 @@ layer_preview_scale (gint type,
for (i = 0; i < height; )
{
src_col = 0;
x_cum = (double) src_col;
x_cum = (gdouble) src_col;
/* determine the fraction of the src pixel we are using for y */
if (y_cum + y_rat <= (src_row + 1 + EPSILON))
@ -1548,7 +1618,7 @@ layer_preview_scale (gint type,
tot_frac = x_frac[frac++] * y_frac;
/* If indexed, transform the color to RGB */
if (type == 2)
if (type == INDEXED)
{
map_to_color (2, cmap, s, rgb);
@ -1591,13 +1661,13 @@ layer_preview_scale (gint type,
{
b = bytes;
while (b--)
*d++ = (unsigned char) ((*r++ * tot_frac)+0.5);
*d++ = (guchar) ((*r++ * tot_frac)+0.5);
}
dest += destwidth;
/* clear the "row" array */
memset (row, 0, sizeof (double) * destwidth);
memset (row, 0, sizeof (gdouble) * destwidth);
i++;
}
@ -1643,10 +1713,10 @@ layer_mask_new (GimpImage *gimage,
/* set the layer_mask color and opacity */
for (i = 0; i < 3; i++)
GIMP_CHANNEL (layer_mask)->col[i] = col[i];
GIMP_CHANNEL (layer_mask)->col[i] = col[i];
GIMP_CHANNEL (layer_mask)->opacity = opacity;
GIMP_CHANNEL (layer_mask)->show_masked = TRUE;
GIMP_CHANNEL (layer_mask)->opacity = opacity;
GIMP_CHANNEL (layer_mask)->show_masked = TRUE;
/* selection mask variables */
GIMP_CHANNEL (layer_mask)->empty = TRUE;
@ -1666,7 +1736,7 @@ layer_mask_new (GimpImage *gimage,
LayerMask *
layer_mask_copy (LayerMask *layer_mask)
{
char * layer_mask_name;
gchar * layer_mask_name;
LayerMask * new_layer_mask;
PixelRegion srcPR, destPR;
@ -1686,10 +1756,14 @@ layer_mask_copy (LayerMask *layer_mask)
GIMP_CHANNEL(new_layer_mask)->show_masked = GIMP_CHANNEL(layer_mask)->show_masked;
/* copy the contents across layer masks */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer_mask)->tiles, 0, 0,
GIMP_DRAWABLE(layer_mask)->width,
GIMP_DRAWABLE(layer_mask)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer_mask)->tiles, 0, 0, GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer_mask)->tiles,
0, 0,
GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer_mask)->tiles,
0, 0,
GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height,
TRUE);
copy_region (&srcPR, &destPR);
/* free up the layer_mask_name memory */
@ -1702,7 +1776,9 @@ LayerMask *
layer_mask_get_ID (gint ID)
{
GimpDrawable *drawable;
drawable = drawable_get_ID (ID);
if (drawable && GIMP_IS_LAYER_MASK (drawable))
return GIMP_LAYER_MASK (drawable);
else
@ -1720,6 +1796,7 @@ layer_mask_ref (LayerMask *mask)
{
gtk_object_ref (GTK_OBJECT (mask));
gtk_object_sink (GTK_OBJECT (mask));
return mask;
}
@ -1747,25 +1824,34 @@ channel_layer_mask (Channel *mask,
Layer *layer)
{
PixelRegion srcPR, destPR;
unsigned char empty = 0;
int x1, y1, x2, y2;
guchar empty = 0;
gint x1, y1, x2, y2;
/* push the current mask onto the undo stack */
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles,
0, 0,
GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height,
TRUE);
color_region (&destPR, &empty);
x1 = CLAMP (GIMP_DRAWABLE(layer)->offset_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = CLAMP (GIMP_DRAWABLE(layer)->offset_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = CLAMP (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = CLAMP (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, 0, GIMP_DRAWABLE(mask)->height);
x2 = CLAMP (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width,
0, GIMP_DRAWABLE(mask)->width);
y2 = CLAMP (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height,
0, GIMP_DRAWABLE(mask)->height);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer->mask)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
(x2 - x1), (y2 - y1),
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles,
x1, y1,
(x2 - x1), (y2 - y1),
TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;

View File

@ -71,66 +71,108 @@ struct _fs_to_layer_undo
/* function declarations */
Layer * layer_new (GimpImage*, gint, gint,
GimpImageType,
gchar *, gint,
LayerModeEffects);
Layer * layer_copy (Layer *, gboolean);
Layer * layer_ref (Layer *);
void layer_unref (Layer *);
Layer * layer_new (GimpImage *gimage,
gint width,
gint height,
GimpImageType type,
gchar *name,
gint opacity,
LayerModeEffects mode);
Layer * layer_copy (Layer *layer,
gboolean add_alpha);
Layer * layer_ref (Layer *layer);
void layer_unref (Layer *layer);
Layer * layer_new_from_tiles (GimpImage *, GimpImageType, TileManager *,
gchar *, gint, LayerModeEffects);
LayerMask * layer_add_mask (Layer *, LayerMask *);
gboolean layer_check_scaling (Layer *, gint, gint);
LayerMask * layer_create_mask (Layer *, AddMaskType);
Layer * layer_get_ID (gint);
void layer_delete (Layer *);
void layer_removed (Layer *, gpointer);
void layer_apply_mask (Layer *, MaskApplyMode);
void layer_temporarily_translate (Layer *, gint, gint);
void layer_translate (Layer *, gint, gint);
void layer_add_alpha (Layer *);
gboolean layer_scale_by_factors (Layer *, gdouble, gdouble);
void layer_scale (Layer *, gint, gint, gboolean);
void layer_resize (Layer *, gint, gint, gint, gint);
void layer_resize_to_image (Layer *);
BoundSeg * layer_boundary (Layer *, gint *);
void layer_invalidate_boundary (Layer *);
gint layer_pick_correlate (Layer *, gint, gint);
Layer * layer_new_from_tiles (GimpImage *gimage,
GimpImageType layer_type,
TileManager *tiles,
gchar *name,
gint opacity,
LayerModeEffects mode);
gboolean layer_check_scaling (Layer *layer,
gint new_width,
gint new_height);
LayerMask * layer_create_mask (Layer *layer,
AddMaskType add_mask_type);
LayerMask * layer_add_mask (Layer *layer,
LayerMask *mask);
Layer * layer_get_ID (gint ID);
void layer_delete (Layer *layer);
void layer_removed (Layer *layer,
gpointer data);
void layer_apply_mask (Layer *layer,
MaskApplyMode mode);
void layer_temporarily_translate (Layer *layer,
gint off_x,
gint off_y);
void layer_translate (Layer *layer,
gint off_x,
gint off_y);
void layer_add_alpha (Layer *layer);
gboolean layer_scale_by_factors (Layer *layer,
gdouble w_factor,
gdouble h_factor);
void layer_scale (Layer *layer,
gint new_width,
gint new_height,
gboolean local_origin);
void layer_resize (Layer *layer,
gint new_width,
gint new_height,
gint offx,
gint offy);
void layer_resize_to_image (Layer *layer);
BoundSeg * layer_boundary (Layer *layer,
gint *num_segs);
void layer_invalidate_boundary (Layer *layer);
gint layer_pick_correlate (Layer *layer,
gint x,
gint y);
LayerMask * layer_mask_new (GimpImage*, gint, gint, gchar *,
gint, guchar *);
LayerMask * layer_mask_copy (LayerMask *);
void layer_mask_delete (LayerMask *);
LayerMask * layer_mask_get_ID (gint);
LayerMask * layer_mask_ref (LayerMask *);
void layer_mask_unref (LayerMask *);
void layer_mask_set_layer (LayerMask *, Layer *);
Layer * layer_mask_get_layer (LayerMask *);
LayerMask * layer_mask_new (GimpImage *gimage,
gint width,
gint height,
gchar *name,
gint opacity,
guchar *col);
LayerMask * layer_mask_copy (LayerMask *layer_mask);
void layer_mask_delete (LayerMask *layer_mask);
LayerMask * layer_mask_get_ID (gint ID);
LayerMask * layer_mask_ref (LayerMask *layer_mask);
void layer_mask_unref (LayerMask *layer_mask);
void layer_mask_set_layer (LayerMask *layer_mask,
Layer *layer);
Layer * layer_mask_get_layer (LayerMask *layer_mask);
/* access functions */
void layer_set_name (Layer *, gchar *);
gchar * layer_get_name (Layer *);
guchar * layer_data (Layer *);
LayerMask * layer_get_mask (Layer *);
gboolean layer_has_alpha (Layer *);
gboolean layer_is_floating_sel (Layer *);
gboolean layer_linked (Layer *);
TempBuf * layer_preview (Layer *, gint, gint);
TempBuf * layer_mask_preview (Layer *, gint, gint);
void layer_set_name (Layer *layer,
gchar *name);
gchar * layer_get_name (Layer *layer);
guchar * layer_data (Layer *layer);
LayerMask * layer_get_mask (Layer *layer);
gboolean layer_has_alpha (Layer *layer);
gboolean layer_is_floating_sel (Layer *layer);
gboolean layer_linked (Layer *layer);
TempBuf * layer_preview (Layer *layer,
gint width,
gint height);
TempBuf * layer_mask_preview (Layer *layer,
gint width,
gint height);
void layer_invalidate_previews (GimpImage *);
Tattoo layer_get_tattoo (const Layer *);
void layer_set_tattoo (const Layer *, Tattoo);
void layer_invalidate_previews (GimpImage *gimage);
Tattoo layer_get_tattoo (const Layer *layer);
void layer_set_tattoo (const Layer *layer,
Tattoo value);
#define drawable_layer GIMP_IS_LAYER
#define drawable_layer_mask GIMP_IS_LAYER_MASK
void channel_layer_alpha (Channel *mask,
Layer *layer);
/* from channel.c */
void channel_layer_alpha (Channel *, Layer *);
void channel_layer_mask (Channel *, Layer *);
void channel_layer_mask (Channel *mask,
Layer *layer);
#endif /* __LAYER_H__ */

View File

@ -238,7 +238,7 @@ channel_get_name (Channel *channel)
void
channel_set_color (Channel *channel,
guchar *color)
guchar *color)
{
gint i;
@ -315,7 +315,7 @@ gimp_channel_destroy (GtkObject *object)
* particular layer. */
void
channel_removed (Channel *channel,
gpointer image)
gpointer data)
{
g_return_if_fail (channel != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (channel));
@ -592,9 +592,10 @@ channel_get_tattoo (const Channel *channel)
}
void
channel_set_tattoo (const Channel *channel, Tattoo val)
channel_set_tattoo (const Channel *channel,
Tattoo value)
{
gimp_drawable_set_tattoo(GIMP_DRAWABLE (channel),val);
gimp_drawable_set_tattoo (GIMP_DRAWABLE (channel), value);
}
/******************************/
@ -602,7 +603,7 @@ channel_set_tattoo (const Channel *channel, Tattoo val)
/******************************/
Channel *
channel_new_mask (GimpImage* gimage,
channel_new_mask (GimpImage *gimage,
gint width,
gint height)
{
@ -731,9 +732,9 @@ channel_bounds (Channel *mask,
guchar *data, *data1;
gint x, y;
gint ex, ey;
void *pr;
gint tx1, tx2, ty1, ty2;
gint minx, maxx;
gpointer pr;
/* if the mask's bounds have already been reliably calculated... */
if (mask->bounds_known)
@ -840,7 +841,7 @@ channel_is_empty (Channel *mask)
PixelRegion maskPR;
guchar * data;
gint x, y;
void * pr;
gpointer pr;
if (mask->bounds_known)
return mask->empty;
@ -896,7 +897,7 @@ channel_add_segment (Channel *mask,
guchar *data;
gint val;
gint x2;
void * pr;
gpointer pr;
/* check horizontal extents... */
x2 = x + width;
@ -939,7 +940,7 @@ channel_sub_segment (Channel *mask,
guchar *data;
gint val;
gint x2;
void * pr;
gpointer pr;
/* check horizontal extents... */
x2 = x + width;
@ -1037,7 +1038,7 @@ channel_combine_ellipse (Channel *mask,
gint y,
gint w,
gint h,
gboolean aa /* antialias selection? */)
gboolean antialias)
{
gint i, j;
gint x0, x1, x2;
@ -1066,7 +1067,7 @@ channel_combine_ellipse (Channel *mask,
if (i >= 0 && i < GIMP_DRAWABLE (mask)->height)
{
/* Non-antialiased code */
if (!aa)
if (!antialias)
{
y_sqr = (i + 0.5 - cy) * (i + 0.5 - cy);
rad = sqrt (a_sqr - a_sqr * y_sqr / (double) b_sqr);
@ -1754,3 +1755,4 @@ channel_invalidate_bounds (Channel *channel)
{
channel->bounds_known = FALSE;
}

View File

@ -71,80 +71,138 @@ struct _MaskUndo
/* function declarations */
Channel * channel_new (GimpImage*,
gint, gint, gchar *, gint, guchar *);
Channel * channel_copy (Channel *);
Channel * channel_ref (Channel *);
void channel_unref (Channel *);
Channel * channel_new (GimpImage *gimage,
gint width,
gint height,
gchar *name,
gint opacity,
guchar *col);
Channel * channel_copy (Channel *channel);
Channel * channel_ref (Channel *channel);
void channel_unref (Channel *channel);
gchar * channel_get_name (Channel *);
void channel_set_name (Channel *, gchar *);
gchar * channel_get_name (Channel *channel);
void channel_set_name (Channel *channel,
gchar *name);
gint channel_get_opacity (Channel *);
void channel_set_opacity (Channel *, gint);
gint channel_get_opacity (Channel *channel);
void channel_set_opacity (Channel *channel,
gint opacity);
guchar * channel_get_color (Channel *);
void channel_set_color (Channel *, guchar *);
guchar * channel_get_color (Channel *channel);
void channel_set_color (Channel *channel,
guchar *color);
Channel * channel_get_ID (gint);
void channel_delete (Channel *);
void channel_removed (Channel *, gpointer);
void channel_scale (Channel *, gint, gint);
void channel_resize (Channel *, gint, gint, gint, gint);
void channel_update (Channel *);
Channel * channel_get_ID (gint ID);
void channel_delete (Channel *channel);
void channel_removed (Channel *channel,
gpointer data);
void channel_scale (Channel *channel,
gint new_width,
gint new_height);
void channel_resize (Channel *channel,
gint new_width,
gint new_height,
gint offx,
gint offy);
void channel_update (Channel *channel);
/* access functions */
gboolean channel_toggle_visibility (Channel *);
TempBuf * channel_preview (Channel *, gint, gint);
gboolean channel_toggle_visibility (Channel *channel);
TempBuf * channel_preview (Channel *channel,
gint width,
gint height);
void channel_invalidate_previews (GimpImage*);
Tattoo channel_get_tattoo (const Channel *);
void channel_set_tattoo (const Channel *,Tattoo);
void channel_invalidate_previews (GimpImage *gimage);
Tattoo channel_get_tattoo (const Channel *channel);
void channel_set_tattoo (const Channel *channel,
Tattoo value);
/* selection mask functions */
Channel * channel_new_mask (GimpImage *, gint, gint);
gboolean channel_boundary (Channel *, BoundSeg **, BoundSeg **,
gint *, gint *, gint, gint, gint, gint);
gboolean channel_bounds (Channel *,
gint *, gint *, gint *, gint *);
gint channel_value (Channel *, gint, gint);
gboolean channel_is_empty (Channel *);
void channel_add_segment (Channel *, gint, gint, gint, gint);
void channel_sub_segment (Channel *, gint, gint, gint, gint);
void channel_inter_segment (Channel *, gint, gint, gint, gint);
void channel_combine_rect (Channel *,
ChannelOps, gint, gint, gint, gint);
void channel_combine_ellipse (Channel *,
ChannelOps,
gint, gint, gint, gint, gboolean);
void channel_combine_mask (Channel *, Channel *,
ChannelOps, gint, gint);
void channel_feather (Channel *, Channel *,
gdouble, gdouble,
ChannelOps, gint, gint);
void channel_push_undo (Channel *);
void channel_clear (Channel *);
void channel_invert (Channel *);
void channel_sharpen (Channel *);
void channel_all (Channel *);
Channel * channel_new_mask (GimpImage *gimage,
gint width,
gint height);
gboolean channel_boundary (Channel *mask,
BoundSeg **segs_in,
BoundSeg **segs_out,
gint *num_segs_in,
gint *num_segs_out,
gint x1,
gint y1,
gint x2,
gint y2);
gboolean channel_bounds (Channel *mask,
gint *x1,
gint *y1,
gint *x2,
gint *y2);
gint channel_value (Channel *mask,
gint x,
gint y);
gboolean channel_is_empty (Channel *mask);
void channel_add_segment (Channel *mask,
gint x,
gint y,
gint width,
gint value);
void channel_sub_segment (Channel *mask,
gint x,
gint y,
gint width,
gint value);
void channel_combine_rect (Channel *mask,
ChannelOps op,
gint x,
gint y,
gint w,
gint h);
void channel_combine_ellipse (Channel *mask,
ChannelOps op,
gint x,
gint y,
gint w,
gint h,
gboolean antialias);
void channel_combine_mask (Channel *mask,
Channel *add_on,
ChannelOps op,
gint off_x,
gint off_y);
void channel_feather (Channel *input,
Channel *output,
gdouble radius_x,
gdouble radius_y,
ChannelOps op,
gint off_x,
gint off_y);
void channel_border (Channel * channel,
gint radius_x,
gint radius_y);
void channel_grow (Channel * channel,
gint radius_x,
gint radius_y);
void channel_shrink (Channel * channel,
gint radius_x,
gint radius_y,
gboolean edge_lock);
void channel_push_undo (Channel *mask);
void channel_clear (Channel *mask);
void channel_invert (Channel *mask);
void channel_sharpen (Channel *mask);
void channel_all (Channel *mask);
void channel_translate (Channel *, gint, gint);
void channel_load (Channel *, Channel *);
void channel_border (Channel *mask,
gint radius_x,
gint radius_y);
void channel_grow (Channel *mask,
gint radius_x,
gint radius_y);
void channel_shrink (Channel *mask,
gint radius_x,
gint radius_y,
gboolean edge_lock);
void channel_invalidate_bounds (Channel *);
void channel_translate (Channel *mask,
gint off_x,
gint off_y);
void channel_load (Channel *mask,
Channel *channel);
void channel_invalidate_bounds (Channel *channel);
#define drawable_channel GIMP_IS_CHANNEL

View File

@ -217,10 +217,8 @@ gimp_drawable_invalidate_preview (GimpDrawable *drawable)
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
drawable->preview_valid = FALSE;
#if 0
gtk_signal_emit (GTK_OBJECT (drawable),
gimp_drawable_signals[INVALIDATE_PREVIEW]);
#endif
gimage = gimp_drawable_gimage (drawable);
if (gimage)
{

View File

@ -53,7 +53,7 @@ enum {
static void gimp_layer_class_init (GimpLayerClass *klass);
static void gimp_layer_init (GimpLayer *layer);
static void gimp_layer_destroy (GtkObject *object);
static void layer_invalidate_preview (GtkObject *);
static void layer_invalidate_preview (GtkObject *object);
static void gimp_layer_mask_class_init (GimpLayerMaskClass *klass);
static void gimp_layer_mask_init (GimpLayerMask *layermask);
@ -138,7 +138,8 @@ gimp_layer_mask_get_type (void)
(GtkClassInitFunc) NULL,
};
layer_mask_type = gtk_type_unique (gimp_channel_get_type (), &layer_mask_info);
layer_mask_type = gtk_type_unique (gimp_channel_get_type (),
&layer_mask_info);
}
return layer_mask_type;
@ -166,11 +167,16 @@ gimp_layer_mask_init (GimpLayerMask *layermask)
/* static functions */
static void transform_color (GImage *, PixelRegion *,
PixelRegion *, GimpDrawable *,
GimpImageBaseType);
static void layer_preview_scale (int, unsigned char *, PixelRegion *,
PixelRegion *, int);
static void transform_color (GImage *gimage,
PixelRegion *layerPR,
PixelRegion *bufPR,
GimpDrawable *drawable,
GimpImageBaseType type);
static void layer_preview_scale (GimpImageBaseType type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample);
/*
* Static variables
@ -207,7 +213,9 @@ transform_color (GImage *gimage,
unsigned char * s, * d;
void * pr;
for (pr = pixel_regions_register (2, layerPR, bufPR); pr != NULL; pr = pixel_regions_process (pr))
for (pr = pixel_regions_register (2, layerPR, bufPR);
pr != NULL;
pr = pixel_regions_process (pr))
{
h = layerPR->h;
s = bufPR->data;
@ -361,24 +369,37 @@ layer_copy (Layer *layer,
/* copy the contents across layers */
if (new_type == GIMP_DRAWABLE (layer)->type)
{
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
copy_region (&srcPR, &destPR);
}
else
{
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
add_alpha_region (&srcPR, &destPR);
}
/* duplicate the layer mask if necessary */
if (layer->mask)
{
new_layer->mask = layer_mask_ref (layer_mask_copy (layer->mask));
new_layer->mask = layer_mask_ref (layer_mask_copy (layer->mask));
new_layer->apply_mask = layer->apply_mask;
new_layer->edit_mask = layer->edit_mask;
new_layer->show_mask = layer->show_mask;
layer_mask_set_layer (new_layer->mask, new_layer);
}
@ -428,8 +449,14 @@ layer_new_from_tiles (GimpImage *gimage,
}
/* Configure the pixel regions */
pixel_region_init (&layerPR, GIMP_DRAWABLE (new_layer)->tiles, 0, 0, GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height, TRUE);
pixel_region_init (&bufPR, tiles, 0, 0, GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height, FALSE);
pixel_region_init (&layerPR, GIMP_DRAWABLE (new_layer)->tiles,
0, 0,
GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height,
TRUE);
pixel_region_init (&bufPR, tiles,
0, 0,
GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height,
FALSE);
if ((tiles->bpp == 4 && GIMP_DRAWABLE (new_layer)->type == RGBA_GIMAGE) ||
(tiles->bpp == 2 && GIMP_DRAWABLE (new_layer)->type == GRAYA_GIMAGE))
@ -486,7 +513,10 @@ layer_create_mask (Layer *layer,
GIMP_DRAWABLE (mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x;
GIMP_DRAWABLE (mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y;
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles, 0, 0, GIMP_DRAWABLE (mask)->width, GIMP_DRAWABLE (mask)->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles,
0, 0,
GIMP_DRAWABLE (mask)->width, GIMP_DRAWABLE (mask)->height,
TRUE);
switch (add_mask_type)
{
@ -500,7 +530,10 @@ layer_create_mask (Layer *layer,
/* Extract the layer's alpha channel */
if (layer_has_alpha (layer))
{
pixel_region_init (&layerPR, GIMP_DRAWABLE (layer)->tiles, 0, 0, GIMP_DRAWABLE (layer)->width, GIMP_DRAWABLE (layer)->height, FALSE);
pixel_region_init (&layerPR, GIMP_DRAWABLE (layer)->tiles,
0, 0,
GIMP_DRAWABLE (layer)->width, GIMP_DRAWABLE (layer)->height,
FALSE);
extract_alpha_region (&layerPR, NULL, &maskPR);
}
break;
@ -563,7 +596,7 @@ gimp_layer_destroy (GtkObject *object)
* particular layer. */
void
layer_removed (Layer *layer,
gpointer image)
gpointer data)
{
g_return_if_fail (layer != NULL);
g_return_if_fail (GIMP_IS_LAYER (layer));
@ -596,8 +629,14 @@ layer_apply_mask (Layer *layer,
NULL, FALSE);
/* Combine the current layer's alpha channel and the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(layer->mask)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(layer->mask)->tiles,
0, 0, GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height,
FALSE);
apply_mask_to_region (&srcPR, &maskPR, OPAQUE_OPACITY);
GIMP_DRAWABLE (layer)->preview_valid = FALSE;
@ -654,7 +693,7 @@ layer_translate_lowlevel (Layer *layer,
if (!temporary)
{
/* invalidate the mask preview */
drawable_invalidate_preview (GIMP_DRAWABLE(layer->mask));
drawable_invalidate_preview (GIMP_DRAWABLE (layer->mask));
}
}
}
@ -703,11 +742,19 @@ layer_add_alpha (Layer *layer)
}
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, (GIMP_DRAWABLE(layer)->bytes + 1));
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height,
GIMP_DRAWABLE(layer)->bytes + 1);
pixel_region_init (&destPR, new_tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
/* Add an alpha channel */
add_alpha_region (&srcPR, &destPR);
@ -727,11 +774,11 @@ layer_add_alpha (Layer *layer)
}
static void
layer_scale_lowlevel(Layer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y)
layer_scale_lowlevel (Layer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y)
{
PixelRegion srcPR, destPR;
TileManager *new_tiles;
@ -742,19 +789,25 @@ layer_scale_lowlevel(Layer *layer,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, GIMP_DRAWABLE(layer)->bytes);
pixel_region_init (&destPR, new_tiles, 0, 0, new_width, new_height, TRUE);
pixel_region_init (&destPR, new_tiles,
0, 0,
new_width, new_height,
TRUE);
/* Scale the layer -
* If the layer is of type INDEXED, then we don't use pixel-value
* resampling because that doesn't necessarily make sense for INDEXED
* images.
*/
if ((GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) || (GIMP_DRAWABLE(layer)->type == INDEXEDA_GIMAGE))
if ((GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) ||
(GIMP_DRAWABLE(layer)->type == INDEXEDA_GIMAGE))
scale_region_no_resample (&srcPR, &destPR);
else
scale_region (&srcPR, &destPR);
@ -868,7 +921,7 @@ layer_scale_by_factors (Layer *layer,
/**
* layer_scale:
* @layer: The layer to be transformed by width & height scale factors
* @layer: The layer to be transformed by width & height scale factors
* @new_width: The width that layer will acquire
* @new_height: The height that the layer will acquire
* @local_origin: sets fixed point of the scaling transform. See below.
@ -973,11 +1026,17 @@ layer_resize (Layer *layer,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, x1, y1, w, h, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
x1, y1,
w, h,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, GIMP_DRAWABLE(layer)->bytes);
pixel_region_init (&destPR, new_tiles, 0, 0, new_width, new_height, TRUE);
pixel_region_init (&destPR, new_tiles,
0, 0,
new_width, new_height,
TRUE);
/* fill with the fill color */
if (layer_has_alpha (layer))
@ -992,7 +1051,10 @@ layer_resize (Layer *layer,
gimage_get_background (GIMP_DRAWABLE(layer)->gimage, GIMP_DRAWABLE(layer), bg);
color_region (&destPR, bg);
}
pixel_region_init (&destPR, new_tiles, x2, y2, w, h, TRUE);
pixel_region_init (&destPR, new_tiles,
x2, y2,
w, h,
TRUE);
/* copy from the old to the new */
if (w && h)
@ -1243,18 +1305,17 @@ layer_preview_private (Layer *layer,
GImage *gimage;
TempBuf *preview_buf;
PixelRegion srcPR, destPR;
int type;
int bytes;
int subsample;
GimpImageBaseType type;
gint bytes;
gint subsample;
TempBuf *ret_buf;
type = 0;
type = RGB;
bytes = 0;
/* The easy way */
if (GIMP_DRAWABLE(layer)->preview_valid &&
(ret_buf = gimp_preview_cache_get(&(GIMP_DRAWABLE(layer)->preview_cache),
w,h)))
(ret_buf = gimp_preview_cache_get (&(GIMP_DRAWABLE(layer)->preview_cache), w,h)))
return ret_buf;
/* The hard way */
else
@ -1263,15 +1324,15 @@ layer_preview_private (Layer *layer,
switch (GIMP_DRAWABLE(layer)->type)
{
case RGB_GIMAGE: case RGBA_GIMAGE:
type = 0;
type = RGB;
bytes = GIMP_DRAWABLE(layer)->bytes;
break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
type = 1;
type = GRAY;
bytes = GIMP_DRAWABLE(layer)->bytes;
break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
type = 2;
type = INDEXED;
bytes = (GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) ? 3 : 4;
break;
}
@ -1285,49 +1346,54 @@ layer_preview_private (Layer *layer,
(h * (subsample + 1) * 2 < GIMP_DRAWABLE(layer)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
preview_buf = temp_buf_new (w, h, bytes, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.rowstride = w * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
destPR.data = temp_buf_data (preview_buf);
layer_preview_scale (type, gimage->cmap, &srcPR, &destPR, subsample);
if (!GIMP_DRAWABLE(layer)->preview_valid)
gimp_preview_cache_invalidate(&(GIMP_DRAWABLE(layer)->preview_cache));
if (!GIMP_DRAWABLE (layer)->preview_valid)
gimp_preview_cache_invalidate (&(GIMP_DRAWABLE (layer)->preview_cache));
GIMP_DRAWABLE(layer)->preview_valid = TRUE;
GIMP_DRAWABLE (layer)->preview_valid = TRUE;
gimp_preview_cache_add (&(GIMP_DRAWABLE (layer)->preview_cache), preview_buf);
gimp_preview_cache_add(&(GIMP_DRAWABLE(layer)->preview_cache),preview_buf);
return preview_buf;
}
}
TempBuf *
layer_preview (Layer *layer,
gint w,
gint h)
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(layer)->preview_valid &&
w <= PREVIEW_CACHE_PRIME_WIDTH &&
h <= PREVIEW_CACHE_PRIME_HEIGHT)
if (!GIMP_DRAWABLE(layer)->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = layer_preview_private(layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
TempBuf * tb = layer_preview_private (layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(w == PREVIEW_CACHE_PRIME_WIDTH &&
h == PREVIEW_CACHE_PRIME_HEIGHT)
if (width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return layer_preview_private(layer,w,h);
return layer_preview_private (layer, width, height);
}
static TempBuf *
@ -1338,7 +1404,7 @@ layer_mask_preview_private (Layer *layer,
TempBuf *preview_buf;
LayerMask *mask;
PixelRegion srcPR, destPR;
int subsample;
gint subsample;
TempBuf *ret_buf;
mask = layer->mask;
@ -1347,8 +1413,7 @@ layer_mask_preview_private (Layer *layer,
/* The easy way */
if (GIMP_DRAWABLE(mask)->preview_valid &&
(ret_buf = gimp_preview_cache_get(&(GIMP_DRAWABLE(mask)->preview_cache),
w,h)))
(ret_buf = gimp_preview_cache_get (&(GIMP_DRAWABLE(mask)->preview_cache), w, h)))
return ret_buf;
/* The hard way */
else
@ -1361,18 +1426,22 @@ layer_mask_preview_private (Layer *layer,
(h * (subsample + 1) * 2 < GIMP_DRAWABLE(layer)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles,
0, 0,
GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height,
FALSE);
preview_buf = temp_buf_new (w, h, 1, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.rowstride = w * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
destPR.data = temp_buf_data (preview_buf);
layer_preview_scale (1 /* GRAY */, NULL, &srcPR, &destPR, subsample);
if(!GIMP_DRAWABLE (mask)->preview_valid)
if (!GIMP_DRAWABLE (mask)->preview_valid)
gimp_preview_cache_invalidate (&(GIMP_DRAWABLE (mask)->preview_cache));
GIMP_DRAWABLE (mask)->preview_valid = TRUE;
@ -1385,26 +1454,26 @@ layer_mask_preview_private (Layer *layer,
TempBuf *
layer_mask_preview (Layer *layer,
gint w,
gint h)
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(layer->mask)->preview_valid &&
w <= PREVIEW_CACHE_PRIME_WIDTH &&
h <= PREVIEW_CACHE_PRIME_HEIGHT)
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = layer_mask_preview_private(layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(w == PREVIEW_CACHE_PRIME_WIDTH &&
h == PREVIEW_CACHE_PRIME_HEIGHT)
if (width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return layer_mask_preview_private(layer,w,h);
return layer_mask_preview_private (layer, width, height);
}
@ -1415,14 +1484,15 @@ layer_get_tattoo (const Layer *layer)
}
void
layer_set_tattoo (const Layer *layer , Tattoo val)
layer_set_tattoo (const Layer *layer,
Tattoo value)
{
gimp_drawable_set_tattoo(GIMP_DRAWABLE (layer),val);
gimp_drawable_set_tattoo (GIMP_DRAWABLE (layer), value);
}
void
layer_invalidate_previews (GimpImage* gimage)
layer_invalidate_previews (GimpImage *gimage)
{
GSList * tmp;
Layer * layer;
@ -1440,54 +1510,54 @@ layer_invalidate_previews (GimpImage* gimage)
}
static void
layer_preview_scale (gint type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
layer_preview_scale (GimpImageBaseType type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
{
#define EPSILON 0.000001
unsigned char * src, * s;
unsigned char * dest, * d;
double * row, * r;
int destwidth;
int src_row, src_col;
int bytes, b;
int width, height;
int orig_width, orig_height;
double x_rat, y_rat;
double x_cum, y_cum;
double x_last, y_last;
double * x_frac, y_frac, tot_frac;
int i, j;
int frac;
int advance_dest;
unsigned char rgb[MAX_CHANNELS];
guchar *src, *s;
guchar *dest, *d;
gdouble *row, *r;
gint destwidth;
gint src_row, src_col;
gint bytes, b;
gint width, height;
gint orig_width, orig_height;
gdouble x_rat, y_rat;
gdouble x_cum, y_cum;
gdouble x_last, y_last;
gdouble * x_frac, y_frac, tot_frac;
gint i, j;
gint frac;
gboolean advance_dest;
guchar rgb[MAX_CHANNELS];
orig_width = srcPR->w / subsample;
orig_width = srcPR->w / subsample;
orig_height = srcPR->h / subsample;
width = destPR->w;
width = destPR->w;
height = destPR->h;
/* Some calculations... */
bytes = destPR->bytes;
bytes = destPR->bytes;
destwidth = destPR->rowstride;
/* the data pointers... */
src = (unsigned char *) g_malloc (orig_width * bytes);
src = g_new (guchar, orig_width * bytes);
dest = destPR->data;
/* find the ratios of old x to new x and old y to new y */
x_rat = (double) orig_width / (double) width;
y_rat = (double) orig_height / (double) height;
x_rat = (gdouble) orig_width / (gdouble) width;
y_rat = (gdouble) orig_height / (gdouble) height;
/* allocate an array to help with the calculations */
row = (double *) g_malloc (sizeof (double) * width * bytes);
x_frac = (double *) g_malloc (sizeof (double) * (width + orig_width));
row = g_new (gdouble, width * bytes);
x_frac = g_new (gdouble, width + orig_width);
/* initialize the pre-calculated pixel fraction array */
src_col = 0;
x_cum = (double) src_col;
x_cum = (gdouble) src_col;
x_last = x_cum;
for (i = 0; i < width + orig_width; i++)
@ -1506,7 +1576,7 @@ layer_preview_scale (gint type,
}
/* clear the "row" array */
memset (row, 0, sizeof (double) * width * bytes);
memset (row, 0, sizeof (gdouble) * width * bytes);
/* counters... */
src_row = 0;
@ -1519,7 +1589,7 @@ layer_preview_scale (gint type,
for (i = 0; i < height; )
{
src_col = 0;
x_cum = (double) src_col;
x_cum = (gdouble) src_col;
/* determine the fraction of the src pixel we are using for y */
if (y_cum + y_rat <= (src_row + 1 + EPSILON))
@ -1548,7 +1618,7 @@ layer_preview_scale (gint type,
tot_frac = x_frac[frac++] * y_frac;
/* If indexed, transform the color to RGB */
if (type == 2)
if (type == INDEXED)
{
map_to_color (2, cmap, s, rgb);
@ -1591,13 +1661,13 @@ layer_preview_scale (gint type,
{
b = bytes;
while (b--)
*d++ = (unsigned char) ((*r++ * tot_frac)+0.5);
*d++ = (guchar) ((*r++ * tot_frac)+0.5);
}
dest += destwidth;
/* clear the "row" array */
memset (row, 0, sizeof (double) * destwidth);
memset (row, 0, sizeof (gdouble) * destwidth);
i++;
}
@ -1643,10 +1713,10 @@ layer_mask_new (GimpImage *gimage,
/* set the layer_mask color and opacity */
for (i = 0; i < 3; i++)
GIMP_CHANNEL (layer_mask)->col[i] = col[i];
GIMP_CHANNEL (layer_mask)->col[i] = col[i];
GIMP_CHANNEL (layer_mask)->opacity = opacity;
GIMP_CHANNEL (layer_mask)->show_masked = TRUE;
GIMP_CHANNEL (layer_mask)->opacity = opacity;
GIMP_CHANNEL (layer_mask)->show_masked = TRUE;
/* selection mask variables */
GIMP_CHANNEL (layer_mask)->empty = TRUE;
@ -1666,7 +1736,7 @@ layer_mask_new (GimpImage *gimage,
LayerMask *
layer_mask_copy (LayerMask *layer_mask)
{
char * layer_mask_name;
gchar * layer_mask_name;
LayerMask * new_layer_mask;
PixelRegion srcPR, destPR;
@ -1686,10 +1756,14 @@ layer_mask_copy (LayerMask *layer_mask)
GIMP_CHANNEL(new_layer_mask)->show_masked = GIMP_CHANNEL(layer_mask)->show_masked;
/* copy the contents across layer masks */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer_mask)->tiles, 0, 0,
GIMP_DRAWABLE(layer_mask)->width,
GIMP_DRAWABLE(layer_mask)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer_mask)->tiles, 0, 0, GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer_mask)->tiles,
0, 0,
GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer_mask)->tiles,
0, 0,
GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height,
TRUE);
copy_region (&srcPR, &destPR);
/* free up the layer_mask_name memory */
@ -1702,7 +1776,9 @@ LayerMask *
layer_mask_get_ID (gint ID)
{
GimpDrawable *drawable;
drawable = drawable_get_ID (ID);
if (drawable && GIMP_IS_LAYER_MASK (drawable))
return GIMP_LAYER_MASK (drawable);
else
@ -1720,6 +1796,7 @@ layer_mask_ref (LayerMask *mask)
{
gtk_object_ref (GTK_OBJECT (mask));
gtk_object_sink (GTK_OBJECT (mask));
return mask;
}
@ -1747,25 +1824,34 @@ channel_layer_mask (Channel *mask,
Layer *layer)
{
PixelRegion srcPR, destPR;
unsigned char empty = 0;
int x1, y1, x2, y2;
guchar empty = 0;
gint x1, y1, x2, y2;
/* push the current mask onto the undo stack */
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles,
0, 0,
GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height,
TRUE);
color_region (&destPR, &empty);
x1 = CLAMP (GIMP_DRAWABLE(layer)->offset_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = CLAMP (GIMP_DRAWABLE(layer)->offset_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = CLAMP (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = CLAMP (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, 0, GIMP_DRAWABLE(mask)->height);
x2 = CLAMP (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width,
0, GIMP_DRAWABLE(mask)->width);
y2 = CLAMP (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height,
0, GIMP_DRAWABLE(mask)->height);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer->mask)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
(x2 - x1), (y2 - y1),
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles,
x1, y1,
(x2 - x1), (y2 - y1),
TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;

View File

@ -71,66 +71,108 @@ struct _fs_to_layer_undo
/* function declarations */
Layer * layer_new (GimpImage*, gint, gint,
GimpImageType,
gchar *, gint,
LayerModeEffects);
Layer * layer_copy (Layer *, gboolean);
Layer * layer_ref (Layer *);
void layer_unref (Layer *);
Layer * layer_new (GimpImage *gimage,
gint width,
gint height,
GimpImageType type,
gchar *name,
gint opacity,
LayerModeEffects mode);
Layer * layer_copy (Layer *layer,
gboolean add_alpha);
Layer * layer_ref (Layer *layer);
void layer_unref (Layer *layer);
Layer * layer_new_from_tiles (GimpImage *, GimpImageType, TileManager *,
gchar *, gint, LayerModeEffects);
LayerMask * layer_add_mask (Layer *, LayerMask *);
gboolean layer_check_scaling (Layer *, gint, gint);
LayerMask * layer_create_mask (Layer *, AddMaskType);
Layer * layer_get_ID (gint);
void layer_delete (Layer *);
void layer_removed (Layer *, gpointer);
void layer_apply_mask (Layer *, MaskApplyMode);
void layer_temporarily_translate (Layer *, gint, gint);
void layer_translate (Layer *, gint, gint);
void layer_add_alpha (Layer *);
gboolean layer_scale_by_factors (Layer *, gdouble, gdouble);
void layer_scale (Layer *, gint, gint, gboolean);
void layer_resize (Layer *, gint, gint, gint, gint);
void layer_resize_to_image (Layer *);
BoundSeg * layer_boundary (Layer *, gint *);
void layer_invalidate_boundary (Layer *);
gint layer_pick_correlate (Layer *, gint, gint);
Layer * layer_new_from_tiles (GimpImage *gimage,
GimpImageType layer_type,
TileManager *tiles,
gchar *name,
gint opacity,
LayerModeEffects mode);
gboolean layer_check_scaling (Layer *layer,
gint new_width,
gint new_height);
LayerMask * layer_create_mask (Layer *layer,
AddMaskType add_mask_type);
LayerMask * layer_add_mask (Layer *layer,
LayerMask *mask);
Layer * layer_get_ID (gint ID);
void layer_delete (Layer *layer);
void layer_removed (Layer *layer,
gpointer data);
void layer_apply_mask (Layer *layer,
MaskApplyMode mode);
void layer_temporarily_translate (Layer *layer,
gint off_x,
gint off_y);
void layer_translate (Layer *layer,
gint off_x,
gint off_y);
void layer_add_alpha (Layer *layer);
gboolean layer_scale_by_factors (Layer *layer,
gdouble w_factor,
gdouble h_factor);
void layer_scale (Layer *layer,
gint new_width,
gint new_height,
gboolean local_origin);
void layer_resize (Layer *layer,
gint new_width,
gint new_height,
gint offx,
gint offy);
void layer_resize_to_image (Layer *layer);
BoundSeg * layer_boundary (Layer *layer,
gint *num_segs);
void layer_invalidate_boundary (Layer *layer);
gint layer_pick_correlate (Layer *layer,
gint x,
gint y);
LayerMask * layer_mask_new (GimpImage*, gint, gint, gchar *,
gint, guchar *);
LayerMask * layer_mask_copy (LayerMask *);
void layer_mask_delete (LayerMask *);
LayerMask * layer_mask_get_ID (gint);
LayerMask * layer_mask_ref (LayerMask *);
void layer_mask_unref (LayerMask *);
void layer_mask_set_layer (LayerMask *, Layer *);
Layer * layer_mask_get_layer (LayerMask *);
LayerMask * layer_mask_new (GimpImage *gimage,
gint width,
gint height,
gchar *name,
gint opacity,
guchar *col);
LayerMask * layer_mask_copy (LayerMask *layer_mask);
void layer_mask_delete (LayerMask *layer_mask);
LayerMask * layer_mask_get_ID (gint ID);
LayerMask * layer_mask_ref (LayerMask *layer_mask);
void layer_mask_unref (LayerMask *layer_mask);
void layer_mask_set_layer (LayerMask *layer_mask,
Layer *layer);
Layer * layer_mask_get_layer (LayerMask *layer_mask);
/* access functions */
void layer_set_name (Layer *, gchar *);
gchar * layer_get_name (Layer *);
guchar * layer_data (Layer *);
LayerMask * layer_get_mask (Layer *);
gboolean layer_has_alpha (Layer *);
gboolean layer_is_floating_sel (Layer *);
gboolean layer_linked (Layer *);
TempBuf * layer_preview (Layer *, gint, gint);
TempBuf * layer_mask_preview (Layer *, gint, gint);
void layer_set_name (Layer *layer,
gchar *name);
gchar * layer_get_name (Layer *layer);
guchar * layer_data (Layer *layer);
LayerMask * layer_get_mask (Layer *layer);
gboolean layer_has_alpha (Layer *layer);
gboolean layer_is_floating_sel (Layer *layer);
gboolean layer_linked (Layer *layer);
TempBuf * layer_preview (Layer *layer,
gint width,
gint height);
TempBuf * layer_mask_preview (Layer *layer,
gint width,
gint height);
void layer_invalidate_previews (GimpImage *);
Tattoo layer_get_tattoo (const Layer *);
void layer_set_tattoo (const Layer *, Tattoo);
void layer_invalidate_previews (GimpImage *gimage);
Tattoo layer_get_tattoo (const Layer *layer);
void layer_set_tattoo (const Layer *layer,
Tattoo value);
#define drawable_layer GIMP_IS_LAYER
#define drawable_layer_mask GIMP_IS_LAYER_MASK
void channel_layer_alpha (Channel *mask,
Layer *layer);
/* from channel.c */
void channel_layer_alpha (Channel *, Layer *);
void channel_layer_mask (Channel *, Layer *);
void channel_layer_mask (Channel *mask,
Layer *layer);
#endif /* __LAYER_H__ */

View File

@ -120,6 +120,9 @@ struct _LayerWidget
gboolean visited;
GimpDropType drop_type;
gboolean layer_pixmap_valid;
guint invalidate_preview_handler;
};
/* layers dialog widget routines */
@ -364,27 +367,26 @@ layers_dialog_create (void)
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
gtk_widget_show (label);
layersD->mode_option_menu = gimp_option_menu_new2
(FALSE, paint_mode_menu_callback,
NULL, (gpointer) NORMAL_MODE,
_("Normal"), (gpointer) NORMAL_MODE, NULL,
_("Dissolve"), (gpointer) DISSOLVE_MODE, NULL,
_("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL,
_("Divide (Dodge)"), (gpointer) DIVIDE_MODE, NULL,
_("Screen"), (gpointer) SCREEN_MODE, NULL,
_("Overlay"), (gpointer) OVERLAY_MODE, NULL,
_("Difference"), (gpointer) DIFFERENCE_MODE, NULL,
_("Addition"), (gpointer) ADDITION_MODE, NULL,
_("Subtract"), (gpointer) SUBTRACT_MODE, NULL,
_("Darken Only"), (gpointer) DARKEN_ONLY_MODE, NULL,
_("Lighten Only"), (gpointer) LIGHTEN_ONLY_MODE, NULL,
_("Hue"), (gpointer) HUE_MODE, NULL,
_("Saturation"), (gpointer) SATURATION_MODE, NULL,
_("Color"), (gpointer) COLOR_MODE, NULL,
_("Value"), (gpointer) VALUE_MODE, NULL,
NULL);
layersD->mode_option_menu =
gimp_option_menu_new2 (FALSE, paint_mode_menu_callback,
NULL, (gpointer) NORMAL_MODE,
_("Normal"), (gpointer) NORMAL_MODE, NULL,
_("Dissolve"), (gpointer) DISSOLVE_MODE, NULL,
_("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL,
_("Divide (Dodge)"), (gpointer) DIVIDE_MODE, NULL,
_("Screen"), (gpointer) SCREEN_MODE, NULL,
_("Overlay"), (gpointer) OVERLAY_MODE, NULL,
_("Difference"), (gpointer) DIFFERENCE_MODE, NULL,
_("Addition"), (gpointer) ADDITION_MODE, NULL,
_("Subtract"), (gpointer) SUBTRACT_MODE, NULL,
_("Darken Only"), (gpointer) DARKEN_ONLY_MODE, NULL,
_("Lighten Only"), (gpointer) LIGHTEN_ONLY_MODE, NULL,
_("Hue"), (gpointer) HUE_MODE, NULL,
_("Saturation"), (gpointer) SATURATION_MODE, NULL,
_("Color"), (gpointer) COLOR_MODE, NULL,
_("Value"), (gpointer) VALUE_MODE, NULL,
NULL);
gtk_box_pack_start (GTK_BOX (util_box), layersD->mode_option_menu,
FALSE, FALSE, 2);
gtk_widget_show (layersD->mode_option_menu);
@ -442,7 +444,7 @@ layers_dialog_create (void)
gtk_signal_connect (GTK_OBJECT (layersD->layer_list), "event",
(GtkSignalFunc) layer_list_events,
layersD);
gtk_container_set_focus_vadjustment (GTK_CONTAINER (layersD->layer_list),
gtk_container_set_focus_vadjustment (GTK_CONTAINER (layersD->layer_list),
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (layersD->scrolled_win)));
GTK_WIDGET_UNSET_FLAGS (GTK_SCROLLED_WINDOW (layersD->scrolled_win)->vscrollbar,
GTK_CAN_FOCUS);
@ -473,7 +475,7 @@ layers_dialog_create (void)
GTK_SIGNAL_FUNC (layers_dialog_drag_duplicate_layer_callback),
NULL);
/* Drop to trahcan */
/* Drop to trashcan */
gtk_drag_dest_set (layers_ops_buttons[5].widget,
GTK_DEST_DEFAULT_ALL,
trashcan_target_table, n_trashcan_targets,
@ -752,7 +754,8 @@ render_preview (TempBuf *preview_buf,
* the preview buf is assumed to be gray despite the number of
* channels it contains
*/
color = (preview_buf->bytes == 3 || preview_buf->bytes == 4) && (channel == -1);
color = (channel == -1) &&
(preview_buf->bytes == 3 || preview_buf->bytes == 4);
if (has_alpha)
{
@ -1218,6 +1221,17 @@ layers_dialog_position_layer (Layer *layer,
suspend_gimage_notify--;
}
static void
invalidate_preview_callback (GtkWidget *widget,
LayerWidget *layer_widget)
{
layer_widget->layer_pixmap_valid = FALSE;
/* synthesize an expose event */
gtk_widget_queue_draw (layer_widget->layer_preview);
}
static void
layers_dialog_add_layer (Layer *layer)
{
@ -1238,6 +1252,11 @@ layers_dialog_add_layer (Layer *layer)
layersD->layer_widgets =
g_slist_insert (layersD->layer_widgets, layer_widget, position);
gtk_list_insert_items (GTK_LIST (layersD->layer_list), item_list, position);
layer_widget->invalidate_preview_handler =
gtk_signal_connect (GTK_OBJECT (layer), "invalidate_pr",
GTK_SIGNAL_FUNC (invalidate_preview_callback),
(gpointer)layer_widget);
}
static void
@ -1253,6 +1272,9 @@ layers_dialog_remove_layer (Layer *layer)
/* Make sure the gimage is not notified of this change */
suspend_gimage_notify++;
gtk_signal_disconnect (GTK_OBJECT (layer),
layer_widget->invalidate_preview_handler);
/* Remove the requested layer from the dialog */
list = g_list_append (list, layer_widget->list_item);
gtk_list_remove_items (GTK_LIST (layersD->layer_list), list);
@ -2025,21 +2047,22 @@ layer_widget_create (GimpImage *gimage,
/* create the layer widget and add it to the list */
layer_widget = g_new (LayerWidget, 1);
layer_widget->gimage = gimage;
layer_widget->layer = layer;
layer_widget->list_item = list_item;
layer_widget->layer_preview = NULL;
layer_widget->mask_preview = NULL;
layer_widget->layer_pixmap = NULL;
layer_widget->mask_pixmap = NULL;
layer_widget->width = -1;
layer_widget->height = -1;
layer_widget->layer_mask = (layer_get_mask (layer) != NULL);
layer_widget->apply_mask = layer->apply_mask;
layer_widget->edit_mask = layer->edit_mask;
layer_widget->show_mask = layer->show_mask;
layer_widget->visited = TRUE;
layer_widget->drop_type = GIMP_DROP_NONE;
layer_widget->gimage = gimage;
layer_widget->layer = layer;
layer_widget->list_item = list_item;
layer_widget->layer_preview = NULL;
layer_widget->mask_preview = NULL;
layer_widget->layer_pixmap = NULL;
layer_widget->mask_pixmap = NULL;
layer_widget->width = -1;
layer_widget->height = -1;
layer_widget->layer_mask = (layer_get_mask (layer) != NULL);
layer_widget->apply_mask = layer->apply_mask;
layer_widget->edit_mask = layer->edit_mask;
layer_widget->show_mask = layer->show_mask;
layer_widget->visited = TRUE;
layer_widget->drop_type = GIMP_DROP_NONE;
layer_widget->layer_pixmap_valid = FALSE;
if (layer_get_mask (layer))
layer_widget->active_preview =
@ -2511,7 +2534,7 @@ layer_widget_button_events (GtkWidget *widget,
GdkEventButton *bevent;
gint return_val;
static gboolean button_down = FALSE;
static gboolean button_down = FALSE;
static GtkWidget *click_widget = NULL;
static gint old_state;
static gint exclusive;
@ -2672,11 +2695,11 @@ layer_widget_preview_events (GtkWidget *widget,
{
case LAYER_PREVIEW:
pixmap = &layer_widget->layer_pixmap;
valid = GIMP_DRAWABLE (layer_widget->layer)->preview_valid;
valid = GIMP_DRAWABLE (layer_widget->layer)->preview_valid;
break;
case MASK_PREVIEW:
pixmap = &layer_widget->mask_pixmap;
valid = GIMP_DRAWABLE (layer_get_mask (layer_widget->layer))->preview_valid;
valid = GIMP_DRAWABLE (layer_get_mask (layer_widget->layer))->preview_valid;
break;
}
@ -2685,7 +2708,7 @@ layer_widget_preview_events (GtkWidget *widget,
switch (event->type)
{
case GDK_BUTTON_PRESS:
case GDK_BUTTON_PRESS:
/* Control-button press disables the application of the mask */
bevent = (GdkEventButton *) event;
@ -2779,17 +2802,33 @@ layer_widget_preview_events (GtkWidget *widget,
h = layersD->image_height - sy;
if ((w > 0) && (h > 0))
gdk_draw_pixmap (widget->window,
widget->style->black_gc,
*pixmap,
sx, sy, dx, dy, w, h);
{
/* Expose events are optimzed away by GTK+ if the widget is not
visible. Therefore, previews not visible in the layers_dialog
are not redrawn when they invalidate. Later the preview gets
validated by the image_preview in lc_dialog but is never
propagated to the layer_pixmap. We work around this by using an
additional flag "layer_pixmap_valid" so that the pixmap gets
updated once the preview scrolls into sight.
We should probably do the same for all drawables (masks,
channels), but it is much more difficult to change one of these
when it's not visible.
*/
if (preview_type == LAYER_PREVIEW && ! layer_widget->layer_pixmap_valid)
layer_widget_preview_redraw (layer_widget, preview_type);
gdk_draw_pixmap (widget->window,
widget->style->black_gc,
*pixmap,
sx, sy, dx, dy, w, h);
}
}
}
}
/* The boundary indicating whether layer or mask is active */
layer_widget_boundary_redraw (layer_widget, preview_type);
break;
default:
break;
}
@ -2923,6 +2962,7 @@ layer_widget_preview_redraw (LayerWidget *layer_widget,
layer_widget->width,
layer_widget->height);
layer_widget->layer_pixmap_valid = TRUE;
break;
case MASK_PREVIEW:
preview_buf = layer_mask_preview (layer_widget->layer,
@ -2942,10 +2982,11 @@ layer_widget_preview_redraw (LayerWidget *layer_widget,
gtk_preview_put (GTK_PREVIEW (layersD->layer_preview),
*pixmap, widget->style->black_gc,
0, 0, 0, 0, layersD->image_width, layersD->image_height);
0, 0, 0, 0,
layersD->image_width, layersD->image_height);
/* make sure the image has been transfered completely to the pixmap before
* we use it again...
/* make sure the image has been transfered completely to the pixmap
* before we use it again...
*/
gdk_flush ();
}

View File

@ -53,7 +53,7 @@ enum {
static void gimp_layer_class_init (GimpLayerClass *klass);
static void gimp_layer_init (GimpLayer *layer);
static void gimp_layer_destroy (GtkObject *object);
static void layer_invalidate_preview (GtkObject *);
static void layer_invalidate_preview (GtkObject *object);
static void gimp_layer_mask_class_init (GimpLayerMaskClass *klass);
static void gimp_layer_mask_init (GimpLayerMask *layermask);
@ -138,7 +138,8 @@ gimp_layer_mask_get_type (void)
(GtkClassInitFunc) NULL,
};
layer_mask_type = gtk_type_unique (gimp_channel_get_type (), &layer_mask_info);
layer_mask_type = gtk_type_unique (gimp_channel_get_type (),
&layer_mask_info);
}
return layer_mask_type;
@ -166,11 +167,16 @@ gimp_layer_mask_init (GimpLayerMask *layermask)
/* static functions */
static void transform_color (GImage *, PixelRegion *,
PixelRegion *, GimpDrawable *,
GimpImageBaseType);
static void layer_preview_scale (int, unsigned char *, PixelRegion *,
PixelRegion *, int);
static void transform_color (GImage *gimage,
PixelRegion *layerPR,
PixelRegion *bufPR,
GimpDrawable *drawable,
GimpImageBaseType type);
static void layer_preview_scale (GimpImageBaseType type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample);
/*
* Static variables
@ -207,7 +213,9 @@ transform_color (GImage *gimage,
unsigned char * s, * d;
void * pr;
for (pr = pixel_regions_register (2, layerPR, bufPR); pr != NULL; pr = pixel_regions_process (pr))
for (pr = pixel_regions_register (2, layerPR, bufPR);
pr != NULL;
pr = pixel_regions_process (pr))
{
h = layerPR->h;
s = bufPR->data;
@ -361,24 +369,37 @@ layer_copy (Layer *layer,
/* copy the contents across layers */
if (new_type == GIMP_DRAWABLE (layer)->type)
{
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
copy_region (&srcPR, &destPR);
}
else
{
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
add_alpha_region (&srcPR, &destPR);
}
/* duplicate the layer mask if necessary */
if (layer->mask)
{
new_layer->mask = layer_mask_ref (layer_mask_copy (layer->mask));
new_layer->mask = layer_mask_ref (layer_mask_copy (layer->mask));
new_layer->apply_mask = layer->apply_mask;
new_layer->edit_mask = layer->edit_mask;
new_layer->show_mask = layer->show_mask;
layer_mask_set_layer (new_layer->mask, new_layer);
}
@ -428,8 +449,14 @@ layer_new_from_tiles (GimpImage *gimage,
}
/* Configure the pixel regions */
pixel_region_init (&layerPR, GIMP_DRAWABLE (new_layer)->tiles, 0, 0, GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height, TRUE);
pixel_region_init (&bufPR, tiles, 0, 0, GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height, FALSE);
pixel_region_init (&layerPR, GIMP_DRAWABLE (new_layer)->tiles,
0, 0,
GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height,
TRUE);
pixel_region_init (&bufPR, tiles,
0, 0,
GIMP_DRAWABLE (new_layer)->width, GIMP_DRAWABLE (new_layer)->height,
FALSE);
if ((tiles->bpp == 4 && GIMP_DRAWABLE (new_layer)->type == RGBA_GIMAGE) ||
(tiles->bpp == 2 && GIMP_DRAWABLE (new_layer)->type == GRAYA_GIMAGE))
@ -486,7 +513,10 @@ layer_create_mask (Layer *layer,
GIMP_DRAWABLE (mask)->offset_x = GIMP_DRAWABLE (layer)->offset_x;
GIMP_DRAWABLE (mask)->offset_y = GIMP_DRAWABLE (layer)->offset_y;
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles, 0, 0, GIMP_DRAWABLE (mask)->width, GIMP_DRAWABLE (mask)->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE (mask)->tiles,
0, 0,
GIMP_DRAWABLE (mask)->width, GIMP_DRAWABLE (mask)->height,
TRUE);
switch (add_mask_type)
{
@ -500,7 +530,10 @@ layer_create_mask (Layer *layer,
/* Extract the layer's alpha channel */
if (layer_has_alpha (layer))
{
pixel_region_init (&layerPR, GIMP_DRAWABLE (layer)->tiles, 0, 0, GIMP_DRAWABLE (layer)->width, GIMP_DRAWABLE (layer)->height, FALSE);
pixel_region_init (&layerPR, GIMP_DRAWABLE (layer)->tiles,
0, 0,
GIMP_DRAWABLE (layer)->width, GIMP_DRAWABLE (layer)->height,
FALSE);
extract_alpha_region (&layerPR, NULL, &maskPR);
}
break;
@ -563,7 +596,7 @@ gimp_layer_destroy (GtkObject *object)
* particular layer. */
void
layer_removed (Layer *layer,
gpointer image)
gpointer data)
{
g_return_if_fail (layer != NULL);
g_return_if_fail (GIMP_IS_LAYER (layer));
@ -596,8 +629,14 @@ layer_apply_mask (Layer *layer,
NULL, FALSE);
/* Combine the current layer's alpha channel and the mask */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(layer->mask)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(layer->mask)->tiles,
0, 0, GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height,
FALSE);
apply_mask_to_region (&srcPR, &maskPR, OPAQUE_OPACITY);
GIMP_DRAWABLE (layer)->preview_valid = FALSE;
@ -654,7 +693,7 @@ layer_translate_lowlevel (Layer *layer,
if (!temporary)
{
/* invalidate the mask preview */
drawable_invalidate_preview (GIMP_DRAWABLE(layer->mask));
drawable_invalidate_preview (GIMP_DRAWABLE (layer->mask));
}
}
}
@ -703,11 +742,19 @@ layer_add_alpha (Layer *layer)
}
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, (GIMP_DRAWABLE(layer)->bytes + 1));
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height,
GIMP_DRAWABLE(layer)->bytes + 1);
pixel_region_init (&destPR, new_tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
TRUE);
/* Add an alpha channel */
add_alpha_region (&srcPR, &destPR);
@ -727,11 +774,11 @@ layer_add_alpha (Layer *layer)
}
static void
layer_scale_lowlevel(Layer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y)
layer_scale_lowlevel (Layer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y)
{
PixelRegion srcPR, destPR;
TileManager *new_tiles;
@ -742,19 +789,25 @@ layer_scale_lowlevel(Layer *layer,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, GIMP_DRAWABLE(layer)->bytes);
pixel_region_init (&destPR, new_tiles, 0, 0, new_width, new_height, TRUE);
pixel_region_init (&destPR, new_tiles,
0, 0,
new_width, new_height,
TRUE);
/* Scale the layer -
* If the layer is of type INDEXED, then we don't use pixel-value
* resampling because that doesn't necessarily make sense for INDEXED
* images.
*/
if ((GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) || (GIMP_DRAWABLE(layer)->type == INDEXEDA_GIMAGE))
if ((GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) ||
(GIMP_DRAWABLE(layer)->type == INDEXEDA_GIMAGE))
scale_region_no_resample (&srcPR, &destPR);
else
scale_region (&srcPR, &destPR);
@ -868,7 +921,7 @@ layer_scale_by_factors (Layer *layer,
/**
* layer_scale:
* @layer: The layer to be transformed by width & height scale factors
* @layer: The layer to be transformed by width & height scale factors
* @new_width: The width that layer will acquire
* @new_height: The height that the layer will acquire
* @local_origin: sets fixed point of the scaling transform. See below.
@ -973,11 +1026,17 @@ layer_resize (Layer *layer,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, x1, y1, w, h, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
x1, y1,
w, h,
FALSE);
/* Allocate the new layer, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, GIMP_DRAWABLE(layer)->bytes);
pixel_region_init (&destPR, new_tiles, 0, 0, new_width, new_height, TRUE);
pixel_region_init (&destPR, new_tiles,
0, 0,
new_width, new_height,
TRUE);
/* fill with the fill color */
if (layer_has_alpha (layer))
@ -992,7 +1051,10 @@ layer_resize (Layer *layer,
gimage_get_background (GIMP_DRAWABLE(layer)->gimage, GIMP_DRAWABLE(layer), bg);
color_region (&destPR, bg);
}
pixel_region_init (&destPR, new_tiles, x2, y2, w, h, TRUE);
pixel_region_init (&destPR, new_tiles,
x2, y2,
w, h,
TRUE);
/* copy from the old to the new */
if (w && h)
@ -1243,18 +1305,17 @@ layer_preview_private (Layer *layer,
GImage *gimage;
TempBuf *preview_buf;
PixelRegion srcPR, destPR;
int type;
int bytes;
int subsample;
GimpImageBaseType type;
gint bytes;
gint subsample;
TempBuf *ret_buf;
type = 0;
type = RGB;
bytes = 0;
/* The easy way */
if (GIMP_DRAWABLE(layer)->preview_valid &&
(ret_buf = gimp_preview_cache_get(&(GIMP_DRAWABLE(layer)->preview_cache),
w,h)))
(ret_buf = gimp_preview_cache_get (&(GIMP_DRAWABLE(layer)->preview_cache), w,h)))
return ret_buf;
/* The hard way */
else
@ -1263,15 +1324,15 @@ layer_preview_private (Layer *layer,
switch (GIMP_DRAWABLE(layer)->type)
{
case RGB_GIMAGE: case RGBA_GIMAGE:
type = 0;
type = RGB;
bytes = GIMP_DRAWABLE(layer)->bytes;
break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
type = 1;
type = GRAY;
bytes = GIMP_DRAWABLE(layer)->bytes;
break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
type = 2;
type = INDEXED;
bytes = (GIMP_DRAWABLE(layer)->type == INDEXED_GIMAGE) ? 3 : 4;
break;
}
@ -1285,49 +1346,54 @@ layer_preview_private (Layer *layer,
(h * (subsample + 1) * 2 < GIMP_DRAWABLE(layer)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
0, 0,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height,
FALSE);
preview_buf = temp_buf_new (w, h, bytes, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.rowstride = w * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
destPR.data = temp_buf_data (preview_buf);
layer_preview_scale (type, gimage->cmap, &srcPR, &destPR, subsample);
if (!GIMP_DRAWABLE(layer)->preview_valid)
gimp_preview_cache_invalidate(&(GIMP_DRAWABLE(layer)->preview_cache));
if (!GIMP_DRAWABLE (layer)->preview_valid)
gimp_preview_cache_invalidate (&(GIMP_DRAWABLE (layer)->preview_cache));
GIMP_DRAWABLE(layer)->preview_valid = TRUE;
GIMP_DRAWABLE (layer)->preview_valid = TRUE;
gimp_preview_cache_add (&(GIMP_DRAWABLE (layer)->preview_cache), preview_buf);
gimp_preview_cache_add(&(GIMP_DRAWABLE(layer)->preview_cache),preview_buf);
return preview_buf;
}
}
TempBuf *
layer_preview (Layer *layer,
gint w,
gint h)
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(layer)->preview_valid &&
w <= PREVIEW_CACHE_PRIME_WIDTH &&
h <= PREVIEW_CACHE_PRIME_HEIGHT)
if (!GIMP_DRAWABLE(layer)->preview_valid &&
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = layer_preview_private(layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
TempBuf * tb = layer_preview_private (layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(w == PREVIEW_CACHE_PRIME_WIDTH &&
h == PREVIEW_CACHE_PRIME_HEIGHT)
if (width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return layer_preview_private(layer,w,h);
return layer_preview_private (layer, width, height);
}
static TempBuf *
@ -1338,7 +1404,7 @@ layer_mask_preview_private (Layer *layer,
TempBuf *preview_buf;
LayerMask *mask;
PixelRegion srcPR, destPR;
int subsample;
gint subsample;
TempBuf *ret_buf;
mask = layer->mask;
@ -1347,8 +1413,7 @@ layer_mask_preview_private (Layer *layer,
/* The easy way */
if (GIMP_DRAWABLE(mask)->preview_valid &&
(ret_buf = gimp_preview_cache_get(&(GIMP_DRAWABLE(mask)->preview_cache),
w,h)))
(ret_buf = gimp_preview_cache_get (&(GIMP_DRAWABLE(mask)->preview_cache), w, h)))
return ret_buf;
/* The hard way */
else
@ -1361,18 +1426,22 @@ layer_mask_preview_private (Layer *layer,
(h * (subsample + 1) * 2 < GIMP_DRAWABLE(layer)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles,
0, 0,
GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height,
FALSE);
preview_buf = temp_buf_new (w, h, 1, 0, 0, NULL);
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.bytes = preview_buf->bytes;
destPR.w = w;
destPR.h = h;
destPR.rowstride = w * destPR.bytes;
destPR.data = temp_buf_data (preview_buf);
destPR.data = temp_buf_data (preview_buf);
layer_preview_scale (1 /* GRAY */, NULL, &srcPR, &destPR, subsample);
if(!GIMP_DRAWABLE (mask)->preview_valid)
if (!GIMP_DRAWABLE (mask)->preview_valid)
gimp_preview_cache_invalidate (&(GIMP_DRAWABLE (mask)->preview_cache));
GIMP_DRAWABLE (mask)->preview_valid = TRUE;
@ -1385,26 +1454,26 @@ layer_mask_preview_private (Layer *layer,
TempBuf *
layer_mask_preview (Layer *layer,
gint w,
gint h)
gint width,
gint height)
{
/* Ok prime the cache with a large preview if the cache is invalid */
if(!GIMP_DRAWABLE(layer->mask)->preview_valid &&
w <= PREVIEW_CACHE_PRIME_WIDTH &&
h <= PREVIEW_CACHE_PRIME_HEIGHT)
width <= PREVIEW_CACHE_PRIME_WIDTH &&
height <= PREVIEW_CACHE_PRIME_HEIGHT)
{
TempBuf * tb = layer_mask_preview_private(layer,
PREVIEW_CACHE_PRIME_WIDTH,
PREVIEW_CACHE_PRIME_HEIGHT);
/* Save the 2nd call */
if(w == PREVIEW_CACHE_PRIME_WIDTH &&
h == PREVIEW_CACHE_PRIME_HEIGHT)
if (width == PREVIEW_CACHE_PRIME_WIDTH &&
height == PREVIEW_CACHE_PRIME_HEIGHT)
return tb;
}
/* Second call - should NOT visit the tile cache...*/
return layer_mask_preview_private(layer,w,h);
return layer_mask_preview_private (layer, width, height);
}
@ -1415,14 +1484,15 @@ layer_get_tattoo (const Layer *layer)
}
void
layer_set_tattoo (const Layer *layer , Tattoo val)
layer_set_tattoo (const Layer *layer,
Tattoo value)
{
gimp_drawable_set_tattoo(GIMP_DRAWABLE (layer),val);
gimp_drawable_set_tattoo (GIMP_DRAWABLE (layer), value);
}
void
layer_invalidate_previews (GimpImage* gimage)
layer_invalidate_previews (GimpImage *gimage)
{
GSList * tmp;
Layer * layer;
@ -1440,54 +1510,54 @@ layer_invalidate_previews (GimpImage* gimage)
}
static void
layer_preview_scale (gint type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
layer_preview_scale (GimpImageBaseType type,
guchar *cmap,
PixelRegion *srcPR,
PixelRegion *destPR,
gint subsample)
{
#define EPSILON 0.000001
unsigned char * src, * s;
unsigned char * dest, * d;
double * row, * r;
int destwidth;
int src_row, src_col;
int bytes, b;
int width, height;
int orig_width, orig_height;
double x_rat, y_rat;
double x_cum, y_cum;
double x_last, y_last;
double * x_frac, y_frac, tot_frac;
int i, j;
int frac;
int advance_dest;
unsigned char rgb[MAX_CHANNELS];
guchar *src, *s;
guchar *dest, *d;
gdouble *row, *r;
gint destwidth;
gint src_row, src_col;
gint bytes, b;
gint width, height;
gint orig_width, orig_height;
gdouble x_rat, y_rat;
gdouble x_cum, y_cum;
gdouble x_last, y_last;
gdouble * x_frac, y_frac, tot_frac;
gint i, j;
gint frac;
gboolean advance_dest;
guchar rgb[MAX_CHANNELS];
orig_width = srcPR->w / subsample;
orig_width = srcPR->w / subsample;
orig_height = srcPR->h / subsample;
width = destPR->w;
width = destPR->w;
height = destPR->h;
/* Some calculations... */
bytes = destPR->bytes;
bytes = destPR->bytes;
destwidth = destPR->rowstride;
/* the data pointers... */
src = (unsigned char *) g_malloc (orig_width * bytes);
src = g_new (guchar, orig_width * bytes);
dest = destPR->data;
/* find the ratios of old x to new x and old y to new y */
x_rat = (double) orig_width / (double) width;
y_rat = (double) orig_height / (double) height;
x_rat = (gdouble) orig_width / (gdouble) width;
y_rat = (gdouble) orig_height / (gdouble) height;
/* allocate an array to help with the calculations */
row = (double *) g_malloc (sizeof (double) * width * bytes);
x_frac = (double *) g_malloc (sizeof (double) * (width + orig_width));
row = g_new (gdouble, width * bytes);
x_frac = g_new (gdouble, width + orig_width);
/* initialize the pre-calculated pixel fraction array */
src_col = 0;
x_cum = (double) src_col;
x_cum = (gdouble) src_col;
x_last = x_cum;
for (i = 0; i < width + orig_width; i++)
@ -1506,7 +1576,7 @@ layer_preview_scale (gint type,
}
/* clear the "row" array */
memset (row, 0, sizeof (double) * width * bytes);
memset (row, 0, sizeof (gdouble) * width * bytes);
/* counters... */
src_row = 0;
@ -1519,7 +1589,7 @@ layer_preview_scale (gint type,
for (i = 0; i < height; )
{
src_col = 0;
x_cum = (double) src_col;
x_cum = (gdouble) src_col;
/* determine the fraction of the src pixel we are using for y */
if (y_cum + y_rat <= (src_row + 1 + EPSILON))
@ -1548,7 +1618,7 @@ layer_preview_scale (gint type,
tot_frac = x_frac[frac++] * y_frac;
/* If indexed, transform the color to RGB */
if (type == 2)
if (type == INDEXED)
{
map_to_color (2, cmap, s, rgb);
@ -1591,13 +1661,13 @@ layer_preview_scale (gint type,
{
b = bytes;
while (b--)
*d++ = (unsigned char) ((*r++ * tot_frac)+0.5);
*d++ = (guchar) ((*r++ * tot_frac)+0.5);
}
dest += destwidth;
/* clear the "row" array */
memset (row, 0, sizeof (double) * destwidth);
memset (row, 0, sizeof (gdouble) * destwidth);
i++;
}
@ -1643,10 +1713,10 @@ layer_mask_new (GimpImage *gimage,
/* set the layer_mask color and opacity */
for (i = 0; i < 3; i++)
GIMP_CHANNEL (layer_mask)->col[i] = col[i];
GIMP_CHANNEL (layer_mask)->col[i] = col[i];
GIMP_CHANNEL (layer_mask)->opacity = opacity;
GIMP_CHANNEL (layer_mask)->show_masked = TRUE;
GIMP_CHANNEL (layer_mask)->opacity = opacity;
GIMP_CHANNEL (layer_mask)->show_masked = TRUE;
/* selection mask variables */
GIMP_CHANNEL (layer_mask)->empty = TRUE;
@ -1666,7 +1736,7 @@ layer_mask_new (GimpImage *gimage,
LayerMask *
layer_mask_copy (LayerMask *layer_mask)
{
char * layer_mask_name;
gchar * layer_mask_name;
LayerMask * new_layer_mask;
PixelRegion srcPR, destPR;
@ -1686,10 +1756,14 @@ layer_mask_copy (LayerMask *layer_mask)
GIMP_CHANNEL(new_layer_mask)->show_masked = GIMP_CHANNEL(layer_mask)->show_masked;
/* copy the contents across layer masks */
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer_mask)->tiles, 0, 0,
GIMP_DRAWABLE(layer_mask)->width,
GIMP_DRAWABLE(layer_mask)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer_mask)->tiles, 0, 0, GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer_mask)->tiles,
0, 0,
GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_layer_mask)->tiles,
0, 0,
GIMP_DRAWABLE(layer_mask)->width, GIMP_DRAWABLE(layer_mask)->height,
TRUE);
copy_region (&srcPR, &destPR);
/* free up the layer_mask_name memory */
@ -1702,7 +1776,9 @@ LayerMask *
layer_mask_get_ID (gint ID)
{
GimpDrawable *drawable;
drawable = drawable_get_ID (ID);
if (drawable && GIMP_IS_LAYER_MASK (drawable))
return GIMP_LAYER_MASK (drawable);
else
@ -1720,6 +1796,7 @@ layer_mask_ref (LayerMask *mask)
{
gtk_object_ref (GTK_OBJECT (mask));
gtk_object_sink (GTK_OBJECT (mask));
return mask;
}
@ -1747,25 +1824,34 @@ channel_layer_mask (Channel *mask,
Layer *layer)
{
PixelRegion srcPR, destPR;
unsigned char empty = 0;
int x1, y1, x2, y2;
guchar empty = 0;
gint x1, y1, x2, y2;
/* push the current mask onto the undo stack */
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles,
0, 0,
GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height,
TRUE);
color_region (&destPR, &empty);
x1 = CLAMP (GIMP_DRAWABLE(layer)->offset_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = CLAMP (GIMP_DRAWABLE(layer)->offset_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = CLAMP (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = CLAMP (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, 0, GIMP_DRAWABLE(mask)->height);
x2 = CLAMP (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width,
0, GIMP_DRAWABLE(mask)->width);
y2 = CLAMP (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height,
0, GIMP_DRAWABLE(mask)->height);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer->mask)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
(x2 - x1), (y2 - y1),
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles,
x1, y1,
(x2 - x1), (y2 - y1),
TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;

View File

@ -71,66 +71,108 @@ struct _fs_to_layer_undo
/* function declarations */
Layer * layer_new (GimpImage*, gint, gint,
GimpImageType,
gchar *, gint,
LayerModeEffects);
Layer * layer_copy (Layer *, gboolean);
Layer * layer_ref (Layer *);
void layer_unref (Layer *);
Layer * layer_new (GimpImage *gimage,
gint width,
gint height,
GimpImageType type,
gchar *name,
gint opacity,
LayerModeEffects mode);
Layer * layer_copy (Layer *layer,
gboolean add_alpha);
Layer * layer_ref (Layer *layer);
void layer_unref (Layer *layer);
Layer * layer_new_from_tiles (GimpImage *, GimpImageType, TileManager *,
gchar *, gint, LayerModeEffects);
LayerMask * layer_add_mask (Layer *, LayerMask *);
gboolean layer_check_scaling (Layer *, gint, gint);
LayerMask * layer_create_mask (Layer *, AddMaskType);
Layer * layer_get_ID (gint);
void layer_delete (Layer *);
void layer_removed (Layer *, gpointer);
void layer_apply_mask (Layer *, MaskApplyMode);
void layer_temporarily_translate (Layer *, gint, gint);
void layer_translate (Layer *, gint, gint);
void layer_add_alpha (Layer *);
gboolean layer_scale_by_factors (Layer *, gdouble, gdouble);
void layer_scale (Layer *, gint, gint, gboolean);
void layer_resize (Layer *, gint, gint, gint, gint);
void layer_resize_to_image (Layer *);
BoundSeg * layer_boundary (Layer *, gint *);
void layer_invalidate_boundary (Layer *);
gint layer_pick_correlate (Layer *, gint, gint);
Layer * layer_new_from_tiles (GimpImage *gimage,
GimpImageType layer_type,
TileManager *tiles,
gchar *name,
gint opacity,
LayerModeEffects mode);
gboolean layer_check_scaling (Layer *layer,
gint new_width,
gint new_height);
LayerMask * layer_create_mask (Layer *layer,
AddMaskType add_mask_type);
LayerMask * layer_add_mask (Layer *layer,
LayerMask *mask);
Layer * layer_get_ID (gint ID);
void layer_delete (Layer *layer);
void layer_removed (Layer *layer,
gpointer data);
void layer_apply_mask (Layer *layer,
MaskApplyMode mode);
void layer_temporarily_translate (Layer *layer,
gint off_x,
gint off_y);
void layer_translate (Layer *layer,
gint off_x,
gint off_y);
void layer_add_alpha (Layer *layer);
gboolean layer_scale_by_factors (Layer *layer,
gdouble w_factor,
gdouble h_factor);
void layer_scale (Layer *layer,
gint new_width,
gint new_height,
gboolean local_origin);
void layer_resize (Layer *layer,
gint new_width,
gint new_height,
gint offx,
gint offy);
void layer_resize_to_image (Layer *layer);
BoundSeg * layer_boundary (Layer *layer,
gint *num_segs);
void layer_invalidate_boundary (Layer *layer);
gint layer_pick_correlate (Layer *layer,
gint x,
gint y);
LayerMask * layer_mask_new (GimpImage*, gint, gint, gchar *,
gint, guchar *);
LayerMask * layer_mask_copy (LayerMask *);
void layer_mask_delete (LayerMask *);
LayerMask * layer_mask_get_ID (gint);
LayerMask * layer_mask_ref (LayerMask *);
void layer_mask_unref (LayerMask *);
void layer_mask_set_layer (LayerMask *, Layer *);
Layer * layer_mask_get_layer (LayerMask *);
LayerMask * layer_mask_new (GimpImage *gimage,
gint width,
gint height,
gchar *name,
gint opacity,
guchar *col);
LayerMask * layer_mask_copy (LayerMask *layer_mask);
void layer_mask_delete (LayerMask *layer_mask);
LayerMask * layer_mask_get_ID (gint ID);
LayerMask * layer_mask_ref (LayerMask *layer_mask);
void layer_mask_unref (LayerMask *layer_mask);
void layer_mask_set_layer (LayerMask *layer_mask,
Layer *layer);
Layer * layer_mask_get_layer (LayerMask *layer_mask);
/* access functions */
void layer_set_name (Layer *, gchar *);
gchar * layer_get_name (Layer *);
guchar * layer_data (Layer *);
LayerMask * layer_get_mask (Layer *);
gboolean layer_has_alpha (Layer *);
gboolean layer_is_floating_sel (Layer *);
gboolean layer_linked (Layer *);
TempBuf * layer_preview (Layer *, gint, gint);
TempBuf * layer_mask_preview (Layer *, gint, gint);
void layer_set_name (Layer *layer,
gchar *name);
gchar * layer_get_name (Layer *layer);
guchar * layer_data (Layer *layer);
LayerMask * layer_get_mask (Layer *layer);
gboolean layer_has_alpha (Layer *layer);
gboolean layer_is_floating_sel (Layer *layer);
gboolean layer_linked (Layer *layer);
TempBuf * layer_preview (Layer *layer,
gint width,
gint height);
TempBuf * layer_mask_preview (Layer *layer,
gint width,
gint height);
void layer_invalidate_previews (GimpImage *);
Tattoo layer_get_tattoo (const Layer *);
void layer_set_tattoo (const Layer *, Tattoo);
void layer_invalidate_previews (GimpImage *gimage);
Tattoo layer_get_tattoo (const Layer *layer);
void layer_set_tattoo (const Layer *layer,
Tattoo value);
#define drawable_layer GIMP_IS_LAYER
#define drawable_layer_mask GIMP_IS_LAYER_MASK
void channel_layer_alpha (Channel *mask,
Layer *layer);
/* from channel.c */
void channel_layer_alpha (Channel *, Layer *);
void channel_layer_mask (Channel *, Layer *);
void channel_layer_mask (Channel *mask,
Layer *layer);
#endif /* __LAYER_H__ */

View File

@ -120,6 +120,9 @@ struct _LayerWidget
gboolean visited;
GimpDropType drop_type;
gboolean layer_pixmap_valid;
guint invalidate_preview_handler;
};
/* layers dialog widget routines */
@ -364,27 +367,26 @@ layers_dialog_create (void)
gtk_box_pack_start (GTK_BOX (util_box), label, FALSE, FALSE, 2);
gtk_widget_show (label);
layersD->mode_option_menu = gimp_option_menu_new2
(FALSE, paint_mode_menu_callback,
NULL, (gpointer) NORMAL_MODE,
_("Normal"), (gpointer) NORMAL_MODE, NULL,
_("Dissolve"), (gpointer) DISSOLVE_MODE, NULL,
_("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL,
_("Divide (Dodge)"), (gpointer) DIVIDE_MODE, NULL,
_("Screen"), (gpointer) SCREEN_MODE, NULL,
_("Overlay"), (gpointer) OVERLAY_MODE, NULL,
_("Difference"), (gpointer) DIFFERENCE_MODE, NULL,
_("Addition"), (gpointer) ADDITION_MODE, NULL,
_("Subtract"), (gpointer) SUBTRACT_MODE, NULL,
_("Darken Only"), (gpointer) DARKEN_ONLY_MODE, NULL,
_("Lighten Only"), (gpointer) LIGHTEN_ONLY_MODE, NULL,
_("Hue"), (gpointer) HUE_MODE, NULL,
_("Saturation"), (gpointer) SATURATION_MODE, NULL,
_("Color"), (gpointer) COLOR_MODE, NULL,
_("Value"), (gpointer) VALUE_MODE, NULL,
NULL);
layersD->mode_option_menu =
gimp_option_menu_new2 (FALSE, paint_mode_menu_callback,
NULL, (gpointer) NORMAL_MODE,
_("Normal"), (gpointer) NORMAL_MODE, NULL,
_("Dissolve"), (gpointer) DISSOLVE_MODE, NULL,
_("Multiply (Burn)"), (gpointer) MULTIPLY_MODE, NULL,
_("Divide (Dodge)"), (gpointer) DIVIDE_MODE, NULL,
_("Screen"), (gpointer) SCREEN_MODE, NULL,
_("Overlay"), (gpointer) OVERLAY_MODE, NULL,
_("Difference"), (gpointer) DIFFERENCE_MODE, NULL,
_("Addition"), (gpointer) ADDITION_MODE, NULL,
_("Subtract"), (gpointer) SUBTRACT_MODE, NULL,
_("Darken Only"), (gpointer) DARKEN_ONLY_MODE, NULL,
_("Lighten Only"), (gpointer) LIGHTEN_ONLY_MODE, NULL,
_("Hue"), (gpointer) HUE_MODE, NULL,
_("Saturation"), (gpointer) SATURATION_MODE, NULL,
_("Color"), (gpointer) COLOR_MODE, NULL,
_("Value"), (gpointer) VALUE_MODE, NULL,
NULL);
gtk_box_pack_start (GTK_BOX (util_box), layersD->mode_option_menu,
FALSE, FALSE, 2);
gtk_widget_show (layersD->mode_option_menu);
@ -442,7 +444,7 @@ layers_dialog_create (void)
gtk_signal_connect (GTK_OBJECT (layersD->layer_list), "event",
(GtkSignalFunc) layer_list_events,
layersD);
gtk_container_set_focus_vadjustment (GTK_CONTAINER (layersD->layer_list),
gtk_container_set_focus_vadjustment (GTK_CONTAINER (layersD->layer_list),
gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (layersD->scrolled_win)));
GTK_WIDGET_UNSET_FLAGS (GTK_SCROLLED_WINDOW (layersD->scrolled_win)->vscrollbar,
GTK_CAN_FOCUS);
@ -473,7 +475,7 @@ layers_dialog_create (void)
GTK_SIGNAL_FUNC (layers_dialog_drag_duplicate_layer_callback),
NULL);
/* Drop to trahcan */
/* Drop to trashcan */
gtk_drag_dest_set (layers_ops_buttons[5].widget,
GTK_DEST_DEFAULT_ALL,
trashcan_target_table, n_trashcan_targets,
@ -752,7 +754,8 @@ render_preview (TempBuf *preview_buf,
* the preview buf is assumed to be gray despite the number of
* channels it contains
*/
color = (preview_buf->bytes == 3 || preview_buf->bytes == 4) && (channel == -1);
color = (channel == -1) &&
(preview_buf->bytes == 3 || preview_buf->bytes == 4);
if (has_alpha)
{
@ -1218,6 +1221,17 @@ layers_dialog_position_layer (Layer *layer,
suspend_gimage_notify--;
}
static void
invalidate_preview_callback (GtkWidget *widget,
LayerWidget *layer_widget)
{
layer_widget->layer_pixmap_valid = FALSE;
/* synthesize an expose event */
gtk_widget_queue_draw (layer_widget->layer_preview);
}
static void
layers_dialog_add_layer (Layer *layer)
{
@ -1238,6 +1252,11 @@ layers_dialog_add_layer (Layer *layer)
layersD->layer_widgets =
g_slist_insert (layersD->layer_widgets, layer_widget, position);
gtk_list_insert_items (GTK_LIST (layersD->layer_list), item_list, position);
layer_widget->invalidate_preview_handler =
gtk_signal_connect (GTK_OBJECT (layer), "invalidate_pr",
GTK_SIGNAL_FUNC (invalidate_preview_callback),
(gpointer)layer_widget);
}
static void
@ -1253,6 +1272,9 @@ layers_dialog_remove_layer (Layer *layer)
/* Make sure the gimage is not notified of this change */
suspend_gimage_notify++;
gtk_signal_disconnect (GTK_OBJECT (layer),
layer_widget->invalidate_preview_handler);
/* Remove the requested layer from the dialog */
list = g_list_append (list, layer_widget->list_item);
gtk_list_remove_items (GTK_LIST (layersD->layer_list), list);
@ -2025,21 +2047,22 @@ layer_widget_create (GimpImage *gimage,
/* create the layer widget and add it to the list */
layer_widget = g_new (LayerWidget, 1);
layer_widget->gimage = gimage;
layer_widget->layer = layer;
layer_widget->list_item = list_item;
layer_widget->layer_preview = NULL;
layer_widget->mask_preview = NULL;
layer_widget->layer_pixmap = NULL;
layer_widget->mask_pixmap = NULL;
layer_widget->width = -1;
layer_widget->height = -1;
layer_widget->layer_mask = (layer_get_mask (layer) != NULL);
layer_widget->apply_mask = layer->apply_mask;
layer_widget->edit_mask = layer->edit_mask;
layer_widget->show_mask = layer->show_mask;
layer_widget->visited = TRUE;
layer_widget->drop_type = GIMP_DROP_NONE;
layer_widget->gimage = gimage;
layer_widget->layer = layer;
layer_widget->list_item = list_item;
layer_widget->layer_preview = NULL;
layer_widget->mask_preview = NULL;
layer_widget->layer_pixmap = NULL;
layer_widget->mask_pixmap = NULL;
layer_widget->width = -1;
layer_widget->height = -1;
layer_widget->layer_mask = (layer_get_mask (layer) != NULL);
layer_widget->apply_mask = layer->apply_mask;
layer_widget->edit_mask = layer->edit_mask;
layer_widget->show_mask = layer->show_mask;
layer_widget->visited = TRUE;
layer_widget->drop_type = GIMP_DROP_NONE;
layer_widget->layer_pixmap_valid = FALSE;
if (layer_get_mask (layer))
layer_widget->active_preview =
@ -2511,7 +2534,7 @@ layer_widget_button_events (GtkWidget *widget,
GdkEventButton *bevent;
gint return_val;
static gboolean button_down = FALSE;
static gboolean button_down = FALSE;
static GtkWidget *click_widget = NULL;
static gint old_state;
static gint exclusive;
@ -2672,11 +2695,11 @@ layer_widget_preview_events (GtkWidget *widget,
{
case LAYER_PREVIEW:
pixmap = &layer_widget->layer_pixmap;
valid = GIMP_DRAWABLE (layer_widget->layer)->preview_valid;
valid = GIMP_DRAWABLE (layer_widget->layer)->preview_valid;
break;
case MASK_PREVIEW:
pixmap = &layer_widget->mask_pixmap;
valid = GIMP_DRAWABLE (layer_get_mask (layer_widget->layer))->preview_valid;
valid = GIMP_DRAWABLE (layer_get_mask (layer_widget->layer))->preview_valid;
break;
}
@ -2685,7 +2708,7 @@ layer_widget_preview_events (GtkWidget *widget,
switch (event->type)
{
case GDK_BUTTON_PRESS:
case GDK_BUTTON_PRESS:
/* Control-button press disables the application of the mask */
bevent = (GdkEventButton *) event;
@ -2779,17 +2802,33 @@ layer_widget_preview_events (GtkWidget *widget,
h = layersD->image_height - sy;
if ((w > 0) && (h > 0))
gdk_draw_pixmap (widget->window,
widget->style->black_gc,
*pixmap,
sx, sy, dx, dy, w, h);
{
/* Expose events are optimzed away by GTK+ if the widget is not
visible. Therefore, previews not visible in the layers_dialog
are not redrawn when they invalidate. Later the preview gets
validated by the image_preview in lc_dialog but is never
propagated to the layer_pixmap. We work around this by using an
additional flag "layer_pixmap_valid" so that the pixmap gets
updated once the preview scrolls into sight.
We should probably do the same for all drawables (masks,
channels), but it is much more difficult to change one of these
when it's not visible.
*/
if (preview_type == LAYER_PREVIEW && ! layer_widget->layer_pixmap_valid)
layer_widget_preview_redraw (layer_widget, preview_type);
gdk_draw_pixmap (widget->window,
widget->style->black_gc,
*pixmap,
sx, sy, dx, dy, w, h);
}
}
}
}
/* The boundary indicating whether layer or mask is active */
layer_widget_boundary_redraw (layer_widget, preview_type);
break;
default:
break;
}
@ -2923,6 +2962,7 @@ layer_widget_preview_redraw (LayerWidget *layer_widget,
layer_widget->width,
layer_widget->height);
layer_widget->layer_pixmap_valid = TRUE;
break;
case MASK_PREVIEW:
preview_buf = layer_mask_preview (layer_widget->layer,
@ -2942,10 +2982,11 @@ layer_widget_preview_redraw (LayerWidget *layer_widget,
gtk_preview_put (GTK_PREVIEW (layersD->layer_preview),
*pixmap, widget->style->black_gc,
0, 0, 0, 0, layersD->image_width, layersD->image_height);
0, 0, 0, 0,
layersD->image_width, layersD->image_height);
/* make sure the image has been transfered completely to the pixmap before
* we use it again...
/* make sure the image has been transfered completely to the pixmap
* before we use it again...
*/
gdk_flush ();
}