Rewrite to make drawables (layers, channels, layer masks) into GtkObjects.

--sg
This commit is contained in:
scott 1998-01-22 07:02:57 +00:00
parent c263b2ff36
commit c267c55bbe
259 changed files with 8340 additions and 7989 deletions

View file

@ -1,3 +1,8 @@
Thu Jan 22 01:54:17 1998 Scott Goehring <scott@poverty.bloomington.in.us>
* Rework of drawables, images, and layers to use GtkObjects. Lots
and lots of secondary changes.
Sun Jan 18 18:07:23 EST 1998 Adrian Likins <adrian@gimp.org>
* added plugins/gflare/gflares and edited the makefiles

View file

@ -40,6 +40,7 @@ gimp_SOURCES = \
by_color_select.h \
channel.c \
channel.h \
channel_pvt.h \
channel_cmds.c \
channel_cmds.h \
channels_dialog.c \
@ -85,6 +86,7 @@ gimp_SOURCES = \
draw_core.h \
drawable.c \
drawable.h \
drawable_pvt.h \
drawable_cmds.c \
drawable_cmds.h \
edit_cmds.c \
@ -167,6 +169,7 @@ gimp_SOURCES = \
iscissors.h \
layer.c \
layer.h \
layer_pvt.h \
layer_cmds.c \
layer_cmds.h \
layer_select.c \
@ -241,6 +244,7 @@ gimp_SOURCES = \
tile_cache.h \
tile_manager.c \
tile_manager.h \
tile_manager_pvt.h \
tile_swap.c \
tile_swap.h \
tips_dialog.c \
@ -270,7 +274,8 @@ CPPFLAGS = \
-DLIBDIR=\""$(gimpplugindir)"\" \
-DDATADIR=\""$(gimpdatadir)"\" \
-DGIMPDIR=\""$(gimpdir)"\" \
-DVERSION=\"$(VERSION)\"
-DVERSION=\"$(VERSION)\" \
-DNDEBUG
INCLUDES = \
$(X_CFLAGS) \

View file

@ -39,6 +39,7 @@
#include "floating_sel.h"
#include "gdisplay_ops.h"
#include "general.h"
#include "gimage_cmds.h"
#include "gimage_mask.h"
#include "gimprc.h"
#include "global_edit.h"
@ -213,7 +214,7 @@ file_new_ok_callback (GtkWidget *widget,
gimage_add_layer (gimage, layer, 0);
gimage_enable_undo (gimage);
drawable_fill (layer->ID, vals->fill_type);
drawable_fill (GIMP_DRAWABLE(layer), vals->fill_type);
gimage_clean_all (gimage);

View file

@ -1041,7 +1041,7 @@ plug_in_repeat (int with_interface)
/* initialize the first 3 plug-in arguments */
args[0].value.pdb_int = (with_interface ? RUN_INTERACTIVE : RUN_WITH_LAST_VALS);
args[1].value.pdb_int = gdisplay->gimage->ID;
args[2].value.pdb_int = gimage_active_drawable (gdisplay->gimage);
args[2].value.pdb_int = drawable_ID (gimage_active_drawable (gdisplay->gimage));
/* run the plug-in procedure */
plug_in_run (last_plug_in, args, FALSE, TRUE);
@ -1220,9 +1220,9 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
tile_info = msg.data;
if (tile_info->shadow)
tm = drawable_shadow (tile_info->drawable_ID);
tm = drawable_shadow (drawable_get_ID (tile_info->drawable_ID));
else
tm = drawable_data (tile_info->drawable_ID);
tm = drawable_data (drawable_get_ID (tile_info->drawable_ID));
if (!tm)
{
@ -1259,9 +1259,9 @@ plug_in_handle_tile_req (GPTileReq *tile_req)
else
{
if (tile_req->shadow)
tm = drawable_shadow (tile_req->drawable_ID);
tm = drawable_shadow (drawable_get_ID (tile_req->drawable_ID));
else
tm = drawable_data (tile_req->drawable_ID);
tm = drawable_data (drawable_get_ID (tile_req->drawable_ID));
if (!tm)
{
@ -2089,7 +2089,7 @@ plug_in_callback (GtkWidget *widget,
/* initialize the first 3 plug-in arguments */
args[0].value.pdb_int = RUN_INTERACTIVE;
args[1].value.pdb_int = gdisplay->gimage->ID;
args[2].value.pdb_int = gimage_active_drawable (gdisplay->gimage);
args[2].value.pdb_int = drawable_ID (gimage_active_drawable (gdisplay->gimage));
}
else
{
@ -2108,7 +2108,7 @@ plug_in_callback (GtkWidget *widget,
if (gdisplay)
{
args[1].value.pdb_int = gdisplay->gimage->ID;
args[2].value.pdb_int = gimage_active_drawable (gdisplay->gimage);
args[2].value.pdb_int = drawable_ID (gimage_active_drawable (gdisplay->gimage));
}
else
{

View file

@ -33,11 +33,11 @@ typedef struct _AirbrushTimeout AirbrushTimeout;
struct _AirbrushTimeout
{
PaintCore *paint_core;
int drawable_id;
GimpDrawable *drawable;
};
/* forward function declarations */
static void airbrush_motion (PaintCore *, int, double);
static void airbrush_motion (PaintCore *, GimpDrawable *, double);
static gint airbrush_time_out (gpointer);
static Argument * airbrush_invoker (Argument *);
@ -139,11 +139,14 @@ create_airbrush_options (void)
void *
airbrush_paint_func (PaintCore *paint_core,
int drawable_id,
GimpDrawable *drawable,
int state)
{
GBrushP brush;
if (!drawable)
return NULL;
brush = get_active_brush ();
switch (state)
{
@ -156,12 +159,12 @@ airbrush_paint_func (PaintCore *paint_core,
gtk_timeout_remove (timer);
timer_state = OFF;
airbrush_motion (paint_core, drawable_id, airbrush_options->pressure);
airbrush_motion (paint_core, drawable, airbrush_options->pressure);
if (airbrush_options->rate != 0.0)
{
airbrush_timeout.paint_core = paint_core;
airbrush_timeout.drawable_id = drawable_id;
airbrush_timeout.drawable = drawable;
timer = gtk_timeout_add ((10000 / airbrush_options->rate),
airbrush_time_out, NULL);
timer_state = ON;
@ -216,7 +219,7 @@ airbrush_time_out (gpointer client_data)
{
/* service the timer */
airbrush_motion (airbrush_timeout.paint_core,
airbrush_timeout.drawable_id,
airbrush_timeout.drawable,
airbrush_options->pressure);
gdisplays_flush ();
@ -230,19 +233,22 @@ airbrush_time_out (gpointer client_data)
static void
airbrush_motion (PaintCore *paint_core,
int drawable_id,
GimpDrawable *drawable,
double pressure)
{
GImage *gimage;
TempBuf * area;
unsigned char col[MAX_CHANNELS];
if (! (gimage = drawable_gimage (drawable_id)))
if (!drawable)
return;
gimage_get_foreground (gimage, drawable_id, col);
if (! (gimage = drawable_gimage (drawable)))
return;
if (! (area = paint_core_get_paint_area (paint_core, drawable_id)))
gimage_get_foreground (gimage, drawable, col);
if (! (area = paint_core_get_paint_area (paint_core, drawable)))
return;
/* color the pixels */
@ -253,7 +259,7 @@ airbrush_motion (PaintCore *paint_core,
area->width * area->height, area->bytes);
/* paste the newly painted area to the image */
paint_core_paste_canvas (paint_core, drawable_id,
paint_core_paste_canvas (paint_core, drawable,
(int) (pressure * 2.55),
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (),
@ -263,10 +269,10 @@ airbrush_motion (PaintCore *paint_core,
static void *
airbrush_non_gui_paint_func (PaintCore *paint_core,
int drawable_id,
GimpDrawable *drawable,
int state)
{
airbrush_motion (paint_core, drawable_id, non_gui_pressure);
airbrush_motion (paint_core, drawable, non_gui_pressure);
return NULL;
}
@ -326,14 +332,14 @@ airbrush_invoker (Argument *args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int num_strokes;
double *stroke_array;
int int_value;
double fp_value;
int i;
drawable_id = -1;
drawable = NULL;
num_strokes = 0;
/* the gimage */
@ -347,10 +353,9 @@ airbrush_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (! (gimage == drawable_gimage (int_value)))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* pressure */
if (success)
@ -377,7 +382,7 @@ airbrush_invoker (Argument *args)
if (success)
/* init the paint core */
success = paint_core_init (&non_gui_paint_core, drawable_id,
success = paint_core_init (&non_gui_paint_core, drawable,
stroke_array[0], stroke_array[1]);
if (success)
@ -389,21 +394,21 @@ airbrush_invoker (Argument *args)
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
if (num_strokes == 1)
airbrush_non_gui_paint_func (&non_gui_paint_core, drawable_id, 0);
airbrush_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
for (i = 1; i < num_strokes; i++)
{
non_gui_paint_core.curx = stroke_array[i * 2 + 0];
non_gui_paint_core.cury = stroke_array[i * 2 + 1];
paint_core_interpolate (&non_gui_paint_core, drawable_id);
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.lastx = non_gui_paint_core.curx;
non_gui_paint_core.lasty = non_gui_paint_core.cury;
}
/* finish the painting */
paint_core_finish (&non_gui_paint_core, drawable_id, -1);
paint_core_finish (&non_gui_paint_core, drawable, -1);
/* cleanup */
paint_core_cleanup ();

View file

@ -22,7 +22,7 @@
#include "paint_core.h"
#include "procedural_db.h"
void * airbrush_paint_func (PaintCore *, int, int);
void * airbrush_paint_func (PaintCore *, GimpDrawable *, int);
Tool * tools_new_airbrush (void);
void tools_free_airbrush (Tool *);

View file

@ -62,7 +62,7 @@ struct _ColorBalanceDialog
GtkAdjustment *magenta_green_data;
GtkAdjustment *yellow_blue_data;
int drawable_id;
GimpDrawable *drawable;
ImageMap image_map;
double cyan_red[3];
@ -330,8 +330,8 @@ color_balance_initialize (void *gdisp_ptr)
color_balance_dialog->magenta_green[i] = 0.0;
color_balance_dialog->yellow_blue[i] = 0.0;
}
color_balance_dialog->drawable_id = gimage_active_drawable (gdisp->gimage);
color_balance_dialog->image_map = image_map_create (gdisp_ptr, color_balance_dialog->drawable_id);
color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage);
color_balance_dialog->image_map = image_map_create (gdisp_ptr, color_balance_dialog->drawable);
color_balance_update (color_balance_dialog, ALL);
}
@ -921,7 +921,6 @@ color_balance_invoker (Argument *args)
int int_value;
ColorBalanceDialog cbd;
GImage *gimage;
int drawable_id;
int transfer_mode;
int preserve_lum;
double cyan_red;
@ -931,8 +930,9 @@ color_balance_invoker (Argument *args)
int x1, y1, x2, y2;
int i;
void *pr;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
transfer_mode = MIDTONES;
cyan_red = 0;
magenta_green = 0;
@ -949,9 +949,8 @@ color_balance_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* transfer_mode */
@ -1016,16 +1015,16 @@ color_balance_invoker (Argument *args)
cbd.yellow_blue[transfer_mode] = yellow_blue;
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
color_balance (&srcPR, &destPR, (void *) &cbd);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&color_balance_proc, success);

View file

@ -81,7 +81,7 @@ struct _CurvesDialog
GtkWidget * graph;
GdkPixmap * pixmap;
int drawable_id;
GimpDrawable * drawable;
ImageMap image_map;
int color;
int channel;
@ -367,12 +367,12 @@ curves_initialize (void *gdisp_ptr)
curves_dialog->points[i][16][1] = 255;
}
curves_dialog->drawable_id = gimage_active_drawable (gdisp->gimage);
curves_dialog->color = drawable_color (curves_dialog->drawable_id);
curves_dialog->image_map = image_map_create (gdisp_ptr, curves_dialog->drawable_id);
curves_dialog->drawable = gimage_active_drawable (gdisp->gimage);
curves_dialog->color = drawable_color ( (curves_dialog->drawable));
curves_dialog->image_map = image_map_create (gdisp_ptr, curves_dialog->drawable);
/* check for alpha channel */
if (drawable_has_alpha (curves_dialog->drawable_id))
if (drawable_has_alpha ( (curves_dialog->drawable)))
gtk_widget_set_sensitive( channel_items[4].widget, TRUE);
else
gtk_widget_set_sensitive( channel_items[4].widget, FALSE);
@ -1326,15 +1326,13 @@ curves_spline_invoker (Argument *args)
int int_value;
CurvesDialog cd;
GImage *gimage;
int drawable_id;
int channel;
int num_cp;
unsigned char *control_pts;
int x1, y1, x2, y2;
int i, j;
void *pr;
drawable_id = -1;
GimpDrawable *drawable;
/* the gimage */
if (success)
@ -1347,9 +1345,8 @@ curves_spline_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* channel */
@ -1358,10 +1355,10 @@ curves_spline_invoker (Argument *args)
int_value = args[2].value.pdb_int;
if (success)
{
if (drawable_gray (drawable_id))
if (drawable_gray (drawable))
if (int_value != 0)
success = FALSE;
else if (drawable_color (drawable_id))
else if (drawable_color (drawable))
if (int_value < 0 || int_value > 3)
success = FALSE;
else
@ -1396,7 +1393,7 @@ curves_spline_invoker (Argument *args)
}
cd.channel = channel;
cd.color = drawable_color (drawable_id);
cd.color = drawable_color (drawable);
cd.curve_type = SMOOTH;
for (j = 0; j < num_cp / 2; j++)
@ -1407,16 +1404,16 @@ curves_spline_invoker (Argument *args)
curves_calculate_curve (&cd);
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
curves (&srcPR, &destPR, (void *) &cd);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&curves_spline_proc, success);
@ -1478,14 +1475,12 @@ curves_explicit_invoker (Argument *args)
int int_value;
CurvesDialog cd;
GImage *gimage;
int drawable_id;
int channel;
unsigned char *curve;
int x1, y1, x2, y2;
int i, j;
void *pr;
drawable_id = -1;
GimpDrawable *drawable;
/* the gimage */
if (success)
@ -1498,9 +1493,8 @@ curves_explicit_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* channel */
@ -1509,10 +1503,10 @@ curves_explicit_invoker (Argument *args)
int_value = args[2].value.pdb_int;
if (success)
{
if (drawable_gray (drawable_id))
if (drawable_gray (drawable))
if (int_value != 0)
success = FALSE;
else if (drawable_color (drawable_id))
else if (drawable_color (drawable))
if (int_value < 0 || int_value > 3)
success = FALSE;
else
@ -1541,22 +1535,22 @@ curves_explicit_invoker (Argument *args)
cd.curve[i][j] = j;
cd.channel = channel;
cd.color = drawable_color (drawable_id);
cd.color = drawable_color (drawable);
for (j = 0; j < 256; j++)
cd.curve[cd.channel][j] = curve[j];
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
curves (&srcPR, &destPR, (void *) &cd);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&curves_explicit_proc, success);

View file

@ -69,7 +69,7 @@ struct _HueSaturationDialog
GtkAdjustment *lightness_data;
GtkAdjustment *saturation_data;
int drawable_id;
GimpDrawable *drawable;
ImageMap image_map;
double hue[7];
@ -373,8 +373,8 @@ hue_saturation_initialize (void *gdisp_ptr)
hue_saturation_dialog->saturation[i] = 0.0;
}
hue_saturation_dialog->drawable_id = gimage_active_drawable (gdisp->gimage);
hue_saturation_dialog->image_map = image_map_create (gdisp_ptr, hue_saturation_dialog->drawable_id);
hue_saturation_dialog->drawable = gimage_active_drawable (gdisp->gimage);
hue_saturation_dialog->image_map = image_map_create (gdisp_ptr, hue_saturation_dialog->drawable);
hue_saturation_update (hue_saturation_dialog, ALL);
}
@ -1066,7 +1066,7 @@ hue_saturation_invoker (Argument *args)
int success = TRUE;
HueSaturationDialog hsd;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int hue_range;
double hue_offset;
double lightness;
@ -1077,7 +1077,7 @@ hue_saturation_invoker (Argument *args)
int i;
void *pr;
drawable_id = -1;
drawable = NULL;
hue_range = 0;
hue_offset = 0.0;
lightness = 0.0;
@ -1094,9 +1094,8 @@ hue_saturation_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* hue_range */
@ -1154,16 +1153,16 @@ hue_saturation_invoker (Argument *args)
hue_saturation_calculate_transfers (&hsd);
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
hue_saturation (&srcPR, &destPR, (void *) &hsd);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&hue_saturation_proc, success);

View file

@ -23,6 +23,7 @@
#include "linked.h"
#include "pixel_region.h"
#include "tile_manager_pvt.h"
typedef struct _PixelRegionHolder PixelRegionHolder;

View file

@ -48,7 +48,7 @@ struct _ThresholdDialog
GtkWidget *high_threshold_text;
Histogram *histogram;
int drawable_id;
GimpDrawable *drawable;
ImageMap image_map;
int color;
int low_threshold;
@ -347,11 +347,11 @@ threshold_initialize (void *gdisp_ptr)
if (!GTK_WIDGET_VISIBLE (threshold_dialog->shell))
gtk_widget_show (threshold_dialog->shell);
threshold_dialog->drawable_id = gimage_active_drawable (gdisp->gimage);
threshold_dialog->color = drawable_color (threshold_dialog->drawable_id);
threshold_dialog->image_map = image_map_create (gdisp_ptr, threshold_dialog->drawable_id);
threshold_dialog->drawable = gimage_active_drawable (gdisp->gimage);
threshold_dialog->color = drawable_color (threshold_dialog->drawable);
threshold_dialog->image_map = image_map_create (gdisp_ptr, threshold_dialog->drawable);
histogram_update (threshold_dialog->histogram,
threshold_dialog->drawable_id,
threshold_dialog->drawable,
threshold_histogram_info,
(void *) threshold_dialog);
histogram_range (threshold_dialog->histogram,
@ -649,14 +649,14 @@ threshold_invoker (args)
int success = TRUE;
ThresholdDialog td;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int low_threshold;
int high_threshold;
int int_value;
int x1, y1, x2, y2;
void *pr;
drawable_id = -1;
drawable = NULL;
low_threshold = 0;
high_threshold = 0;
@ -671,9 +671,8 @@ threshold_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* low threhsold */
@ -700,21 +699,21 @@ threshold_invoker (args)
/* arrange to modify the levels */
if (success)
{
td.color = drawable_color (drawable_id);
td.color = drawable_color (drawable);
td.low_threshold = low_threshold;
td.high_threshold = high_threshold;
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
threshold (&srcPR, &destPR, (void *) &td);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&threshold_proc, success);

View file

@ -0,0 +1,47 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __TILE_MANAGER_PVT_H__
#define __TILE_MANAGER_PVT_H__
#include "tile.h"
struct _TileLevel
{
int width; /* the width of the tiled area */
int height; /* the height of the tiled area */
int bpp; /* the bpp of each tile */
int ntile_rows; /* the number of tiles in each row */
int ntile_cols; /* the number of tiles in each columns */
Tile *tiles; /* the tiles for this level */
};
struct _TileManager
{
int x, y; /* tile manager offsets */
int nlevels; /* the number of tile levels in the hierarchy */
TileLevel *levels; /* the hierarchy */
TileValidateProc validate_proc; /* this proc is called when an attempt to get an
* invalid tile is made.
*/
void *user_data; /* hook for hanging data off of */
};
#endif /* __TILE_MANAGER_PVT_H__ */

View file

@ -1,7 +1,26 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "tile_cache.h"
#include "tile_manager.h"
#include "tile_swap.h"
#include "tile_manager_pvt.h"
static void tile_manager_destroy_level (TileLevel *level);

View file

@ -1,3 +1,20 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __TILE_MANAGER_H__
#define __TILE_MANAGER_H__
@ -12,29 +29,6 @@ typedef void (*TileValidateProc) (TileManager *tm,
Tile *tile,
int level);
struct _TileLevel
{
int width; /* the width of the tiled area */
int height; /* the height of the tiled area */
int bpp; /* the bpp of each tile */
int ntile_rows; /* the number of tiles in each row */
int ntile_cols; /* the number of tiles in each columns */
Tile *tiles; /* the tiles for this level */
};
struct _TileManager
{
int x, y; /* tile manager offsets */
int nlevels; /* the number of tile levels in the hierarchy */
TileLevel *levels; /* the hierarchy */
TileValidateProc validate_proc; /* this proc is called when an attempt to get an
* invalid tile is made.
*/
void *user_data; /* hook for hanging data off of */
};
/* Creates a new tile manager with the specified
* width for the toplevel. The toplevel sizes is

View file

@ -1114,8 +1114,10 @@ bezier_convert (BezierSelect *bezier_sel,
bezier_convert_line (bezier_sel->scanlines, lastx, lasty,
bezier_sel->points->x, bezier_sel->points->y);
pixel_region_init (&maskPR, bezier_sel->mask->tiles, 0, 0,
bezier_sel->mask->width, bezier_sel->mask->height, TRUE);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(bezier_sel->mask)),
0, 0,
drawable_width (GIMP_DRAWABLE(bezier_sel->mask)),
drawable_height (GIMP_DRAWABLE(bezier_sel->mask)), TRUE);
for (i = 0; i < height; i++)
{
list = bezier_sel->scanlines[i];
@ -1162,7 +1164,8 @@ bezier_convert (BezierSelect *bezier_sel,
*b++ = (unsigned char) (val / SUPERSAMPLE2);
}
pixel_region_set_row (&maskPR, 0, (i / SUPERSAMPLE), bezier_sel->mask->width, buf);
pixel_region_set_row (&maskPR, 0, (i / SUPERSAMPLE),
drawable_width (GIMP_DRAWABLE(bezier_sel->mask)), buf);
}
free_list (bezier_sel->scanlines[i]);
@ -1177,7 +1180,7 @@ bezier_convert (BezierSelect *bezier_sel,
g_free (bezier_sel->scanlines);
bezier_sel->scanlines = NULL;
bezier_sel->mask->bounds_known = FALSE;
channel_invalidate_bounds (bezier_sel->mask);
}
static void

View file

@ -136,7 +136,7 @@ static void blend_motion (Tool *, GdkEventMotion *, gpointer)
static void blend_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void blend_control (Tool *, int, gpointer);
static void blend (GImage *gimage, int drawable_id,
static void blend (GImage *gimage, GimpDrawable *drawable,
BlendMode blend_mode, int paint_mode,
GradientType gradient_type,
double opacity, double offset,
@ -165,12 +165,12 @@ static double gradient_repeat_none(double val);
static double gradient_repeat_sawtooth(double val);
static double gradient_repeat_triangular(double val);
static void gradient_precalc_shapeburst (GImage *gimage, int, PixelRegion *PR, double dist);
static void gradient_precalc_shapeburst (GImage *gimage, GimpDrawable *drawable, PixelRegion *PR, double dist);
static void gradient_render_pixel(double x, double y, color_t *color, void *render_data);
static void gradient_put_pixel(int x, int y, color_t color, void *put_pixel_data);
static void gradient_fill_region (GImage *gimage, int, PixelRegion *PR,
static void gradient_fill_region (GImage *gimage, GimpDrawable *drawable, PixelRegion *PR,
int width, int height,
BlendMode blend_mode, GradientType gradient_type,
double offset, RepeatMode repeat,
@ -594,7 +594,7 @@ blend_button_release (Tool *tool,
return_vals = procedural_db_run_proc ("gimp_blend",
&nreturn_vals,
PDB_IMAGE, gimage->ID,
PDB_DRAWABLE, gimage_active_drawable (gimage),
PDB_DRAWABLE, drawable_ID (gimage_active_drawable (gimage)),
PDB_INT32, (gint32) blend_options->blend_mode,
PDB_INT32, (gint32) blend_options->paint_mode,
PDB_INT32, (gint32) blend_options->gradient_type,
@ -726,7 +726,7 @@ blend_control (Tool *tool,
/* The actual blending procedure */
static void
blend (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
BlendMode blend_mode,
int paint_mode,
GradientType gradient_type,
@ -748,10 +748,10 @@ blend (GImage *gimage,
int bytes;
int x1, y1, x2, y2;
has_selection = drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
has_selection = drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
has_alpha = drawable_has_alpha (drawable_id);
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable);
bytes = drawable_bytes (drawable);
/* Always create an alpha temp buf (for generality) */
if (! has_alpha)
@ -763,7 +763,7 @@ blend (GImage *gimage,
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), bytes);
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
gradient_fill_region (gimage, drawable_id,
gradient_fill_region (gimage, drawable,
&bufPR, (x2 - x1), (y2 - y1),
blend_mode, gradient_type, offset, repeat,
supersample, max_depth, threshold,
@ -771,11 +771,11 @@ blend (GImage *gimage,
(endx - x1), (endy - y1));
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
gimage_apply_image (gimage, drawable_id, &bufPR, TRUE,
gimage_apply_image (gimage, drawable, &bufPR, TRUE,
(opacity * 255) / 100, paint_mode, NULL, x1, y1);
/* update the image */
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
/* free the temporary buffer */
tile_manager_destroy (buf_tiles);
@ -1085,7 +1085,7 @@ gradient_repeat_triangular(double val)
/*****/
static void
gradient_precalc_shapeburst (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
PixelRegion *PR,
double dist)
{
@ -1113,12 +1113,13 @@ gradient_precalc_shapeburst (GImage *gimage,
int x1, y1, x2, y2;
int offx, offy;
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_offsets (drawable_id, &offx, &offy);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
drawable_offsets (drawable, &offx, &offy);
/* the selection mask */
mask = gimage_get_mask (gimage);
pixel_region_init (&maskR, mask->tiles, x1 + offx, y1 + offy, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&maskR, drawable_data (GIMP_DRAWABLE(mask)),
x1 + offx, y1 + offy, (x2 - x1), (y2 - y1), FALSE);
/* copy the mask to the temp mask */
copy_region (&maskR, &tempR);
@ -1127,11 +1128,11 @@ gradient_precalc_shapeburst (GImage *gimage,
else
{
/* If the intended drawable has an alpha channel, use that */
if (drawable_has_alpha (drawable_id))
if (drawable_has_alpha (drawable))
{
PixelRegion drawableR;
pixel_region_init (&drawableR, drawable_data (drawable_id), PR->x, PR->y, PR->w, PR->h, FALSE);
pixel_region_init (&drawableR, drawable_data (drawable), PR->x, PR->y, PR->w, PR->h, FALSE);
extract_alpha_region (&drawableR, NULL, &tempR);
}
@ -1286,7 +1287,7 @@ gradient_put_pixel(int x, int y, color_t color, void *put_pixel_data)
static void
gradient_fill_region (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
PixelRegion *PR,
int width,
int height,
@ -1387,7 +1388,7 @@ gradient_fill_region (GImage *gimage,
case ShapeburstSpherical:
case ShapeburstDimpled:
rbd.dist = sqrt(SQR(ex - sx) + SQR(ey - sy));
gradient_precalc_shapeburst(gimage, drawable_id, PR, rbd.dist);
gradient_precalc_shapeburst(gimage, drawable, PR, rbd.dist);
break;
default:
@ -1769,7 +1770,7 @@ blend_invoker (Argument *args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
BlendMode blend_mode;
int paint_mode;
GradientType gradient_type;
@ -1784,7 +1785,7 @@ blend_invoker (Argument *args)
int int_value;
double fp_value;
drawable_id = -1;
drawable = NULL;
blend_mode = FG_BG_RGB_MODE;
paint_mode = NORMAL_MODE;
gradient_type = Linear;
@ -1806,9 +1807,8 @@ blend_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* blend mode */
@ -1920,7 +1920,7 @@ blend_invoker (Argument *args)
/* call the blend procedure */
if (success)
{
blend (gimage, drawable_id, blend_mode, paint_mode, gradient_type,
blend (gimage, drawable, blend_mode, paint_mode, gradient_type,
opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
}

View file

@ -57,7 +57,7 @@ struct _BrightnessContrastDialog
GtkAdjustment *brightness_data;
GtkAdjustment *contrast_data;
int drawable_id;
GimpDrawable *drawable;
ImageMap image_map;
double brightness;
@ -293,9 +293,9 @@ brightness_contrast_initialize (void *gdisp_ptr)
brightness_contrast_dialog->brightness = 0.0;
brightness_contrast_dialog->contrast = 0.0;
brightness_contrast_dialog->drawable_id = gimage_active_drawable (gdisp->gimage);
brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage);
brightness_contrast_dialog->image_map = image_map_create (gdisp_ptr,
brightness_contrast_dialog->drawable_id);
brightness_contrast_dialog->drawable);
brightness_contrast_update (brightness_contrast_dialog, ALL);
}
@ -676,13 +676,13 @@ brightness_contrast_invoker (Argument *args)
int int_value;
BrightnessContrastDialog bcd;
GImage *gimage;
int drawable_id;
int brightness;
int contrast;
int x1, y1, x2, y2;
void *pr;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
brightness = 0;
contrast = 0;
@ -697,9 +697,8 @@ brightness_contrast_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* brightness */
@ -728,16 +727,16 @@ brightness_contrast_invoker (Argument *args)
bcd.contrast = contrast;
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
brightness_contrast (&srcPR, &destPR, (void *) &bcd);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&brightness_contrast_proc, success);

View file

@ -54,7 +54,7 @@ static void bucket_fill_motion (Tool *, GdkEventMotion *, gpointer);
static void bucket_fill_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void bucket_fill_control (Tool *, int, gpointer);
static void bucket_fill (GImage *, int, FillMode, int,
static void bucket_fill (GImage *, GimpDrawable *, FillMode, int,
double, double, int, double, double);
static void bucket_fill_region (FillMode, PixelRegion *, PixelRegion *,
@ -314,7 +314,7 @@ bucket_fill_button_release (tool, bevent, gdisp_ptr)
return_vals = procedural_db_run_proc ("gimp_bucket_fill",
&nreturn_vals,
PDB_IMAGE, gdisp->gimage->ID,
PDB_DRAWABLE, gimage_active_drawable (gdisp->gimage),
PDB_DRAWABLE, drawable_ID (gimage_active_drawable (gdisp->gimage)),
PDB_INT32, (gint32) fill_mode,
PDB_INT32, (gint32) bucket_options->paint_mode,
PDB_FLOAT, (gdouble) bucket_options->opacity,
@ -355,23 +355,27 @@ bucket_fill_cursor_update (tool, mevent, gdisp_ptr)
Layer *layer;
GdkCursorType ctype = GDK_TOP_LEFT_ARROW;
int x, y;
int off_x, off_y;
gdisp = (GDisplay *) gdisp_ptr;
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE);
if ((layer = gimage_get_active_layer (gdisp->gimage)))
if (x >= layer->offset_x && y >= layer->offset_y &&
x < (layer->offset_x + layer->width) &&
y < (layer->offset_y + layer->height))
{
/* One more test--is there a selected region?
* if so, is cursor inside?
*/
if (gimage_mask_is_empty (gdisp->gimage))
ctype = GDK_TCROSS;
else if (gimage_mask_value (gdisp->gimage, x, y))
ctype = GDK_TCROSS;
}
if ((layer = gimage_get_active_layer (gdisp->gimage)))
{
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
if (x >= off_x && y >= off_y &&
x < (off_x + drawable_width (GIMP_DRAWABLE(layer))) &&
y < (off_y + drawable_height (GIMP_DRAWABLE(layer))))
{
/* One more test--is there a selected region?
* if so, is cursor inside?
*/
if (gimage_mask_is_empty (gdisp->gimage))
ctype = GDK_TCROSS;
else if (gimage_mask_value (gdisp->gimage, x, y))
ctype = GDK_TCROSS;
}
}
gdisplay_install_tool_cursor (gdisp, ctype);
}
@ -386,10 +390,10 @@ bucket_fill_control (tool, action, gdisp_ptr)
static void
bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
bucket_fill (gimage, drawable, fill_mode, paint_mode,
opacity, threshold, sample_merged, x, y)
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
FillMode fill_mode;
int paint_mode;
double opacity;
@ -411,9 +415,9 @@ bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
pat_buf = NULL;
if (fill_mode == FgColorFill)
gimage_get_foreground (gimage, drawable_id, col);
gimage_get_foreground (gimage, drawable, col);
else if (fill_mode == BgColorFill)
gimage_get_background (gimage, drawable_id, col);
gimage_get_background (gimage, drawable, col);
else if (fill_mode == PatternFill)
{
pattern = get_active_pattern ();
@ -427,12 +431,12 @@ bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
/* If the pattern doesn't match the image in terms of color type,
* transform it. (ie pattern is RGB, image is indexed)
*/
if (((pattern->mask->bytes == 3) && !drawable_color (drawable_id)) ||
((pattern->mask->bytes == 1) && !drawable_gray (drawable_id)))
if (((pattern->mask->bytes == 3) && !drawable_color (drawable)) ||
((pattern->mask->bytes == 1) && !drawable_gray (drawable)))
{
int size;
if ((pattern->mask->bytes == 1) && drawable_color (drawable_id))
if ((pattern->mask->bytes == 1) && drawable_color (drawable))
pat_buf = temp_buf_new (pattern->mask->width, pattern->mask->height, 3, 0, 0, NULL);
else
pat_buf = temp_buf_new (pattern->mask->width, pattern->mask->height, 1, 0, 0, NULL);
@ -443,7 +447,7 @@ bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
size = pattern->mask->width * pattern->mask->height;
while (size--)
{
gimage_transform_color (gimage, drawable_id, d1, d2,
gimage_transform_color (gimage, drawable, d1, d2,
(pattern->mask->bytes == 3) ? RGB : GRAY);
d1 += pattern->mask->bytes;
d2 += pat_buf->bytes;
@ -455,15 +459,15 @@ bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
pat_buf = pattern->mask;
}
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable_id);
bytes = drawable_bytes (drawable);
has_alpha = drawable_has_alpha (drawable);
/* If there is no selection mask, the do a seed bucket
* fill...To do this, calculate a new contiguous region
*/
if (! drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2))
if (! drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2))
{
mask = find_contiguous_region (gimage, drawable_id, TRUE, (int) threshold,
mask = find_contiguous_region (gimage, drawable, TRUE, (int) threshold,
(int) x, (int) y, sample_merged);
channel_bounds (mask, &x1, &y1, &x2, &y2);
@ -474,13 +478,14 @@ bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
int off_x, off_y;
/* Limit the channel bounds to the drawable's extents */
drawable_offsets (drawable_id, &off_x, &off_y);
x1 = BOUNDS (x1, off_x, (off_x + drawable_width (drawable_id)));
y1 = BOUNDS (y1, off_y, (off_y + drawable_height (drawable_id)));
x2 = BOUNDS (x2, off_x, (off_x + drawable_width (drawable_id)));
y2 = BOUNDS (y2, off_y, (off_y + drawable_height (drawable_id)));
drawable_offsets (drawable, &off_x, &off_y);
x1 = BOUNDS (x1, off_x, (off_x + drawable_width (drawable)));
y1 = BOUNDS (y1, off_y, (off_y + drawable_height (drawable)));
x2 = BOUNDS (x2, off_x, (off_x + drawable_width (drawable)));
y2 = BOUNDS (y2, off_y, (off_y + drawable_height (drawable)));
pixel_region_init (&maskPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)),
x1, y1, (x2 - x1), (y2 - y1), TRUE);
/* translate mask bounds to drawable coords */
x1 -= off_x;
@ -489,7 +494,8 @@ bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
y2 -= off_y;
}
else
pixel_region_init (&maskPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)),
x1, y1, (x2 - x1), (y2 - y1), TRUE);
/* if the gimage doesn't have an alpha channel,
* make sure that the temp buf does. We need the
@ -511,11 +517,11 @@ bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
bucket_fill_region (fill_mode, &bufPR, NULL, col, pat_buf, x1, y1, has_alpha);
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
gimage_apply_image (gimage, drawable_id, &bufPR, TRUE,
gimage_apply_image (gimage, drawable, &bufPR, TRUE,
(opacity * 255) / 100, paint_mode, NULL, x1, y1);
/* update the image */
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
/* free the temporary buffer */
tile_manager_destroy (buf_tiles);
@ -755,7 +761,7 @@ bucket_fill_invoker (args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
FillMode fill_mode;
int paint_mode;
double opacity;
@ -765,7 +771,7 @@ bucket_fill_invoker (args)
int int_value;
double fp_value;
drawable_id = -1;
drawable = NULL;
fill_mode = BgColorFill;
paint_mode = NORMAL_MODE;
opacity = 100.0;
@ -782,9 +788,8 @@ bucket_fill_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* fill mode */
@ -842,7 +847,7 @@ bucket_fill_invoker (args)
/* call the blend procedure */
if (success)
{
bucket_fill (gimage, drawable_id, fill_mode, paint_mode,
bucket_fill (gimage, drawable, fill_mode, paint_mode,
opacity, threshold, sample_merged, x, y);
}

View file

@ -83,8 +83,8 @@ static SelectionOptions *by_color_options = NULL;
static ByColorDialog *by_color_dialog = NULL;
static int is_pixel_sufficiently_different (unsigned char *, unsigned char *, int, int, int, int);
static Channel * by_color_select_color (GImage *, int, unsigned char *, int, int, int);
static void by_color_select (GImage *, int, unsigned char *, int, int, int, int, double, int);
static Channel * by_color_select_color (GImage *, GimpDrawable *, unsigned char *, int, int, int);
static void by_color_select (GImage *, GimpDrawable *, unsigned char *, int, int, int, int, double, int);
static Argument * by_color_select_invoker (Argument *);
/* by_color selection machinery */
@ -140,7 +140,7 @@ is_pixel_sufficiently_different (unsigned char *col1,
static Channel *
by_color_select_color (GImage *gimage,
int drawable,
GimpDrawable *drawable,
unsigned char *color,
int antialias,
int threshold,
@ -199,7 +199,8 @@ by_color_select_color (GImage *gimage,
alpha = bytes - 1;
mask = channel_new_mask (gimage->ID, width, height);
pixel_region_init (&maskPR, mask->tiles, 0, 0, width, height, TRUE);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)),
0, 0, width, height, TRUE);
/* iterate over the entire image */
for (pr = pixel_regions_register (2, &imagePR, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
@ -237,7 +238,7 @@ by_color_select_color (GImage *gimage,
static void
by_color_select (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
unsigned char *color,
int threshold,
int op,
@ -249,7 +250,10 @@ by_color_select (GImage *gimage,
Channel * new_mask;
int off_x, off_y;
new_mask = by_color_select_color (gimage, drawable_id, color, antialias, threshold, sample_merged);
if (!drawable)
return;
new_mask = by_color_select_color (gimage, drawable, color, antialias, threshold, sample_merged);
/* if applicable, replace the current selection */
if (op == REPLACE)
@ -262,7 +266,7 @@ by_color_select (GImage *gimage,
off_x = 0; off_y = 0;
}
else
drawable_offsets (drawable_id, &off_x, &off_y);
drawable_offsets (drawable, &off_x, &off_y);
if (feather)
channel_feather (new_mask, gimage_get_mask (gimage),
@ -329,7 +333,7 @@ by_color_select_button_release (Tool *tool,
ByColorSelect * by_color_sel;
GDisplay * gdisp;
int x, y;
int drawable_id;
GimpDrawable *drawable;
Tile *tile;
unsigned char col[MAX_CHANNELS];
unsigned char *data;
@ -337,7 +341,7 @@ by_color_select_button_release (Tool *tool,
gdisp = (GDisplay *) gdisp_ptr;
by_color_sel = (ByColorSelect *) tool->private;
drawable_id = gimage_active_drawable (gdisp->gimage);
drawable = gimage_active_drawable (gdisp->gimage);
tool->state = INACTIVE;
@ -358,9 +362,9 @@ by_color_select_button_release (Tool *tool,
}
else
{
if (x < 0 || y < 0 || x >= drawable_width (drawable_id) || y >= drawable_height (drawable_id))
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable_id), x, y, 0);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref (tile);
data = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
@ -369,7 +373,7 @@ by_color_select_button_release (Tool *tool,
tile_unref (tile, FALSE);
/* select the area */
by_color_select (gdisp->gimage, drawable_id, col,
by_color_select (gdisp->gimage, drawable, col,
by_color_dialog->threshold,
by_color_sel->operation,
by_color_options->antialias,
@ -406,7 +410,7 @@ by_color_select_cursor_update (Tool *tool,
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE);
if ((layer = gimage_pick_correlate_layer (gdisp->gimage, x, y)))
if (layer->ID == gdisp->gimage->active_layer)
if (layer == gdisp->gimage->active_layer)
{
gdisplay_install_tool_cursor (gdisp, GDK_TCROSS);
return;
@ -686,18 +690,18 @@ by_color_select_render (ByColorDialog *bcd,
int scale;
mask = gimage_get_mask (gimage);
if ((mask->width > PREVIEW_WIDTH) ||
(mask->height > PREVIEW_HEIGHT))
if ((drawable_width (GIMP_DRAWABLE(mask)) > PREVIEW_WIDTH) ||
(drawable_height (GIMP_DRAWABLE(mask)) > PREVIEW_HEIGHT))
{
if (((float) mask->width / (float) PREVIEW_WIDTH) >
((float) mask->height / (float) PREVIEW_HEIGHT))
if (((float) drawable_width (GIMP_DRAWABLE (mask)) / (float) PREVIEW_WIDTH) >
((float) drawable_height (GIMP_DRAWABLE (mask)) / (float) PREVIEW_HEIGHT))
{
width = PREVIEW_WIDTH;
height = (mask->height * PREVIEW_WIDTH) / mask->width;
height = (drawable_height (GIMP_DRAWABLE (mask)) * PREVIEW_WIDTH) / drawable_width (GIMP_DRAWABLE (mask));
}
else
{
width = (mask->width * PREVIEW_HEIGHT) / mask->height;
width = (drawable_width (GIMP_DRAWABLE (mask)) * PREVIEW_HEIGHT) / drawable_height (GIMP_DRAWABLE (mask));
height = PREVIEW_HEIGHT;
}
@ -705,8 +709,8 @@ by_color_select_render (ByColorDialog *bcd,
}
else
{
width = mask->width;
height = mask->height;
width = drawable_width (GIMP_DRAWABLE (mask));
height = drawable_height (GIMP_DRAWABLE (mask));
scale = FALSE;
}
@ -730,11 +734,14 @@ by_color_select_render (ByColorDialog *bcd,
{
/* calculate 'acceptable' subsample */
subsample = 1;
while ((width * (subsample + 1) * 2 < mask->width) &&
(height * (subsample + 1) * 2 < mask->height))
while ((width * (subsample + 1) * 2 < drawable_width (GIMP_DRAWABLE (mask))) &&
(height * (subsample + 1) * 2 < drawable_height (GIMP_DRAWABLE (mask))))
subsample = subsample + 1;
pixel_region_init (&srcPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&srcPR, drawable_data (GIMP_DRAWABLE (mask)),
0, 0,
drawable_width (GIMP_DRAWABLE (mask)),
drawable_height (GIMP_DRAWABLE (mask)), FALSE);
scaled_buf = mask_buf_new (width, height);
destPR.bytes = 1;
@ -750,7 +757,10 @@ by_color_select_render (ByColorDialog *bcd,
}
else
{
pixel_region_init (&srcPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&srcPR, drawable_data (GIMP_DRAWABLE (mask)),
0, 0,
drawable_width (GIMP_DRAWABLE (mask)),
drawable_height (GIMP_DRAWABLE (mask)), FALSE);
scaled_buf = mask_buf_new (width, height);
destPR.bytes = 1;
@ -871,13 +881,13 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
{
int x, y;
int replace, operation;
int drawable_id;
GimpDrawable *drawable;
Tile *tile;
unsigned char *col;
if (!bcd->gimage)
return;
drawable_id = gimage_active_drawable (bcd->gimage);
drawable = gimage_active_drawable (bcd->gimage);
/* Defaults */
replace = FALSE;
@ -910,17 +920,17 @@ by_color_select_preview_button_press (ByColorDialog *bcd,
{
int offx, offy;
drawable_offsets (drawable_id, &offx, &offy);
x = drawable_width (drawable_id) * bevent->x / bcd->preview->requisition.width - offx;
y = drawable_height (drawable_id) * bevent->y / bcd->preview->requisition.height - offy;
if (x < 0 || y < 0 || x >= drawable_width (drawable_id) || y >= drawable_height (drawable_id))
drawable_offsets (drawable, &offx, &offy);
x = drawable_width (drawable) * bevent->x / bcd->preview->requisition.width - offx;
y = drawable_height (drawable) * bevent->y / bcd->preview->requisition.height - offy;
if (x < 0 || y < 0 || x >= drawable_width (drawable) || y >= drawable_height (drawable))
return;
tile = tile_manager_get_tile (drawable_data (drawable_id), x, y, 0);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref (tile);
col = tile->data + tile->bpp * (tile->ewidth * (y % TILE_HEIGHT) + (x % TILE_WIDTH));
}
by_color_select (bcd->gimage, drawable_id, col,
by_color_select (bcd->gimage, drawable, col,
bcd->threshold,
operation,
by_color_options->antialias,
@ -1008,7 +1018,7 @@ by_color_select_invoker (Argument *args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int op;
int threshold;
int antialias;
@ -1018,7 +1028,7 @@ by_color_select_invoker (Argument *args)
double feather_radius;
int int_value;
drawable_id = -1;
drawable = NULL;
op = REPLACE;
threshold = 0;
@ -1033,10 +1043,9 @@ by_color_select_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* color */
if (success)
@ -1096,7 +1105,7 @@ by_color_select_invoker (Argument *args)
/* call the ellipse_select procedure */
if (success)
by_color_select (gimage, drawable_id, color, threshold, op,
by_color_select (gimage, drawable, color, threshold, op,
antialias, feather, feather_radius, sample_merged);
return procedural_db_return_args (&by_color_select_proc, success);

View file

@ -31,6 +31,61 @@
#include "temp_buf.h"
#include "undo.h"
#include "channel_pvt.h"
enum {
LAST_SIGNAL
};
static void gimp_channel_class_init (GimpChannelClass *klass);
static void gimp_channel_init (GimpChannel *channel);
static void gimp_channel_destroy (GtkObject *object);
static gint channel_signals[LAST_SIGNAL] = { 0 };
static GimpDrawableClass *parent_class = NULL;
guint
gimp_channel_get_type ()
{
static guint channel_type = 0;
if (!channel_type)
{
GtkTypeInfo channel_info =
{
"GimpChannel",
sizeof (GimpChannel),
sizeof (GimpChannelClass),
(GtkClassInitFunc) gimp_channel_class_init,
(GtkObjectInitFunc) gimp_channel_init,
(GtkArgFunc) NULL,
};
channel_type = gtk_type_unique (gimp_drawable_get_type (), &channel_info);
}
return channel_type;
}
static void
gimp_channel_class_init (GimpChannelClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gimp_drawable_get_type ());
gtk_object_class_add_signals (object_class, channel_signals, LAST_SIGNAL);
object_class->destroy = gimp_channel_destroy;
}
static void
gimp_channel_init (GimpChannel *channel)
{
}
#define ROUND(x) ((int) (x + 0.5))
@ -38,8 +93,8 @@
* Static variables
*/
extern int global_drawable_ID;
static link_ptr channel_list = NULL;
int channel_get_count = 0;
/**************************/
@ -53,19 +108,6 @@ channel_validate (TileManager *tm, Tile *tile, int level)
}
void
channel_allocate (Channel *channel, int width, int height)
{
channel->tiles = tile_manager_new (width, height, 1);
}
void
channel_deallocate (Channel *channel)
{
if (channel->tiles)
tile_manager_destroy (channel->tiles);
}
Channel *
@ -75,37 +117,16 @@ channel_new (int gimage_ID, int width, int height, char *name, int opacity,
Channel * channel;
int i;
channel = (Channel *) g_malloc (sizeof (Channel));
channel = gtk_type_new (gimp_channel_get_type ());
if (!name)
name = "unnamed";
channel->name = (char *) g_malloc (strlen (name) + 1);
strcpy (channel->name, name);
/* set size information */
channel->width = width;
channel->height = height;
channel->bytes = 1;
/* allocate the memory for this channel */
channel_allocate (channel, width, height);
channel->visible = 1;
gimp_drawable_configure (GIMP_DRAWABLE(channel),
gimage_ID, width, height, GRAY_GIMAGE, name);
/* set the channel color and opacity */
for (i = 0; i < 3; i++)
channel->col[i] = col[i];
channel->opacity = opacity;
channel->show_masked = 1;
channel->dirty = 0;
/* give this channel an ID */
channel->ID = global_drawable_ID++;
channel->layer_ID = -1;
channel->gimage_ID = gimage_ID;
/* add the new channel to the global list */
channel_list = append_to_list (channel_list, (void *) channel);
/* selection mask variables */
channel->empty = TRUE;
@ -119,10 +140,6 @@ channel_new (int gimage_ID, int width, int height, char *name, int opacity,
channel->x2 = width;
channel->y2 = height;
/* preview variables */
channel->preview = NULL;
channel->preview_valid = FALSE;
return channel;
}
@ -135,18 +152,22 @@ channel_copy (Channel *channel)
PixelRegion srcPR, destPR;
/* formulate the new channel name */
channel_name = (char *) g_malloc (strlen (channel->name) + 6);
sprintf (channel_name, "%s copy", channel->name);
channel_name = (char *) g_malloc (strlen (GIMP_DRAWABLE(channel)->name) + 6);
sprintf (channel_name, "%s copy", GIMP_DRAWABLE(channel)->name);
/* allocate a new channel object */
new_channel = channel_new (channel->gimage_ID, channel->width, channel->height, channel_name,
channel->opacity, channel->col);
new_channel->visible = channel->visible;
new_channel = channel_new (GIMP_DRAWABLE(channel)->gimage_ID,
GIMP_DRAWABLE(channel)->width,
GIMP_DRAWABLE(channel)->height,
channel_name, channel->opacity, channel->col);
GIMP_DRAWABLE(new_channel)->visible = GIMP_DRAWABLE(channel)->visible;
new_channel->show_masked = channel->show_masked;
/* copy the contents across channels */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&destPR, new_channel->tiles, 0, 0, channel->width, channel->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0,
GIMP_DRAWABLE(channel)->width,
GIMP_DRAWABLE(channel)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, TRUE);
copy_region (&srcPR, &destPR);
/* free up the channel_name memory */
@ -159,56 +180,42 @@ channel_copy (Channel *channel)
Channel *
channel_get_ID (int ID)
{
link_ptr tmp = channel_list;
Channel * channel;
while (tmp)
{
channel = (Channel *) tmp->data;
if (channel->ID == ID)
return channel;
tmp = next_item (tmp);
}
return NULL;
GimpDrawable *drawable;
drawable = drawable_get_ID (ID);
if (drawable && GIMP_IS_CHANNEL (drawable))
return GIMP_CHANNEL (drawable);
else
return NULL;
}
void
channel_delete (Channel *channel)
{
gtk_object_destroy (GTK_OBJECT (channel));
}
static void
gimp_channel_destroy (GtkObject *object)
{
GimpChannel *channel;
g_return_if_fail (object != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (object));
channel = GIMP_CHANNEL (object);
/* free the segments? */
if (channel->segs_in)
g_free (channel->segs_in);
if (channel->segs_out)
g_free (channel->segs_out);
/* remove this image from the global list */
channel_list = remove_from_list (channel_list, (void *) channel);
/* deallocate the channel mem */
channel_deallocate (channel);
/* free the channel name buffer */
g_free (channel->name);
g_free (channel);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
void
channel_apply_image (Channel *channel, int x1, int y1, int x2, int y2,
TileManager *tiles, int sparse)
{
/* Need to push an undo operation */
if (! tiles)
undo_push_image (gimage_get_ID (channel->gimage_ID), channel->ID, x1, y1, x2, y2);
else
undo_push_image_mod (gimage_get_ID (channel->gimage_ID), channel->ID, x1, y1, x2, y2, tiles, sparse);
}
void
channel_scale (Channel *channel, int new_width, int new_height)
{
@ -219,10 +226,10 @@ channel_scale (Channel *channel, int new_width, int new_height)
return;
/* Update the old channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
/* Allocate the new channel, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, 1);
@ -232,18 +239,18 @@ channel_scale (Channel *channel, int new_width, int new_height)
scale_region (&srcPR, &destPR);
/* Push the channel on the undo stack */
undo_push_channel_mod (gimage_get_ID (channel->gimage_ID), channel);
undo_push_channel_mod (gimage_get_ID (GIMP_DRAWABLE(channel)->gimage_ID), channel);
/* Configure the new channel */
channel->tiles = new_tiles;
channel->width = new_width;
channel->height = new_height;
GIMP_DRAWABLE(channel)->tiles = new_tiles;
GIMP_DRAWABLE(channel)->width = new_width;
GIMP_DRAWABLE(channel)->height = new_height;
/* bounds are now unknown */
channel->bounds_known = FALSE;
/* Update the new channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
}
@ -263,8 +270,8 @@ channel_resize (Channel *channel, int new_width, int new_height,
x1 = BOUNDS (offx, 0, new_width);
y1 = BOUNDS (offy, 0, new_height);
x2 = BOUNDS ((offx + channel->width), 0, new_width);
y2 = BOUNDS ((offy + channel->height), 0, new_height);
x2 = BOUNDS ((offx + GIMP_DRAWABLE(channel)->width), 0, new_width);
y2 = BOUNDS ((offy + GIMP_DRAWABLE(channel)->height), 0, new_height);
w = x2 - x1;
h = y2 - y1;
@ -291,14 +298,14 @@ channel_resize (Channel *channel, int new_width, int new_height,
}
/* Update the old channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, channel->tiles, x1, y1, w, h, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, x1, y1, w, h, FALSE);
/* Determine whether the new channel needs to be initially cleared */
if ((new_width > channel->width) ||
(new_height > channel->height) ||
if ((new_width > GIMP_DRAWABLE(channel)->width) ||
(new_height > GIMP_DRAWABLE(channel)->height) ||
(x2 || y2))
clear = TRUE;
else
@ -320,18 +327,18 @@ channel_resize (Channel *channel, int new_width, int new_height,
copy_region (&srcPR, &destPR);
/* Push the channel on the undo stack */
undo_push_channel_mod (gimage_get_ID (channel->gimage_ID), channel);
undo_push_channel_mod (gimage_get_ID (GIMP_DRAWABLE(channel)->gimage_ID), channel);
/* Configure the new channel */
channel->tiles = new_tiles;
channel->width = new_width;
channel->height = new_height;
GIMP_DRAWABLE(channel)->tiles = new_tiles;
GIMP_DRAWABLE(channel)->width = new_width;
GIMP_DRAWABLE(channel)->height = new_height;
/* bounds are now unknown */
channel->bounds_known = FALSE;
/* update the new channel area */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
}
@ -348,9 +355,9 @@ channel_data (Channel *channel)
int
channel_toggle_visibility (Channel *channel)
{
channel->visible = !channel->visible;
GIMP_DRAWABLE(channel)->visible = !GIMP_DRAWABLE(channel)->visible;
return channel->visible;
return GIMP_DRAWABLE(channel)->visible;
}
@ -362,10 +369,10 @@ channel_preview (Channel *channel, int width, int height)
int subsample;
/* The easy way */
if (channel->preview_valid &&
channel->preview->width == width &&
channel->preview->height == height)
return channel->preview;
if (GIMP_DRAWABLE(channel)->preview_valid &&
GIMP_DRAWABLE(channel)->preview->width == width &&
GIMP_DRAWABLE(channel)->preview->height == height)
return GIMP_DRAWABLE(channel)->preview;
/* The hard way */
else
{
@ -373,11 +380,11 @@ channel_preview (Channel *channel, int width, int height)
subsample = 1;
if (width < 1) width = 1;
if (height < 1) height = 1;
while ((width * (subsample + 1) * 2 < channel->width) &&
(height * (subsample + 1) * 2 < channel->height))
while ((width * (subsample + 1) * 2 < GIMP_DRAWABLE(channel)->width) &&
(height * (subsample + 1) * 2 < GIMP_DRAWABLE(channel)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
preview_buf = mask_buf_new (width, height);
destPR.bytes = 1;
@ -390,13 +397,13 @@ channel_preview (Channel *channel, int width, int height)
subsample_region (&srcPR, &destPR, subsample);
if (channel->preview_valid)
mask_buf_free (channel->preview);
if (GIMP_DRAWABLE(channel)->preview_valid)
mask_buf_free (GIMP_DRAWABLE(channel)->preview);
channel->preview = preview_buf;
channel->preview_valid = 1;
GIMP_DRAWABLE(channel)->preview = preview_buf;
GIMP_DRAWABLE(channel)->preview_valid = 1;
return channel->preview;
return GIMP_DRAWABLE(channel)->preview;
}
}
@ -404,14 +411,19 @@ channel_preview (Channel *channel, int width, int height)
void
channel_invalidate_previews (int gimage_id)
{
link_ptr tmp = channel_list;
link_ptr tmp;
Channel * channel;
GImage * gimage;
if (! (gimage = gimage_get_ID (gimage_id)))
return;
tmp = gimage->channels;
while (tmp)
{
channel = (Channel *) tmp->data;
if (gimage_id == -1 || (channel->gimage_ID == gimage_id))
drawable_invalidate_preview (channel->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(channel));
tmp = next_item (tmp);
}
}
@ -431,7 +443,7 @@ channel_new_mask (int gimage_ID, int width, int height)
new_channel = channel_new (gimage_ID, width, height, "Selection Mask", 127, black);
/* Set the validate procedure */
tile_manager_set_validate_proc (new_channel->tiles, channel_validate);
tile_manager_set_validate_proc (GIMP_DRAWABLE(new_channel)->tiles, channel_validate);
return new_channel;
}
@ -455,7 +467,7 @@ channel_boundary (Channel *mask, BoundSeg **segs_in, BoundSeg **segs_out,
if (channel_bounds (mask, &x3, &y3, &x4, &y4))
{
pixel_region_init (&bPR, mask->tiles, x3, y3, (x4 - x3), (y4 - y3), FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x3, y3, (x4 - x3), (y4 - y3), FALSE);
mask->segs_out = find_mask_boundary (&bPR, &mask->num_segs_out,
IgnoreBounds,
x1, y1,
@ -467,7 +479,7 @@ channel_boundary (Channel *mask, BoundSeg **segs_in, BoundSeg **segs_out,
if (x2 > x1 && y2 > y1)
{
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
mask->segs_in = find_mask_boundary (&bPR, &mask->num_segs_in,
WithinBounds,
x1, y1,
@ -514,11 +526,11 @@ channel_value (Channel *mask, int x, int y)
}
else
{
if (x < 0 || x >= mask->width || y < 0 || y >= mask->height)
if (x < 0 || x >= GIMP_DRAWABLE(mask)->width || y < 0 || y >= GIMP_DRAWABLE(mask)->height)
return 0;
}
tile = tile_manager_get_tile (mask->tiles, x, y, 0);
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0);
tile_ref (tile);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
@ -549,12 +561,12 @@ channel_bounds (Channel *mask, int *x1, int *y1, int *x2, int *y2)
}
/* go through and calculate the bounds */
*x1 = mask->width;
*y1 = mask->height;
*x1 = GIMP_DRAWABLE(mask)->width;
*y1 = GIMP_DRAWABLE(mask)->height;
*x2 = 0;
*y2 = 0;
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -583,15 +595,15 @@ channel_bounds (Channel *mask, int *x1, int *y1, int *x2, int *y2)
}
}
*x2 = BOUNDS (*x2 + 1, 0, mask->width);
*y2 = BOUNDS (*y2 + 1, 0, mask->height);
*x2 = BOUNDS (*x2 + 1, 0, GIMP_DRAWABLE(mask)->width);
*y2 = BOUNDS (*y2 + 1, 0, GIMP_DRAWABLE(mask)->height);
if (*x1 == mask->width && *y1 == mask->height)
if (*x1 == GIMP_DRAWABLE(mask)->width && *y1 == GIMP_DRAWABLE(mask)->height)
{
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
else
{
@ -618,7 +630,7 @@ channel_is_empty (Channel *mask)
if (mask->bounds_known)
return mask->empty;
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* check if any pixel in the mask is non-zero */
@ -646,8 +658,8 @@ channel_is_empty (Channel *mask)
mask->bounds_known = TRUE;
mask->boundary_known = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
return TRUE;
}
@ -665,16 +677,16 @@ channel_add_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -702,16 +714,16 @@ channel_sub_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -739,16 +751,16 @@ channel_inter_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -768,7 +780,7 @@ channel_combine_rect (Channel *mask, int op, int x, int y, int w, int h)
for (i = y; i < y + h; i++)
{
if (i >= 0 && i < mask->height)
if (i >= 0 && i < GIMP_DRAWABLE(mask)->height)
switch (op)
{
case ADD: case REPLACE:
@ -806,10 +818,10 @@ channel_combine_rect (Channel *mask, int op, int x, int y, int w, int h)
else
mask->bounds_known = FALSE;
mask->x1 = BOUNDS (mask->x1, 0, mask->width);
mask->y1 = BOUNDS (mask->y1, 0, mask->height);
mask->x2 = BOUNDS (mask->x2, 0, mask->width);
mask->y2 = BOUNDS (mask->y2, 0, mask->height);
mask->x1 = BOUNDS (mask->x1, 0, GIMP_DRAWABLE(mask)->width);
mask->y1 = BOUNDS (mask->y1, 0, GIMP_DRAWABLE(mask)->height);
mask->x2 = BOUNDS (mask->x2, 0, GIMP_DRAWABLE(mask)->width);
mask->y2 = BOUNDS (mask->y2, 0, GIMP_DRAWABLE(mask)->height);
}
@ -842,7 +854,7 @@ channel_combine_ellipse (Channel *mask, int op, int x, int y, int w, int h,
for (i = y; i < (y + h); i++)
{
if (i >= 0 && i < mask->height)
if (i >= 0 && i < GIMP_DRAWABLE(mask)->height)
{
/* Non-antialiased code */
if (!aa)
@ -952,10 +964,10 @@ channel_combine_ellipse (Channel *mask, int op, int x, int y, int w, int h,
else
mask->bounds_known = FALSE;
mask->x1 = BOUNDS (mask->x1, 0, mask->width);
mask->y1 = BOUNDS (mask->y1, 0, mask->height);
mask->x2 = BOUNDS (mask->x2, 0, mask->width);
mask->y2 = BOUNDS (mask->y2, 0, mask->height);
mask->x1 = BOUNDS (mask->x1, 0, GIMP_DRAWABLE(mask)->width);
mask->y1 = BOUNDS (mask->y1, 0, GIMP_DRAWABLE(mask)->height);
mask->x2 = BOUNDS (mask->x2, 0, GIMP_DRAWABLE(mask)->width);
mask->y2 = BOUNDS (mask->y2, 0, GIMP_DRAWABLE(mask)->height);
}
@ -972,16 +984,16 @@ channel_combine_mask (Channel *mask, Channel *add_on, int op,
int w, h;
void * pr;
x1 = BOUNDS (off_x, 0, mask->width);
y1 = BOUNDS (off_y, 0, mask->height);
x2 = BOUNDS (off_x + add_on->width, 0, mask->width);
y2 = BOUNDS (off_y + add_on->height, 0, mask->height);
x1 = BOUNDS (off_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS (off_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS (off_x + GIMP_DRAWABLE(add_on)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS (off_y + GIMP_DRAWABLE(add_on)->height, 0, GIMP_DRAWABLE(mask)->height);
w = (x2 - x1);
h = (y2 - y1);
pixel_region_init (&srcPR, add_on->tiles, (x1 - off_x), (y1 - off_y), w, h, FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, w, h, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(add_on)->tiles, (x1 - off_x), (y1 - off_y), w, h, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, w, h, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -1027,12 +1039,12 @@ channel_feather (Channel *input, Channel *output, double radius,
int x1, y1, x2, y2;
PixelRegion srcPR;
x1 = BOUNDS (off_x, 0, output->width);
y1 = BOUNDS (off_y, 0, output->height);
x2 = BOUNDS (off_x + input->width, 0, output->width);
y2 = BOUNDS (off_y + input->height, 0, output->height);
x1 = BOUNDS (off_x, 0, GIMP_DRAWABLE(output)->width);
y1 = BOUNDS (off_y, 0, GIMP_DRAWABLE(output)->height);
x2 = BOUNDS (off_x + GIMP_DRAWABLE(input)->width, 0, GIMP_DRAWABLE(output)->width);
y2 = BOUNDS (off_y + GIMP_DRAWABLE(input)->height, 0, GIMP_DRAWABLE(output)->height);
pixel_region_init (&srcPR, input->tiles, (x1 - off_x), (y1 - off_y), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(input)->tiles, (x1 - off_x), (y1 - off_y), (x2 - x1), (y2 - y1), FALSE);
gaussian_blur_region (&srcPR, radius);
if (input != output)
@ -1055,7 +1067,7 @@ channel_push_undo (Channel *mask)
if (channel_bounds (mask, &x1, &y1, &x2, &y2))
{
undo_tiles = tile_manager_new ((x2 - x1), (y2 - y1), 1);
pixel_region_init (&srcPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, undo_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
}
@ -1067,12 +1079,12 @@ channel_push_undo (Channel *mask)
mask_undo->y = y1;
/* push the undo buffer onto the undo stack */
gimage = gimage_get_ID (mask->gimage_ID);
gimage = gimage_get_ID (GIMP_DRAWABLE(mask)->gimage_ID);
undo_push_mask (gimage, mask_undo);
gimage_mask_invalidate (gimage);
/* invalidate the preview */
mask->preview_valid = 0;
GIMP_DRAWABLE(mask)->preview_valid = 0;
}
@ -1087,14 +1099,14 @@ channel_clear (Channel *mask)
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&maskPR, mask->tiles, mask->x1, mask->y1,
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&maskPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&maskPR, &bg);
}
@ -1102,8 +1114,8 @@ channel_clear (Channel *mask)
mask->bounds_known = TRUE;
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
@ -1118,7 +1130,7 @@ channel_invert (Channel *mask)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* subtract each pixel in the mask from 255 */
@ -1146,7 +1158,7 @@ channel_sharpen (Channel *mask)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* if a pixel in the mask has a non-zero value, make it 255 */
@ -1175,15 +1187,15 @@ channel_all (Channel *mask)
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&maskPR, &bg);
/* we know the bounds */
mask->bounds_known = TRUE;
mask->empty = FALSE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
@ -1202,25 +1214,25 @@ channel_border (Channel *mask, int radius)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
bs = find_mask_boundary (&bPR, &num_segs, WithinBounds, x1, y1, x2, y2);
/* clear the channel */
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&bPR, mask->tiles, mask->x1, mask->y1,
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&bPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&bPR, &bg);
}
/* calculate a border of specified radius based on the boundary segments */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
border_region (&bPR, bs, num_segs, radius);
g_free (bs);
@ -1241,7 +1253,7 @@ channel_grow (Channel *mask, int steps)
channel_push_undo (mask);
/* need full extents for grow */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
while (steps--)
thin_region (&bPR, GROW_REGION);
@ -1262,7 +1274,7 @@ channel_shrink (Channel *mask, int steps)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
while (steps--)
thin_region (&bPR, SHRINK_REGION);
@ -1286,10 +1298,10 @@ channel_translate (Channel *mask, int off_x, int off_y)
channel_push_undo (mask);
channel_bounds (mask, &x1, &y1, &x2, &y2);
x1 = BOUNDS ((x1 + off_x), 0, mask->width);
y1 = BOUNDS ((y1 + off_y), 0, mask->height);
x2 = BOUNDS ((x2 + off_x), 0, mask->width);
y2 = BOUNDS ((y2 + off_y), 0, mask->height);
x1 = BOUNDS ((x1 + off_x), 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS ((y1 + off_y), 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS ((x2 + off_x), 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS ((y2 + off_y), 0, GIMP_DRAWABLE(mask)->height);
width = x2 - x1;
height = y2 - y1;
@ -1300,22 +1312,22 @@ channel_translate (Channel *mask, int off_x, int off_y)
/* copy the portion of the mask we will keep to a
* temporary buffer
*/
tmp_mask = channel_new_mask (mask->gimage_ID, width, height);
tmp_mask = channel_new_mask (GIMP_DRAWABLE(mask)->gimage_ID, width, height);
pixel_region_init (&srcPR, mask->tiles, x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, tmp_mask->tiles, 0, 0, width, height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(tmp_mask)->tiles, 0, 0, width, height, TRUE);
copy_region (&srcPR, &destPR);
}
/* clear the mask */
pixel_region_init (&srcPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&srcPR, &empty);
if (width != 0 && height != 0)
{
/* copy the temp mask back to the mask */
pixel_region_init (&srcPR, tmp_mask->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, width, height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(tmp_mask)->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, width, height, TRUE);
copy_region (&srcPR, &destPR);
/* free the temporary mask */
@ -1327,8 +1339,8 @@ channel_translate (Channel *mask, int off_x, int off_y)
{
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
else
{
@ -1341,10 +1353,9 @@ channel_translate (Channel *mask, int off_x, int off_y)
void
channel_layer_alpha (Channel *mask, int layer_id)
channel_layer_alpha (Channel *mask, Layer *layer)
{
PixelRegion srcPR, destPR;
Layer *layer;
unsigned char empty = 0;
int x1, y1, x2, y2;
@ -1352,54 +1363,24 @@ channel_layer_alpha (Channel *mask, int layer_id)
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, mask->tiles, 0, 0, mask->width, 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);
layer = layer_get_ID (layer_id);
x1 = BOUNDS (layer->offset_x, 0, mask->width);
y1 = BOUNDS (layer->offset_y, 0, mask->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, mask->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, mask->height);
x1 = BOUNDS (GIMP_DRAWABLE(layer)->offset_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS (GIMP_DRAWABLE(layer)->offset_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, 0, GIMP_DRAWABLE(mask)->height);
pixel_region_init (&srcPR, layer->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
extract_alpha_region (&srcPR, NULL, &destPR);
mask->bounds_known = FALSE;
}
void
channel_layer_mask (Channel *mask, int layer_id)
{
PixelRegion srcPR, destPR;
Layer *layer;
unsigned char empty = 0;
int x1, y1, x2, y2;
/* push the current mask onto the undo stack */
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
color_region (&destPR, &empty);
layer = layer_get_ID (layer_id);
x1 = BOUNDS (layer->offset_x, 0, mask->width);
y1 = BOUNDS (layer->offset_y, 0, mask->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, mask->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, mask->height);
pixel_region_init (&srcPR, layer->mask->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;
}
void
@ -1411,9 +1392,15 @@ channel_load (Channel *mask, Channel *channel)
channel_push_undo (mask);
/* copy the channel to the mask */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&destPR, mask->tiles, 0, 0, channel->width, channel->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;
}
void
channel_invalidate_bounds (Channel *channel)
{
channel->bounds_known = FALSE;
}

View file

@ -18,6 +18,8 @@
#ifndef __CHANNEL_H__
#define __CHANNEL_H__
#include "drawable.h"
#include "boundary.h"
#include "temp_buf.h"
#include "tile_manager.h"
@ -34,45 +36,16 @@
/* structure declarations */
typedef struct _Channel Channel;
#define GIMP_CHANNEL(obj) GTK_CHECK_CAST (obj, gimp_channel_get_type (), GimpChannel)
#define GIMP_CHANNEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_channel_get_type(), GimpChannelClass)
#define GIMP_IS_CHANNEL(obj) GTK_CHECK_TYPE (obj, gimp_channel_get_type())
struct _Channel
{
char * name; /* name of the channel */
typedef struct _GimpChannel GimpChannel;
typedef struct _GimpChannelClass GimpChannelClass;
TileManager *tiles; /* tiles for channel data */
int visible; /* controls visibility */
int width, height; /* size of channel */
int bytes; /* bytes per pixel */
unsigned char col[3]; /* RGB triplet for channel color*/
int opacity; /* Channel opacity */
int show_masked; /* Show masked areas--as */
/* opposed to selected areas */
int dirty; /* dirty bit */
int ID; /* provides a unique ID */
int layer_ID; /* ID of layer-if a layer mask */
int gimage_ID; /* ID of gimage owner */
/* Selection mask variables */
int boundary_known; /* is the current boundary valid*/
BoundSeg *segs_in; /* outline of selected region */
BoundSeg *segs_out; /* outline of selected region */
int num_segs_in; /* number of lines in boundary */
int num_segs_out; /* number of lines in boundary */
int empty; /* is the region empty? */
int bounds_known; /* recalculate the bounds? */
int x1, y1; /* coordinates for bounding box */
int x2, y2; /* lower right hand coordinate */
/* Preview variables */
TempBuf *preview; /* preview of the channel */
int preview_valid; /* is the preview valid? */
};
typedef GimpChannel Channel; /* convenience */
guint gimp_channel_get_type (void);
/* Special undo type */
typedef struct _channel_undo ChannelUndo;
@ -81,7 +54,7 @@ struct _channel_undo
{
Channel * channel; /* the actual channel */
int prev_position; /* former position in list */
int prev_channel; /* previous active channel */
Channel * prev_channel; /* previous active channel */
int undo_type; /* is this a new channel undo */
/* or a remove channel undo? */
};
@ -98,13 +71,10 @@ struct _mask_undo
/* function declarations */
void channel_allocate (Channel *, int, int);
void channel_deallocate (Channel *);
Channel * channel_new (int, int, int, char *, int, unsigned char *);
Channel * channel_copy (Channel *);
Channel * channel_get_ID (int);
void channel_delete (Channel *);
void channel_apply_image (Channel *, int, int, int, int, TileManager *, int);
void channel_scale (Channel *, int, int);
void channel_resize (Channel *, int, int, int, int);
@ -140,8 +110,12 @@ void channel_border (Channel *, int);
void channel_grow (Channel *, int);
void channel_shrink (Channel *, int);
void channel_translate (Channel *, int, int);
void channel_layer_alpha (Channel *, int);
void channel_layer_mask (Channel *, int);
void channel_load (Channel *, Channel *);
void channel_invalidate_bounds (Channel *);
extern int channel_get_count;
/* from drawable.c */
Channel * drawable_channel (GimpDrawable *);
#endif /* __CHANNEL_H__ */

View file

@ -23,6 +23,8 @@
#include "channel.h"
#include "channel_cmds.h"
#include "channel_pvt.h"
static int int_value;
static double fp_value;
static int success;
@ -87,7 +89,7 @@ channel_new_invoker (Argument *args)
return_args = procedural_db_return_args (&channel_new_proc, success);
if (success)
return_args[1].value.pdb_int = channel->ID;
return_args[1].value.pdb_int = GIMP_DRAWABLE(channel)->ID;
return return_args;
}
@ -178,7 +180,7 @@ channel_copy_invoker (Argument *args)
return_args = procedural_db_return_args (&channel_copy_proc, success);
if (success)
return_args[1].value.pdb_int = copy->ID;
return_args[1].value.pdb_int = GIMP_DRAWABLE(copy)->ID;
return return_args;
}
@ -292,7 +294,7 @@ channel_get_name_invoker (Argument *args)
{
int_value = args[0].value.pdb_int;
if ((channel = channel_get_ID (int_value)))
name = channel->name;
name = GIMP_DRAWABLE(channel)->name;
else
success = FALSE;
}
@ -364,10 +366,10 @@ channel_set_name_invoker (Argument *args)
if (success)
{
name = (char *) args[1].value.pdb_pointer;
if (channel->name)
if (GIMP_DRAWABLE(channel)->name)
{
g_free (channel->name);
channel->name = (name) ? g_strdup (name) : NULL;
g_free (GIMP_DRAWABLE(channel)->name);
GIMP_DRAWABLE(channel)->name = (name) ? g_strdup (name) : NULL;
}
}
@ -427,7 +429,7 @@ channel_get_visible_invoker (Argument *args)
{
int_value = args[0].value.pdb_int;
if ((channel = channel_get_ID (int_value)))
visible = channel->visible;
visible = GIMP_DRAWABLE(channel)->visible;
else
success = FALSE;
}
@ -499,7 +501,7 @@ channel_set_visible_invoker (Argument *args)
if (success)
{
visible = args[1].value.pdb_int;
channel->visible = (visible) ? TRUE : FALSE;
GIMP_DRAWABLE(channel)->visible = (visible) ? TRUE : FALSE;
}
return procedural_db_return_args (&channel_set_visible_proc, success);

View file

@ -28,6 +28,8 @@
#include "interface.h"
#include "palette.h"
#include "channel_pvt.h"
#define ENTRY_WIDTH 60
#define OFFSET_BACKGROUND 0
#define OFFSET_TRANSPARENT 1
@ -47,9 +49,8 @@ typedef struct
} OffsetDialog;
/* Local procedures */
static GImage * duplicate (GImage *gimage);
static void offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
@ -71,22 +72,9 @@ static void offset_wraparound_update (GtkWidget *widget,
static void offset_halfheight_update (GtkWidget *widget,
gpointer data);
static Argument * channel_ops_duplicate_invoker (Argument *args);
static Argument * channel_ops_offset_invoker (Argument *args);
void
channel_ops_duplicate (void *gimage_ptr)
{
GImage *gimage;
GImage *new_gimage;
gimage = (GImage *) gimage_ptr;
new_gimage = duplicate (gimage);
gdisplay_new (new_gimage, 0x0101);
}
void
channel_ops_offset (void *gimage_ptr)
{
@ -100,15 +88,15 @@ channel_ops_offset (void *gimage_ptr)
GtkWidget *toggle_vbox;
GtkWidget *table;
GSList *group = NULL;
int drawable_id;
GimpDrawable *drawable;
GImage *gimage;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
off_d = g_new (OffsetDialog, 1);
off_d->wrap_around = TRUE;
off_d->transparent = drawable_has_alpha (drawable_id);
off_d->transparent = drawable_has_alpha (drawable);
off_d->background = !off_d->transparent;
off_d->gimage_id = gimage->ID;
@ -190,7 +178,7 @@ channel_ops_offset (void *gimage_ptr)
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), off_d->background);
gtk_widget_show (toggle);
if (drawable_has_alpha (drawable_id))
if (drawable_has_alpha (drawable))
{
toggle = gtk_radio_button_new_with_label (group, "Transparent");
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
@ -224,142 +212,25 @@ channel_ops_offset (void *gimage_ptr)
off_d);
}
static GImage *
duplicate (GImage *gimage)
{
PixelRegion srcPR, destPR;
GImage *new_gimage;
Layer *layer, *new_layer;
Layer *floating_layer;
Channel *channel, *new_channel;
link_ptr list;
int active_layer = -1;
int active_channel = -1;
int new_floating_sel_drawable = -1;
int floating_sel_drawable = -1;
int count;
/* Create a new image */
new_gimage = gimage_new (gimage->width, gimage->height, gimage->base_type);
gimage_disable_undo (new_gimage);
floating_layer = gimage_floating_sel (gimage);
if (floating_layer)
{
floating_sel_relax (floating_layer, FALSE);
floating_sel_drawable = floating_layer->fs.drawable;
floating_layer = NULL;
}
/* Copy the layers */
list = gimage->layers;
count = 0;
layer = NULL;
while (list)
{
layer = (Layer *) list->data;
list = next_item (list);
new_layer = layer_copy (layer, FALSE);
new_layer->gimage_ID = new_gimage->ID;
/* Make sure the copied layer doesn't say: "<old layer> copy" */
g_free (new_layer->name);
new_layer->name = g_strdup (layer->name);
/* Make sure if the layer has a layer mask, it's name isn't screwed up */
if (new_layer->mask)
{
g_free (new_layer->mask->name);
new_layer->mask->name = g_strdup (layer->mask->name);
}
if (gimage->active_layer == layer->ID)
active_layer = new_layer->ID;
if (gimage->floating_sel == layer->ID)
floating_layer = new_layer;
if (floating_sel_drawable == layer->ID)
new_floating_sel_drawable = new_layer->ID;
/* Add the layer */
if (floating_layer != new_layer)
gimage_add_layer (new_gimage, new_layer, count++);
}
/* Copy the channels */
list = gimage->channels;
count = 0;
while (list)
{
channel = (Channel *) list->data;
list = next_item (list);
new_channel = channel_copy (channel);
/* Make sure the copied channel doesn't say: "<old channel> copy" */
g_free (new_channel->name);
new_channel->name = g_strdup (channel->name);
if (gimage->active_channel == layer->ID)
active_channel = new_channel->ID;
if (floating_sel_drawable == channel->ID)
new_floating_sel_drawable = new_channel->ID;
/* Add the channel */
gimage_add_channel (new_gimage, new_channel, count++);
}
/* Copy the selection mask */
pixel_region_init (&srcPR, gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, FALSE);
pixel_region_init (&destPR, new_gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, TRUE);
copy_region (&srcPR, &destPR);
new_gimage->selection_mask->bounds_known = FALSE;
new_gimage->selection_mask->boundary_known = FALSE;
/* Set active layer, active channel */
new_gimage->active_layer = active_layer;
new_gimage->active_channel = active_channel;
if (floating_layer)
floating_sel_attach (floating_layer, new_floating_sel_drawable);
/* Copy the colormap if necessary */
if (new_gimage->base_type == INDEXED)
memcpy (new_gimage->cmap, gimage->cmap, gimage->num_cols * 3);
new_gimage->num_cols = gimage->num_cols;
/* copy state of all color channels */
for (count = 0; count < MAX_CHANNELS; count++)
{
new_gimage->visible[count] = gimage->visible[count];
new_gimage->active[count] = gimage->active[count];
}
gimage_enable_undo (new_gimage);
return new_gimage;
}
static void
offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
int offset_y)
{
PixelRegion srcPR, destPR;
Channel *channel;
Layer *layer;
TileManager *new_tiles;
int width, height;
int src_x, src_y;
int dest_x, dest_y;
unsigned char fill[MAX_CHANNELS] = { 0 };
if (!drawable)
return;
width = drawable_width (drawable);
height = drawable_height (drawable);
@ -565,10 +436,7 @@ offset (GImage *gimage,
drawable_data (drawable), FALSE);
/* swap the tiles */
if ((channel = channel_get_ID (drawable)))
channel->tiles = new_tiles;
else if ((layer = layer_get_ID (drawable)))
layer->tiles = new_tiles;
drawable->tiles = new_tiles;
/* update the drawable */
drawable_update (drawable, 0, 0, drawable_width (drawable), drawable_height (drawable));
@ -584,14 +452,14 @@ offset_ok_callback (GtkWidget *widget,
{
OffsetDialog *off_d;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int offset_x, offset_y;
int fill_type;
off_d = (OffsetDialog *) data;
if ((gimage = gimage_get_ID (off_d->gimage_id)) != NULL)
{
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
offset_x = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_x_entry)));
offset_y = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_y_entry)));
@ -601,7 +469,7 @@ offset_ok_callback (GtkWidget *widget,
else
fill_type = OFFSET_BACKGROUND;
offset (gimage, drawable_id, off_d->wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, off_d->wrap_around, fill_type, offset_x, offset_y);
gdisplays_flush ();
}
@ -684,76 +552,6 @@ offset_halfheight_update (GtkWidget *widget,
* Procedure database functions and data structures
*/
/* The duplicate procedure definition */
ProcArg channel_ops_duplicate_args[] =
{
{ PDB_IMAGE,
"image",
"the image"
}
};
ProcArg channel_ops_duplicate_out_args[] =
{
{ PDB_IMAGE,
"new_image",
"the new, duplicated image"
}
};
ProcRecord channel_ops_duplicate_proc =
{
"gimp_channel_ops_duplicate",
"Duplicate the specified image",
"This procedure duplicates the specified image, copying all layers, channels, and image information.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1997",
PDB_INTERNAL,
/* Input arguments */
1,
channel_ops_duplicate_args,
/* Output arguments */
1,
channel_ops_duplicate_out_args,
/* Exec method */
{ { channel_ops_duplicate_invoker } },
};
static Argument *
channel_ops_duplicate_invoker (Argument *args)
{
Argument *return_args;
int success = TRUE;
int int_value;
GImage *gimage, *new_gimage;
new_gimage = NULL;
/* the gimage */
if (success)
{
int_value = args[0].value.pdb_int;
if (! (gimage = gimage_get_ID (int_value)))
success = FALSE;
}
if (success)
success = ((new_gimage = duplicate ((void *) gimage)) != NULL);
return_args = procedural_db_return_args (&channel_ops_duplicate_proc, success);
if (success)
return_args[1].value.pdb_int = new_gimage->ID;
return return_args;
}
/*
* Procedure database functions and data structures
*/
@ -816,7 +614,7 @@ channel_ops_offset_invoker (Argument *args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int wrap_around;
int fill_type;
int offset_x;
@ -831,8 +629,9 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
{
drawable_id = args[1].value.pdb_int;
if (gimage != drawable_gimage (drawable_id))
int_value = args[1].value.pdb_int;
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
if (success)
@ -852,7 +651,7 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
offset (gimage, drawable_id, wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, wrap_around, fill_type, offset_x, offset_y);
return procedural_db_return_args (&channel_ops_offset_proc, success);
}

View file

@ -21,11 +21,9 @@
#include "procedural_db.h"
/* channel_ops functions */
void channel_ops_duplicate (void *);
void channel_ops_offset (void *);
/* Procedure definition and marshalling function */
extern ProcRecord channel_ops_duplicate_proc;
extern ProcRecord channel_ops_offset_proc;
#endif /* __CHANNEL_OPS_H__ */

55
app/channel_pvt.h Normal file
View file

@ -0,0 +1,55 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __CHANNEL_PVT_H__
#define __CHANNEL_PVT_H__
#include "drawable.h"
#include "boundary.h"
#include "temp_buf.h"
#include "tile_manager.h"
#include "drawable_pvt.h"
struct _GimpChannel
{
GimpDrawable drawable;
unsigned char col[3]; /* RGB triplet for channel color*/
int opacity; /* Channel opacity */
int show_masked; /* Show masked areas--as */
/* opposed to selected areas */
/* Selection mask variables */
int boundary_known; /* is the current boundary valid*/
BoundSeg *segs_in; /* outline of selected region */
BoundSeg *segs_out; /* outline of selected region */
int num_segs_in; /* number of lines in boundary */
int num_segs_out; /* number of lines in boundary */
int empty; /* is the region empty? */
int bounds_known; /* recalculate the bounds? */
int x1, y1; /* coordinates for bounding box */
int x2, y2; /* lower right hand coordinate */
};
struct _GimpChannelClass
{
GimpDrawableClass parent_class;
};
#endif /* __CHANNEL_PVT_H__ */

View file

@ -40,6 +40,8 @@
#include "tools/eye.xbm"
#include "tools/channel.xbm"
#include "channel_pvt.h"
#define PREVIEW_EVENT_MASK GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_ENTER_NOTIFY_MASK
#define BUTTON_EVENT_MASK GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | \
@ -67,8 +69,8 @@ struct _ChannelWidget {
Channel *channel;
GdkPixmap *channel_pixmap;
ChannelType type;
int width, height;
int ID;
int width, height;
int visited;
};
@ -90,19 +92,19 @@ struct _ChannelsDialog {
/* state information */
int gimage_id;
int active_channel_id;
int floating_sel_id;
Channel * active_channel;
Layer *floating_sel;
link_ptr channel_widgets;
};
/* channels dialog widget routines */
static void channels_dialog_preview_extents (void);
static void channels_dialog_set_menu_sensitivity (void);
static void channels_dialog_set_channel (int);
static void channels_dialog_unset_channel (int);
static void channels_dialog_position_channel (int, int);
static void channels_dialog_add_channel (int);
static void channels_dialog_remove_channel (int);
static void channels_dialog_set_channel (ChannelWidget *);
static void channels_dialog_unset_channel (ChannelWidget *);
static void channels_dialog_position_channel (ChannelWidget *, int);
static void channels_dialog_add_channel (Channel *);
static void channels_dialog_remove_channel (ChannelWidget *);
static gint channel_list_events (GtkWidget *, GdkEvent *);
/* channels dialog menu callbacks */
@ -116,7 +118,7 @@ static void channels_dialog_delete_channel_callback (GtkWidget *, gpointer);
static void channels_dialog_channel_to_sel_callback (GtkWidget *, gpointer);
/* channel widget function prototypes */
static ChannelWidget *channel_widget_get_ID (int);
static ChannelWidget *channel_widget_get_ID (Channel *);
static ChannelWidget *create_channel_widget (GImage *, Channel *, ChannelType);
static void channel_widget_delete (ChannelWidget *);
static void channel_widget_select_update (GtkWidget *, gpointer);
@ -174,8 +176,8 @@ channels_dialog_create ()
channelsD = g_malloc (sizeof (ChannelsDialog));
channelsD->preview = NULL;
channelsD->gimage_id = -1;
channelsD->active_channel_id = -1;
channelsD->floating_sel_id = -1;
channelsD->active_channel = NULL;
channelsD->floating_sel = NULL;
channelsD->channel_widgets = NULL;
channelsD->accel_table = gtk_accelerator_table_new ();
@ -261,11 +263,11 @@ channels_dialog_flush ()
while (list)
{
channel = (Channel *) list->data;
cw = channel_widget_get_ID (channel->ID);
cw = channel_widget_get_ID (channel);
/* If the channel isn't in the channel widget list, add it */
if (cw == NULL)
channels_dialog_add_channel (channel->ID);
channels_dialog_add_channel (channel);
else
cw->visited = TRUE;
@ -281,7 +283,7 @@ channels_dialog_flush ()
if (cw->visited == FALSE && cw->type == Auxillary)
/* will only be true for auxillary channels */
channels_dialog_remove_channel (cw->channel->ID);
channels_dialog_remove_channel (cw);
}
/* Switch positions of items if necessary */
@ -293,19 +295,19 @@ channels_dialog_flush ()
list = next_item (list);
if (cw->type == Auxillary)
if ((gimage_pos = gimage_get_channel_index (gimage, cw->channel->ID)) != pos)
channels_dialog_position_channel (cw->channel->ID, gimage_pos);
if ((gimage_pos = gimage_get_channel_index (gimage, cw->channel)) != pos)
channels_dialog_position_channel (cw, gimage_pos);
pos++;
}
/* Set the active channel */
if (channelsD->active_channel_id != gimage->active_channel)
channelsD->active_channel_id = gimage->active_channel;
if (channelsD->active_channel != gimage->active_channel)
channelsD->active_channel = gimage->active_channel;
/* set the menus if floating sel status has changed */
if (channelsD->floating_sel_id != gimage->floating_sel)
channelsD->floating_sel_id = gimage->floating_sel;
if (channelsD->floating_sel != gimage->floating_sel)
channelsD->floating_sel = gimage->floating_sel;
channels_dialog_set_menu_sensitivity ();
@ -354,8 +356,8 @@ channels_dialog_update (int gimage_id)
/* Find the preview extents */
channels_dialog_preview_extents ();
channelsD->active_channel_id = -1;
channelsD->floating_sel_id = -1;
channelsD->active_channel = NULL;
channelsD->floating_sel = NULL;
/* The image components */
item_list = NULL;
@ -448,8 +450,8 @@ channels_dialog_free ()
channel_widget_delete (cw);
}
channelsD->channel_widgets = NULL;
channelsD->active_channel_id = -1;
channelsD->floating_sel_id = -1;
channelsD->active_channel = NULL;
channelsD->floating_sel = NULL;
if (channelsD->preview)
gtk_widget_destroy (channelsD->preview);
@ -501,8 +503,8 @@ channels_dialog_set_menu_sensitivity ()
gint fs_sensitive;
gint aux_sensitive;
cw = channel_widget_get_ID (channelsD->active_channel_id);
fs_sensitive = (channelsD->floating_sel_id != -1);
cw = channel_widget_get_ID (channelsD->active_channel);
fs_sensitive = (channelsD->floating_sel != NULL);
if (cw)
aux_sensitive = (cw->type == Auxillary);
@ -525,13 +527,11 @@ channels_dialog_set_menu_sensitivity ()
void
channels_dialog_set_channel (int channel_ID)
channels_dialog_set_channel (ChannelWidget *channel_widget)
{
ChannelWidget *channel_widget;
GtkStateType state;
int index;
channel_widget = channel_widget_get_ID (channel_ID);
if (!channelsD || !channel_widget)
return;
@ -541,20 +541,19 @@ channels_dialog_set_channel (int channel_ID)
/* get the list item data */
state = channel_widget->list_item->state;
if (channel_widget->type == Auxillary)
if (channel_widget->type == Auxillary)
{
/* turn on the specified auxillary channel */
index = gimage_get_channel_index (channel_widget->gimage, channel_ID);
index = gimage_get_channel_index (channel_widget->gimage, channel_widget->channel);
if ((index >= 0) && (state != GTK_STATE_SELECTED))
{
gtk_object_set_user_data (GTK_OBJECT (channel_widget->list_item), NULL);
gtk_list_select_item (GTK_LIST (channelsD->channel_list), index + channelsD->num_components);
gtk_object_set_user_data (GTK_OBJECT (channel_widget->list_item), channel_widget);
}
}
else /* component channel */
}
else
{
/* turn on the specified auxillary channel */
if (state != GTK_STATE_SELECTED)
{
gtk_object_set_user_data (GTK_OBJECT (channel_widget->list_item), NULL);
@ -570,24 +569,23 @@ channels_dialog_set_channel (int channel_ID)
gtk_list_select_item (GTK_LIST (channelsD->channel_list), 2);
break;
case Auxillary:
g_error ("error in %s at %d: this shouldn't happen.",
__FILE__, __LINE__);
break;
}
gtk_object_set_user_data (GTK_OBJECT (channel_widget->list_item), channel_widget);
}
}
suspend_gimage_notify--;
}
void
channels_dialog_unset_channel (int channel_ID)
channels_dialog_unset_channel (ChannelWidget * channel_widget)
{
ChannelWidget *channel_widget;
GtkStateType state;
int index;
channel_widget = channel_widget_get_ID (channel_ID);
if (!channelsD || !channel_widget)
return;
@ -597,10 +595,10 @@ channels_dialog_unset_channel (int channel_ID)
/* get the list item data */
state = channel_widget->list_item->state;
if (channel_widget->type == Auxillary)
if (channel_widget->type == Auxillary)
{
/* turn off the specified auxillary channel */
index = gimage_get_channel_index (channel_widget->gimage, channel_ID);
index = gimage_get_channel_index (channel_widget->gimage, channel_widget->channel);
if ((index >= 0) && (state == GTK_STATE_SELECTED))
{
gtk_object_set_user_data (GTK_OBJECT (channel_widget->list_item), NULL);
@ -608,10 +606,9 @@ channels_dialog_unset_channel (int channel_ID)
gtk_object_set_user_data (GTK_OBJECT (channel_widget->list_item), channel_widget);
}
}
else /* component channel */
else
{
/* turn on the specified auxillary channel */
if (state != GTK_STATE_SELECTED)
if (state == GTK_STATE_SELECTED)
{
gtk_object_set_user_data (GTK_OBJECT (channel_widget->list_item), NULL);
switch (channel_widget->type)
@ -626,24 +623,24 @@ channels_dialog_unset_channel (int channel_ID)
gtk_list_unselect_item (GTK_LIST (channelsD->channel_list), 2);
break;
case Auxillary:
g_error ("error in %s at %d: this shouldn't happen.",
__FILE__, __LINE__);
break;
}
gtk_object_set_user_data (GTK_OBJECT (channel_widget->list_item), channel_widget);
}
}
suspend_gimage_notify--;
}
void
channels_dialog_position_channel (int channel_ID,
channels_dialog_position_channel (ChannelWidget *channel_widget,
int new_index)
{
ChannelWidget *channel_widget;
GList *list = NULL;
channel_widget = channel_widget_get_ID (channel_ID);
if (!channelsD || !channel_widget)
return;
@ -662,16 +659,13 @@ channels_dialog_position_channel (int channel_ID,
void
channels_dialog_add_channel (int channel_id)
channels_dialog_add_channel (Channel *channel)
{
GImage *gimage;
Channel *channel;
GList *item_list;
ChannelWidget *channel_widget;
int position;
channel = channel_get_ID (channel_id);
if (!channelsD || !channel)
return;
if (! (gimage = gimage_get_ID (channelsD->gimage_id)))
@ -682,7 +676,7 @@ channels_dialog_add_channel (int channel_id)
channel_widget = create_channel_widget (gimage, channel, Auxillary);
item_list = g_list_append (item_list, channel_widget->list_item);
position = gimage_get_channel_index (gimage, channel_id);
position = gimage_get_channel_index (gimage, channel);
channelsD->channel_widgets = insert_in_list (channelsD->channel_widgets, channel_widget,
position + channelsD->num_components);
gtk_list_insert_items (GTK_LIST (channelsD->channel_list), item_list,
@ -691,13 +685,10 @@ channels_dialog_add_channel (int channel_id)
void
channels_dialog_remove_channel (int channel_ID)
channels_dialog_remove_channel (ChannelWidget *channel_widget)
{
ChannelWidget *channel_widget;
GList *list = NULL;
channel_widget = channel_widget_get_ID (channel_ID);
if (!channelsD || !channel_widget)
return;
@ -828,7 +819,7 @@ channels_dialog_raise_channel_callback (GtkWidget *w,
if (! (gimage = gimage_get_ID (channelsD->gimage_id)))
return;
if (gimage->active_channel != -1)
if (gimage->active_channel != NULL)
{
gimage_raise_channel (gimage, gimage->active_channel);
gdisplays_flush ();
@ -847,7 +838,7 @@ channels_dialog_lower_channel_callback (GtkWidget *w,
if (! (gimage = gimage_get_ID (channelsD->gimage_id)))
return;
if (gimage->active_channel != -1)
if (gimage->active_channel != NULL)
{
gimage_lower_channel (gimage, gimage->active_channel);
gdisplays_flush ();
@ -892,7 +883,7 @@ channels_dialog_delete_channel_callback (GtkWidget *w,
if (! (gimage = gimage_get_ID (channelsD->gimage_id)))
return;
if (gimage->active_channel != -1)
if (gimage->active_channel != NULL)
{
gimage_remove_channel (gimage, gimage->active_channel);
gdisplays_flush ();
@ -913,7 +904,7 @@ channels_dialog_channel_to_sel_callback (GtkWidget *w,
if (! (gimage = gimage_get_ID (channelsD->gimage_id)))
return;
if (gimage->active_channel != -1)
if (gimage->active_channel != NULL)
{
gimage_mask_load (gimage, gimage->active_channel);
gdisplays_flush ();
@ -926,7 +917,7 @@ channels_dialog_channel_to_sel_callback (GtkWidget *w,
/****************************/
static ChannelWidget *
channel_widget_get_ID (int ID)
channel_widget_get_ID (Channel *channel)
{
ChannelWidget *lw;
link_ptr list;
@ -939,7 +930,7 @@ channel_widget_get_ID (int ID)
while (list)
{
lw = (ChannelWidget *) list->data;
if (lw->ID == ID)
if (lw->channel == channel)
return lw;
list = next_item(list);
@ -969,7 +960,7 @@ create_channel_widget (GImage *gimage,
channel_widget->channel_preview = NULL;
channel_widget->channel_pixmap = NULL;
channel_widget->type = type;
channel_widget->ID = (type == Auxillary) ? channel->ID : (COMPONENT_BASE_ID + type);
channel_widget->ID = (type == Auxillary) ? GIMP_DRAWABLE(channel)->ID : (COMPONENT_BASE_ID + type);
channel_widget->list_item = list_item;
channel_widget->width = -1;
channel_widget->height = -1;
@ -1030,7 +1021,7 @@ create_channel_widget (GImage *gimage,
case Blue: channel_widget->label = gtk_label_new ("Blue"); break;
case Gray: channel_widget->label = gtk_label_new ("Gray"); break;
case Indexed: channel_widget->label = gtk_label_new ("Indexed"); break;
case Auxillary: channel_widget->label = gtk_label_new (channel->name); break;
case Auxillary: channel_widget->label = gtk_label_new (GIMP_DRAWABLE(channel)->name); break;
}
gtk_box_pack_start (GTK_BOX (hbox), channel_widget->label, FALSE, FALSE, 2);
@ -1073,7 +1064,7 @@ channel_widget_select_update (GtkWidget *w,
{
if (w->state == GTK_STATE_SELECTED)
/* set the gimage's active channel to be this channel */
gimage_set_active_channel (channel_widget->gimage, channel_widget->channel->ID);
gimage_set_active_channel (channel_widget->gimage, channel_widget->channel);
else
/* unset the gimage's active channel */
gimage_unset_active_channel (channel_widget->gimage);
@ -1109,9 +1100,9 @@ channel_widget_button_events (GtkWidget *widget,
switch (channel_widget->type)
{
case Auxillary:
visible = channel_widget->channel->visible;
width = channel_widget->channel->width;
height = channel_widget->channel->height;
visible = GIMP_DRAWABLE(channel_widget->channel)->visible;
width = GIMP_DRAWABLE(channel_widget->channel)->width;
height = GIMP_DRAWABLE(channel_widget->channel)->height;
break;
default:
visible = gimage_get_component_visible (channel_widget->gimage, channel_widget->type);
@ -1150,7 +1141,7 @@ channel_widget_button_events (GtkWidget *widget,
{
exclusive = FALSE;
if (channel_widget->type == Auxillary)
channel_widget->channel->visible = !visible;
GIMP_DRAWABLE(channel_widget->channel)->visible = !visible;
else
gimage_set_component_visible (channel_widget->gimage, channel_widget->type, !visible);
channel_widget_eye_redraw (channel_widget);
@ -1194,7 +1185,7 @@ channel_widget_button_events (GtkWidget *widget,
else
{
if (channel_widget->type == Auxillary)
channel_widget->channel->visible = !visible;
GIMP_DRAWABLE(channel_widget->channel)->visible = !visible;
else
gimage_set_component_visible (channel_widget->gimage, channel_widget->type, !visible);
channel_widget_eye_redraw (channel_widget);
@ -1231,7 +1222,7 @@ channel_widget_preview_events (GtkWidget *widget,
switch (channel_widget->type)
{
case Auxillary:
valid = channel_widget->channel->preview_valid;
valid = GIMP_DRAWABLE(channel_widget->channel)->preview_valid;
break;
default:
valid = gimage_preview_valid (channel_widget->gimage, channel_widget->type);
@ -1289,8 +1280,8 @@ channel_widget_preview_redraw (ChannelWidget *channel_widget)
switch (channel_widget->type)
{
case Auxillary:
width = channel_widget->channel->width;
height = channel_widget->channel->height;
width = GIMP_DRAWABLE(channel_widget->channel)->width;
height = GIMP_DRAWABLE(channel_widget->channel)->height;
channel_widget->width = (int) (channelsD->ratio * width);
channel_widget->height = (int) (channelsD->ratio * height);
preview_buf = channel_preview (channel_widget->channel,
@ -1433,7 +1424,7 @@ channel_widget_eye_redraw (ChannelWidget *channel_widget)
switch (channel_widget->type)
{
case Auxillary:
visible = channel_widget->channel->visible;
visible = GIMP_DRAWABLE(channel_widget->channel)->visible;
break;
default:
visible = gimage_get_component_visible (channel_widget->gimage, channel_widget->type);
@ -1502,7 +1493,7 @@ channel_widget_exclusive_visible (ChannelWidget *channel_widget)
switch (cw->type)
{
case Auxillary:
visible |= cw->channel->visible;
visible |= GIMP_DRAWABLE(cw->channel)->visible;
break;
default:
visible |= gimage_get_component_visible (cw->gimage, cw->type);
@ -1522,7 +1513,7 @@ channel_widget_exclusive_visible (ChannelWidget *channel_widget)
switch (cw->type)
{
case Auxillary:
cw->channel->visible = !visible;
GIMP_DRAWABLE(cw->channel)->visible = !visible;
break;
default:
gimage_set_component_visible (cw->gimage, cw->type, !visible);
@ -1532,7 +1523,7 @@ channel_widget_exclusive_visible (ChannelWidget *channel_widget)
switch (cw->type)
{
case Auxillary:
cw->channel->visible = TRUE;
GIMP_DRAWABLE(cw->channel)->visible = TRUE;
break;
default:
gimage_set_component_visible (cw->gimage, cw->type, TRUE);
@ -1558,7 +1549,7 @@ channel_widget_channel_flush (GtkWidget *widget,
/*** Sensitivity ***/
/* If there is a floating selection... */
if (channelsD->floating_sel_id != -1)
if (channelsD->floating_sel != NULL)
{
/* to insensitive if this is an auxillary channel */
if (channel_widget->type == Auxillary)
@ -1576,7 +1567,7 @@ channel_widget_channel_flush (GtkWidget *widget,
else
{
/* to insensitive if there is an active channel, and this is a component channel */
if (channel_widget->type != Auxillary && channelsD->active_channel_id != -1)
if (channel_widget->type != Auxillary && channelsD->active_channel != NULL)
{
if (GTK_WIDGET_IS_SENSITIVE (channel_widget->list_item))
gtk_widget_set_sensitive (channel_widget->list_item, FALSE);
@ -1595,25 +1586,25 @@ channel_widget_channel_flush (GtkWidget *widget,
if (channel_widget->type == Auxillary)
{
/* select if this is the active channel */
if (channelsD->active_channel_id == channel_widget->channel->ID)
channels_dialog_set_channel (channel_widget->ID);
if (channelsD->active_channel == (channel_widget->channel))
channels_dialog_set_channel (channel_widget);
/* unselect if this is not the active channel */
else
channels_dialog_unset_channel (channel_widget->ID);
channels_dialog_unset_channel (channel_widget);
}
else
{
/* If the component is active, select. otherwise, deselect */
if (gimage_get_component_active (channel_widget->gimage, channel_widget->type))
channels_dialog_set_channel (channel_widget->ID);
channels_dialog_set_channel (channel_widget);
else
channels_dialog_unset_channel (channel_widget->ID);
channels_dialog_unset_channel (channel_widget);
}
switch (channel_widget->type)
{
case Auxillary:
update_preview = !channel_widget->channel->preview_valid;
update_preview = !GIMP_DRAWABLE(channel_widget->channel)->preview_valid;
break;
default:
update_preview = !gimage_preview_valid (channel_widget->gimage, channel_widget->type);
@ -1662,7 +1653,7 @@ new_channel_query_ok_callback (GtkWidget *w,
new_channel = channel_new (gimage->ID, gimage->width, gimage->height,
channel_name, (int) (255 * options->opacity) / 100,
options->color_panel->color);
drawable_fill (new_channel->ID, TRANSPARENT_FILL);
drawable_fill (GIMP_DRAWABLE(new_channel), TRANSPARENT_FILL);
for (i = 0; i < 3; i++)
channel_color[i] = options->color_panel->color[i];
@ -1825,10 +1816,10 @@ edit_channel_query_ok_callback (GtkWidget *w,
opacity = (int) (255 * options->opacity) / 100;
/* Set the new channel name */
if (channel->name)
g_free (channel->name);
channel->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (options->name_entry)));
gtk_label_set (GTK_LABEL (options->channel_widget->label), channel->name);
if (GIMP_DRAWABLE(channel)->name)
g_free (GIMP_DRAWABLE(channel)->name);
GIMP_DRAWABLE(channel)->name = g_strdup (gtk_entry_get_text (GTK_ENTRY (options->name_entry)));
gtk_label_set (GTK_LABEL (options->channel_widget->label), GIMP_DRAWABLE(channel)->name);
if (channel->opacity != opacity)
{
@ -1844,7 +1835,7 @@ edit_channel_query_ok_callback (GtkWidget *w,
if (update)
{
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
gdisplays_flush ();
}
@ -1929,7 +1920,7 @@ channels_dialog_edit_channel_query (ChannelWidget *channel_widget)
gtk_widget_show (label);
options->name_entry = gtk_entry_new ();
gtk_box_pack_start (GTK_BOX (hbox), options->name_entry, TRUE, TRUE, 0);
gtk_entry_set_text (GTK_ENTRY (options->name_entry), channel_widget->channel->name);
gtk_entry_set_text (GTK_ENTRY (options->name_entry), GIMP_DRAWABLE(channel_widget->channel)->name);
gtk_widget_show (options->name_entry);
gtk_widget_show (hbox);

View file

@ -42,16 +42,16 @@ typedef enum
/* forward function declarations */
static void clone_draw (Tool *);
static void clone_motion (PaintCore *, int, int, CloneType, int, int);
static void clone_line_image (GImage *, GImage *, int, int, unsigned char *,
static void clone_motion (PaintCore *, GimpDrawable *, GimpDrawable *, CloneType, int, int);
static void clone_line_image (GImage *, GImage *, GimpDrawable *, GimpDrawable *, unsigned char *,
unsigned char *, int, int, int, int);
static void clone_line_pattern (GImage *, int, GPatternP, unsigned char *,
static void clone_line_pattern (GImage *, GimpDrawable *, GPatternP, unsigned char *,
int, int, int, int);
static Argument * clone_invoker (Argument *);
static int non_gui_src_drawable;
static GimpDrawable *non_gui_src_drawable;
static int non_gui_offset_x;
static int non_gui_offset_y;
static CloneType non_gui_type;
@ -73,7 +73,7 @@ static int offset_y = 0; /* offset for cloning */
static int first = TRUE;
static int trans_tx, trans_ty; /* transformed target */
static int src_gdisp_ID = -1; /* ID of source gdisplay */
static int src_drawable_ID = -1; /* ID of source drawable */
static GimpDrawable * src_drawable_ = NULL; /* source drawable */
static CloneOptions *clone_options = NULL;
@ -167,7 +167,7 @@ create_clone_options (void)
void *
clone_paint_func (PaintCore *paint_core,
int drawable_id,
GimpDrawable *drawable,
int state)
{
GDisplay * gdisp;
@ -208,7 +208,7 @@ clone_paint_func (PaintCore *paint_core,
src_y = dest_y + offset_y;
}
clone_motion (paint_core, drawable_id, src_drawable_ID, clone_options->type, offset_x, offset_y);
clone_motion (paint_core, drawable, src_drawable_, clone_options->type, offset_x, offset_y);
}
draw_core_pause (paint_core->core, active_tool);
@ -218,7 +218,7 @@ clone_paint_func (PaintCore *paint_core,
if (paint_core->state & ControlMask)
{
src_gdisp_ID = gdisp->ID;
src_drawable_ID = drawable_id;
src_drawable_ = drawable;
src_x = paint_core->curx;
src_y = paint_core->cury;
first = TRUE;
@ -306,8 +306,8 @@ clone_draw (Tool *tool)
static void
clone_motion (PaintCore *paint_core,
int drawable_id,
int src_drawable_id,
GimpDrawable *drawable,
GimpDrawable *src_drawable,
CloneType type,
int offset_x,
int offset_y)
@ -329,16 +329,16 @@ clone_motion (PaintCore *paint_core,
pattern = NULL;
/* Make sure we still have a source! */
if ((! (src_gimage = drawable_gimage (src_drawable_id)) && type == ImageClone) ||
! (gimage = drawable_gimage (drawable_id)))
if ((! (src_gimage = drawable_gimage (src_drawable)) && type == ImageClone) ||
! (gimage = drawable_gimage (drawable)))
return;
/* Get a region which can be used to paint to */
if (! (area = paint_core_get_paint_area (paint_core, drawable_id)))
if (! (area = paint_core_get_paint_area (paint_core, drawable)))
return;
/* Determine whether the source image has an alpha channel */
has_alpha = drawable_has_alpha (src_drawable_id);
has_alpha = drawable_has_alpha (src_drawable);
switch (type)
{
@ -352,34 +352,34 @@ clone_motion (PaintCore *paint_core,
* Otherwise, we need a call to get_orig_image to make sure
* we get a copy of the unblemished (offset) image
*/
if (src_drawable_id != drawable_id)
if (src_drawable != drawable)
{
x1 = BOUNDS (area->x + offset_x, 0, drawable_width (src_drawable_id));
y1 = BOUNDS (area->y + offset_y, 0, drawable_height (src_drawable_id));
x1 = BOUNDS (area->x + offset_x, 0, drawable_width (src_drawable));
y1 = BOUNDS (area->y + offset_y, 0, drawable_height (src_drawable));
x2 = BOUNDS (area->x + offset_x + area->width,
0, drawable_width (src_drawable_id));
0, drawable_width (src_drawable));
y2 = BOUNDS (area->y + offset_y + area->height,
0, drawable_height (src_drawable_id));
0, drawable_height (src_drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
pixel_region_init (&srcPR, drawable_data (src_drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, drawable_data (src_drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
}
else
{
x1 = BOUNDS (area->x + offset_x, 0, drawable_width (drawable_id));
y1 = BOUNDS (area->y + offset_y, 0, drawable_height (drawable_id));
x1 = BOUNDS (area->x + offset_x, 0, drawable_width (drawable));
y1 = BOUNDS (area->y + offset_y, 0, drawable_height (drawable));
x2 = BOUNDS (area->x + offset_x + area->width,
0, drawable_width (drawable_id));
0, drawable_width (drawable));
y2 = BOUNDS (area->y + offset_y + area->height,
0, drawable_height (drawable_id));
0, drawable_height (drawable));
if (!(x2 - x1) || !(y2 - y1))
return;
/* get the original image */
orig = paint_core_get_orig_image (paint_core, drawable_id, x1, y1, x2, y2);
orig = paint_core_get_orig_image (paint_core, drawable, x1, y1, x2, y2);
srcPR.bytes = orig->bytes;
srcPR.x = 0; srcPR.y = 0;
@ -430,12 +430,12 @@ clone_motion (PaintCore *paint_core,
switch (type)
{
case ImageClone:
clone_line_image (gimage, src_gimage, drawable_id, src_drawable_id, s, d,
clone_line_image (gimage, src_gimage, drawable, src_drawable, s, d,
has_alpha, srcPR.bytes, destPR.bytes, destPR.w);
s += srcPR.rowstride;
break;
case PatternClone:
clone_line_pattern (gimage, drawable_id, pattern, d,
clone_line_pattern (gimage, drawable, pattern, d,
area->x + offset_x, area->y + y + offset_y,
destPR.bytes, destPR.w);
break;
@ -446,7 +446,7 @@ clone_motion (PaintCore *paint_core,
}
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable_id, OPAQUE,
paint_core_paste_canvas (paint_core, drawable, OPAQUE,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
}
@ -454,8 +454,8 @@ clone_motion (PaintCore *paint_core,
static void
clone_line_image (GImage *dest,
GImage *src,
int d_drawable,
int s_drawable,
GimpDrawable *d_drawable,
GimpDrawable *s_drawable,
unsigned char *s,
unsigned char *d,
int has_alpha,
@ -486,7 +486,7 @@ clone_line_image (GImage *dest,
static void
clone_line_pattern (GImage *dest,
int drawable_id,
GimpDrawable *drawable,
GPatternP pattern,
unsigned char *d,
int x,
@ -515,7 +515,7 @@ clone_line_pattern (GImage *dest,
{
p = pat + ((i + x) % pattern->mask->width) * pattern->mask->bytes;
gimage_transform_color (dest, drawable_id, p, d, color);
gimage_transform_color (dest, drawable, p, d, color);
d[alpha] = OPAQUE;
@ -525,10 +525,10 @@ clone_line_pattern (GImage *dest,
static void *
clone_non_gui_paint_func (PaintCore *paint_core,
int drawable_id,
GimpDrawable *drawable,
int state)
{
clone_motion (paint_core, drawable_id, non_gui_src_drawable,
clone_motion (paint_core, drawable, non_gui_src_drawable,
non_gui_type, non_gui_offset_x, non_gui_offset_y);
return NULL;
@ -601,14 +601,15 @@ clone_invoker (Argument *args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
GimpDrawable *src_drawable;
double src_x, src_y;
int num_strokes;
double *stroke_array;
CloneType int_value;
int i;
drawable_id = -1;
drawable = NULL;
num_strokes = 0;
/* the gimage */
@ -622,19 +623,19 @@ clone_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (! (gimage == drawable_gimage (int_value)))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* the src drawable */
if (success)
{
int_value = args[2].value.pdb_int;
if (! drawable_gimage (int_value))
src_drawable = drawable_get_ID (int_value);
if (src_drawable == NULL || gimage != drawable_gimage (src_drawable))
success = FALSE;
else
non_gui_src_drawable = int_value;
non_gui_src_drawable = src_drawable;
}
/* the clone type */
if (success)
@ -669,7 +670,7 @@ clone_invoker (Argument *args)
if (success)
/* init the paint core */
success = paint_core_init (&non_gui_paint_core, drawable_id,
success = paint_core_init (&non_gui_paint_core, drawable,
stroke_array[0], stroke_array[1]);
if (success)
@ -684,21 +685,21 @@ clone_invoker (Argument *args)
non_gui_offset_y = (int) (src_y - non_gui_paint_core.starty);
if (num_strokes == 1)
clone_non_gui_paint_func (&non_gui_paint_core, drawable_id, 0);
clone_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
for (i = 1; i < num_strokes; i++)
{
non_gui_paint_core.curx = stroke_array[i * 2 + 0];
non_gui_paint_core.cury = stroke_array[i * 2 + 1];
paint_core_interpolate (&non_gui_paint_core, drawable_id);
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.lastx = non_gui_paint_core.curx;
non_gui_paint_core.lasty = non_gui_paint_core.cury;
}
/* finish the painting */
paint_core_finish (&non_gui_paint_core, drawable_id, -1);
paint_core_finish (&non_gui_paint_core, drawable, -1);
/* cleanup */
paint_core_cleanup ();

View file

@ -22,7 +22,7 @@
#include "procedural_db.h"
#include "tools.h"
void * clone_paint_func (PaintCore *, int, int);
void * clone_paint_func (PaintCore *, GimpDrawable *, int);
Tool * tools_new_clone (void);
void tools_free_clone (Tool *);

View file

@ -62,7 +62,7 @@ struct _ColorBalanceDialog
GtkAdjustment *magenta_green_data;
GtkAdjustment *yellow_blue_data;
int drawable_id;
GimpDrawable *drawable;
ImageMap image_map;
double cyan_red[3];
@ -330,8 +330,8 @@ color_balance_initialize (void *gdisp_ptr)
color_balance_dialog->magenta_green[i] = 0.0;
color_balance_dialog->yellow_blue[i] = 0.0;
}
color_balance_dialog->drawable_id = gimage_active_drawable (gdisp->gimage);
color_balance_dialog->image_map = image_map_create (gdisp_ptr, color_balance_dialog->drawable_id);
color_balance_dialog->drawable = gimage_active_drawable (gdisp->gimage);
color_balance_dialog->image_map = image_map_create (gdisp_ptr, color_balance_dialog->drawable);
color_balance_update (color_balance_dialog, ALL);
}
@ -921,7 +921,6 @@ color_balance_invoker (Argument *args)
int int_value;
ColorBalanceDialog cbd;
GImage *gimage;
int drawable_id;
int transfer_mode;
int preserve_lum;
double cyan_red;
@ -931,8 +930,9 @@ color_balance_invoker (Argument *args)
int x1, y1, x2, y2;
int i;
void *pr;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
transfer_mode = MIDTONES;
cyan_red = 0;
magenta_green = 0;
@ -949,9 +949,8 @@ color_balance_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* transfer_mode */
@ -1016,16 +1015,16 @@ color_balance_invoker (Argument *args)
cbd.yellow_blue[transfer_mode] = yellow_blue;
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
color_balance (&srcPR, &destPR, (void *) &cbd);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&color_balance_proc, success);

View file

@ -39,7 +39,7 @@ static void color_picker_motion (Tool *, GdkEventMotion *, gpointer);
static void color_picker_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void color_picker_control (Tool *, int, void *);
static int get_color (GImage *, int, int, int, int, int);
static int get_color (GImage *, GimpDrawable *, int, int, int, int);
static void color_picker_info_update (Tool *, int);
static Argument *color_picker_invoker (Argument *);
@ -47,7 +47,7 @@ static Argument *color_picker_invoker (Argument *);
/* local variables */
static int col_value [5] = { 0, 0, 0, 0, 0 };
static int drawable_id;
static GimpDrawable * active_drawable;
static int update_type;
static int sample_type;
static InfoDialog * color_picker_info = NULL;
@ -131,17 +131,17 @@ color_picker_button_press (Tool *tool,
* create (or recreate) the info dialog...
*/
if (tool->state == INACTIVE || gdisp_ptr != tool->gdisp_ptr ||
drawable_id != gimage_active_drawable (gdisp->gimage))
active_drawable != gimage_active_drawable (gdisp->gimage))
{
/* if the dialog exists, free it */
if (color_picker_info)
info_dialog_free (color_picker_info);
color_picker_info = info_dialog_new ("Color Picker");
drawable_id = gimage_active_drawable (gdisp->gimage);
active_drawable = gimage_active_drawable (gdisp->gimage);
/* if the gdisplay is for a color image, the dialog must have RGB */
switch (drawable_type (drawable_id))
switch (drawable_type (active_drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
info_dialog_add_field (color_picker_info, "Red", red_buf);
@ -186,14 +186,14 @@ color_picker_button_press (Tool *tool,
*/
if (bevent->state & GDK_SHIFT_MASK)
{
color_picker_info_update (tool, get_color (gdisp->gimage, drawable_id, x, y,
color_picker_info_update (tool, get_color (gdisp->gimage, active_drawable, x, y,
color_picker_options->sample_merged,
COLOR_NEW));
update_type = COLOR_UPDATE_NEW;
}
else
{
color_picker_info_update (tool, get_color (gdisp->gimage, drawable_id, x, y,
color_picker_info_update (tool, get_color (gdisp->gimage, active_drawable, x, y,
color_picker_options->sample_merged,
COLOR_UPDATE));
update_type = COLOR_UPDATE;
@ -215,7 +215,7 @@ color_picker_button_release (Tool *tool,
/* First, transform the coordinates to gimp image space */
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y, FALSE, FALSE);
color_picker_info_update (tool, get_color (gdisp->gimage, drawable_id, x, y,
color_picker_info_update (tool, get_color (gdisp->gimage, active_drawable, x, y,
color_picker_options->sample_merged,
update_type));
}
@ -233,7 +233,7 @@ color_picker_motion (Tool *tool,
/* First, transform the coordinates to gimp image space */
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y, FALSE, FALSE);
color_picker_info_update (tool, get_color (gdisp->gimage, drawable_id, x, y,
color_picker_info_update (tool, get_color (gdisp->gimage, active_drawable, x, y,
color_picker_options->sample_merged,
update_type));
}
@ -264,7 +264,7 @@ color_picker_control (Tool *tool,
static int
get_color (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
int x,
int y,
int sample_merged,
@ -279,18 +279,21 @@ get_color (GImage *gimage,
int index;
int has_alpha;
if (!drawable && !sample_merged)
return FALSE;
if (! sample_merged)
{
drawable_offsets (drawable_id, &offx, &offy);
drawable_offsets (drawable, &offx, &offy);
x -= offx;
y -= offy;
width = drawable_width (drawable_id);
height = drawable_height (drawable_id);
tiles = drawable_data (drawable_id);
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable_id);
sample_type = drawable_type (drawable_id);
cmap = drawable_cmap (drawable_id);
width = drawable_width (drawable);
height = drawable_height (drawable);
tiles = drawable_data (drawable);
bytes = drawable_bytes (drawable);
has_alpha = drawable_has_alpha (drawable);
sample_type = drawable_type (drawable);
cmap = drawable_cmap (drawable);
}
else
{
@ -509,7 +512,7 @@ color_picker_invoker (Argument *args)
{
GImage *gimage;
int success = TRUE;
int drawable_id;
GimpDrawable *drawable;
double x, y;
int sample_merged;
int save_color;
@ -517,7 +520,7 @@ color_picker_invoker (Argument *args)
Argument *return_args;
unsigned char *color;
drawable_id = -1;
drawable = NULL;
x = 0;
y = 0;
sample_merged = FALSE;
@ -534,7 +537,7 @@ color_picker_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
drawable_id = int_value;
drawable = drawable_get_ID (int_value);
}
/* x, y */
if (success)
@ -557,12 +560,12 @@ color_picker_invoker (Argument *args)
/* Make sure that if we're not using the composite, the specified drawable is valid */
if (success && !sample_merged)
if ((drawable_gimage (int_value)) != gimage)
if (!drawable || (drawable_gimage (drawable)) != gimage)
success = FALSE;
/* call the color_picker procedure */
if (success)
success = get_color (gimage, drawable_id, (int) x, (int) y, sample_merged, save_color);
success = get_color (gimage, drawable, (int) x, (int) y, sample_merged, save_color);
return_args = procedural_db_return_args (&color_picker_proc, success);

View file

@ -39,6 +39,7 @@
#include "floating_sel.h"
#include "gdisplay_ops.h"
#include "general.h"
#include "gimage_cmds.h"
#include "gimage_mask.h"
#include "gimprc.h"
#include "global_edit.h"
@ -213,7 +214,7 @@ file_new_ok_callback (GtkWidget *widget,
gimage_add_layer (gimage, layer, 0);
gimage_enable_undo (gimage);
drawable_fill (layer->ID, vals->fill_type);
drawable_fill (GIMP_DRAWABLE(layer), vals->fill_type);
gimage_clean_all (gimage);

View file

@ -66,6 +66,10 @@
#include "undo.h"
#include "palette.h"
#include "layer_pvt.h" /* ick. */
#include "drawable_pvt.h" /* ick ick. */
#include "tile_manager_pvt.h" /* ick ick ick. */
#define MAXNUMCOLORS 256
#define NODITHER 0
@ -738,7 +742,7 @@ convert_image (GImage *gimage,
break;
}
new_tiles = tile_manager_new (layer->width, layer->height, new_layer_bytes);
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, new_layer_bytes);
switch (new_type)
{
@ -758,9 +762,10 @@ convert_image (GImage *gimage,
/* Push the layer on the undo stack */
undo_push_layer_mod (gimage, layer);
layer->tiles = new_tiles;
layer->bytes = new_layer_bytes;
layer->type = new_layer_type;
GIMP_DRAWABLE(layer)->tiles = new_tiles;
GIMP_DRAWABLE(layer)->bytes = new_layer_bytes;
GIMP_DRAWABLE(layer)->type = new_layer_type;
GIMP_DRAWABLE(layer)->has_alpha = TYPE_HAS_ALPHA(new_layer_type);
}
/* Delete the quantizer object, if there is one */
@ -800,8 +805,8 @@ rgb_converter (Layer *layer,
void *pr;
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -832,7 +837,7 @@ rgb_converter (Layer *layer,
}
break;
case INDEXED:
cmap = drawable_cmap (layer->ID);
cmap = drawable_cmap (GIMP_DRAWABLE(layer));
for (row = 0; row < srcPR.h; row++)
{
s = src;
@ -874,8 +879,8 @@ grayscale_converter (Layer *layer,
void *pr;
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -903,7 +908,7 @@ grayscale_converter (Layer *layer,
}
break;
case INDEXED:
cmap = drawable_cmap (layer->ID);
cmap = drawable_cmap (GIMP_DRAWABLE(layer));
for (row = 0; row < srcPR.h; row++)
{
s = src;
@ -966,7 +971,7 @@ generate_histogram_gray (Histogram histogram,
has_alpha = (gboolean) layer_has_alpha(layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
for (pr = pixel_regions_register (1, &srcPR);
pr != NULL;
pr = pixel_regions_process (pr))
@ -999,7 +1004,7 @@ generate_histogram_rgb (Histogram histogram,
g_print ("col_limit = %d, nfc = %d\n", col_limit, num_found_cols);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
for (pr = pixel_regions_register (1, &srcPR);
pr != NULL;
pr = pixel_regions_process (pr))
@ -2057,8 +2062,8 @@ median_cut_pass2_no_dither_gray (QuantizeObj *quantobj,
zero_histogram_gray (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2107,14 +2112,14 @@ median_cut_pass2_no_dither_rgb (QuantizeObj *quantobj,
/* In the case of web/mono palettes, we actually force
* grayscale drawables through the rgb pass2 functions
*/
if (drawable_gray (layer->ID))
if (drawable_gray (GIMP_DRAWABLE(layer)))
red_pix = green_pix = blue_pix = GRAY_PIX;
zero_histogram_rgb (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2167,8 +2172,8 @@ median_cut_pass2_nodestruct_dither_rgb (QuantizeObj *quantobj,
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2322,12 +2327,12 @@ median_cut_pass2_fs_dither_gray (QuantizeObj *quantobj,
zero_histogram_gray (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, layer->height, TRUE);
src_bytes = layer->bytes;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
src_bytes = GIMP_DRAWABLE(layer)->bytes;
dest_bytes = new_tiles->levels[0].bpp;
width = layer->width;
height = layer->height;
width = GIMP_DRAWABLE(layer)->width;
height = GIMP_DRAWABLE(layer)->height;
error_limiter = init_error_limit ();
range_limiter = range_array + 256;
@ -2472,18 +2477,18 @@ median_cut_pass2_fs_dither_rgb (QuantizeObj *quantobj,
/* In the case of web/mono palettes, we actually force
* grayscale drawables through the rgb pass2 functions
*/
if (drawable_gray (layer->ID))
if (drawable_gray (GIMP_DRAWABLE(layer)))
red_pix = green_pix = blue_pix = GRAY_PIX;
zero_histogram_rgb (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, layer->height, TRUE);
src_bytes = layer->bytes;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
src_bytes = GIMP_DRAWABLE(layer)->bytes;
dest_bytes = new_tiles->levels[0].bpp;
width = layer->width;
height = layer->height;
width = GIMP_DRAWABLE(layer)->width;
height = GIMP_DRAWABLE(layer)->height;
error_limiter = init_error_limit ();
range_limiter = range_array + 256;

View file

@ -41,7 +41,7 @@ static void integer_matrix (float *, int *, int);
static void copy_matrix (float *, float *, int);
static int sum_matrix (int *, int);
static void convolve_motion (PaintCore *, int);
static void convolve_motion (PaintCore *, GimpDrawable *);
static Argument * convolve_invoker (Argument *);
#define FIELD_COLS 4
@ -186,7 +186,7 @@ create_convolve_options (void)
void *
convolve_paint_func (PaintCore *paint_core,
int drawable_id,
GimpDrawable *drawable,
int state)
{
switch (state)
@ -197,7 +197,7 @@ convolve_paint_func (PaintCore *paint_core,
break;
case MOTION_PAINT:
convolve_motion (paint_core, drawable_id);
convolve_motion (paint_core, drawable);
break;
case FINISH_PAINT:
@ -232,26 +232,26 @@ tools_free_convolve (Tool *tool)
void
convolve_motion (PaintCore *paint_core,
int drawable_id)
GimpDrawable *drawable)
{
GImage *gimage;
TempBuf * area;
unsigned char *temp_data;
PixelRegion srcPR, destPR, tempPR;
if (! (gimage = drawable_gimage (drawable_id)))
if (! (gimage = drawable_gimage (drawable)))
return;
/* If the image type is indexed, don't convolve */
if (drawable_type (drawable_id) == INDEXED_GIMAGE)
if (drawable_type (drawable) == INDEXED_GIMAGE)
return;
/* Get a region which can be used to paint to */
if (! (area = paint_core_get_paint_area (paint_core, drawable_id)))
if (! (area = paint_core_get_paint_area (paint_core, drawable)))
return;
/* configure the pixel regions correctly */
pixel_region_init (&srcPR, drawable_data (drawable_id), area->x, area->y, area->width, area->height, FALSE);
pixel_region_init (&srcPR, drawable_data (drawable), area->x, area->y, area->width, area->height, FALSE);
destPR.bytes = area->bytes;
destPR.x = 0; destPR.y = 0;
@ -264,7 +264,7 @@ convolve_motion (PaintCore *paint_core,
if (srcPR.w >= matrix_size && srcPR.h >= matrix_size)
{
/* if the source has no alpha, then add alpha pixels */
if (!drawable_has_alpha (drawable_id))
if (!drawable_has_alpha (drawable))
{
/* note: this architecture needlessly convolves the totally-
opaque alpha channel. A faster approach would be to keep
@ -310,7 +310,7 @@ convolve_motion (PaintCore *paint_core,
convolve_region (&tempPR, &destPR, matrix, matrix_size,
matrix_divisor, NORMAL);
if (drawable_has_alpha (drawable_id))
if (drawable_has_alpha (drawable))
separate_alpha_region (&destPR);
/* Free the allocated temp space */
@ -319,14 +319,14 @@ convolve_motion (PaintCore *paint_core,
else
{
/* if the source has no alpha, then add alpha pixels, otherwise copy */
if (!drawable_has_alpha (drawable_id))
if (!drawable_has_alpha (drawable))
add_alpha_region (&srcPR, &destPR);
else
copy_region (&srcPR, &destPR);
}
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_replace_canvas (paint_core, drawable_id, OPAQUE,
paint_core_replace_canvas (paint_core, drawable, OPAQUE,
(int) (get_brush_opacity () * 255),
SOFT, INCREMENTAL);
}
@ -408,10 +408,10 @@ sum_matrix (int *matrix,
static void *
convolve_non_gui_paint_func (PaintCore *paint_core,
int drawable_id,
GimpDrawable *drawable,
int state)
{
convolve_motion (paint_core, drawable_id);
convolve_motion (paint_core, drawable);
return NULL;
}
@ -475,7 +475,7 @@ convolve_invoker (Argument *args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
double pressure;
ConvolveType type;
int num_strokes;
@ -484,7 +484,7 @@ convolve_invoker (Argument *args)
double fp_value;
int i;
drawable_id = -1;
drawable = NULL;
pressure = 100.0;
type = Blur;
num_strokes = 0;
@ -500,10 +500,9 @@ convolve_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (! (gimage == drawable_gimage (int_value)))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* the pressure */
if (success)
@ -542,7 +541,7 @@ convolve_invoker (Argument *args)
if (success)
/* init the paint core */
success = paint_core_init (&non_gui_paint_core, drawable_id,
success = paint_core_init (&non_gui_paint_core, drawable,
stroke_array[0], stroke_array[1]);
if (success)
@ -557,21 +556,21 @@ convolve_invoker (Argument *args)
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
if (num_strokes == 1)
convolve_non_gui_paint_func (&non_gui_paint_core, drawable_id, 0);
convolve_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
for (i = 1; i < num_strokes; i++)
{
non_gui_paint_core.curx = stroke_array[i * 2 + 0];
non_gui_paint_core.cury = stroke_array[i * 2 + 1];
paint_core_interpolate (&non_gui_paint_core, drawable_id);
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.lastx = non_gui_paint_core.curx;
non_gui_paint_core.lasty = non_gui_paint_core.cury;
}
/* finish the painting */
paint_core_finish (&non_gui_paint_core, drawable_id, -1);
paint_core_finish (&non_gui_paint_core, drawable, -1);
/* cleanup */
paint_core_cleanup ();

View file

@ -22,7 +22,7 @@
#include "procedural_db.h"
#include "tools.h"
void * convolve_paint_func (PaintCore *, int, int);
void * convolve_paint_func (PaintCore *, GimpDrawable *, int);
Tool * tools_new_convolve (void);
void tools_free_convolve (Tool *);

View file

@ -32,6 +32,9 @@
#include "tools.h"
#include "undo.h"
#include "tile_manager_pvt.h"
#include "drawable_pvt.h"
/* The named paste dialog */
typedef struct _PasteNamedDlg PasteNamedDlg;
@ -165,13 +168,13 @@ crop_buffer (TileManager *tiles,
TileManager *
edit_cut (GImage *gimage,
int drawable_id)
GimpDrawable *drawable)
{
TileManager *cut;
TileManager *cropped_cut;
int empty;
if (!gimage || drawable_id == -1)
if (!gimage || drawable == NULL)
return NULL;
/* Start a group undo */
@ -181,7 +184,7 @@ edit_cut (GImage *gimage,
empty = gimage_mask_is_empty (gimage);
/* Next, cut the mask portion from the gimage */
cut = gimage_mask_extract (gimage, drawable_id, TRUE, FALSE);
cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
/* Only crop if the gimage mask wasn't empty */
if (cut && empty == FALSE)
@ -215,20 +218,20 @@ edit_cut (GImage *gimage,
TileManager *
edit_copy (GImage *gimage,
int drawable_id)
GimpDrawable *drawable)
{
TileManager * copy;
TileManager * cropped_copy;
int empty;
if (!gimage || drawable_id == -1)
if (!gimage || drawable == NULL)
return NULL;
/* See if the gimage mask is empty */
empty = gimage_mask_is_empty (gimage);
/* First, copy the masked portion of the gimage */
copy = gimage_mask_extract (gimage, drawable_id, FALSE, FALSE);
copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE);
/* Only crop if the gimage mask wasn't empty */
if (copy && empty == FALSE)
@ -259,7 +262,7 @@ edit_copy (GImage *gimage,
int
edit_paste (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
TileManager *paste,
int paste_into)
{
@ -268,7 +271,7 @@ edit_paste (GImage *gimage,
int cx, cy;
/* Make a new floating layer */
float_layer = layer_from_tiles (gimage, drawable_id, paste, "Pasted Layer", OPAQUE, NORMAL);
float_layer = layer_from_tiles (gimage, drawable, paste, "Pasted Layer", OPAQUE, NORMAL);
if (float_layer)
{
@ -276,13 +279,13 @@ edit_paste (GImage *gimage,
undo_push_group_start (gimage, EDIT_PASTE_UNDO);
/* Set the offsets to the center of the image */
drawable_offsets (drawable_id, &cx, &cy);
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_offsets ( (drawable), &cx, &cy);
drawable_mask_bounds ( (drawable), &x1, &y1, &x2, &y2);
cx += (x1 + x2) >> 1;
cy += (y1 + y2) >> 1;
float_layer->offset_x = cx - (float_layer->width >> 1);
float_layer->offset_y = cy - (float_layer->height >> 1);
GIMP_DRAWABLE(float_layer)->offset_x = cx - (GIMP_DRAWABLE(float_layer)->width >> 1);
GIMP_DRAWABLE(float_layer)->offset_y = cy - (GIMP_DRAWABLE(float_layer)->height >> 1);
/* If there is a selection mask clear it--
* this might not always be desired, but in general,
@ -292,12 +295,12 @@ edit_paste (GImage *gimage,
channel_clear (gimage_get_mask (gimage));
/* add a new floating selection */
floating_sel_attach (float_layer, drawable_id);
floating_sel_attach (float_layer, drawable);
/* end the group undo */
undo_push_group_end (gimage);
return float_layer->ID;
return GIMP_DRAWABLE(float_layer)->ID;
}
else
return 0;
@ -305,35 +308,35 @@ edit_paste (GImage *gimage,
int
edit_clear (GImage *gimage,
int drawable_id)
GimpDrawable *drawable)
{
TileManager *buf_tiles;
PixelRegion bufPR;
int x1, y1, x2, y2;
unsigned char col[MAX_CHANNELS];
if (!gimage || drawable_id == -1)
if (!gimage || drawable == NULL)
return FALSE;
gimage_get_background (gimage, drawable_id, col);
if (drawable_has_alpha (drawable_id))
col [drawable_bytes (drawable_id) - 1] = OPAQUE;
gimage_get_background (gimage, drawable, col);
if (drawable_has_alpha (drawable))
col [drawable_bytes (drawable) - 1] = OPAQUE;
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
if (!(x2 - x1) || !(y2 - y1))
return FALSE;
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable_id));
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable));
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
color_region (&bufPR, col);
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
gimage_apply_image (gimage, drawable_id, &bufPR, 1, OPAQUE,
gimage_apply_image (gimage, drawable, &bufPR, 1, OPAQUE,
ERASE_MODE, NULL, x1, y1);
/* update the image */
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
/* free the temporary tiles */
tile_manager_destroy (buf_tiles);
@ -343,35 +346,35 @@ edit_clear (GImage *gimage,
int
edit_fill (GImage *gimage,
int drawable_id)
GimpDrawable *drawable)
{
TileManager *buf_tiles;
PixelRegion bufPR;
int x1, y1, x2, y2;
unsigned char col[MAX_CHANNELS];
if (!gimage || drawable_id == -1)
if (!gimage || drawable == NULL)
return FALSE;
gimage_get_background (gimage, drawable_id, col);
if (drawable_has_alpha (drawable_id))
col [drawable_bytes (drawable_id) - 1] = OPAQUE;
gimage_get_background (gimage, drawable, col);
if (drawable_has_alpha (drawable))
col [drawable_bytes (drawable) - 1] = OPAQUE;
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
if (!(x2 - x1) || !(y2 - y1))
return FALSE;
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable_id));
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable));
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
color_region (&bufPR, col);
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
gimage_apply_image (gimage, drawable_id, &bufPR, 1, OPAQUE,
gimage_apply_image (gimage, drawable, &bufPR, 1, OPAQUE,
NORMAL_MODE, NULL, x1, y1);
/* update the image */
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
/* free the temporary tiles */
tile_manager_destroy (buf_tiles);

View file

@ -22,11 +22,11 @@
/* The interface functions */
TileManager * crop_buffer (TileManager *, int);
TileManager * edit_cut (GImage *, int);
TileManager * edit_copy (GImage *, int);
int edit_paste (GImage *, int, TileManager *, int);
int edit_clear (GImage *, int);
int edit_fill (GImage *, int);
TileManager * edit_cut (GImage *, GimpDrawable *);
TileManager * edit_copy (GImage *, GimpDrawable *);
int edit_paste (GImage *, GimpDrawable *, TileManager *, int);
int edit_clear (GImage *, GimpDrawable *);
int edit_fill (GImage *, GimpDrawable *);
int global_edit_cut (void *);
int global_edit_copy (void *);

View file

@ -31,6 +31,61 @@
#include "temp_buf.h"
#include "undo.h"
#include "channel_pvt.h"
enum {
LAST_SIGNAL
};
static void gimp_channel_class_init (GimpChannelClass *klass);
static void gimp_channel_init (GimpChannel *channel);
static void gimp_channel_destroy (GtkObject *object);
static gint channel_signals[LAST_SIGNAL] = { 0 };
static GimpDrawableClass *parent_class = NULL;
guint
gimp_channel_get_type ()
{
static guint channel_type = 0;
if (!channel_type)
{
GtkTypeInfo channel_info =
{
"GimpChannel",
sizeof (GimpChannel),
sizeof (GimpChannelClass),
(GtkClassInitFunc) gimp_channel_class_init,
(GtkObjectInitFunc) gimp_channel_init,
(GtkArgFunc) NULL,
};
channel_type = gtk_type_unique (gimp_drawable_get_type (), &channel_info);
}
return channel_type;
}
static void
gimp_channel_class_init (GimpChannelClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gimp_drawable_get_type ());
gtk_object_class_add_signals (object_class, channel_signals, LAST_SIGNAL);
object_class->destroy = gimp_channel_destroy;
}
static void
gimp_channel_init (GimpChannel *channel)
{
}
#define ROUND(x) ((int) (x + 0.5))
@ -38,8 +93,8 @@
* Static variables
*/
extern int global_drawable_ID;
static link_ptr channel_list = NULL;
int channel_get_count = 0;
/**************************/
@ -53,19 +108,6 @@ channel_validate (TileManager *tm, Tile *tile, int level)
}
void
channel_allocate (Channel *channel, int width, int height)
{
channel->tiles = tile_manager_new (width, height, 1);
}
void
channel_deallocate (Channel *channel)
{
if (channel->tiles)
tile_manager_destroy (channel->tiles);
}
Channel *
@ -75,37 +117,16 @@ channel_new (int gimage_ID, int width, int height, char *name, int opacity,
Channel * channel;
int i;
channel = (Channel *) g_malloc (sizeof (Channel));
channel = gtk_type_new (gimp_channel_get_type ());
if (!name)
name = "unnamed";
channel->name = (char *) g_malloc (strlen (name) + 1);
strcpy (channel->name, name);
/* set size information */
channel->width = width;
channel->height = height;
channel->bytes = 1;
/* allocate the memory for this channel */
channel_allocate (channel, width, height);
channel->visible = 1;
gimp_drawable_configure (GIMP_DRAWABLE(channel),
gimage_ID, width, height, GRAY_GIMAGE, name);
/* set the channel color and opacity */
for (i = 0; i < 3; i++)
channel->col[i] = col[i];
channel->opacity = opacity;
channel->show_masked = 1;
channel->dirty = 0;
/* give this channel an ID */
channel->ID = global_drawable_ID++;
channel->layer_ID = -1;
channel->gimage_ID = gimage_ID;
/* add the new channel to the global list */
channel_list = append_to_list (channel_list, (void *) channel);
/* selection mask variables */
channel->empty = TRUE;
@ -119,10 +140,6 @@ channel_new (int gimage_ID, int width, int height, char *name, int opacity,
channel->x2 = width;
channel->y2 = height;
/* preview variables */
channel->preview = NULL;
channel->preview_valid = FALSE;
return channel;
}
@ -135,18 +152,22 @@ channel_copy (Channel *channel)
PixelRegion srcPR, destPR;
/* formulate the new channel name */
channel_name = (char *) g_malloc (strlen (channel->name) + 6);
sprintf (channel_name, "%s copy", channel->name);
channel_name = (char *) g_malloc (strlen (GIMP_DRAWABLE(channel)->name) + 6);
sprintf (channel_name, "%s copy", GIMP_DRAWABLE(channel)->name);
/* allocate a new channel object */
new_channel = channel_new (channel->gimage_ID, channel->width, channel->height, channel_name,
channel->opacity, channel->col);
new_channel->visible = channel->visible;
new_channel = channel_new (GIMP_DRAWABLE(channel)->gimage_ID,
GIMP_DRAWABLE(channel)->width,
GIMP_DRAWABLE(channel)->height,
channel_name, channel->opacity, channel->col);
GIMP_DRAWABLE(new_channel)->visible = GIMP_DRAWABLE(channel)->visible;
new_channel->show_masked = channel->show_masked;
/* copy the contents across channels */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&destPR, new_channel->tiles, 0, 0, channel->width, channel->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0,
GIMP_DRAWABLE(channel)->width,
GIMP_DRAWABLE(channel)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, TRUE);
copy_region (&srcPR, &destPR);
/* free up the channel_name memory */
@ -159,56 +180,42 @@ channel_copy (Channel *channel)
Channel *
channel_get_ID (int ID)
{
link_ptr tmp = channel_list;
Channel * channel;
while (tmp)
{
channel = (Channel *) tmp->data;
if (channel->ID == ID)
return channel;
tmp = next_item (tmp);
}
return NULL;
GimpDrawable *drawable;
drawable = drawable_get_ID (ID);
if (drawable && GIMP_IS_CHANNEL (drawable))
return GIMP_CHANNEL (drawable);
else
return NULL;
}
void
channel_delete (Channel *channel)
{
gtk_object_destroy (GTK_OBJECT (channel));
}
static void
gimp_channel_destroy (GtkObject *object)
{
GimpChannel *channel;
g_return_if_fail (object != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (object));
channel = GIMP_CHANNEL (object);
/* free the segments? */
if (channel->segs_in)
g_free (channel->segs_in);
if (channel->segs_out)
g_free (channel->segs_out);
/* remove this image from the global list */
channel_list = remove_from_list (channel_list, (void *) channel);
/* deallocate the channel mem */
channel_deallocate (channel);
/* free the channel name buffer */
g_free (channel->name);
g_free (channel);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
void
channel_apply_image (Channel *channel, int x1, int y1, int x2, int y2,
TileManager *tiles, int sparse)
{
/* Need to push an undo operation */
if (! tiles)
undo_push_image (gimage_get_ID (channel->gimage_ID), channel->ID, x1, y1, x2, y2);
else
undo_push_image_mod (gimage_get_ID (channel->gimage_ID), channel->ID, x1, y1, x2, y2, tiles, sparse);
}
void
channel_scale (Channel *channel, int new_width, int new_height)
{
@ -219,10 +226,10 @@ channel_scale (Channel *channel, int new_width, int new_height)
return;
/* Update the old channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
/* Allocate the new channel, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, 1);
@ -232,18 +239,18 @@ channel_scale (Channel *channel, int new_width, int new_height)
scale_region (&srcPR, &destPR);
/* Push the channel on the undo stack */
undo_push_channel_mod (gimage_get_ID (channel->gimage_ID), channel);
undo_push_channel_mod (gimage_get_ID (GIMP_DRAWABLE(channel)->gimage_ID), channel);
/* Configure the new channel */
channel->tiles = new_tiles;
channel->width = new_width;
channel->height = new_height;
GIMP_DRAWABLE(channel)->tiles = new_tiles;
GIMP_DRAWABLE(channel)->width = new_width;
GIMP_DRAWABLE(channel)->height = new_height;
/* bounds are now unknown */
channel->bounds_known = FALSE;
/* Update the new channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
}
@ -263,8 +270,8 @@ channel_resize (Channel *channel, int new_width, int new_height,
x1 = BOUNDS (offx, 0, new_width);
y1 = BOUNDS (offy, 0, new_height);
x2 = BOUNDS ((offx + channel->width), 0, new_width);
y2 = BOUNDS ((offy + channel->height), 0, new_height);
x2 = BOUNDS ((offx + GIMP_DRAWABLE(channel)->width), 0, new_width);
y2 = BOUNDS ((offy + GIMP_DRAWABLE(channel)->height), 0, new_height);
w = x2 - x1;
h = y2 - y1;
@ -291,14 +298,14 @@ channel_resize (Channel *channel, int new_width, int new_height,
}
/* Update the old channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, channel->tiles, x1, y1, w, h, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, x1, y1, w, h, FALSE);
/* Determine whether the new channel needs to be initially cleared */
if ((new_width > channel->width) ||
(new_height > channel->height) ||
if ((new_width > GIMP_DRAWABLE(channel)->width) ||
(new_height > GIMP_DRAWABLE(channel)->height) ||
(x2 || y2))
clear = TRUE;
else
@ -320,18 +327,18 @@ channel_resize (Channel *channel, int new_width, int new_height,
copy_region (&srcPR, &destPR);
/* Push the channel on the undo stack */
undo_push_channel_mod (gimage_get_ID (channel->gimage_ID), channel);
undo_push_channel_mod (gimage_get_ID (GIMP_DRAWABLE(channel)->gimage_ID), channel);
/* Configure the new channel */
channel->tiles = new_tiles;
channel->width = new_width;
channel->height = new_height;
GIMP_DRAWABLE(channel)->tiles = new_tiles;
GIMP_DRAWABLE(channel)->width = new_width;
GIMP_DRAWABLE(channel)->height = new_height;
/* bounds are now unknown */
channel->bounds_known = FALSE;
/* update the new channel area */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
}
@ -348,9 +355,9 @@ channel_data (Channel *channel)
int
channel_toggle_visibility (Channel *channel)
{
channel->visible = !channel->visible;
GIMP_DRAWABLE(channel)->visible = !GIMP_DRAWABLE(channel)->visible;
return channel->visible;
return GIMP_DRAWABLE(channel)->visible;
}
@ -362,10 +369,10 @@ channel_preview (Channel *channel, int width, int height)
int subsample;
/* The easy way */
if (channel->preview_valid &&
channel->preview->width == width &&
channel->preview->height == height)
return channel->preview;
if (GIMP_DRAWABLE(channel)->preview_valid &&
GIMP_DRAWABLE(channel)->preview->width == width &&
GIMP_DRAWABLE(channel)->preview->height == height)
return GIMP_DRAWABLE(channel)->preview;
/* The hard way */
else
{
@ -373,11 +380,11 @@ channel_preview (Channel *channel, int width, int height)
subsample = 1;
if (width < 1) width = 1;
if (height < 1) height = 1;
while ((width * (subsample + 1) * 2 < channel->width) &&
(height * (subsample + 1) * 2 < channel->height))
while ((width * (subsample + 1) * 2 < GIMP_DRAWABLE(channel)->width) &&
(height * (subsample + 1) * 2 < GIMP_DRAWABLE(channel)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
preview_buf = mask_buf_new (width, height);
destPR.bytes = 1;
@ -390,13 +397,13 @@ channel_preview (Channel *channel, int width, int height)
subsample_region (&srcPR, &destPR, subsample);
if (channel->preview_valid)
mask_buf_free (channel->preview);
if (GIMP_DRAWABLE(channel)->preview_valid)
mask_buf_free (GIMP_DRAWABLE(channel)->preview);
channel->preview = preview_buf;
channel->preview_valid = 1;
GIMP_DRAWABLE(channel)->preview = preview_buf;
GIMP_DRAWABLE(channel)->preview_valid = 1;
return channel->preview;
return GIMP_DRAWABLE(channel)->preview;
}
}
@ -404,14 +411,19 @@ channel_preview (Channel *channel, int width, int height)
void
channel_invalidate_previews (int gimage_id)
{
link_ptr tmp = channel_list;
link_ptr tmp;
Channel * channel;
GImage * gimage;
if (! (gimage = gimage_get_ID (gimage_id)))
return;
tmp = gimage->channels;
while (tmp)
{
channel = (Channel *) tmp->data;
if (gimage_id == -1 || (channel->gimage_ID == gimage_id))
drawable_invalidate_preview (channel->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(channel));
tmp = next_item (tmp);
}
}
@ -431,7 +443,7 @@ channel_new_mask (int gimage_ID, int width, int height)
new_channel = channel_new (gimage_ID, width, height, "Selection Mask", 127, black);
/* Set the validate procedure */
tile_manager_set_validate_proc (new_channel->tiles, channel_validate);
tile_manager_set_validate_proc (GIMP_DRAWABLE(new_channel)->tiles, channel_validate);
return new_channel;
}
@ -455,7 +467,7 @@ channel_boundary (Channel *mask, BoundSeg **segs_in, BoundSeg **segs_out,
if (channel_bounds (mask, &x3, &y3, &x4, &y4))
{
pixel_region_init (&bPR, mask->tiles, x3, y3, (x4 - x3), (y4 - y3), FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x3, y3, (x4 - x3), (y4 - y3), FALSE);
mask->segs_out = find_mask_boundary (&bPR, &mask->num_segs_out,
IgnoreBounds,
x1, y1,
@ -467,7 +479,7 @@ channel_boundary (Channel *mask, BoundSeg **segs_in, BoundSeg **segs_out,
if (x2 > x1 && y2 > y1)
{
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
mask->segs_in = find_mask_boundary (&bPR, &mask->num_segs_in,
WithinBounds,
x1, y1,
@ -514,11 +526,11 @@ channel_value (Channel *mask, int x, int y)
}
else
{
if (x < 0 || x >= mask->width || y < 0 || y >= mask->height)
if (x < 0 || x >= GIMP_DRAWABLE(mask)->width || y < 0 || y >= GIMP_DRAWABLE(mask)->height)
return 0;
}
tile = tile_manager_get_tile (mask->tiles, x, y, 0);
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0);
tile_ref (tile);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
@ -549,12 +561,12 @@ channel_bounds (Channel *mask, int *x1, int *y1, int *x2, int *y2)
}
/* go through and calculate the bounds */
*x1 = mask->width;
*y1 = mask->height;
*x1 = GIMP_DRAWABLE(mask)->width;
*y1 = GIMP_DRAWABLE(mask)->height;
*x2 = 0;
*y2 = 0;
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -583,15 +595,15 @@ channel_bounds (Channel *mask, int *x1, int *y1, int *x2, int *y2)
}
}
*x2 = BOUNDS (*x2 + 1, 0, mask->width);
*y2 = BOUNDS (*y2 + 1, 0, mask->height);
*x2 = BOUNDS (*x2 + 1, 0, GIMP_DRAWABLE(mask)->width);
*y2 = BOUNDS (*y2 + 1, 0, GIMP_DRAWABLE(mask)->height);
if (*x1 == mask->width && *y1 == mask->height)
if (*x1 == GIMP_DRAWABLE(mask)->width && *y1 == GIMP_DRAWABLE(mask)->height)
{
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
else
{
@ -618,7 +630,7 @@ channel_is_empty (Channel *mask)
if (mask->bounds_known)
return mask->empty;
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* check if any pixel in the mask is non-zero */
@ -646,8 +658,8 @@ channel_is_empty (Channel *mask)
mask->bounds_known = TRUE;
mask->boundary_known = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
return TRUE;
}
@ -665,16 +677,16 @@ channel_add_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -702,16 +714,16 @@ channel_sub_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -739,16 +751,16 @@ channel_inter_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -768,7 +780,7 @@ channel_combine_rect (Channel *mask, int op, int x, int y, int w, int h)
for (i = y; i < y + h; i++)
{
if (i >= 0 && i < mask->height)
if (i >= 0 && i < GIMP_DRAWABLE(mask)->height)
switch (op)
{
case ADD: case REPLACE:
@ -806,10 +818,10 @@ channel_combine_rect (Channel *mask, int op, int x, int y, int w, int h)
else
mask->bounds_known = FALSE;
mask->x1 = BOUNDS (mask->x1, 0, mask->width);
mask->y1 = BOUNDS (mask->y1, 0, mask->height);
mask->x2 = BOUNDS (mask->x2, 0, mask->width);
mask->y2 = BOUNDS (mask->y2, 0, mask->height);
mask->x1 = BOUNDS (mask->x1, 0, GIMP_DRAWABLE(mask)->width);
mask->y1 = BOUNDS (mask->y1, 0, GIMP_DRAWABLE(mask)->height);
mask->x2 = BOUNDS (mask->x2, 0, GIMP_DRAWABLE(mask)->width);
mask->y2 = BOUNDS (mask->y2, 0, GIMP_DRAWABLE(mask)->height);
}
@ -842,7 +854,7 @@ channel_combine_ellipse (Channel *mask, int op, int x, int y, int w, int h,
for (i = y; i < (y + h); i++)
{
if (i >= 0 && i < mask->height)
if (i >= 0 && i < GIMP_DRAWABLE(mask)->height)
{
/* Non-antialiased code */
if (!aa)
@ -952,10 +964,10 @@ channel_combine_ellipse (Channel *mask, int op, int x, int y, int w, int h,
else
mask->bounds_known = FALSE;
mask->x1 = BOUNDS (mask->x1, 0, mask->width);
mask->y1 = BOUNDS (mask->y1, 0, mask->height);
mask->x2 = BOUNDS (mask->x2, 0, mask->width);
mask->y2 = BOUNDS (mask->y2, 0, mask->height);
mask->x1 = BOUNDS (mask->x1, 0, GIMP_DRAWABLE(mask)->width);
mask->y1 = BOUNDS (mask->y1, 0, GIMP_DRAWABLE(mask)->height);
mask->x2 = BOUNDS (mask->x2, 0, GIMP_DRAWABLE(mask)->width);
mask->y2 = BOUNDS (mask->y2, 0, GIMP_DRAWABLE(mask)->height);
}
@ -972,16 +984,16 @@ channel_combine_mask (Channel *mask, Channel *add_on, int op,
int w, h;
void * pr;
x1 = BOUNDS (off_x, 0, mask->width);
y1 = BOUNDS (off_y, 0, mask->height);
x2 = BOUNDS (off_x + add_on->width, 0, mask->width);
y2 = BOUNDS (off_y + add_on->height, 0, mask->height);
x1 = BOUNDS (off_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS (off_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS (off_x + GIMP_DRAWABLE(add_on)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS (off_y + GIMP_DRAWABLE(add_on)->height, 0, GIMP_DRAWABLE(mask)->height);
w = (x2 - x1);
h = (y2 - y1);
pixel_region_init (&srcPR, add_on->tiles, (x1 - off_x), (y1 - off_y), w, h, FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, w, h, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(add_on)->tiles, (x1 - off_x), (y1 - off_y), w, h, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, w, h, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -1027,12 +1039,12 @@ channel_feather (Channel *input, Channel *output, double radius,
int x1, y1, x2, y2;
PixelRegion srcPR;
x1 = BOUNDS (off_x, 0, output->width);
y1 = BOUNDS (off_y, 0, output->height);
x2 = BOUNDS (off_x + input->width, 0, output->width);
y2 = BOUNDS (off_y + input->height, 0, output->height);
x1 = BOUNDS (off_x, 0, GIMP_DRAWABLE(output)->width);
y1 = BOUNDS (off_y, 0, GIMP_DRAWABLE(output)->height);
x2 = BOUNDS (off_x + GIMP_DRAWABLE(input)->width, 0, GIMP_DRAWABLE(output)->width);
y2 = BOUNDS (off_y + GIMP_DRAWABLE(input)->height, 0, GIMP_DRAWABLE(output)->height);
pixel_region_init (&srcPR, input->tiles, (x1 - off_x), (y1 - off_y), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(input)->tiles, (x1 - off_x), (y1 - off_y), (x2 - x1), (y2 - y1), FALSE);
gaussian_blur_region (&srcPR, radius);
if (input != output)
@ -1055,7 +1067,7 @@ channel_push_undo (Channel *mask)
if (channel_bounds (mask, &x1, &y1, &x2, &y2))
{
undo_tiles = tile_manager_new ((x2 - x1), (y2 - y1), 1);
pixel_region_init (&srcPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, undo_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
}
@ -1067,12 +1079,12 @@ channel_push_undo (Channel *mask)
mask_undo->y = y1;
/* push the undo buffer onto the undo stack */
gimage = gimage_get_ID (mask->gimage_ID);
gimage = gimage_get_ID (GIMP_DRAWABLE(mask)->gimage_ID);
undo_push_mask (gimage, mask_undo);
gimage_mask_invalidate (gimage);
/* invalidate the preview */
mask->preview_valid = 0;
GIMP_DRAWABLE(mask)->preview_valid = 0;
}
@ -1087,14 +1099,14 @@ channel_clear (Channel *mask)
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&maskPR, mask->tiles, mask->x1, mask->y1,
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&maskPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&maskPR, &bg);
}
@ -1102,8 +1114,8 @@ channel_clear (Channel *mask)
mask->bounds_known = TRUE;
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
@ -1118,7 +1130,7 @@ channel_invert (Channel *mask)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* subtract each pixel in the mask from 255 */
@ -1146,7 +1158,7 @@ channel_sharpen (Channel *mask)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* if a pixel in the mask has a non-zero value, make it 255 */
@ -1175,15 +1187,15 @@ channel_all (Channel *mask)
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&maskPR, &bg);
/* we know the bounds */
mask->bounds_known = TRUE;
mask->empty = FALSE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
@ -1202,25 +1214,25 @@ channel_border (Channel *mask, int radius)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
bs = find_mask_boundary (&bPR, &num_segs, WithinBounds, x1, y1, x2, y2);
/* clear the channel */
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&bPR, mask->tiles, mask->x1, mask->y1,
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&bPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&bPR, &bg);
}
/* calculate a border of specified radius based on the boundary segments */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
border_region (&bPR, bs, num_segs, radius);
g_free (bs);
@ -1241,7 +1253,7 @@ channel_grow (Channel *mask, int steps)
channel_push_undo (mask);
/* need full extents for grow */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
while (steps--)
thin_region (&bPR, GROW_REGION);
@ -1262,7 +1274,7 @@ channel_shrink (Channel *mask, int steps)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
while (steps--)
thin_region (&bPR, SHRINK_REGION);
@ -1286,10 +1298,10 @@ channel_translate (Channel *mask, int off_x, int off_y)
channel_push_undo (mask);
channel_bounds (mask, &x1, &y1, &x2, &y2);
x1 = BOUNDS ((x1 + off_x), 0, mask->width);
y1 = BOUNDS ((y1 + off_y), 0, mask->height);
x2 = BOUNDS ((x2 + off_x), 0, mask->width);
y2 = BOUNDS ((y2 + off_y), 0, mask->height);
x1 = BOUNDS ((x1 + off_x), 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS ((y1 + off_y), 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS ((x2 + off_x), 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS ((y2 + off_y), 0, GIMP_DRAWABLE(mask)->height);
width = x2 - x1;
height = y2 - y1;
@ -1300,22 +1312,22 @@ channel_translate (Channel *mask, int off_x, int off_y)
/* copy the portion of the mask we will keep to a
* temporary buffer
*/
tmp_mask = channel_new_mask (mask->gimage_ID, width, height);
tmp_mask = channel_new_mask (GIMP_DRAWABLE(mask)->gimage_ID, width, height);
pixel_region_init (&srcPR, mask->tiles, x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, tmp_mask->tiles, 0, 0, width, height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(tmp_mask)->tiles, 0, 0, width, height, TRUE);
copy_region (&srcPR, &destPR);
}
/* clear the mask */
pixel_region_init (&srcPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&srcPR, &empty);
if (width != 0 && height != 0)
{
/* copy the temp mask back to the mask */
pixel_region_init (&srcPR, tmp_mask->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, width, height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(tmp_mask)->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, width, height, TRUE);
copy_region (&srcPR, &destPR);
/* free the temporary mask */
@ -1327,8 +1339,8 @@ channel_translate (Channel *mask, int off_x, int off_y)
{
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
else
{
@ -1341,10 +1353,9 @@ channel_translate (Channel *mask, int off_x, int off_y)
void
channel_layer_alpha (Channel *mask, int layer_id)
channel_layer_alpha (Channel *mask, Layer *layer)
{
PixelRegion srcPR, destPR;
Layer *layer;
unsigned char empty = 0;
int x1, y1, x2, y2;
@ -1352,54 +1363,24 @@ channel_layer_alpha (Channel *mask, int layer_id)
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, mask->tiles, 0, 0, mask->width, 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);
layer = layer_get_ID (layer_id);
x1 = BOUNDS (layer->offset_x, 0, mask->width);
y1 = BOUNDS (layer->offset_y, 0, mask->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, mask->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, mask->height);
x1 = BOUNDS (GIMP_DRAWABLE(layer)->offset_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS (GIMP_DRAWABLE(layer)->offset_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, 0, GIMP_DRAWABLE(mask)->height);
pixel_region_init (&srcPR, layer->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
extract_alpha_region (&srcPR, NULL, &destPR);
mask->bounds_known = FALSE;
}
void
channel_layer_mask (Channel *mask, int layer_id)
{
PixelRegion srcPR, destPR;
Layer *layer;
unsigned char empty = 0;
int x1, y1, x2, y2;
/* push the current mask onto the undo stack */
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
color_region (&destPR, &empty);
layer = layer_get_ID (layer_id);
x1 = BOUNDS (layer->offset_x, 0, mask->width);
y1 = BOUNDS (layer->offset_y, 0, mask->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, mask->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, mask->height);
pixel_region_init (&srcPR, layer->mask->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;
}
void
@ -1411,9 +1392,15 @@ channel_load (Channel *mask, Channel *channel)
channel_push_undo (mask);
/* copy the channel to the mask */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&destPR, mask->tiles, 0, 0, channel->width, channel->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;
}
void
channel_invalidate_bounds (Channel *channel)
{
channel->bounds_known = FALSE;
}

View file

@ -18,6 +18,8 @@
#ifndef __CHANNEL_H__
#define __CHANNEL_H__
#include "drawable.h"
#include "boundary.h"
#include "temp_buf.h"
#include "tile_manager.h"
@ -34,45 +36,16 @@
/* structure declarations */
typedef struct _Channel Channel;
#define GIMP_CHANNEL(obj) GTK_CHECK_CAST (obj, gimp_channel_get_type (), GimpChannel)
#define GIMP_CHANNEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_channel_get_type(), GimpChannelClass)
#define GIMP_IS_CHANNEL(obj) GTK_CHECK_TYPE (obj, gimp_channel_get_type())
struct _Channel
{
char * name; /* name of the channel */
typedef struct _GimpChannel GimpChannel;
typedef struct _GimpChannelClass GimpChannelClass;
TileManager *tiles; /* tiles for channel data */
int visible; /* controls visibility */
int width, height; /* size of channel */
int bytes; /* bytes per pixel */
unsigned char col[3]; /* RGB triplet for channel color*/
int opacity; /* Channel opacity */
int show_masked; /* Show masked areas--as */
/* opposed to selected areas */
int dirty; /* dirty bit */
int ID; /* provides a unique ID */
int layer_ID; /* ID of layer-if a layer mask */
int gimage_ID; /* ID of gimage owner */
/* Selection mask variables */
int boundary_known; /* is the current boundary valid*/
BoundSeg *segs_in; /* outline of selected region */
BoundSeg *segs_out; /* outline of selected region */
int num_segs_in; /* number of lines in boundary */
int num_segs_out; /* number of lines in boundary */
int empty; /* is the region empty? */
int bounds_known; /* recalculate the bounds? */
int x1, y1; /* coordinates for bounding box */
int x2, y2; /* lower right hand coordinate */
/* Preview variables */
TempBuf *preview; /* preview of the channel */
int preview_valid; /* is the preview valid? */
};
typedef GimpChannel Channel; /* convenience */
guint gimp_channel_get_type (void);
/* Special undo type */
typedef struct _channel_undo ChannelUndo;
@ -81,7 +54,7 @@ struct _channel_undo
{
Channel * channel; /* the actual channel */
int prev_position; /* former position in list */
int prev_channel; /* previous active channel */
Channel * prev_channel; /* previous active channel */
int undo_type; /* is this a new channel undo */
/* or a remove channel undo? */
};
@ -98,13 +71,10 @@ struct _mask_undo
/* function declarations */
void channel_allocate (Channel *, int, int);
void channel_deallocate (Channel *);
Channel * channel_new (int, int, int, char *, int, unsigned char *);
Channel * channel_copy (Channel *);
Channel * channel_get_ID (int);
void channel_delete (Channel *);
void channel_apply_image (Channel *, int, int, int, int, TileManager *, int);
void channel_scale (Channel *, int, int);
void channel_resize (Channel *, int, int, int, int);
@ -140,8 +110,12 @@ void channel_border (Channel *, int);
void channel_grow (Channel *, int);
void channel_shrink (Channel *, int);
void channel_translate (Channel *, int, int);
void channel_layer_alpha (Channel *, int);
void channel_layer_mask (Channel *, int);
void channel_load (Channel *, Channel *);
void channel_invalidate_bounds (Channel *);
extern int channel_get_count;
/* from drawable.c */
Channel * drawable_channel (GimpDrawable *);
#endif /* __CHANNEL_H__ */

View file

@ -31,6 +31,61 @@
#include "temp_buf.h"
#include "undo.h"
#include "channel_pvt.h"
enum {
LAST_SIGNAL
};
static void gimp_channel_class_init (GimpChannelClass *klass);
static void gimp_channel_init (GimpChannel *channel);
static void gimp_channel_destroy (GtkObject *object);
static gint channel_signals[LAST_SIGNAL] = { 0 };
static GimpDrawableClass *parent_class = NULL;
guint
gimp_channel_get_type ()
{
static guint channel_type = 0;
if (!channel_type)
{
GtkTypeInfo channel_info =
{
"GimpChannel",
sizeof (GimpChannel),
sizeof (GimpChannelClass),
(GtkClassInitFunc) gimp_channel_class_init,
(GtkObjectInitFunc) gimp_channel_init,
(GtkArgFunc) NULL,
};
channel_type = gtk_type_unique (gimp_drawable_get_type (), &channel_info);
}
return channel_type;
}
static void
gimp_channel_class_init (GimpChannelClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gimp_drawable_get_type ());
gtk_object_class_add_signals (object_class, channel_signals, LAST_SIGNAL);
object_class->destroy = gimp_channel_destroy;
}
static void
gimp_channel_init (GimpChannel *channel)
{
}
#define ROUND(x) ((int) (x + 0.5))
@ -38,8 +93,8 @@
* Static variables
*/
extern int global_drawable_ID;
static link_ptr channel_list = NULL;
int channel_get_count = 0;
/**************************/
@ -53,19 +108,6 @@ channel_validate (TileManager *tm, Tile *tile, int level)
}
void
channel_allocate (Channel *channel, int width, int height)
{
channel->tiles = tile_manager_new (width, height, 1);
}
void
channel_deallocate (Channel *channel)
{
if (channel->tiles)
tile_manager_destroy (channel->tiles);
}
Channel *
@ -75,37 +117,16 @@ channel_new (int gimage_ID, int width, int height, char *name, int opacity,
Channel * channel;
int i;
channel = (Channel *) g_malloc (sizeof (Channel));
channel = gtk_type_new (gimp_channel_get_type ());
if (!name)
name = "unnamed";
channel->name = (char *) g_malloc (strlen (name) + 1);
strcpy (channel->name, name);
/* set size information */
channel->width = width;
channel->height = height;
channel->bytes = 1;
/* allocate the memory for this channel */
channel_allocate (channel, width, height);
channel->visible = 1;
gimp_drawable_configure (GIMP_DRAWABLE(channel),
gimage_ID, width, height, GRAY_GIMAGE, name);
/* set the channel color and opacity */
for (i = 0; i < 3; i++)
channel->col[i] = col[i];
channel->opacity = opacity;
channel->show_masked = 1;
channel->dirty = 0;
/* give this channel an ID */
channel->ID = global_drawable_ID++;
channel->layer_ID = -1;
channel->gimage_ID = gimage_ID;
/* add the new channel to the global list */
channel_list = append_to_list (channel_list, (void *) channel);
/* selection mask variables */
channel->empty = TRUE;
@ -119,10 +140,6 @@ channel_new (int gimage_ID, int width, int height, char *name, int opacity,
channel->x2 = width;
channel->y2 = height;
/* preview variables */
channel->preview = NULL;
channel->preview_valid = FALSE;
return channel;
}
@ -135,18 +152,22 @@ channel_copy (Channel *channel)
PixelRegion srcPR, destPR;
/* formulate the new channel name */
channel_name = (char *) g_malloc (strlen (channel->name) + 6);
sprintf (channel_name, "%s copy", channel->name);
channel_name = (char *) g_malloc (strlen (GIMP_DRAWABLE(channel)->name) + 6);
sprintf (channel_name, "%s copy", GIMP_DRAWABLE(channel)->name);
/* allocate a new channel object */
new_channel = channel_new (channel->gimage_ID, channel->width, channel->height, channel_name,
channel->opacity, channel->col);
new_channel->visible = channel->visible;
new_channel = channel_new (GIMP_DRAWABLE(channel)->gimage_ID,
GIMP_DRAWABLE(channel)->width,
GIMP_DRAWABLE(channel)->height,
channel_name, channel->opacity, channel->col);
GIMP_DRAWABLE(new_channel)->visible = GIMP_DRAWABLE(channel)->visible;
new_channel->show_masked = channel->show_masked;
/* copy the contents across channels */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&destPR, new_channel->tiles, 0, 0, channel->width, channel->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0,
GIMP_DRAWABLE(channel)->width,
GIMP_DRAWABLE(channel)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, TRUE);
copy_region (&srcPR, &destPR);
/* free up the channel_name memory */
@ -159,56 +180,42 @@ channel_copy (Channel *channel)
Channel *
channel_get_ID (int ID)
{
link_ptr tmp = channel_list;
Channel * channel;
while (tmp)
{
channel = (Channel *) tmp->data;
if (channel->ID == ID)
return channel;
tmp = next_item (tmp);
}
return NULL;
GimpDrawable *drawable;
drawable = drawable_get_ID (ID);
if (drawable && GIMP_IS_CHANNEL (drawable))
return GIMP_CHANNEL (drawable);
else
return NULL;
}
void
channel_delete (Channel *channel)
{
gtk_object_destroy (GTK_OBJECT (channel));
}
static void
gimp_channel_destroy (GtkObject *object)
{
GimpChannel *channel;
g_return_if_fail (object != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (object));
channel = GIMP_CHANNEL (object);
/* free the segments? */
if (channel->segs_in)
g_free (channel->segs_in);
if (channel->segs_out)
g_free (channel->segs_out);
/* remove this image from the global list */
channel_list = remove_from_list (channel_list, (void *) channel);
/* deallocate the channel mem */
channel_deallocate (channel);
/* free the channel name buffer */
g_free (channel->name);
g_free (channel);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
void
channel_apply_image (Channel *channel, int x1, int y1, int x2, int y2,
TileManager *tiles, int sparse)
{
/* Need to push an undo operation */
if (! tiles)
undo_push_image (gimage_get_ID (channel->gimage_ID), channel->ID, x1, y1, x2, y2);
else
undo_push_image_mod (gimage_get_ID (channel->gimage_ID), channel->ID, x1, y1, x2, y2, tiles, sparse);
}
void
channel_scale (Channel *channel, int new_width, int new_height)
{
@ -219,10 +226,10 @@ channel_scale (Channel *channel, int new_width, int new_height)
return;
/* Update the old channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
/* Allocate the new channel, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, 1);
@ -232,18 +239,18 @@ channel_scale (Channel *channel, int new_width, int new_height)
scale_region (&srcPR, &destPR);
/* Push the channel on the undo stack */
undo_push_channel_mod (gimage_get_ID (channel->gimage_ID), channel);
undo_push_channel_mod (gimage_get_ID (GIMP_DRAWABLE(channel)->gimage_ID), channel);
/* Configure the new channel */
channel->tiles = new_tiles;
channel->width = new_width;
channel->height = new_height;
GIMP_DRAWABLE(channel)->tiles = new_tiles;
GIMP_DRAWABLE(channel)->width = new_width;
GIMP_DRAWABLE(channel)->height = new_height;
/* bounds are now unknown */
channel->bounds_known = FALSE;
/* Update the new channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
}
@ -263,8 +270,8 @@ channel_resize (Channel *channel, int new_width, int new_height,
x1 = BOUNDS (offx, 0, new_width);
y1 = BOUNDS (offy, 0, new_height);
x2 = BOUNDS ((offx + channel->width), 0, new_width);
y2 = BOUNDS ((offy + channel->height), 0, new_height);
x2 = BOUNDS ((offx + GIMP_DRAWABLE(channel)->width), 0, new_width);
y2 = BOUNDS ((offy + GIMP_DRAWABLE(channel)->height), 0, new_height);
w = x2 - x1;
h = y2 - y1;
@ -291,14 +298,14 @@ channel_resize (Channel *channel, int new_width, int new_height,
}
/* Update the old channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, channel->tiles, x1, y1, w, h, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, x1, y1, w, h, FALSE);
/* Determine whether the new channel needs to be initially cleared */
if ((new_width > channel->width) ||
(new_height > channel->height) ||
if ((new_width > GIMP_DRAWABLE(channel)->width) ||
(new_height > GIMP_DRAWABLE(channel)->height) ||
(x2 || y2))
clear = TRUE;
else
@ -320,18 +327,18 @@ channel_resize (Channel *channel, int new_width, int new_height,
copy_region (&srcPR, &destPR);
/* Push the channel on the undo stack */
undo_push_channel_mod (gimage_get_ID (channel->gimage_ID), channel);
undo_push_channel_mod (gimage_get_ID (GIMP_DRAWABLE(channel)->gimage_ID), channel);
/* Configure the new channel */
channel->tiles = new_tiles;
channel->width = new_width;
channel->height = new_height;
GIMP_DRAWABLE(channel)->tiles = new_tiles;
GIMP_DRAWABLE(channel)->width = new_width;
GIMP_DRAWABLE(channel)->height = new_height;
/* bounds are now unknown */
channel->bounds_known = FALSE;
/* update the new channel area */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
}
@ -348,9 +355,9 @@ channel_data (Channel *channel)
int
channel_toggle_visibility (Channel *channel)
{
channel->visible = !channel->visible;
GIMP_DRAWABLE(channel)->visible = !GIMP_DRAWABLE(channel)->visible;
return channel->visible;
return GIMP_DRAWABLE(channel)->visible;
}
@ -362,10 +369,10 @@ channel_preview (Channel *channel, int width, int height)
int subsample;
/* The easy way */
if (channel->preview_valid &&
channel->preview->width == width &&
channel->preview->height == height)
return channel->preview;
if (GIMP_DRAWABLE(channel)->preview_valid &&
GIMP_DRAWABLE(channel)->preview->width == width &&
GIMP_DRAWABLE(channel)->preview->height == height)
return GIMP_DRAWABLE(channel)->preview;
/* The hard way */
else
{
@ -373,11 +380,11 @@ channel_preview (Channel *channel, int width, int height)
subsample = 1;
if (width < 1) width = 1;
if (height < 1) height = 1;
while ((width * (subsample + 1) * 2 < channel->width) &&
(height * (subsample + 1) * 2 < channel->height))
while ((width * (subsample + 1) * 2 < GIMP_DRAWABLE(channel)->width) &&
(height * (subsample + 1) * 2 < GIMP_DRAWABLE(channel)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
preview_buf = mask_buf_new (width, height);
destPR.bytes = 1;
@ -390,13 +397,13 @@ channel_preview (Channel *channel, int width, int height)
subsample_region (&srcPR, &destPR, subsample);
if (channel->preview_valid)
mask_buf_free (channel->preview);
if (GIMP_DRAWABLE(channel)->preview_valid)
mask_buf_free (GIMP_DRAWABLE(channel)->preview);
channel->preview = preview_buf;
channel->preview_valid = 1;
GIMP_DRAWABLE(channel)->preview = preview_buf;
GIMP_DRAWABLE(channel)->preview_valid = 1;
return channel->preview;
return GIMP_DRAWABLE(channel)->preview;
}
}
@ -404,14 +411,19 @@ channel_preview (Channel *channel, int width, int height)
void
channel_invalidate_previews (int gimage_id)
{
link_ptr tmp = channel_list;
link_ptr tmp;
Channel * channel;
GImage * gimage;
if (! (gimage = gimage_get_ID (gimage_id)))
return;
tmp = gimage->channels;
while (tmp)
{
channel = (Channel *) tmp->data;
if (gimage_id == -1 || (channel->gimage_ID == gimage_id))
drawable_invalidate_preview (channel->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(channel));
tmp = next_item (tmp);
}
}
@ -431,7 +443,7 @@ channel_new_mask (int gimage_ID, int width, int height)
new_channel = channel_new (gimage_ID, width, height, "Selection Mask", 127, black);
/* Set the validate procedure */
tile_manager_set_validate_proc (new_channel->tiles, channel_validate);
tile_manager_set_validate_proc (GIMP_DRAWABLE(new_channel)->tiles, channel_validate);
return new_channel;
}
@ -455,7 +467,7 @@ channel_boundary (Channel *mask, BoundSeg **segs_in, BoundSeg **segs_out,
if (channel_bounds (mask, &x3, &y3, &x4, &y4))
{
pixel_region_init (&bPR, mask->tiles, x3, y3, (x4 - x3), (y4 - y3), FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x3, y3, (x4 - x3), (y4 - y3), FALSE);
mask->segs_out = find_mask_boundary (&bPR, &mask->num_segs_out,
IgnoreBounds,
x1, y1,
@ -467,7 +479,7 @@ channel_boundary (Channel *mask, BoundSeg **segs_in, BoundSeg **segs_out,
if (x2 > x1 && y2 > y1)
{
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
mask->segs_in = find_mask_boundary (&bPR, &mask->num_segs_in,
WithinBounds,
x1, y1,
@ -514,11 +526,11 @@ channel_value (Channel *mask, int x, int y)
}
else
{
if (x < 0 || x >= mask->width || y < 0 || y >= mask->height)
if (x < 0 || x >= GIMP_DRAWABLE(mask)->width || y < 0 || y >= GIMP_DRAWABLE(mask)->height)
return 0;
}
tile = tile_manager_get_tile (mask->tiles, x, y, 0);
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0);
tile_ref (tile);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
@ -549,12 +561,12 @@ channel_bounds (Channel *mask, int *x1, int *y1, int *x2, int *y2)
}
/* go through and calculate the bounds */
*x1 = mask->width;
*y1 = mask->height;
*x1 = GIMP_DRAWABLE(mask)->width;
*y1 = GIMP_DRAWABLE(mask)->height;
*x2 = 0;
*y2 = 0;
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -583,15 +595,15 @@ channel_bounds (Channel *mask, int *x1, int *y1, int *x2, int *y2)
}
}
*x2 = BOUNDS (*x2 + 1, 0, mask->width);
*y2 = BOUNDS (*y2 + 1, 0, mask->height);
*x2 = BOUNDS (*x2 + 1, 0, GIMP_DRAWABLE(mask)->width);
*y2 = BOUNDS (*y2 + 1, 0, GIMP_DRAWABLE(mask)->height);
if (*x1 == mask->width && *y1 == mask->height)
if (*x1 == GIMP_DRAWABLE(mask)->width && *y1 == GIMP_DRAWABLE(mask)->height)
{
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
else
{
@ -618,7 +630,7 @@ channel_is_empty (Channel *mask)
if (mask->bounds_known)
return mask->empty;
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* check if any pixel in the mask is non-zero */
@ -646,8 +658,8 @@ channel_is_empty (Channel *mask)
mask->bounds_known = TRUE;
mask->boundary_known = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
return TRUE;
}
@ -665,16 +677,16 @@ channel_add_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -702,16 +714,16 @@ channel_sub_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -739,16 +751,16 @@ channel_inter_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -768,7 +780,7 @@ channel_combine_rect (Channel *mask, int op, int x, int y, int w, int h)
for (i = y; i < y + h; i++)
{
if (i >= 0 && i < mask->height)
if (i >= 0 && i < GIMP_DRAWABLE(mask)->height)
switch (op)
{
case ADD: case REPLACE:
@ -806,10 +818,10 @@ channel_combine_rect (Channel *mask, int op, int x, int y, int w, int h)
else
mask->bounds_known = FALSE;
mask->x1 = BOUNDS (mask->x1, 0, mask->width);
mask->y1 = BOUNDS (mask->y1, 0, mask->height);
mask->x2 = BOUNDS (mask->x2, 0, mask->width);
mask->y2 = BOUNDS (mask->y2, 0, mask->height);
mask->x1 = BOUNDS (mask->x1, 0, GIMP_DRAWABLE(mask)->width);
mask->y1 = BOUNDS (mask->y1, 0, GIMP_DRAWABLE(mask)->height);
mask->x2 = BOUNDS (mask->x2, 0, GIMP_DRAWABLE(mask)->width);
mask->y2 = BOUNDS (mask->y2, 0, GIMP_DRAWABLE(mask)->height);
}
@ -842,7 +854,7 @@ channel_combine_ellipse (Channel *mask, int op, int x, int y, int w, int h,
for (i = y; i < (y + h); i++)
{
if (i >= 0 && i < mask->height)
if (i >= 0 && i < GIMP_DRAWABLE(mask)->height)
{
/* Non-antialiased code */
if (!aa)
@ -952,10 +964,10 @@ channel_combine_ellipse (Channel *mask, int op, int x, int y, int w, int h,
else
mask->bounds_known = FALSE;
mask->x1 = BOUNDS (mask->x1, 0, mask->width);
mask->y1 = BOUNDS (mask->y1, 0, mask->height);
mask->x2 = BOUNDS (mask->x2, 0, mask->width);
mask->y2 = BOUNDS (mask->y2, 0, mask->height);
mask->x1 = BOUNDS (mask->x1, 0, GIMP_DRAWABLE(mask)->width);
mask->y1 = BOUNDS (mask->y1, 0, GIMP_DRAWABLE(mask)->height);
mask->x2 = BOUNDS (mask->x2, 0, GIMP_DRAWABLE(mask)->width);
mask->y2 = BOUNDS (mask->y2, 0, GIMP_DRAWABLE(mask)->height);
}
@ -972,16 +984,16 @@ channel_combine_mask (Channel *mask, Channel *add_on, int op,
int w, h;
void * pr;
x1 = BOUNDS (off_x, 0, mask->width);
y1 = BOUNDS (off_y, 0, mask->height);
x2 = BOUNDS (off_x + add_on->width, 0, mask->width);
y2 = BOUNDS (off_y + add_on->height, 0, mask->height);
x1 = BOUNDS (off_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS (off_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS (off_x + GIMP_DRAWABLE(add_on)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS (off_y + GIMP_DRAWABLE(add_on)->height, 0, GIMP_DRAWABLE(mask)->height);
w = (x2 - x1);
h = (y2 - y1);
pixel_region_init (&srcPR, add_on->tiles, (x1 - off_x), (y1 - off_y), w, h, FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, w, h, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(add_on)->tiles, (x1 - off_x), (y1 - off_y), w, h, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, w, h, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -1027,12 +1039,12 @@ channel_feather (Channel *input, Channel *output, double radius,
int x1, y1, x2, y2;
PixelRegion srcPR;
x1 = BOUNDS (off_x, 0, output->width);
y1 = BOUNDS (off_y, 0, output->height);
x2 = BOUNDS (off_x + input->width, 0, output->width);
y2 = BOUNDS (off_y + input->height, 0, output->height);
x1 = BOUNDS (off_x, 0, GIMP_DRAWABLE(output)->width);
y1 = BOUNDS (off_y, 0, GIMP_DRAWABLE(output)->height);
x2 = BOUNDS (off_x + GIMP_DRAWABLE(input)->width, 0, GIMP_DRAWABLE(output)->width);
y2 = BOUNDS (off_y + GIMP_DRAWABLE(input)->height, 0, GIMP_DRAWABLE(output)->height);
pixel_region_init (&srcPR, input->tiles, (x1 - off_x), (y1 - off_y), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(input)->tiles, (x1 - off_x), (y1 - off_y), (x2 - x1), (y2 - y1), FALSE);
gaussian_blur_region (&srcPR, radius);
if (input != output)
@ -1055,7 +1067,7 @@ channel_push_undo (Channel *mask)
if (channel_bounds (mask, &x1, &y1, &x2, &y2))
{
undo_tiles = tile_manager_new ((x2 - x1), (y2 - y1), 1);
pixel_region_init (&srcPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, undo_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
}
@ -1067,12 +1079,12 @@ channel_push_undo (Channel *mask)
mask_undo->y = y1;
/* push the undo buffer onto the undo stack */
gimage = gimage_get_ID (mask->gimage_ID);
gimage = gimage_get_ID (GIMP_DRAWABLE(mask)->gimage_ID);
undo_push_mask (gimage, mask_undo);
gimage_mask_invalidate (gimage);
/* invalidate the preview */
mask->preview_valid = 0;
GIMP_DRAWABLE(mask)->preview_valid = 0;
}
@ -1087,14 +1099,14 @@ channel_clear (Channel *mask)
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&maskPR, mask->tiles, mask->x1, mask->y1,
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&maskPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&maskPR, &bg);
}
@ -1102,8 +1114,8 @@ channel_clear (Channel *mask)
mask->bounds_known = TRUE;
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
@ -1118,7 +1130,7 @@ channel_invert (Channel *mask)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* subtract each pixel in the mask from 255 */
@ -1146,7 +1158,7 @@ channel_sharpen (Channel *mask)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* if a pixel in the mask has a non-zero value, make it 255 */
@ -1175,15 +1187,15 @@ channel_all (Channel *mask)
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&maskPR, &bg);
/* we know the bounds */
mask->bounds_known = TRUE;
mask->empty = FALSE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
@ -1202,25 +1214,25 @@ channel_border (Channel *mask, int radius)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
bs = find_mask_boundary (&bPR, &num_segs, WithinBounds, x1, y1, x2, y2);
/* clear the channel */
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&bPR, mask->tiles, mask->x1, mask->y1,
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&bPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&bPR, &bg);
}
/* calculate a border of specified radius based on the boundary segments */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
border_region (&bPR, bs, num_segs, radius);
g_free (bs);
@ -1241,7 +1253,7 @@ channel_grow (Channel *mask, int steps)
channel_push_undo (mask);
/* need full extents for grow */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
while (steps--)
thin_region (&bPR, GROW_REGION);
@ -1262,7 +1274,7 @@ channel_shrink (Channel *mask, int steps)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
while (steps--)
thin_region (&bPR, SHRINK_REGION);
@ -1286,10 +1298,10 @@ channel_translate (Channel *mask, int off_x, int off_y)
channel_push_undo (mask);
channel_bounds (mask, &x1, &y1, &x2, &y2);
x1 = BOUNDS ((x1 + off_x), 0, mask->width);
y1 = BOUNDS ((y1 + off_y), 0, mask->height);
x2 = BOUNDS ((x2 + off_x), 0, mask->width);
y2 = BOUNDS ((y2 + off_y), 0, mask->height);
x1 = BOUNDS ((x1 + off_x), 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS ((y1 + off_y), 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS ((x2 + off_x), 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS ((y2 + off_y), 0, GIMP_DRAWABLE(mask)->height);
width = x2 - x1;
height = y2 - y1;
@ -1300,22 +1312,22 @@ channel_translate (Channel *mask, int off_x, int off_y)
/* copy the portion of the mask we will keep to a
* temporary buffer
*/
tmp_mask = channel_new_mask (mask->gimage_ID, width, height);
tmp_mask = channel_new_mask (GIMP_DRAWABLE(mask)->gimage_ID, width, height);
pixel_region_init (&srcPR, mask->tiles, x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, tmp_mask->tiles, 0, 0, width, height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(tmp_mask)->tiles, 0, 0, width, height, TRUE);
copy_region (&srcPR, &destPR);
}
/* clear the mask */
pixel_region_init (&srcPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&srcPR, &empty);
if (width != 0 && height != 0)
{
/* copy the temp mask back to the mask */
pixel_region_init (&srcPR, tmp_mask->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, width, height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(tmp_mask)->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, width, height, TRUE);
copy_region (&srcPR, &destPR);
/* free the temporary mask */
@ -1327,8 +1339,8 @@ channel_translate (Channel *mask, int off_x, int off_y)
{
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
else
{
@ -1341,10 +1353,9 @@ channel_translate (Channel *mask, int off_x, int off_y)
void
channel_layer_alpha (Channel *mask, int layer_id)
channel_layer_alpha (Channel *mask, Layer *layer)
{
PixelRegion srcPR, destPR;
Layer *layer;
unsigned char empty = 0;
int x1, y1, x2, y2;
@ -1352,54 +1363,24 @@ channel_layer_alpha (Channel *mask, int layer_id)
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, mask->tiles, 0, 0, mask->width, 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);
layer = layer_get_ID (layer_id);
x1 = BOUNDS (layer->offset_x, 0, mask->width);
y1 = BOUNDS (layer->offset_y, 0, mask->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, mask->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, mask->height);
x1 = BOUNDS (GIMP_DRAWABLE(layer)->offset_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS (GIMP_DRAWABLE(layer)->offset_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, 0, GIMP_DRAWABLE(mask)->height);
pixel_region_init (&srcPR, layer->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
extract_alpha_region (&srcPR, NULL, &destPR);
mask->bounds_known = FALSE;
}
void
channel_layer_mask (Channel *mask, int layer_id)
{
PixelRegion srcPR, destPR;
Layer *layer;
unsigned char empty = 0;
int x1, y1, x2, y2;
/* push the current mask onto the undo stack */
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
color_region (&destPR, &empty);
layer = layer_get_ID (layer_id);
x1 = BOUNDS (layer->offset_x, 0, mask->width);
y1 = BOUNDS (layer->offset_y, 0, mask->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, mask->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, mask->height);
pixel_region_init (&srcPR, layer->mask->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;
}
void
@ -1411,9 +1392,15 @@ channel_load (Channel *mask, Channel *channel)
channel_push_undo (mask);
/* copy the channel to the mask */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&destPR, mask->tiles, 0, 0, channel->width, channel->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;
}
void
channel_invalidate_bounds (Channel *channel)
{
channel->bounds_known = FALSE;
}

View file

@ -18,6 +18,8 @@
#ifndef __CHANNEL_H__
#define __CHANNEL_H__
#include "drawable.h"
#include "boundary.h"
#include "temp_buf.h"
#include "tile_manager.h"
@ -34,45 +36,16 @@
/* structure declarations */
typedef struct _Channel Channel;
#define GIMP_CHANNEL(obj) GTK_CHECK_CAST (obj, gimp_channel_get_type (), GimpChannel)
#define GIMP_CHANNEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_channel_get_type(), GimpChannelClass)
#define GIMP_IS_CHANNEL(obj) GTK_CHECK_TYPE (obj, gimp_channel_get_type())
struct _Channel
{
char * name; /* name of the channel */
typedef struct _GimpChannel GimpChannel;
typedef struct _GimpChannelClass GimpChannelClass;
TileManager *tiles; /* tiles for channel data */
int visible; /* controls visibility */
int width, height; /* size of channel */
int bytes; /* bytes per pixel */
unsigned char col[3]; /* RGB triplet for channel color*/
int opacity; /* Channel opacity */
int show_masked; /* Show masked areas--as */
/* opposed to selected areas */
int dirty; /* dirty bit */
int ID; /* provides a unique ID */
int layer_ID; /* ID of layer-if a layer mask */
int gimage_ID; /* ID of gimage owner */
/* Selection mask variables */
int boundary_known; /* is the current boundary valid*/
BoundSeg *segs_in; /* outline of selected region */
BoundSeg *segs_out; /* outline of selected region */
int num_segs_in; /* number of lines in boundary */
int num_segs_out; /* number of lines in boundary */
int empty; /* is the region empty? */
int bounds_known; /* recalculate the bounds? */
int x1, y1; /* coordinates for bounding box */
int x2, y2; /* lower right hand coordinate */
/* Preview variables */
TempBuf *preview; /* preview of the channel */
int preview_valid; /* is the preview valid? */
};
typedef GimpChannel Channel; /* convenience */
guint gimp_channel_get_type (void);
/* Special undo type */
typedef struct _channel_undo ChannelUndo;
@ -81,7 +54,7 @@ struct _channel_undo
{
Channel * channel; /* the actual channel */
int prev_position; /* former position in list */
int prev_channel; /* previous active channel */
Channel * prev_channel; /* previous active channel */
int undo_type; /* is this a new channel undo */
/* or a remove channel undo? */
};
@ -98,13 +71,10 @@ struct _mask_undo
/* function declarations */
void channel_allocate (Channel *, int, int);
void channel_deallocate (Channel *);
Channel * channel_new (int, int, int, char *, int, unsigned char *);
Channel * channel_copy (Channel *);
Channel * channel_get_ID (int);
void channel_delete (Channel *);
void channel_apply_image (Channel *, int, int, int, int, TileManager *, int);
void channel_scale (Channel *, int, int);
void channel_resize (Channel *, int, int, int, int);
@ -140,8 +110,12 @@ void channel_border (Channel *, int);
void channel_grow (Channel *, int);
void channel_shrink (Channel *, int);
void channel_translate (Channel *, int, int);
void channel_layer_alpha (Channel *, int);
void channel_layer_mask (Channel *, int);
void channel_load (Channel *, Channel *);
void channel_invalidate_bounds (Channel *);
extern int channel_get_count;
/* from drawable.c */
Channel * drawable_channel (GimpDrawable *);
#endif /* __CHANNEL_H__ */

View file

@ -136,7 +136,7 @@ static void blend_motion (Tool *, GdkEventMotion *, gpointer)
static void blend_cursor_update (Tool *, GdkEventMotion *, gpointer);
static void blend_control (Tool *, int, gpointer);
static void blend (GImage *gimage, int drawable_id,
static void blend (GImage *gimage, GimpDrawable *drawable,
BlendMode blend_mode, int paint_mode,
GradientType gradient_type,
double opacity, double offset,
@ -165,12 +165,12 @@ static double gradient_repeat_none(double val);
static double gradient_repeat_sawtooth(double val);
static double gradient_repeat_triangular(double val);
static void gradient_precalc_shapeburst (GImage *gimage, int, PixelRegion *PR, double dist);
static void gradient_precalc_shapeburst (GImage *gimage, GimpDrawable *drawable, PixelRegion *PR, double dist);
static void gradient_render_pixel(double x, double y, color_t *color, void *render_data);
static void gradient_put_pixel(int x, int y, color_t color, void *put_pixel_data);
static void gradient_fill_region (GImage *gimage, int, PixelRegion *PR,
static void gradient_fill_region (GImage *gimage, GimpDrawable *drawable, PixelRegion *PR,
int width, int height,
BlendMode blend_mode, GradientType gradient_type,
double offset, RepeatMode repeat,
@ -594,7 +594,7 @@ blend_button_release (Tool *tool,
return_vals = procedural_db_run_proc ("gimp_blend",
&nreturn_vals,
PDB_IMAGE, gimage->ID,
PDB_DRAWABLE, gimage_active_drawable (gimage),
PDB_DRAWABLE, drawable_ID (gimage_active_drawable (gimage)),
PDB_INT32, (gint32) blend_options->blend_mode,
PDB_INT32, (gint32) blend_options->paint_mode,
PDB_INT32, (gint32) blend_options->gradient_type,
@ -726,7 +726,7 @@ blend_control (Tool *tool,
/* The actual blending procedure */
static void
blend (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
BlendMode blend_mode,
int paint_mode,
GradientType gradient_type,
@ -748,10 +748,10 @@ blend (GImage *gimage,
int bytes;
int x1, y1, x2, y2;
has_selection = drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
has_selection = drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
has_alpha = drawable_has_alpha (drawable_id);
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable);
bytes = drawable_bytes (drawable);
/* Always create an alpha temp buf (for generality) */
if (! has_alpha)
@ -763,7 +763,7 @@ blend (GImage *gimage,
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), bytes);
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
gradient_fill_region (gimage, drawable_id,
gradient_fill_region (gimage, drawable,
&bufPR, (x2 - x1), (y2 - y1),
blend_mode, gradient_type, offset, repeat,
supersample, max_depth, threshold,
@ -771,11 +771,11 @@ blend (GImage *gimage,
(endx - x1), (endy - y1));
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
gimage_apply_image (gimage, drawable_id, &bufPR, TRUE,
gimage_apply_image (gimage, drawable, &bufPR, TRUE,
(opacity * 255) / 100, paint_mode, NULL, x1, y1);
/* update the image */
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
/* free the temporary buffer */
tile_manager_destroy (buf_tiles);
@ -1085,7 +1085,7 @@ gradient_repeat_triangular(double val)
/*****/
static void
gradient_precalc_shapeburst (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
PixelRegion *PR,
double dist)
{
@ -1113,12 +1113,13 @@ gradient_precalc_shapeburst (GImage *gimage,
int x1, y1, x2, y2;
int offx, offy;
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_offsets (drawable_id, &offx, &offy);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
drawable_offsets (drawable, &offx, &offy);
/* the selection mask */
mask = gimage_get_mask (gimage);
pixel_region_init (&maskR, mask->tiles, x1 + offx, y1 + offy, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&maskR, drawable_data (GIMP_DRAWABLE(mask)),
x1 + offx, y1 + offy, (x2 - x1), (y2 - y1), FALSE);
/* copy the mask to the temp mask */
copy_region (&maskR, &tempR);
@ -1127,11 +1128,11 @@ gradient_precalc_shapeburst (GImage *gimage,
else
{
/* If the intended drawable has an alpha channel, use that */
if (drawable_has_alpha (drawable_id))
if (drawable_has_alpha (drawable))
{
PixelRegion drawableR;
pixel_region_init (&drawableR, drawable_data (drawable_id), PR->x, PR->y, PR->w, PR->h, FALSE);
pixel_region_init (&drawableR, drawable_data (drawable), PR->x, PR->y, PR->w, PR->h, FALSE);
extract_alpha_region (&drawableR, NULL, &tempR);
}
@ -1286,7 +1287,7 @@ gradient_put_pixel(int x, int y, color_t color, void *put_pixel_data)
static void
gradient_fill_region (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
PixelRegion *PR,
int width,
int height,
@ -1387,7 +1388,7 @@ gradient_fill_region (GImage *gimage,
case ShapeburstSpherical:
case ShapeburstDimpled:
rbd.dist = sqrt(SQR(ex - sx) + SQR(ey - sy));
gradient_precalc_shapeburst(gimage, drawable_id, PR, rbd.dist);
gradient_precalc_shapeburst(gimage, drawable, PR, rbd.dist);
break;
default:
@ -1769,7 +1770,7 @@ blend_invoker (Argument *args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
BlendMode blend_mode;
int paint_mode;
GradientType gradient_type;
@ -1784,7 +1785,7 @@ blend_invoker (Argument *args)
int int_value;
double fp_value;
drawable_id = -1;
drawable = NULL;
blend_mode = FG_BG_RGB_MODE;
paint_mode = NORMAL_MODE;
gradient_type = Linear;
@ -1806,9 +1807,8 @@ blend_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* blend mode */
@ -1920,7 +1920,7 @@ blend_invoker (Argument *args)
/* call the blend procedure */
if (success)
{
blend (gimage, drawable_id, blend_mode, paint_mode, gradient_type,
blend (gimage, drawable, blend_mode, paint_mode, gradient_type,
opacity, offset, repeat, supersample, max_depth, threshold, x1, y1, x2, y2);
}

View file

@ -23,8 +23,9 @@
#include "desaturate.h"
#include "interface.h"
#include "paint_funcs.h"
#include "gimage.h"
static void desaturate (int);
static void desaturate (GimpDrawable *);
static Argument * desaturate_invoker (Argument *);
@ -33,25 +34,24 @@ image_desaturate (gimage_ptr)
void *gimage_ptr;
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
if (! drawable_color (drawable_id))
if (! drawable_color (drawable))
{
message_box ("Desaturate operates only on RGB color drawables.", NULL, NULL);
return;
}
desaturate (drawable_id);
desaturate (drawable);
}
/* Desaturateer */
static void
desaturate (drawable_id)
int drawable_id;
desaturate (GimpDrawable *drawable)
{
PixelRegion srcPR, destPR;
unsigned char *src, *s;
@ -62,10 +62,13 @@ desaturate (drawable_id)
void *pr;
int x1, y1, x2, y2;
has_alpha = drawable_has_alpha (drawable_id);
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
if (!drawable)
return;
has_alpha = drawable_has_alpha (drawable);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -103,8 +106,8 @@ desaturate (drawable_id)
}
}
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
@ -151,9 +154,9 @@ desaturate_invoker (args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
/* the gimage */
if (success)
@ -166,18 +169,17 @@ desaturate_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* check to make sure the drawable is color */
if (success)
success = drawable_color (drawable_id);
success = drawable_color (drawable);
if (success)
desaturate (drawable_id);
desaturate (drawable);
return procedural_db_return_args (&desaturate_proc, success);
}

View file

@ -22,8 +22,9 @@
#include "drawable.h"
#include "equalize.h"
#include "interface.h"
#include "gimage.h"
static void equalize (GImage *, int, int);
static void equalize (GImage *, GimpDrawable *, int);
static void eq_histogram (double [3][256], unsigned char [3][256], int, double);
static Argument * equalize_invoker (Argument *);
@ -33,25 +34,25 @@ image_equalize (gimage_ptr)
void *gimage_ptr;
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int mask_only = TRUE;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
if (drawable_indexed (drawable_id))
if (drawable_indexed (drawable))
{
message_box ("Equalize does not operate on indexed drawables.", NULL, NULL);
return;
}
equalize (gimage, drawable_id, mask_only);
equalize (gimage, drawable, mask_only);
}
static void
equalize(gimage, drawable_id, mask_only)
equalize(gimage, drawable, mask_only)
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int mask_only;
{
Channel *sel_mask;
@ -73,18 +74,18 @@ equalize(gimage, drawable_id, mask_only)
mask = NULL;
sel_mask = gimage_get_mask (gimage);
drawable_offsets (drawable_id, &off_x, &off_y);
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable_id);
drawable_offsets (drawable, &off_x, &off_y);
bytes = drawable_bytes (drawable);
has_alpha = drawable_has_alpha (drawable);
alpha = has_alpha ? (bytes - 1) : bytes;
count = 0.0;
/* Determine the histogram from the drawable data and the attendant mask */
no_mask = (drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
no_mask = (drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
sel_maskPR = (no_mask) ? NULL : &maskPR;
if (sel_maskPR)
pixel_region_init (sel_maskPR, sel_mask->tiles, x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (sel_maskPR, drawable_data (GIMP_DRAWABLE (sel_mask)), x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
/* Initialize histogram */
for (b = 0; b < alpha; b++)
@ -135,8 +136,8 @@ equalize(gimage, drawable_id, mask_only)
eq_histogram (hist, lut, alpha, count);
/* Apply the histogram */
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -166,8 +167,8 @@ equalize(gimage, drawable_id, mask_only)
}
}
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
@ -276,9 +277,9 @@ equalize_invoker (args)
int int_value;
int mask_only;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
/* the gimage */
if (success)
@ -291,10 +292,9 @@ equalize_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* the mask only option */
if (success)
@ -304,10 +304,10 @@ equalize_invoker (args)
}
/* make sure the drawable is not indexed color */
if (success)
success = ! drawable_indexed (drawable_id);
success = ! drawable_indexed (drawable);
if (success)
equalize (gimage, drawable_id, mask_only);
equalize (gimage, drawable, mask_only);
return procedural_db_return_args (&equalize_proc, success);
}

View file

@ -22,8 +22,9 @@
#include "drawable.h"
#include "interface.h"
#include "invert.h"
#include "gimage.h"
static void invert (int);
static void invert (GimpDrawable *);
static Argument * invert_invoker (Argument *);
@ -32,14 +33,14 @@ image_invert (gimage_ptr)
void *gimage_ptr;
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
Argument *return_vals;
int nreturn_vals;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
if (drawable_indexed (drawable_id))
if (drawable_indexed (drawable))
{
message_box ("Invert does not operate on indexed drawables.", NULL, NULL);
return;
@ -48,7 +49,7 @@ image_invert (gimage_ptr)
return_vals = procedural_db_run_proc ("gimp_invert",
&nreturn_vals,
PDB_IMAGE, gimage->ID,
PDB_DRAWABLE, drawable_id,
PDB_DRAWABLE, drawable_ID (drawable),
PDB_END);
if (return_vals[0].value.pdb_int != PDB_SUCCESS)
@ -61,8 +62,8 @@ image_invert (gimage_ptr)
/* Inverter */
static void
invert (drawable_id)
int drawable_id;
invert (drawable)
GimpDrawable *drawable;
{
PixelRegion srcPR, destPR;
unsigned char *src, *s;
@ -73,12 +74,12 @@ invert (drawable_id)
void *pr;
int x1, y1, x2, y2;
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable_id);
bytes = drawable_bytes (drawable);
has_alpha = drawable_has_alpha (drawable);
alpha = has_alpha ? (bytes - 1) : bytes;
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -108,8 +109,8 @@ invert (drawable_id)
}
}
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
@ -156,9 +157,9 @@ invert_invoker (args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
/* the gimage */
if (success)
@ -171,17 +172,16 @@ invert_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* make sure the drawable is not indexed color */
if (success)
success = ! drawable_indexed (drawable_id);
success = ! drawable_indexed (drawable);
if (success)
invert (drawable_id);
invert (drawable);
return procedural_db_return_args (&invert_proc, success);
}

View file

@ -28,6 +28,8 @@
#include "interface.h"
#include "palette.h"
#include "channel_pvt.h"
#define ENTRY_WIDTH 60
#define OFFSET_BACKGROUND 0
#define OFFSET_TRANSPARENT 1
@ -47,9 +49,8 @@ typedef struct
} OffsetDialog;
/* Local procedures */
static GImage * duplicate (GImage *gimage);
static void offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
@ -71,22 +72,9 @@ static void offset_wraparound_update (GtkWidget *widget,
static void offset_halfheight_update (GtkWidget *widget,
gpointer data);
static Argument * channel_ops_duplicate_invoker (Argument *args);
static Argument * channel_ops_offset_invoker (Argument *args);
void
channel_ops_duplicate (void *gimage_ptr)
{
GImage *gimage;
GImage *new_gimage;
gimage = (GImage *) gimage_ptr;
new_gimage = duplicate (gimage);
gdisplay_new (new_gimage, 0x0101);
}
void
channel_ops_offset (void *gimage_ptr)
{
@ -100,15 +88,15 @@ channel_ops_offset (void *gimage_ptr)
GtkWidget *toggle_vbox;
GtkWidget *table;
GSList *group = NULL;
int drawable_id;
GimpDrawable *drawable;
GImage *gimage;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
off_d = g_new (OffsetDialog, 1);
off_d->wrap_around = TRUE;
off_d->transparent = drawable_has_alpha (drawable_id);
off_d->transparent = drawable_has_alpha (drawable);
off_d->background = !off_d->transparent;
off_d->gimage_id = gimage->ID;
@ -190,7 +178,7 @@ channel_ops_offset (void *gimage_ptr)
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), off_d->background);
gtk_widget_show (toggle);
if (drawable_has_alpha (drawable_id))
if (drawable_has_alpha (drawable))
{
toggle = gtk_radio_button_new_with_label (group, "Transparent");
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
@ -224,142 +212,25 @@ channel_ops_offset (void *gimage_ptr)
off_d);
}
static GImage *
duplicate (GImage *gimage)
{
PixelRegion srcPR, destPR;
GImage *new_gimage;
Layer *layer, *new_layer;
Layer *floating_layer;
Channel *channel, *new_channel;
link_ptr list;
int active_layer = -1;
int active_channel = -1;
int new_floating_sel_drawable = -1;
int floating_sel_drawable = -1;
int count;
/* Create a new image */
new_gimage = gimage_new (gimage->width, gimage->height, gimage->base_type);
gimage_disable_undo (new_gimage);
floating_layer = gimage_floating_sel (gimage);
if (floating_layer)
{
floating_sel_relax (floating_layer, FALSE);
floating_sel_drawable = floating_layer->fs.drawable;
floating_layer = NULL;
}
/* Copy the layers */
list = gimage->layers;
count = 0;
layer = NULL;
while (list)
{
layer = (Layer *) list->data;
list = next_item (list);
new_layer = layer_copy (layer, FALSE);
new_layer->gimage_ID = new_gimage->ID;
/* Make sure the copied layer doesn't say: "<old layer> copy" */
g_free (new_layer->name);
new_layer->name = g_strdup (layer->name);
/* Make sure if the layer has a layer mask, it's name isn't screwed up */
if (new_layer->mask)
{
g_free (new_layer->mask->name);
new_layer->mask->name = g_strdup (layer->mask->name);
}
if (gimage->active_layer == layer->ID)
active_layer = new_layer->ID;
if (gimage->floating_sel == layer->ID)
floating_layer = new_layer;
if (floating_sel_drawable == layer->ID)
new_floating_sel_drawable = new_layer->ID;
/* Add the layer */
if (floating_layer != new_layer)
gimage_add_layer (new_gimage, new_layer, count++);
}
/* Copy the channels */
list = gimage->channels;
count = 0;
while (list)
{
channel = (Channel *) list->data;
list = next_item (list);
new_channel = channel_copy (channel);
/* Make sure the copied channel doesn't say: "<old channel> copy" */
g_free (new_channel->name);
new_channel->name = g_strdup (channel->name);
if (gimage->active_channel == layer->ID)
active_channel = new_channel->ID;
if (floating_sel_drawable == channel->ID)
new_floating_sel_drawable = new_channel->ID;
/* Add the channel */
gimage_add_channel (new_gimage, new_channel, count++);
}
/* Copy the selection mask */
pixel_region_init (&srcPR, gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, FALSE);
pixel_region_init (&destPR, new_gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, TRUE);
copy_region (&srcPR, &destPR);
new_gimage->selection_mask->bounds_known = FALSE;
new_gimage->selection_mask->boundary_known = FALSE;
/* Set active layer, active channel */
new_gimage->active_layer = active_layer;
new_gimage->active_channel = active_channel;
if (floating_layer)
floating_sel_attach (floating_layer, new_floating_sel_drawable);
/* Copy the colormap if necessary */
if (new_gimage->base_type == INDEXED)
memcpy (new_gimage->cmap, gimage->cmap, gimage->num_cols * 3);
new_gimage->num_cols = gimage->num_cols;
/* copy state of all color channels */
for (count = 0; count < MAX_CHANNELS; count++)
{
new_gimage->visible[count] = gimage->visible[count];
new_gimage->active[count] = gimage->active[count];
}
gimage_enable_undo (new_gimage);
return new_gimage;
}
static void
offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
int offset_y)
{
PixelRegion srcPR, destPR;
Channel *channel;
Layer *layer;
TileManager *new_tiles;
int width, height;
int src_x, src_y;
int dest_x, dest_y;
unsigned char fill[MAX_CHANNELS] = { 0 };
if (!drawable)
return;
width = drawable_width (drawable);
height = drawable_height (drawable);
@ -565,10 +436,7 @@ offset (GImage *gimage,
drawable_data (drawable), FALSE);
/* swap the tiles */
if ((channel = channel_get_ID (drawable)))
channel->tiles = new_tiles;
else if ((layer = layer_get_ID (drawable)))
layer->tiles = new_tiles;
drawable->tiles = new_tiles;
/* update the drawable */
drawable_update (drawable, 0, 0, drawable_width (drawable), drawable_height (drawable));
@ -584,14 +452,14 @@ offset_ok_callback (GtkWidget *widget,
{
OffsetDialog *off_d;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int offset_x, offset_y;
int fill_type;
off_d = (OffsetDialog *) data;
if ((gimage = gimage_get_ID (off_d->gimage_id)) != NULL)
{
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
offset_x = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_x_entry)));
offset_y = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_y_entry)));
@ -601,7 +469,7 @@ offset_ok_callback (GtkWidget *widget,
else
fill_type = OFFSET_BACKGROUND;
offset (gimage, drawable_id, off_d->wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, off_d->wrap_around, fill_type, offset_x, offset_y);
gdisplays_flush ();
}
@ -684,76 +552,6 @@ offset_halfheight_update (GtkWidget *widget,
* Procedure database functions and data structures
*/
/* The duplicate procedure definition */
ProcArg channel_ops_duplicate_args[] =
{
{ PDB_IMAGE,
"image",
"the image"
}
};
ProcArg channel_ops_duplicate_out_args[] =
{
{ PDB_IMAGE,
"new_image",
"the new, duplicated image"
}
};
ProcRecord channel_ops_duplicate_proc =
{
"gimp_channel_ops_duplicate",
"Duplicate the specified image",
"This procedure duplicates the specified image, copying all layers, channels, and image information.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1997",
PDB_INTERNAL,
/* Input arguments */
1,
channel_ops_duplicate_args,
/* Output arguments */
1,
channel_ops_duplicate_out_args,
/* Exec method */
{ { channel_ops_duplicate_invoker } },
};
static Argument *
channel_ops_duplicate_invoker (Argument *args)
{
Argument *return_args;
int success = TRUE;
int int_value;
GImage *gimage, *new_gimage;
new_gimage = NULL;
/* the gimage */
if (success)
{
int_value = args[0].value.pdb_int;
if (! (gimage = gimage_get_ID (int_value)))
success = FALSE;
}
if (success)
success = ((new_gimage = duplicate ((void *) gimage)) != NULL);
return_args = procedural_db_return_args (&channel_ops_duplicate_proc, success);
if (success)
return_args[1].value.pdb_int = new_gimage->ID;
return return_args;
}
/*
* Procedure database functions and data structures
*/
@ -816,7 +614,7 @@ channel_ops_offset_invoker (Argument *args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int wrap_around;
int fill_type;
int offset_x;
@ -831,8 +629,9 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
{
drawable_id = args[1].value.pdb_int;
if (gimage != drawable_gimage (drawable_id))
int_value = args[1].value.pdb_int;
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
if (success)
@ -852,7 +651,7 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
offset (gimage, drawable_id, wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, wrap_around, fill_type, offset_x, offset_y);
return procedural_db_return_args (&channel_ops_offset_proc, success);
}

View file

@ -21,11 +21,9 @@
#include "procedural_db.h"
/* channel_ops functions */
void channel_ops_duplicate (void *);
void channel_ops_offset (void *);
/* Procedure definition and marshalling function */
extern ProcRecord channel_ops_duplicate_proc;
extern ProcRecord channel_ops_offset_proc;
#endif /* __CHANNEL_OPS_H__ */

View file

@ -32,6 +32,9 @@
#include "tools.h"
#include "undo.h"
#include "tile_manager_pvt.h"
#include "drawable_pvt.h"
/* The named paste dialog */
typedef struct _PasteNamedDlg PasteNamedDlg;
@ -165,13 +168,13 @@ crop_buffer (TileManager *tiles,
TileManager *
edit_cut (GImage *gimage,
int drawable_id)
GimpDrawable *drawable)
{
TileManager *cut;
TileManager *cropped_cut;
int empty;
if (!gimage || drawable_id == -1)
if (!gimage || drawable == NULL)
return NULL;
/* Start a group undo */
@ -181,7 +184,7 @@ edit_cut (GImage *gimage,
empty = gimage_mask_is_empty (gimage);
/* Next, cut the mask portion from the gimage */
cut = gimage_mask_extract (gimage, drawable_id, TRUE, FALSE);
cut = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
/* Only crop if the gimage mask wasn't empty */
if (cut && empty == FALSE)
@ -215,20 +218,20 @@ edit_cut (GImage *gimage,
TileManager *
edit_copy (GImage *gimage,
int drawable_id)
GimpDrawable *drawable)
{
TileManager * copy;
TileManager * cropped_copy;
int empty;
if (!gimage || drawable_id == -1)
if (!gimage || drawable == NULL)
return NULL;
/* See if the gimage mask is empty */
empty = gimage_mask_is_empty (gimage);
/* First, copy the masked portion of the gimage */
copy = gimage_mask_extract (gimage, drawable_id, FALSE, FALSE);
copy = gimage_mask_extract (gimage, drawable, FALSE, FALSE);
/* Only crop if the gimage mask wasn't empty */
if (copy && empty == FALSE)
@ -259,7 +262,7 @@ edit_copy (GImage *gimage,
int
edit_paste (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
TileManager *paste,
int paste_into)
{
@ -268,7 +271,7 @@ edit_paste (GImage *gimage,
int cx, cy;
/* Make a new floating layer */
float_layer = layer_from_tiles (gimage, drawable_id, paste, "Pasted Layer", OPAQUE, NORMAL);
float_layer = layer_from_tiles (gimage, drawable, paste, "Pasted Layer", OPAQUE, NORMAL);
if (float_layer)
{
@ -276,13 +279,13 @@ edit_paste (GImage *gimage,
undo_push_group_start (gimage, EDIT_PASTE_UNDO);
/* Set the offsets to the center of the image */
drawable_offsets (drawable_id, &cx, &cy);
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_offsets ( (drawable), &cx, &cy);
drawable_mask_bounds ( (drawable), &x1, &y1, &x2, &y2);
cx += (x1 + x2) >> 1;
cy += (y1 + y2) >> 1;
float_layer->offset_x = cx - (float_layer->width >> 1);
float_layer->offset_y = cy - (float_layer->height >> 1);
GIMP_DRAWABLE(float_layer)->offset_x = cx - (GIMP_DRAWABLE(float_layer)->width >> 1);
GIMP_DRAWABLE(float_layer)->offset_y = cy - (GIMP_DRAWABLE(float_layer)->height >> 1);
/* If there is a selection mask clear it--
* this might not always be desired, but in general,
@ -292,12 +295,12 @@ edit_paste (GImage *gimage,
channel_clear (gimage_get_mask (gimage));
/* add a new floating selection */
floating_sel_attach (float_layer, drawable_id);
floating_sel_attach (float_layer, drawable);
/* end the group undo */
undo_push_group_end (gimage);
return float_layer->ID;
return GIMP_DRAWABLE(float_layer)->ID;
}
else
return 0;
@ -305,35 +308,35 @@ edit_paste (GImage *gimage,
int
edit_clear (GImage *gimage,
int drawable_id)
GimpDrawable *drawable)
{
TileManager *buf_tiles;
PixelRegion bufPR;
int x1, y1, x2, y2;
unsigned char col[MAX_CHANNELS];
if (!gimage || drawable_id == -1)
if (!gimage || drawable == NULL)
return FALSE;
gimage_get_background (gimage, drawable_id, col);
if (drawable_has_alpha (drawable_id))
col [drawable_bytes (drawable_id) - 1] = OPAQUE;
gimage_get_background (gimage, drawable, col);
if (drawable_has_alpha (drawable))
col [drawable_bytes (drawable) - 1] = OPAQUE;
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
if (!(x2 - x1) || !(y2 - y1))
return FALSE;
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable_id));
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable));
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
color_region (&bufPR, col);
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
gimage_apply_image (gimage, drawable_id, &bufPR, 1, OPAQUE,
gimage_apply_image (gimage, drawable, &bufPR, 1, OPAQUE,
ERASE_MODE, NULL, x1, y1);
/* update the image */
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
/* free the temporary tiles */
tile_manager_destroy (buf_tiles);
@ -343,35 +346,35 @@ edit_clear (GImage *gimage,
int
edit_fill (GImage *gimage,
int drawable_id)
GimpDrawable *drawable)
{
TileManager *buf_tiles;
PixelRegion bufPR;
int x1, y1, x2, y2;
unsigned char col[MAX_CHANNELS];
if (!gimage || drawable_id == -1)
if (!gimage || drawable == NULL)
return FALSE;
gimage_get_background (gimage, drawable_id, col);
if (drawable_has_alpha (drawable_id))
col [drawable_bytes (drawable_id) - 1] = OPAQUE;
gimage_get_background (gimage, drawable, col);
if (drawable_has_alpha (drawable))
col [drawable_bytes (drawable) - 1] = OPAQUE;
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
if (!(x2 - x1) || !(y2 - y1))
return FALSE;
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable_id));
buf_tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable));
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
color_region (&bufPR, col);
pixel_region_init (&bufPR, buf_tiles, 0, 0, (x2 - x1), (y2 - y1), FALSE);
gimage_apply_image (gimage, drawable_id, &bufPR, 1, OPAQUE,
gimage_apply_image (gimage, drawable, &bufPR, 1, OPAQUE,
NORMAL_MODE, NULL, x1, y1);
/* update the image */
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
/* free the temporary tiles */
tile_manager_destroy (buf_tiles);

View file

@ -22,11 +22,11 @@
/* The interface functions */
TileManager * crop_buffer (TileManager *, int);
TileManager * edit_cut (GImage *, int);
TileManager * edit_copy (GImage *, int);
int edit_paste (GImage *, int, TileManager *, int);
int edit_clear (GImage *, int);
int edit_fill (GImage *, int);
TileManager * edit_cut (GImage *, GimpDrawable *);
TileManager * edit_copy (GImage *, GimpDrawable *);
int edit_paste (GImage *, GimpDrawable *, TileManager *, int);
int edit_clear (GImage *, GimpDrawable *);
int edit_fill (GImage *, GimpDrawable *);
int global_edit_cut (void *);
int global_edit_copy (void *);

View file

@ -66,6 +66,10 @@
#include "undo.h"
#include "palette.h"
#include "layer_pvt.h" /* ick. */
#include "drawable_pvt.h" /* ick ick. */
#include "tile_manager_pvt.h" /* ick ick ick. */
#define MAXNUMCOLORS 256
#define NODITHER 0
@ -738,7 +742,7 @@ convert_image (GImage *gimage,
break;
}
new_tiles = tile_manager_new (layer->width, layer->height, new_layer_bytes);
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, new_layer_bytes);
switch (new_type)
{
@ -758,9 +762,10 @@ convert_image (GImage *gimage,
/* Push the layer on the undo stack */
undo_push_layer_mod (gimage, layer);
layer->tiles = new_tiles;
layer->bytes = new_layer_bytes;
layer->type = new_layer_type;
GIMP_DRAWABLE(layer)->tiles = new_tiles;
GIMP_DRAWABLE(layer)->bytes = new_layer_bytes;
GIMP_DRAWABLE(layer)->type = new_layer_type;
GIMP_DRAWABLE(layer)->has_alpha = TYPE_HAS_ALPHA(new_layer_type);
}
/* Delete the quantizer object, if there is one */
@ -800,8 +805,8 @@ rgb_converter (Layer *layer,
void *pr;
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -832,7 +837,7 @@ rgb_converter (Layer *layer,
}
break;
case INDEXED:
cmap = drawable_cmap (layer->ID);
cmap = drawable_cmap (GIMP_DRAWABLE(layer));
for (row = 0; row < srcPR.h; row++)
{
s = src;
@ -874,8 +879,8 @@ grayscale_converter (Layer *layer,
void *pr;
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -903,7 +908,7 @@ grayscale_converter (Layer *layer,
}
break;
case INDEXED:
cmap = drawable_cmap (layer->ID);
cmap = drawable_cmap (GIMP_DRAWABLE(layer));
for (row = 0; row < srcPR.h; row++)
{
s = src;
@ -966,7 +971,7 @@ generate_histogram_gray (Histogram histogram,
has_alpha = (gboolean) layer_has_alpha(layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
for (pr = pixel_regions_register (1, &srcPR);
pr != NULL;
pr = pixel_regions_process (pr))
@ -999,7 +1004,7 @@ generate_histogram_rgb (Histogram histogram,
g_print ("col_limit = %d, nfc = %d\n", col_limit, num_found_cols);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
for (pr = pixel_regions_register (1, &srcPR);
pr != NULL;
pr = pixel_regions_process (pr))
@ -2057,8 +2062,8 @@ median_cut_pass2_no_dither_gray (QuantizeObj *quantobj,
zero_histogram_gray (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2107,14 +2112,14 @@ median_cut_pass2_no_dither_rgb (QuantizeObj *quantobj,
/* In the case of web/mono palettes, we actually force
* grayscale drawables through the rgb pass2 functions
*/
if (drawable_gray (layer->ID))
if (drawable_gray (GIMP_DRAWABLE(layer)))
red_pix = green_pix = blue_pix = GRAY_PIX;
zero_histogram_rgb (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2167,8 +2172,8 @@ median_cut_pass2_nodestruct_dither_rgb (QuantizeObj *quantobj,
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2322,12 +2327,12 @@ median_cut_pass2_fs_dither_gray (QuantizeObj *quantobj,
zero_histogram_gray (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, layer->height, TRUE);
src_bytes = layer->bytes;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
src_bytes = GIMP_DRAWABLE(layer)->bytes;
dest_bytes = new_tiles->levels[0].bpp;
width = layer->width;
height = layer->height;
width = GIMP_DRAWABLE(layer)->width;
height = GIMP_DRAWABLE(layer)->height;
error_limiter = init_error_limit ();
range_limiter = range_array + 256;
@ -2472,18 +2477,18 @@ median_cut_pass2_fs_dither_rgb (QuantizeObj *quantobj,
/* In the case of web/mono palettes, we actually force
* grayscale drawables through the rgb pass2 functions
*/
if (drawable_gray (layer->ID))
if (drawable_gray (GIMP_DRAWABLE(layer)))
red_pix = green_pix = blue_pix = GRAY_PIX;
zero_histogram_rgb (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, layer->height, TRUE);
src_bytes = layer->bytes;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
src_bytes = GIMP_DRAWABLE(layer)->bytes;
dest_bytes = new_tiles->levels[0].bpp;
width = layer->width;
height = layer->height;
width = GIMP_DRAWABLE(layer)->width;
height = GIMP_DRAWABLE(layer)->height;
error_limiter = init_error_limit ();
range_limiter = range_array + 256;

View file

@ -28,6 +28,8 @@
#include "interface.h"
#include "palette.h"
#include "channel_pvt.h"
#define ENTRY_WIDTH 60
#define OFFSET_BACKGROUND 0
#define OFFSET_TRANSPARENT 1
@ -47,9 +49,8 @@ typedef struct
} OffsetDialog;
/* Local procedures */
static GImage * duplicate (GImage *gimage);
static void offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
@ -71,22 +72,9 @@ static void offset_wraparound_update (GtkWidget *widget,
static void offset_halfheight_update (GtkWidget *widget,
gpointer data);
static Argument * channel_ops_duplicate_invoker (Argument *args);
static Argument * channel_ops_offset_invoker (Argument *args);
void
channel_ops_duplicate (void *gimage_ptr)
{
GImage *gimage;
GImage *new_gimage;
gimage = (GImage *) gimage_ptr;
new_gimage = duplicate (gimage);
gdisplay_new (new_gimage, 0x0101);
}
void
channel_ops_offset (void *gimage_ptr)
{
@ -100,15 +88,15 @@ channel_ops_offset (void *gimage_ptr)
GtkWidget *toggle_vbox;
GtkWidget *table;
GSList *group = NULL;
int drawable_id;
GimpDrawable *drawable;
GImage *gimage;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
off_d = g_new (OffsetDialog, 1);
off_d->wrap_around = TRUE;
off_d->transparent = drawable_has_alpha (drawable_id);
off_d->transparent = drawable_has_alpha (drawable);
off_d->background = !off_d->transparent;
off_d->gimage_id = gimage->ID;
@ -190,7 +178,7 @@ channel_ops_offset (void *gimage_ptr)
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), off_d->background);
gtk_widget_show (toggle);
if (drawable_has_alpha (drawable_id))
if (drawable_has_alpha (drawable))
{
toggle = gtk_radio_button_new_with_label (group, "Transparent");
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
@ -224,142 +212,25 @@ channel_ops_offset (void *gimage_ptr)
off_d);
}
static GImage *
duplicate (GImage *gimage)
{
PixelRegion srcPR, destPR;
GImage *new_gimage;
Layer *layer, *new_layer;
Layer *floating_layer;
Channel *channel, *new_channel;
link_ptr list;
int active_layer = -1;
int active_channel = -1;
int new_floating_sel_drawable = -1;
int floating_sel_drawable = -1;
int count;
/* Create a new image */
new_gimage = gimage_new (gimage->width, gimage->height, gimage->base_type);
gimage_disable_undo (new_gimage);
floating_layer = gimage_floating_sel (gimage);
if (floating_layer)
{
floating_sel_relax (floating_layer, FALSE);
floating_sel_drawable = floating_layer->fs.drawable;
floating_layer = NULL;
}
/* Copy the layers */
list = gimage->layers;
count = 0;
layer = NULL;
while (list)
{
layer = (Layer *) list->data;
list = next_item (list);
new_layer = layer_copy (layer, FALSE);
new_layer->gimage_ID = new_gimage->ID;
/* Make sure the copied layer doesn't say: "<old layer> copy" */
g_free (new_layer->name);
new_layer->name = g_strdup (layer->name);
/* Make sure if the layer has a layer mask, it's name isn't screwed up */
if (new_layer->mask)
{
g_free (new_layer->mask->name);
new_layer->mask->name = g_strdup (layer->mask->name);
}
if (gimage->active_layer == layer->ID)
active_layer = new_layer->ID;
if (gimage->floating_sel == layer->ID)
floating_layer = new_layer;
if (floating_sel_drawable == layer->ID)
new_floating_sel_drawable = new_layer->ID;
/* Add the layer */
if (floating_layer != new_layer)
gimage_add_layer (new_gimage, new_layer, count++);
}
/* Copy the channels */
list = gimage->channels;
count = 0;
while (list)
{
channel = (Channel *) list->data;
list = next_item (list);
new_channel = channel_copy (channel);
/* Make sure the copied channel doesn't say: "<old channel> copy" */
g_free (new_channel->name);
new_channel->name = g_strdup (channel->name);
if (gimage->active_channel == layer->ID)
active_channel = new_channel->ID;
if (floating_sel_drawable == channel->ID)
new_floating_sel_drawable = new_channel->ID;
/* Add the channel */
gimage_add_channel (new_gimage, new_channel, count++);
}
/* Copy the selection mask */
pixel_region_init (&srcPR, gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, FALSE);
pixel_region_init (&destPR, new_gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, TRUE);
copy_region (&srcPR, &destPR);
new_gimage->selection_mask->bounds_known = FALSE;
new_gimage->selection_mask->boundary_known = FALSE;
/* Set active layer, active channel */
new_gimage->active_layer = active_layer;
new_gimage->active_channel = active_channel;
if (floating_layer)
floating_sel_attach (floating_layer, new_floating_sel_drawable);
/* Copy the colormap if necessary */
if (new_gimage->base_type == INDEXED)
memcpy (new_gimage->cmap, gimage->cmap, gimage->num_cols * 3);
new_gimage->num_cols = gimage->num_cols;
/* copy state of all color channels */
for (count = 0; count < MAX_CHANNELS; count++)
{
new_gimage->visible[count] = gimage->visible[count];
new_gimage->active[count] = gimage->active[count];
}
gimage_enable_undo (new_gimage);
return new_gimage;
}
static void
offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
int offset_y)
{
PixelRegion srcPR, destPR;
Channel *channel;
Layer *layer;
TileManager *new_tiles;
int width, height;
int src_x, src_y;
int dest_x, dest_y;
unsigned char fill[MAX_CHANNELS] = { 0 };
if (!drawable)
return;
width = drawable_width (drawable);
height = drawable_height (drawable);
@ -565,10 +436,7 @@ offset (GImage *gimage,
drawable_data (drawable), FALSE);
/* swap the tiles */
if ((channel = channel_get_ID (drawable)))
channel->tiles = new_tiles;
else if ((layer = layer_get_ID (drawable)))
layer->tiles = new_tiles;
drawable->tiles = new_tiles;
/* update the drawable */
drawable_update (drawable, 0, 0, drawable_width (drawable), drawable_height (drawable));
@ -584,14 +452,14 @@ offset_ok_callback (GtkWidget *widget,
{
OffsetDialog *off_d;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int offset_x, offset_y;
int fill_type;
off_d = (OffsetDialog *) data;
if ((gimage = gimage_get_ID (off_d->gimage_id)) != NULL)
{
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
offset_x = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_x_entry)));
offset_y = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_y_entry)));
@ -601,7 +469,7 @@ offset_ok_callback (GtkWidget *widget,
else
fill_type = OFFSET_BACKGROUND;
offset (gimage, drawable_id, off_d->wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, off_d->wrap_around, fill_type, offset_x, offset_y);
gdisplays_flush ();
}
@ -684,76 +552,6 @@ offset_halfheight_update (GtkWidget *widget,
* Procedure database functions and data structures
*/
/* The duplicate procedure definition */
ProcArg channel_ops_duplicate_args[] =
{
{ PDB_IMAGE,
"image",
"the image"
}
};
ProcArg channel_ops_duplicate_out_args[] =
{
{ PDB_IMAGE,
"new_image",
"the new, duplicated image"
}
};
ProcRecord channel_ops_duplicate_proc =
{
"gimp_channel_ops_duplicate",
"Duplicate the specified image",
"This procedure duplicates the specified image, copying all layers, channels, and image information.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1997",
PDB_INTERNAL,
/* Input arguments */
1,
channel_ops_duplicate_args,
/* Output arguments */
1,
channel_ops_duplicate_out_args,
/* Exec method */
{ { channel_ops_duplicate_invoker } },
};
static Argument *
channel_ops_duplicate_invoker (Argument *args)
{
Argument *return_args;
int success = TRUE;
int int_value;
GImage *gimage, *new_gimage;
new_gimage = NULL;
/* the gimage */
if (success)
{
int_value = args[0].value.pdb_int;
if (! (gimage = gimage_get_ID (int_value)))
success = FALSE;
}
if (success)
success = ((new_gimage = duplicate ((void *) gimage)) != NULL);
return_args = procedural_db_return_args (&channel_ops_duplicate_proc, success);
if (success)
return_args[1].value.pdb_int = new_gimage->ID;
return return_args;
}
/*
* Procedure database functions and data structures
*/
@ -816,7 +614,7 @@ channel_ops_offset_invoker (Argument *args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int wrap_around;
int fill_type;
int offset_x;
@ -831,8 +629,9 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
{
drawable_id = args[1].value.pdb_int;
if (gimage != drawable_gimage (drawable_id))
int_value = args[1].value.pdb_int;
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
if (success)
@ -852,7 +651,7 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
offset (gimage, drawable_id, wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, wrap_around, fill_type, offset_x, offset_y);
return procedural_db_return_args (&channel_ops_offset_proc, success);
}

View file

@ -21,11 +21,9 @@
#include "procedural_db.h"
/* channel_ops functions */
void channel_ops_duplicate (void *);
void channel_ops_offset (void *);
/* Procedure definition and marshalling function */
extern ProcRecord channel_ops_duplicate_proc;
extern ProcRecord channel_ops_offset_proc;
#endif /* __CHANNEL_OPS_H__ */

View file

@ -31,6 +31,10 @@
#include "paint_core.h"
#include "undo.h"
#include "layer_pvt.h"
#include "tile_manager_pvt.h"
#include "drawable_pvt.h"
/* feathering variables */
double gimage_mask_feather_radius = 5;
int gimage_mask_border_radius = 5;
@ -39,7 +43,7 @@ int gimage_mask_shrink_pixels = 1;
int gimage_mask_stroking = FALSE;
/* local functions */
static void * gimage_mask_stroke_paint_func (PaintCore *, int, int);
static void * gimage_mask_stroke_paint_func (PaintCore *, GimpDrawable *, int);
/* functions */
int
@ -86,10 +90,12 @@ gimage_mask_boundary (gimage, segs_in, segs_out, num_segs_in, num_segs_out)
/* if a layer is active, we return multiple boundaries based on the extents */
else if ((layer = gimage_get_active_layer (gimage)))
{
x1 = BOUNDS (layer->offset_x, 0, gimage->width);
y1 = BOUNDS (layer->offset_y, 0, gimage->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, gimage->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, gimage->height);
int off_x, off_y;
drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
x1 = BOUNDS (off_x, 0, gimage->width);
y1 = BOUNDS (off_y, 0, gimage->height);
x2 = BOUNDS (off_x + drawable_width (GIMP_DRAWABLE(layer)), 0, gimage->width);
y2 = BOUNDS (off_y + drawable_height (GIMP_DRAWABLE(layer)), 0, gimage->height);
return channel_boundary (gimage_get_mask (gimage),
segs_in, segs_out,
@ -135,7 +141,7 @@ gimage_mask_invalidate (gimage)
*/
layer = gimage_get_active_layer (gimage);
if (layer && layer_is_floating_sel (layer))
drawable_update (layer->ID, 0, 0, layer->width, layer->height);
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
}
@ -174,15 +180,14 @@ gimage_mask_translate (gimage, off_x, off_y)
TileManager *
gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
gimage_mask_extract (gimage, drawable, cut_gimage, keep_indexed)
GImage * gimage;
int drawable_id;
GimpDrawable *drawable;
int cut_gimage;
int keep_indexed;
{
TileManager * tiles;
Channel * sel_mask;
Channel * channel;
PixelRegion srcPR, destPR, maskPR;
unsigned char bg[MAX_CHANNELS];
int bytes, type;
@ -190,13 +195,16 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
int off_x, off_y;
int non_empty;
if (!drawable)
return NULL;
/* If there are no bounds, then just extract the entire image
* This may not be the correct behavior, but after getting rid
* of floating selections, it's still tempting to "cut" or "copy"
* a small layer and expect it to work, even though there is no
* actual selection mask
*/
non_empty = drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
non_empty = drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
if (non_empty && (!(x2 - x1) || !(y2 - y1)))
{
message_box ("Unable to cut/copy because the selected\nregion is empty.", NULL, NULL);
@ -204,7 +212,7 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
}
/* How many bytes in the temp buffer? */
switch (drawable_type (drawable_id))
switch (drawable_type (drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
bytes = 4; type = RGB; break;
@ -232,13 +240,13 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
else
sel_mask = NULL;
gimage_get_background (gimage, drawable_id, bg);
gimage_get_background (gimage, drawable, bg);
/* If a cut was specified, and the selection mask is not empty, push an undo */
if (cut_gimage && non_empty)
drawable_apply_image (drawable_id, x1, y1, x2, y2, NULL, FALSE);
drawable_apply_image (drawable, x1, y1, x2, y2, NULL, FALSE);
drawable_offsets (drawable_id, &off_x, &off_y);
drawable_offsets (drawable, &off_x, &off_y);
/* Allocate the temp buffer */
tiles = tile_manager_new ((x2 - x1), (y2 - y1), bytes);
@ -246,16 +254,16 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
tiles->y = y1 + off_y;
/* configure the pixel regions */
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), cut_gimage);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), cut_gimage);
pixel_region_init (&destPR, tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
/* If there is a selection, extract from it */
if (non_empty)
{
pixel_region_init (&maskPR, sel_mask->tiles, (x1 + off_x), (y1 + off_y), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(sel_mask)->tiles, (x1 + off_x), (y1 + off_y), (x2 - x1), (y2 - y1), FALSE);
extract_from_region (&srcPR, &destPR, &maskPR, drawable_cmap (drawable_id),
bg, type, drawable_has_alpha (drawable_id), cut_gimage);
extract_from_region (&srcPR, &destPR, &maskPR, drawable_cmap (drawable),
bg, type, drawable_has_alpha (drawable), cut_gimage);
if (cut_gimage)
{
@ -267,7 +275,7 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
tiles->levels[0].width, tiles->levels[0].height);
/* Invalidate the preview */
drawable_invalidate_preview (drawable_id);
drawable_invalidate_preview (drawable);
}
}
/* Otherwise, get the entire active layer */
@ -275,8 +283,8 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
{
/* If the layer is indexed...we need to extract pixels */
if (type == INDEXED && !keep_indexed)
extract_from_region (&srcPR, &destPR, NULL, drawable_cmap (drawable_id),
bg, type, drawable_has_alpha (drawable_id), FALSE);
extract_from_region (&srcPR, &destPR, NULL, drawable_cmap (drawable),
bg, type, drawable_has_alpha (drawable), FALSE);
/* If the layer doesn't have an alpha channel, add one */
else if (bytes > srcPR.bytes)
add_alpha_region (&srcPR, &destPR);
@ -287,20 +295,19 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
/* If we're cutting, remove either the layer (or floating selection),
* the layer mask, or the channel
*/
if (cut_gimage && drawable_layer (drawable_id))
if (cut_gimage && drawable_layer (drawable))
{
if (layer_is_floating_sel (drawable_layer (drawable_id)))
floating_sel_remove (drawable_layer (drawable_id));
if (layer_is_floating_sel (drawable_layer (drawable)))
floating_sel_remove (drawable_layer (drawable));
else
gimage_remove_layer (gimage, drawable_id);
gimage_remove_layer (gimage, GIMP_LAYER (drawable));
}
else if (cut_gimage && drawable_layer_mask (drawable_id))
else if (cut_gimage && drawable_layer_mask (drawable))
{
if ((channel = channel_get_ID (drawable_id)))
gimage_remove_layer_mask (gimage, channel->layer_ID, DISCARD);
gimage_remove_layer_mask (gimage, GIMP_LAYER_MASK(drawable)->layer, DISCARD);
}
else if (cut_gimage && drawable_channel (drawable_id))
gimage_remove_channel (gimage, drawable_id);
else if (cut_gimage && drawable_channel (drawable))
gimage_remove_channel (gimage, GIMP_CHANNEL(drawable));
}
return tiles;
@ -308,9 +315,9 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
Layer *
gimage_mask_float (gimage, drawable_id, off_x, off_y)
gimage_mask_float (gimage, drawable, off_x, off_y)
GImage * gimage;
int drawable_id;
GimpDrawable* drawable;
int off_x, off_y; /* optional offset */
{
Layer *layer;
@ -320,7 +327,7 @@ gimage_mask_float (gimage, drawable_id, off_x, off_y)
int x1, y1, x2, y2;
/* Make sure there is a region to float... */
non_empty = drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
non_empty = drawable_mask_bounds ( (drawable), &x1, &y1, &x2, &y2);
if (! non_empty || (x2 - x1) == 0 || (y2 - y1) == 0)
{
message_box ("Float Selection: No selection to float.", NULL, NULL);
@ -331,20 +338,20 @@ gimage_mask_float (gimage, drawable_id, off_x, off_y)
undo_push_group_start (gimage, FLOAT_MASK_UNDO);
/* Cut the selected region */
tiles = gimage_mask_extract (gimage, drawable_id, TRUE, FALSE);
tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
/* Create a new layer from the buffer */
layer = layer_from_tiles (gimage, drawable_id, tiles, "Floated Layer", OPAQUE, NORMAL);
layer = layer_from_tiles (gimage, drawable, tiles, "Floated Layer", OPAQUE, NORMAL);
/* Set the offsets */
layer->offset_x = tiles->x + off_x;
layer->offset_y = tiles->y + off_y;
GIMP_DRAWABLE(layer)->offset_x = tiles->x + off_x;
GIMP_DRAWABLE(layer)->offset_y = tiles->y + off_y;
/* Free the temp buffer */
tile_manager_destroy (tiles);
/* Add the floating layer to the gimage */
floating_sel_attach (layer, drawable_id);
floating_sel_attach (layer, drawable);
/* End an undo group */
undo_push_group_end (gimage);
@ -465,15 +472,15 @@ gimage_mask_shrink (gimage, shrink_pixels)
void
gimage_mask_layer_alpha (gimage, layer_id)
gimage_mask_layer_alpha (gimage, layer)
GImage *gimage;
int layer_id;
Layer *layer;
{
/* extract the layer's alpha channel */
if (drawable_has_alpha (layer_id))
if (drawable_has_alpha (GIMP_DRAWABLE (layer)))
{
/* load the mask with the given layer's alpha channel */
channel_layer_alpha (gimage_get_mask (gimage), layer_id);
channel_layer_alpha (gimage_get_mask (gimage), layer);
}
else
{
@ -484,20 +491,15 @@ gimage_mask_layer_alpha (gimage, layer_id)
void
gimage_mask_layer_mask (gimage, layer_id)
gimage_mask_layer_mask (gimage, layer)
GImage *gimage;
int layer_id;
Layer *layer;
{
Layer *layer;
if ((layer = layer_get_ID (layer_id)) == NULL)
return;
/* extract the layer's alpha channel */
if (layer->mask)
{
/* load the mask with the given layer's alpha channel */
channel_layer_mask (gimage_get_mask (gimage), layer_id);
channel_layer_mask (gimage_get_mask (gimage), layer);
}
else
{
@ -508,12 +510,12 @@ gimage_mask_layer_mask (gimage, layer_id)
void
gimage_mask_load (gimage, channel_id)
gimage_mask_load (gimage, channel)
GImage *gimage;
int channel_id;
Channel *channel;
{
/* Load the specified channel to the gimage mask */
channel_load (gimage_get_mask (gimage), channel_get_ID (channel_id));
channel_load (gimage_get_mask (gimage), (channel));
}
@ -526,7 +528,7 @@ gimage_mask_save (gimage)
new_channel = channel_copy (gimage_get_mask (gimage));
/* saved selections are not visible by default */
new_channel->visible = FALSE;
GIMP_DRAWABLE(new_channel)->visible = FALSE;
gimage_add_channel (gimage, new_channel, -1);
return new_channel;
@ -534,9 +536,9 @@ gimage_mask_save (gimage)
int
gimage_mask_stroke (gimage, drawable_id)
gimage_mask_stroke (gimage, drawable)
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
{
BoundSeg *bs_in;
BoundSeg *bs_out;
@ -559,10 +561,10 @@ gimage_mask_stroke (gimage, drawable_id)
return TRUE;
/* find the drawable offsets */
drawable_offsets (drawable_id, &offx, &offy);
drawable_offsets (drawable, &offx, &offy);
/* init the paint core */
if (! paint_core_init (&non_gui_paint_core, drawable_id,
if (! paint_core_init (&non_gui_paint_core, drawable,
(stroke_segs[0].x1 - offx),
(stroke_segs[0].y1 - offy)))
return FALSE;
@ -582,7 +584,7 @@ gimage_mask_stroke (gimage, drawable_id)
non_gui_paint_core.curx = (stroke_segs[seg].x2 - offx);
non_gui_paint_core.cury = (stroke_segs[seg].y2 - offy);
paint_core_interpolate (&non_gui_paint_core, drawable_id);
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.lastx = non_gui_paint_core.curx;
non_gui_paint_core.lasty = non_gui_paint_core.cury;
@ -596,7 +598,7 @@ gimage_mask_stroke (gimage, drawable_id)
}
/* finish the painting */
paint_core_finish (&non_gui_paint_core, drawable_id, -1);
paint_core_finish (&non_gui_paint_core, drawable, -1);
/* cleanup */
gimage_mask_stroking = FALSE;
@ -607,22 +609,22 @@ gimage_mask_stroke (gimage, drawable_id)
}
static void *
gimage_mask_stroke_paint_func (paint_core, drawable_id, state)
gimage_mask_stroke_paint_func (paint_core, drawable, state)
PaintCore *paint_core;
int drawable_id;
GimpDrawable *drawable;
int state;
{
GImage *gimage;
TempBuf * area;
unsigned char col[MAX_CHANNELS];
if (! (gimage = drawable_gimage (drawable_id)))
if (! (gimage = drawable_gimage (drawable)))
return NULL;
gimage_get_foreground (gimage, drawable_id, col);
gimage_get_foreground (gimage, drawable, col);
/* Get a region which can be used to paint to */
if (! (area = paint_core_get_paint_area (paint_core, drawable_id)))
if (! (area = paint_core_get_paint_area (paint_core, drawable)))
return NULL;
/* set the alpha channel */
@ -633,7 +635,7 @@ gimage_mask_stroke_paint_func (paint_core, drawable_id, state)
area->width * area->height, area->bytes);
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable_id, OPAQUE,
paint_core_paste_canvas (paint_core, drawable, OPAQUE,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);

View file

@ -28,8 +28,8 @@ void gimage_mask_invalidate (GImage *);
int gimage_mask_value (GImage *, int, int);
int gimage_mask_is_empty (GImage *);
void gimage_mask_translate (GImage *, int, int);
TileManager * gimage_mask_extract (GImage *, int, int, int);
Layer * gimage_mask_float (GImage *, int, int, int);
TileManager * gimage_mask_extract (GImage *, GimpDrawable *, int, int);
Layer * gimage_mask_float (GImage *, GimpDrawable *, int, int);
void gimage_mask_clear (GImage *);
void gimage_mask_undo (GImage *);
void gimage_mask_invert (GImage *);
@ -40,10 +40,10 @@ void gimage_mask_feather (GImage *, double);
void gimage_mask_border (GImage *, int);
void gimage_mask_grow (GImage *, int);
void gimage_mask_shrink (GImage *, int);
void gimage_mask_layer_alpha (GImage *, int);
void gimage_mask_layer_mask (GImage *, int);
void gimage_mask_load (GImage *, int);
void gimage_mask_layer_alpha (GImage *, Layer *);
void gimage_mask_layer_mask (GImage *, Layer *);
void gimage_mask_load (GImage *, Channel *);
Channel * gimage_mask_save (GImage *);
int gimage_mask_stroke (GImage *, int);
int gimage_mask_stroke (GImage *, GimpDrawable *);
#endif /* __GIMAGE_MASK_H__ */

View file

@ -37,6 +37,11 @@
#include "transform_core.h"
#include "undo.h"
#include "drawable_pvt.h"
#include "layer_pvt.h"
#include "channel_pvt.h"
#include "tile_manager_pvt.h"
typedef int (* UndoPopFunc) (GImage *, int, int, void *);
typedef void (* UndoFreeFunc) (int, void *);
@ -105,11 +110,11 @@ layer_size (Layer *layer)
{
int size;
size = sizeof (Layer) + layer->width * layer->height * layer->bytes +
strlen (layer->name);
size = sizeof (Layer) + GIMP_DRAWABLE(layer)->width * GIMP_DRAWABLE(layer)->height * GIMP_DRAWABLE(layer)->bytes +
strlen (GIMP_DRAWABLE(layer)->name);
if (layer_mask (layer))
size += channel_size (layer_mask (layer));
size += channel_size (GIMP_CHANNEL (layer_mask (layer)));
return size;
}
@ -120,8 +125,8 @@ channel_size (Channel *channel)
{
int size;
size = sizeof (Channel) + channel->width * channel->height +
strlen (channel->name);
size = sizeof (Channel) + GIMP_DRAWABLE(channel)->width * GIMP_DRAWABLE(channel)->height +
strlen (GIMP_DRAWABLE(channel)->name);
return size;
}
@ -409,7 +414,7 @@ typedef struct _image_undo ImageUndo;
struct _image_undo
{
TileManager *tiles;
int drawable;
GimpDrawable *drawable;
int x1, y1, x2, y2;
int sparse;
};
@ -417,7 +422,7 @@ struct _image_undo
int
undo_push_image (GImage *gimage,
int drawable_ID,
GimpDrawable *drawable,
int x1,
int y1,
int x2,
@ -431,14 +436,14 @@ undo_push_image (GImage *gimage,
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
drawable_dirty (drawable_ID);
drawable_dirty (drawable);
x1 = BOUNDS (x1, 0, drawable_width (drawable_ID));
y1 = BOUNDS (y1, 0, drawable_height (drawable_ID));
x2 = BOUNDS (x2, 0, drawable_width (drawable_ID));
y2 = BOUNDS (y2, 0, drawable_height (drawable_ID));
x1 = BOUNDS (x1, 0, drawable_width (drawable));
y1 = BOUNDS (y1, 0, drawable_height (drawable));
x2 = BOUNDS (x2, 0, drawable_width (drawable));
y2 = BOUNDS (y2, 0, drawable_height (drawable));
size = (x2 - x1) * (y2 - y1) * drawable_bytes (drawable_ID) + sizeof (void *) * 2;
size = (x2 - x1) * (y2 - y1) * drawable_bytes (drawable) + sizeof (void *) * 2;
if ((new = undo_push (gimage, size, IMAGE_UNDO)))
{
@ -447,14 +452,14 @@ undo_push_image (GImage *gimage,
/* If we cannot create a new temp buf--either because our parameters are
* degenerate or something else failed, simply return an unsuccessful push.
*/
tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable_ID));
pixel_region_init (&srcPR, drawable_data (drawable_ID), x1, y1, (x2 - x1), (y2 - y1), FALSE);
tiles = tile_manager_new ((x2 - x1), (y2 - y1), drawable_bytes (drawable));
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
/* set the image undo structure */
image_undo->tiles = tiles;
image_undo->drawable = drawable_ID;
image_undo->drawable = drawable;
image_undo->x1 = x1;
image_undo->y1 = y1;
image_undo->x2 = x2;
@ -474,7 +479,7 @@ undo_push_image (GImage *gimage,
int
undo_push_image_mod (GImage *gimage,
int drawable_ID,
GimpDrawable *drawable,
int x1,
int y1,
int x2,
@ -489,15 +494,15 @@ undo_push_image_mod (GImage *gimage,
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
drawable_dirty (drawable_ID);
drawable_dirty (drawable);
if (! tiles_ptr)
return FALSE;
x1 = BOUNDS (x1, 0, drawable_width (drawable_ID));
y1 = BOUNDS (y1, 0, drawable_height (drawable_ID));
x2 = BOUNDS (x2, 0, drawable_width (drawable_ID));
y2 = BOUNDS (y2, 0, drawable_height (drawable_ID));
x1 = BOUNDS (x1, 0, drawable_width (drawable));
y1 = BOUNDS (y1, 0, drawable_height (drawable));
x2 = BOUNDS (x2, 0, drawable_width (drawable));
y2 = BOUNDS (y2, 0, drawable_height (drawable));
tiles = (TileManager *) tiles_ptr;
size = tiles->levels[0].width * tiles->levels[0].height *
@ -507,7 +512,7 @@ undo_push_image_mod (GImage *gimage,
{
image_undo = (ImageUndo *) g_malloc (sizeof (ImageUndo));
image_undo->tiles = tiles;
image_undo->drawable = drawable_ID;
image_undo->drawable = drawable;
image_undo->x1 = x1;
image_undo->y1 = y1;
image_undo->x2 = x2;
@ -674,7 +679,7 @@ undo_pop_mask (GImage *gimage,
/* save current selection mask */
sel_mask = gimage_get_mask (gimage);
selection = channel_bounds (sel_mask, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, sel_mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(sel_mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
if (selection)
{
@ -683,7 +688,7 @@ undo_pop_mask (GImage *gimage,
copy_region (&srcPR, &destPR);
pixel_region_init (&srcPR, sel_mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(sel_mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
color_region (&srcPR, &empty);
}
else
@ -694,7 +699,7 @@ undo_pop_mask (GImage *gimage,
width = mask_undo->tiles->levels[0].width;
height = mask_undo->tiles->levels[0].height;
pixel_region_init (&srcPR, mask_undo->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, sel_mask->tiles, mask_undo->x, mask_undo->y, width, height, TRUE);
pixel_region_init (&destPR, GIMP_DRAWABLE(sel_mask)->tiles, mask_undo->x, mask_undo->y, width, height, TRUE);
copy_region (&srcPR, &destPR);
tile_manager_destroy (mask_undo->tiles);
@ -716,8 +721,8 @@ undo_pop_mask (GImage *gimage,
sel_mask->empty = TRUE;
sel_mask->x1 = 0;
sel_mask->y1 = 0;
sel_mask->x2 = sel_mask->width;
sel_mask->y2 = sel_mask->height;
sel_mask->x2 = GIMP_DRAWABLE(sel_mask)->width;
sel_mask->y2 = GIMP_DRAWABLE(sel_mask)->height;
}
/* set the new mask undo parameters */
@ -772,8 +777,8 @@ undo_push_layer_displace (GImage *gimage,
info = (int *) new->data;
info[0] = layer_ID;
info[1] = layer->offset_x;
info[2] = layer->offset_y;
info[1] = GIMP_DRAWABLE(layer)->offset_x;
info[2] = GIMP_DRAWABLE(layer)->offset_y;
return TRUE;
}
@ -796,13 +801,19 @@ undo_pop_layer_displace (GImage *gimage,
layer = layer_get_ID (info[0]);
if (layer)
{
old_offsets[0] = layer->offset_x;
old_offsets[1] = layer->offset_y;
drawable_update (layer->ID, 0, 0, layer->width, layer->height);
old_offsets[0] = GIMP_DRAWABLE(layer)->offset_x;
old_offsets[1] = GIMP_DRAWABLE(layer)->offset_y;
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
GIMP_DRAWABLE(layer)->offset_x = info[1];
GIMP_DRAWABLE(layer)->offset_y = info[2];
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
if (layer->mask)
{
GIMP_DRAWABLE(layer->mask)->offset_x = info[1];
GIMP_DRAWABLE(layer->mask)->offset_y = info[2];
}
layer->offset_x = info[1];
layer->offset_y = info[2];
drawable_update (layer->ID, 0, 0, layer->width, layer->height);
/* invalidate the selection boundary because of a layer modification */
layer_invalidate_boundary (layer);
@ -1006,7 +1017,7 @@ undo_push_layer (GImage *gimage,
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
drawable_dirty (lu->layer->ID);
drawable_dirty (GIMP_DRAWABLE(lu->layer));
size = layer_size (lu->layer) + sizeof (LayerUndo);
@ -1043,11 +1054,11 @@ undo_pop_layer (GImage *gimage,
{
case UNDO:
gimage_clean (gimage);
drawable_clean (lu->layer->ID);
drawable_clean (GIMP_DRAWABLE(lu->layer));
break;
case REDO:
gimage_dirty (gimage);
drawable_dirty (lu->layer->ID);
drawable_dirty (GIMP_DRAWABLE(lu->layer));
break;
}
@ -1056,7 +1067,7 @@ undo_pop_layer (GImage *gimage,
(state == REDO && lu->undo_type == 1))
{
/* record the current position */
lu->prev_position = gimage_get_layer_index (gimage, lu->layer->ID);
lu->prev_position = gimage_get_layer_index (gimage, lu->layer);
/* set the previous layer */
gimage_set_active_layer (gimage, lu->prev_layer);
@ -1067,12 +1078,12 @@ undo_pop_layer (GImage *gimage,
/* reset the gimage values */
if (layer_is_floating_sel (lu->layer))
{
gimage->floating_sel = -1;
gimage->floating_sel = NULL;
/* reset the old drawable */
floating_sel_reset (lu->layer);
}
drawable_update (lu->layer->ID, 0, 0, lu->layer->width, lu->layer->height);
drawable_update (GIMP_DRAWABLE(lu->layer), 0, 0, GIMP_DRAWABLE(lu->layer)->width, GIMP_DRAWABLE(lu->layer)->height);
}
/* restore layer */
else
@ -1081,18 +1092,18 @@ undo_pop_layer (GImage *gimage,
lu->prev_layer = gimage->active_layer;
/* hide the current selection--for all views */
if (gimage->active_layer != -1)
layer_invalidate_boundary (layer_get_ID (gimage->active_layer));
if (gimage->active_layer != NULL)
layer_invalidate_boundary ((gimage->active_layer));
/* if this is a floating selection, set the fs pointer */
if (layer_is_floating_sel (lu->layer))
gimage->floating_sel = lu->layer->ID;
gimage->floating_sel = lu->layer;
/* add the new layer */
gimage->layers = insert_in_list (gimage->layers, lu->layer, lu->prev_position);
gimage->layer_stack = add_to_list (gimage->layer_stack, lu->layer);
gimage->active_layer = lu->layer->ID;
drawable_update (lu->layer->ID, 0, 0, lu->layer->width, lu->layer->height);
gimage->active_layer = lu->layer;
drawable_update (GIMP_DRAWABLE(lu->layer), 0, 0, GIMP_DRAWABLE(lu->layer)->width, GIMP_DRAWABLE(lu->layer)->height);
}
return TRUE;
@ -1137,12 +1148,12 @@ undo_push_layer_mod (GImage *gimage,
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
drawable_dirty (layer->ID);
drawable_dirty (GIMP_DRAWABLE(layer));
tiles = layer->tiles;
tiles->x = layer->offset_x;
tiles->y = layer->offset_y;
size = layer->width * layer->height * layer->bytes + sizeof (void *) * 3;
tiles = GIMP_DRAWABLE(layer)->tiles;
tiles->x = GIMP_DRAWABLE(layer)->offset_x;
tiles->y = GIMP_DRAWABLE(layer)->offset_y;
size = GIMP_DRAWABLE(layer)->width * GIMP_DRAWABLE(layer)->height * GIMP_DRAWABLE(layer)->bytes + sizeof (void *) * 3;
if ((new = undo_push (gimage, size, LAYER_MOD)))
{
@ -1153,7 +1164,7 @@ undo_push_layer_mod (GImage *gimage,
data[0] = layer_ptr;
data[1] = (void *) tiles;
data[2] = (void *) ((long) layer->type);
data[2] = (void *) ((long) GIMP_DRAWABLE(layer)->type);
return TRUE;
}
@ -1184,11 +1195,11 @@ undo_pop_layer_mod (GImage *gimage,
{
case UNDO:
gimage_clean (gimage);
drawable_clean (layer->ID);
drawable_clean (GIMP_DRAWABLE(layer));
break;
case REDO:
gimage_dirty (gimage);
drawable_dirty (layer->ID);
drawable_dirty (GIMP_DRAWABLE(layer));
break;
}
@ -1196,34 +1207,40 @@ undo_pop_layer_mod (GImage *gimage,
/* Issue the first update */
gdisplays_update_area (gimage->ID,
layer->offset_x, layer->offset_y,
layer->width, layer->height);
GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* Create a tile manager to store the current layer contents */
temp = layer->tiles;
temp->x = layer->offset_x;
temp->y = layer->offset_y;
temp = GIMP_DRAWABLE(layer)->tiles;
temp->x = GIMP_DRAWABLE(layer)->offset_x;
temp->y = GIMP_DRAWABLE(layer)->offset_y;
layer_type = (long) data[2];
data[2] = (void *) ((long) layer->type);
data[2] = (void *) ((long) GIMP_DRAWABLE(layer)->type);
/* restore the layer's data */
layer->tiles = tiles;
layer->offset_x = tiles->x;
layer->offset_y = tiles->y;
layer->width = tiles->levels[0].width;
layer->height = tiles->levels[0].height;
layer->bytes = tiles->levels[0].bpp;
layer->type = layer_type;
GIMP_DRAWABLE(layer)->tiles = tiles;
GIMP_DRAWABLE(layer)->offset_x = tiles->x;
GIMP_DRAWABLE(layer)->offset_y = tiles->y;
GIMP_DRAWABLE(layer)->width = tiles->levels[0].width;
GIMP_DRAWABLE(layer)->height = tiles->levels[0].height;
GIMP_DRAWABLE(layer)->bytes = tiles->levels[0].bpp;
GIMP_DRAWABLE(layer)->type = layer_type;
if (layer->mask)
{
GIMP_DRAWABLE(layer->mask)->offset_x = tiles->x;
GIMP_DRAWABLE(layer->mask)->offset_y = tiles->y;
}
/* If the layer type changed, update the gdisplay titles */
if (layer->type != (long) data[2])
gdisplays_update_title (layer->gimage_ID);
if (GIMP_DRAWABLE(layer)->type != (long) data[2])
gdisplays_update_title (GIMP_DRAWABLE(layer)->gimage_ID);
/* Set the new tile manager */
data[1] = temp;
/* Issue the second update */
drawable_update (layer->ID, 0, 0, layer->width, layer->height);
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
return TRUE;
}
@ -1256,9 +1273,9 @@ undo_push_layer_mask (GImage *gimage,
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
drawable_dirty (lmu->layer->ID);
drawable_dirty (GIMP_DRAWABLE(lmu->layer));
size = channel_size (lmu->mask) + sizeof (LayerMaskUndo);
size = channel_size (GIMP_CHANNEL (lmu->mask)) + sizeof (LayerMaskUndo);
if ((new = undo_push (gimage, size, LAYER_MASK_UNDO)))
{
@ -1271,7 +1288,7 @@ undo_push_layer_mask (GImage *gimage,
else
{
if (lmu->undo_type == 1)
channel_delete (lmu->mask);
layer_mask_delete (lmu->mask);
g_free (lmu);
return FALSE;
}
@ -1292,11 +1309,11 @@ undo_pop_layer_mask (GImage *gimage,
{
case UNDO:
gimage_clean (gimage);
drawable_clean (lmu->layer->ID);
drawable_clean (GIMP_DRAWABLE(lmu->layer));
break;
case REDO:
gimage_dirty (gimage);
drawable_dirty (lmu->layer->ID);
drawable_dirty (GIMP_DRAWABLE(lmu->layer));
break;
}
@ -1315,7 +1332,7 @@ undo_pop_layer_mask (GImage *gimage,
* this is undoing an add...
*/
if ((state == REDO && lmu->mode == DISCARD) || state == UNDO)
drawable_update (lmu->layer->ID, 0, 0, lmu->layer->width, lmu->layer->height);
drawable_update (GIMP_DRAWABLE(lmu->layer), 0, 0, GIMP_DRAWABLE(lmu->layer)->width, GIMP_DRAWABLE(lmu->layer)->height);
}
/* restore layer */
else
@ -1325,14 +1342,14 @@ undo_pop_layer_mask (GImage *gimage,
lmu->layer->edit_mask = lmu->edit_mask;
lmu->layer->show_mask = lmu->show_mask;
gimage_set_layer_mask_edit (gimage, lmu->layer->ID, lmu->edit_mask);
gimage_set_layer_mask_edit (gimage, lmu->layer, lmu->edit_mask);
/* if this is undoing a remove operation &
* the mode of application was DISCARD or
* this is redoing an add
*/
if ((state == UNDO && lmu->mode == DISCARD) || state == REDO)
drawable_update (lmu->layer->ID, 0, 0, lmu->layer->width, lmu->layer->height);
drawable_update (GIMP_DRAWABLE(lmu->layer), 0, 0, GIMP_DRAWABLE(lmu->layer)->width, GIMP_DRAWABLE(lmu->layer)->height);
}
return TRUE;
@ -1353,7 +1370,7 @@ undo_free_layer_mask (int state,
*/
if ((state == REDO && lmu->undo_type == 0) ||
(state == UNDO && lmu->undo_type == 1))
channel_delete (lmu->mask);
layer_mask_delete (lmu->mask);
g_free (lmu);
}
@ -1374,7 +1391,7 @@ undo_push_channel (GImage *gimage,
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
drawable_dirty (cu->channel->ID);
drawable_dirty (GIMP_DRAWABLE(cu->channel));
size = channel_size (cu->channel) + sizeof (ChannelUndo);
@ -1410,11 +1427,11 @@ undo_pop_channel (GImage *gimage,
{
case UNDO:
gimage_clean (gimage);
drawable_clean (cu->channel->ID);
drawable_clean (GIMP_DRAWABLE(cu->channel));
break;
case REDO:
gimage_dirty (gimage);
drawable_dirty (cu->channel->ID);
drawable_dirty (GIMP_DRAWABLE(cu->channel));
break;
}
@ -1423,7 +1440,7 @@ undo_pop_channel (GImage *gimage,
(state == REDO && cu->undo_type == 1))
{
/* record the current position */
cu->prev_position = gimage_get_channel_index (gimage, cu->channel->ID);
cu->prev_position = gimage_get_channel_index (gimage, cu->channel);
/* remove the channel */
gimage->channels = remove_from_list (gimage->channels, cu->channel);
@ -1432,7 +1449,7 @@ undo_pop_channel (GImage *gimage,
gimage_set_active_channel (gimage, cu->prev_channel);
/* update the area */
drawable_update (cu->channel->ID, 0, 0, cu->channel->width, cu->channel->height);
drawable_update (GIMP_DRAWABLE(cu->channel), 0, 0, GIMP_DRAWABLE(cu->channel)->width, GIMP_DRAWABLE(cu->channel)->height);
}
/* restore channel */
else
@ -1444,10 +1461,10 @@ undo_pop_channel (GImage *gimage,
gimage->channels = insert_in_list (gimage->channels, cu->channel, cu->prev_position);
/* set the new channel */
gimage_set_active_channel (gimage, cu->channel->ID);
gimage_set_active_channel (gimage, cu->channel);
/* update the area */
drawable_update (cu->channel->ID, 0, 0, cu->channel->width, cu->channel->height);
drawable_update (GIMP_DRAWABLE(cu->channel), 0, 0, GIMP_DRAWABLE(cu->channel)->width, GIMP_DRAWABLE(cu->channel)->height);
}
return TRUE;
@ -1492,10 +1509,10 @@ undo_push_channel_mod (GImage *gimage,
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
drawable_dirty (channel->ID);
drawable_dirty (GIMP_DRAWABLE(channel));
tiles = channel->tiles;
size = channel->width * channel->height + sizeof (void *) * 2;
tiles = GIMP_DRAWABLE(channel)->tiles;
size = GIMP_DRAWABLE(channel)->width * GIMP_DRAWABLE(channel)->height + sizeof (void *) * 2;
if ((new = undo_push (gimage, size, CHANNEL_MOD)))
{
@ -1535,29 +1552,29 @@ undo_pop_channel_mod (GImage *gimage,
{
case UNDO:
gimage_clean (gimage);
drawable_clean (channel->ID);
drawable_clean (GIMP_DRAWABLE(channel));
break;
case REDO:
gimage_dirty (gimage);
drawable_dirty (channel->ID);
drawable_dirty (GIMP_DRAWABLE(channel));
break;
}
tiles = (TileManager *) data[1];
/* Issue the first update */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
temp = channel->tiles;
channel->tiles = tiles;
channel->width = tiles->levels[0].width;
channel->height = tiles->levels[0].height;
temp = GIMP_DRAWABLE(channel)->tiles;
GIMP_DRAWABLE(channel)->tiles = tiles;
GIMP_DRAWABLE(channel)->width = tiles->levels[0].width;
GIMP_DRAWABLE(channel)->height = tiles->levels[0].height;
/* Set the new buffer */
data[1] = temp;
/* Issue the second update */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
return TRUE;
}
@ -1590,7 +1607,7 @@ undo_push_fs_to_layer (GImage *gimage,
/* increment the dirty flag for this gimage */
gimage_dirty (gimage);
drawable_dirty (fsu->layer->ID);
drawable_dirty (GIMP_DRAWABLE(fsu->layer));
size = sizeof (FStoLayerUndo);
@ -1625,11 +1642,11 @@ undo_pop_fs_to_layer (GImage *gimage,
{
case UNDO:
gimage_clean (gimage);
drawable_clean (fsu->layer->ID);
drawable_clean (GIMP_DRAWABLE(fsu->layer));
break;
case REDO:
gimage_dirty (gimage);
drawable_dirty (fsu->layer->ID);
drawable_dirty (GIMP_DRAWABLE(fsu->layer));
break;
}
@ -1637,41 +1654,41 @@ undo_pop_fs_to_layer (GImage *gimage,
{
case UNDO:
/* Update the preview for the floating sel */
drawable_invalidate_preview (fsu->layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(fsu->layer));
fsu->layer->fs.drawable = fsu->drawable;
gimage->active_layer = fsu->layer->ID;
gimage->floating_sel = fsu->layer->ID;
gimage->active_layer = fsu->layer;
gimage->floating_sel = fsu->layer;
/* restore the contents of the drawable */
floating_sel_store (fsu->layer, fsu->layer->offset_x, fsu->layer->offset_y,
fsu->layer->width, fsu->layer->height);
floating_sel_store (fsu->layer, GIMP_DRAWABLE(fsu->layer)->offset_x, GIMP_DRAWABLE(fsu->layer)->offset_y,
GIMP_DRAWABLE(fsu->layer)->width, GIMP_DRAWABLE(fsu->layer)->height);
fsu->layer->fs.initial = TRUE;
/* clear the selection */
layer_invalidate_boundary (fsu->layer);
/* Update the preview for the gimage and underlying drawable */
drawable_invalidate_preview (fsu->layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(fsu->layer));
break;
case REDO:
/* restore the contents of the drawable */
floating_sel_restore (fsu->layer, fsu->layer->offset_x, fsu->layer->offset_y,
fsu->layer->width, fsu->layer->height);
floating_sel_restore (fsu->layer, GIMP_DRAWABLE(fsu->layer)->offset_x, GIMP_DRAWABLE(fsu->layer)->offset_y,
GIMP_DRAWABLE(fsu->layer)->width, GIMP_DRAWABLE(fsu->layer)->height);
/* Update the preview for the gimage and underlying drawable */
drawable_invalidate_preview (fsu->layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(fsu->layer));
/* clear the selection */
layer_invalidate_boundary (fsu->layer);
/* update the pointers */
fsu->layer->fs.drawable = -1;
gimage->floating_sel = -1;
fsu->layer->fs.drawable = NULL;
gimage->floating_sel = NULL;
/* Update the fs drawable */
drawable_invalidate_preview (fsu->layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(fsu->layer));
break;
}
@ -1741,16 +1758,16 @@ undo_pop_fs_rigor (GImage *gimage,
/* restore the contents of drawable the floating layer is attached to */
if (floating_layer->fs.initial == FALSE)
floating_sel_restore (floating_layer,
floating_layer->offset_x, floating_layer->offset_y,
floating_layer->width, floating_layer->height);
GIMP_DRAWABLE(floating_layer)->offset_x, GIMP_DRAWABLE(floating_layer)->offset_y,
GIMP_DRAWABLE(floating_layer)->width, GIMP_DRAWABLE(floating_layer)->height);
floating_layer->fs.initial = TRUE;
break;
case REDO:
/* store the affected area from the drawable in the backing store */
floating_sel_store (floating_layer,
floating_layer->offset_x, floating_layer->offset_y,
floating_layer->width, floating_layer->height);
GIMP_DRAWABLE(floating_layer)->offset_x, GIMP_DRAWABLE(floating_layer)->offset_y,
GIMP_DRAWABLE(floating_layer)->width, GIMP_DRAWABLE(floating_layer)->height);
floating_layer->fs.initial = TRUE;
break;
}
@ -1814,8 +1831,8 @@ undo_pop_fs_relax (GImage *gimage,
case UNDO:
/* store the affected area from the drawable in the backing store */
floating_sel_store (floating_layer,
floating_layer->offset_x, floating_layer->offset_y,
floating_layer->width, floating_layer->height);
GIMP_DRAWABLE(floating_layer)->offset_x, GIMP_DRAWABLE(floating_layer)->offset_y,
GIMP_DRAWABLE(floating_layer)->width, GIMP_DRAWABLE(floating_layer)->height);
floating_layer->fs.initial = TRUE;
break;
@ -1823,8 +1840,8 @@ undo_pop_fs_relax (GImage *gimage,
/* restore the contents of drawable the floating layer is attached to */
if (floating_layer->fs.initial == FALSE)
floating_sel_restore (floating_layer,
floating_layer->offset_x, floating_layer->offset_y,
floating_layer->width, floating_layer->height);
GIMP_DRAWABLE(floating_layer)->offset_x, GIMP_DRAWABLE(floating_layer)->offset_y,
GIMP_DRAWABLE(floating_layer)->width, GIMP_DRAWABLE(floating_layer)->height);
floating_layer->fs.initial = TRUE;
break;
}

View file

@ -61,8 +61,8 @@
int undo_push_group_start (GImage *, int);
int undo_push_group_end (GImage *);
int undo_push_image (GImage *, int, int, int, int, int);
int undo_push_image_mod (GImage *, int, int, int, int, int, void *, int);
int undo_push_image (GImage *, GimpDrawable *, int, int, int, int);
int undo_push_image_mod (GImage *, GimpDrawable *, int, int, int, int, void *, int);
int undo_push_mask (GImage *, void *);
int undo_push_layer_displace (GImage *, int);
int undo_push_transform (GImage *, void *);

View file

@ -27,6 +27,8 @@
#include "image_map.h"
#include "tile_manager.h"
#include "tile_manager_pvt.h"
#define WAITING 0
#define WORKING 1
@ -36,7 +38,7 @@
typedef struct _ImageMap
{
GDisplay * gdisp;
int drawable_id;
GimpDrawable * drawable;
TileManager * undo_tiles;
ImageMapApplyFunc apply_func;
void * user_data;
@ -60,7 +62,7 @@ image_map_do (gpointer data)
_image_map = (_ImageMap *) data;
if (! (gimage = drawable_gimage (_image_map->drawable_id)))
if (! (gimage = drawable_gimage ( (_image_map->drawable))))
{
_image_map->state = WAITING;
return FALSE;
@ -76,13 +78,13 @@ image_map_do (gpointer data)
/* apply the results */
pixel_region_init (&shadowPR, gimage->shadow, x, y, w, h, FALSE);
gimage_apply_image (gimage, _image_map->drawable_id, &shadowPR,
gimage_apply_image (gimage, _image_map->drawable, &shadowPR,
FALSE, OPAQUE, REPLACE_MODE, NULL, x, y);
/* display the results */
if (_image_map->gdisp)
{
drawable_update (_image_map->drawable_id, x, y, w, h);
drawable_update ( (_image_map->drawable), x, y, w, h);
gdisplay_flush (_image_map->gdisp);
}
@ -100,13 +102,13 @@ image_map_do (gpointer data)
ImageMap
image_map_create (void *gdisp_ptr,
int drawable_id)
GimpDrawable *drawable)
{
_ImageMap *_image_map;
_image_map = (_ImageMap *) g_malloc (sizeof (_ImageMap));
_image_map->gdisp = (GDisplay *) gdisp_ptr;
_image_map->drawable_id = drawable_id;
_image_map->drawable = drawable;
_image_map->undo_tiles = NULL;
_image_map->state = WAITING;
@ -134,11 +136,11 @@ image_map_apply (ImageMap image_map,
}
/* Make sure the drawable is still valid */
if (! drawable_gimage (_image_map->drawable_id))
if (! drawable_gimage ( (_image_map->drawable)))
return;
/* The application should occur only within selection bounds */
drawable_mask_bounds (_image_map->drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds ( (_image_map->drawable), &x1, &y1, &x2, &y2);
/* If undo tiles don't exist, or change size, (re)allocate */
if (!_image_map->undo_tiles ||
@ -155,7 +157,7 @@ image_map_apply (ImageMap image_map,
_image_map->undo_tiles->levels[0].width,
_image_map->undo_tiles->levels[0].height,
FALSE);
pixel_region_init (&_image_map->destPR, drawable_data (_image_map->drawable_id),
pixel_region_init (&_image_map->destPR, drawable_data ( (_image_map->drawable)),
_image_map->undo_tiles->x, _image_map->undo_tiles->y,
_image_map->undo_tiles->levels[0].width,
_image_map->undo_tiles->levels[0].height,
@ -175,11 +177,11 @@ image_map_apply (ImageMap image_map,
/* Allocate new tiles */
_image_map->undo_tiles = tile_manager_new ((x2 - x1), (y2 - y1),
drawable_bytes (_image_map->drawable_id));
drawable_bytes ( (_image_map->drawable)));
}
/* Copy from the image to the new tiles */
pixel_region_init (&_image_map->srcPR, drawable_data (_image_map->drawable_id),
pixel_region_init (&_image_map->srcPR, drawable_data ( (_image_map->drawable)),
x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&_image_map->destPR, _image_map->undo_tiles,
0, 0, (x2 - x1), (y2 - y1), TRUE);
@ -196,7 +198,7 @@ image_map_apply (ImageMap image_map,
0, 0, (x2 - x1), (y2 - y1), FALSE);
/* Configure the dest as the shadow buffer */
pixel_region_init (&_image_map->destPR, drawable_shadow (_image_map->drawable_id),
pixel_region_init (&_image_map->destPR, drawable_shadow ( (_image_map->drawable)),
x1, y1, (x2 - x1), (y2 - y1), TRUE);
/* Apply the image transformation to the pixels */
@ -224,7 +226,7 @@ image_map_commit (ImageMap image_map)
}
/* Make sure the drawable is still valid */
if (! drawable_gimage (_image_map->drawable_id))
if (! drawable_gimage ( (_image_map->drawable)))
return;
/* Register an undo step */
@ -234,7 +236,7 @@ image_map_commit (ImageMap image_map)
y1 = _image_map->undo_tiles->y;
x2 = _image_map->undo_tiles->x + _image_map->undo_tiles->levels[0].width;
y2 = _image_map->undo_tiles->y + _image_map->undo_tiles->levels[0].height;
drawable_apply_image (_image_map->drawable_id, x1, y1, x2, y2, _image_map->undo_tiles, FALSE);
drawable_apply_image ( (_image_map->drawable), x1, y1, x2, y2, _image_map->undo_tiles, FALSE);
}
g_free (_image_map);
@ -256,7 +258,7 @@ image_map_abort (ImageMap image_map)
}
/* Make sure the drawable is still valid */
if (! drawable_gimage (_image_map->drawable_id))
if (! drawable_gimage ( (_image_map->drawable)))
return;
/* restore the original image */
@ -267,7 +269,7 @@ image_map_abort (ImageMap image_map)
_image_map->undo_tiles->levels[0].width,
_image_map->undo_tiles->levels[0].height,
FALSE);
pixel_region_init (&destPR, drawable_data (_image_map->drawable_id),
pixel_region_init (&destPR, drawable_data ( (_image_map->drawable)),
_image_map->undo_tiles->x, _image_map->undo_tiles->y,
_image_map->undo_tiles->levels[0].width,
_image_map->undo_tiles->levels[0].height,
@ -285,7 +287,7 @@ image_map_abort (ImageMap image_map)
copy_region (&srcPR, &destPR);
/* Update the area */
drawable_update (_image_map->drawable_id,
drawable_update ( (_image_map->drawable),
_image_map->undo_tiles->x, _image_map->undo_tiles->y,
_image_map->undo_tiles->levels[0].width,
_image_map->undo_tiles->levels[0].height);

View file

@ -30,7 +30,7 @@ typedef void (* ImageMapApplyFunc) (PixelRegion *, PixelRegion *, void *);
* MUST be followed with an image_map_commit or an image_map_abort call
* The image map is no longer valid after a call to commit or abort.
*/
ImageMap image_map_create (void *, int);
ImageMap image_map_create (void *, GimpDrawable *);
void image_map_apply (ImageMap, ImageMapApplyFunc, void *);
void image_map_commit (ImageMap);
void image_map_abort (ImageMap);

View file

@ -21,6 +21,7 @@
#include "appenv.h"
#include "channels_dialog.h"
#include "drawable.h"
#include "layer.h"
#include "errors.h"
#include "floating_sel.h"
#include "gimage.h"
@ -29,38 +30,40 @@
#include "paint_funcs.h"
#include "undo.h"
#include "layer_pvt.h"
#include "tile_manager_pvt.h" /* ick. */
void
floating_sel_attach (Layer *layer,
int drawable_id)
GimpDrawable *drawable)
{
GImage *gimage;
int floating_sel;
Layer *floating_sel;
if (! (gimage = drawable_gimage (drawable_id)))
if (! (gimage = drawable_gimage (drawable)))
return;
/* If there is already a floating selection, anchor it */
if (gimage->floating_sel != -1)
if (gimage->floating_sel != NULL)
{
floating_sel = gimage->floating_sel;
floating_sel_anchor (gimage_floating_sel (gimage));
/* if we were pasting to the old floating selection, paste now to the drawable */
if (drawable_id == floating_sel)
drawable_id = gimage_active_drawable (gimage);
if (drawable == GIMP_DRAWABLE(floating_sel))
drawable = gimage_active_drawable (gimage);
}
/* set the drawable and allocate a backing store */
layer->preserve_trans = TRUE;
layer->fs.drawable = drawable_id;
layer->fs.backing_store = tile_manager_new (layer->width, layer->height, drawable_bytes (drawable_id));
layer->fs.drawable = drawable;
layer->fs.backing_store = tile_manager_new (GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, drawable_bytes (drawable));
/* because setting the sensitivity in the layers_dialog lock call redraws the
* previews, we need to lock the dialogs before the floating sel is actually added.
* however, they won't lock unless we set the gimage's floating sel pointer
*/
gimage->floating_sel = layer->ID;
gimage->floating_sel = layer;
/* add the layer to the gimage */
gimage_add_layer (gimage, layer, 0);
@ -74,7 +77,7 @@ floating_sel_remove (Layer *layer)
{
GImage *gimage;
if (! (gimage = drawable_gimage (layer->fs.drawable)))
if (! (gimage = drawable_gimage ( (layer->fs.drawable))))
return;
/* store the affected area from the drawable in the backing store */
@ -84,10 +87,10 @@ floating_sel_remove (Layer *layer)
* because it will not be done until the floating selection is removed,
* at which point the obscured drawable's preview will not be declared invalid
*/
drawable_invalidate_preview (layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(layer));
/* remove the layer from the gimage */
gimage_remove_layer (gimage, layer->ID);
gimage_remove_layer (gimage, layer);
}
void
@ -95,7 +98,7 @@ floating_sel_anchor (Layer *layer)
{
GImage *gimage;
if (! (gimage = drawable_gimage (layer->ID)))
if (! (gimage = drawable_gimage (GIMP_DRAWABLE(layer))))
return;
if (! layer_is_floating_sel (layer))
{
@ -111,11 +114,11 @@ floating_sel_anchor (Layer *layer)
floating_sel_relax (layer, TRUE);
/* Composite the floating selection contents */
floating_sel_composite (layer, layer->offset_x, layer->offset_y,
layer->width, layer->height, TRUE);
floating_sel_composite (layer, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
/* remove the floating selection */
gimage_remove_layer (gimage, layer->ID);
gimage_remove_layer (gimage, layer);
/* end the group undo */
undo_push_group_end (gimage);
@ -129,23 +132,23 @@ floating_sel_reset (layer)
Layer *layer;
{
GImage *gimage;
Channel *lm;
LayerMask *lm;
if (! (gimage = drawable_gimage (layer->ID)))
if (! (gimage = drawable_gimage (GIMP_DRAWABLE(layer))))
return;
/* set the underlying drawable to active */
if (drawable_layer (layer->fs.drawable))
gimage_set_active_layer (gimage, layer->fs.drawable);
else if ((lm = drawable_layer_mask (layer->fs.drawable)))
gimage_set_active_layer (gimage, lm->layer_ID);
else if (drawable_channel (layer->fs.drawable))
if (drawable_layer ( (layer->fs.drawable)))
gimage_set_active_layer (gimage, GIMP_LAYER (layer->fs.drawable));
else if ((lm = drawable_layer_mask ( (layer->fs.drawable))))
gimage_set_active_layer (gimage, lm->layer);
else if (drawable_channel ( (layer->fs.drawable)))
{
gimage_set_active_channel (gimage, layer->fs.drawable);
gimage_set_active_channel (gimage, GIMP_CHANNEL(layer->fs.drawable));
if (gimage->layers)
gimage->active_layer = ((Layer *) gimage->layer_stack->data)->ID;
gimage->active_layer = (((Layer *) gimage->layer_stack->data));
else
gimage->active_layer = -1;
gimage->active_layer = NULL;
}
}
@ -159,7 +162,7 @@ floating_sel_to_layer (Layer *layer)
GImage *gimage;
if (! (gimage = drawable_gimage (layer->ID)))
if (! (gimage = drawable_gimage (GIMP_DRAWABLE(layer))))
return;
/* Check if the floating layer belongs to a channel... */
@ -173,21 +176,21 @@ floating_sel_to_layer (Layer *layer)
}
/* restore the contents of the drawable */
floating_sel_restore (layer, layer->offset_x, layer->offset_y, layer->width, layer->height);
floating_sel_restore (layer, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* determine whether the resulting layer needs an update */
drawable_offsets (layer->fs.drawable, &off_x, &off_y);
width = drawable_width (layer->fs.drawable);
height = drawable_height (layer->fs.drawable);
update = (update || ((layer->offset_x < off_x) ||
(layer->offset_y < off_y) ||
(layer->offset_x + layer->width > off_x + width) ||
(layer->offset_y + layer->height > off_y + height)) ? TRUE : FALSE);
update = (update || ((GIMP_DRAWABLE(layer)->offset_x < off_x) ||
(GIMP_DRAWABLE(layer)->offset_y < off_y) ||
(GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width > off_x + width) ||
(GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height > off_y + height)) ? TRUE : FALSE);
/* update the fs drawable--this updates the gimage composite preview
* as well as the underlying drawable's
*/
drawable_invalidate_preview (layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(layer));
/* allocate the undo structure */
fsu = (FStoLayerUndo *) g_malloc (sizeof (FStoLayerUndo));
@ -200,15 +203,15 @@ floating_sel_to_layer (Layer *layer)
layer_invalidate_boundary (layer);
/* Set pointers */
layer->fs.drawable = -1;
gimage->floating_sel = -1;
layer->fs.drawable = NULL;
gimage->floating_sel = NULL;
/* if the floating selection exceeds the attached layer's extents, update the new layer */
if (update)
drawable_update (layer->ID, 0, 0, layer->width, layer->height);
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* otherwise, just update the preview, because the image is valid as is */
else
drawable_invalidate_preview (layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(layer));
}
void
@ -223,14 +226,15 @@ floating_sel_store (Layer *layer,
int x1, y1, x2, y2;
/* Check the backing store & make sure it has the correct dimensions */
if (layer->fs.backing_store->levels[0].width != layer->width ||
layer->fs.backing_store->levels[0].height != layer->height ||
if (layer->fs.backing_store->levels[0].width != drawable_width (GIMP_DRAWABLE(layer)) ||
layer->fs.backing_store->levels[0].height != drawable_height (GIMP_DRAWABLE(layer)) ||
layer->fs.backing_store->levels[0].bpp != drawable_bytes (layer->fs.drawable))
{
/* free the backing store and allocate anew */
tile_manager_destroy (layer->fs.backing_store);
layer->fs.backing_store = tile_manager_new (layer->width, layer->height,
layer->fs.backing_store = tile_manager_new (GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height,
drawable_bytes (layer->fs.drawable));
}
@ -241,10 +245,10 @@ floating_sel_store (Layer *layer,
drawable_offsets (layer->fs.drawable, &offx, &offy);
/* Find the minimum area we need to uncover -- in gimage space */
x1 = MAXIMUM (layer->offset_x, offx);
y1 = MAXIMUM (layer->offset_y, offy);
x2 = MINIMUM (layer->offset_x + layer->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (layer->offset_y + layer->height, offy + drawable_height (layer->fs.drawable));
x1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_x, offx);
y1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_y, offy);
x2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, offy + drawable_height (layer->fs.drawable));
x1 = BOUNDS (x, x1, x2);
y1 = BOUNDS (y, y1, y2);
@ -257,7 +261,7 @@ floating_sel_store (Layer *layer,
pixel_region_init (&srcPR, drawable_data (layer->fs.drawable),
(x1 - offx), (y1 - offy), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, layer->fs.backing_store,
(x1 - layer->offset_x), (y1 - layer->offset_y), (x2 - x1), (y2 - y1), TRUE);
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y), (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
}
@ -282,10 +286,10 @@ floating_sel_restore (Layer *layer,
/* Find the minimum area we need to uncover -- in gimage space */
drawable_offsets (layer->fs.drawable, &offx, &offy);
x1 = MAXIMUM (layer->offset_x, offx);
y1 = MAXIMUM (layer->offset_y, offy);
x2 = MINIMUM (layer->offset_x + layer->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (layer->offset_y + layer->height, offy + drawable_height (layer->fs.drawable));
x1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_x, offx);
y1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_y, offy);
x2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, offy + drawable_height (layer->fs.drawable));
x1 = BOUNDS (x, x1, x2);
y1 = BOUNDS (y, y1, y2);
@ -296,7 +300,7 @@ floating_sel_restore (Layer *layer,
{
/* Copy the area from the backing store to the drawable */
pixel_region_init (&srcPR, layer->fs.backing_store,
(x1 - layer->offset_x), (y1 - layer->offset_y), (x2 - x1), (y2 - y1), FALSE);
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_data (layer->fs.drawable),
(x1 - offx), (y1 - offy), (x2 - x1), (y2 - y1), TRUE);
@ -310,15 +314,15 @@ floating_sel_rigor (Layer *layer,
{
GImage *gimage;
if ((gimage = gimage_get_ID (layer->gimage_ID)) == NULL)
if ((gimage = gimage_get_ID (GIMP_DRAWABLE(layer)->gimage_ID)) == NULL)
return;
/* store the affected area from the drawable in the backing store */
floating_sel_store (layer, layer->offset_x, layer->offset_y, layer->width, layer->height);
floating_sel_store (layer, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
layer->fs.initial = TRUE;
if (undo)
undo_push_fs_rigor (gimage, layer->ID);
undo_push_fs_rigor (gimage, GIMP_DRAWABLE(layer)->ID);
}
void
@ -327,16 +331,16 @@ floating_sel_relax (Layer *layer,
{
GImage *gimage;
if ((gimage = gimage_get_ID (layer->gimage_ID)) == NULL)
if ((gimage = gimage_get_ID (GIMP_DRAWABLE(layer)->gimage_ID)) == NULL)
return;
/* restore the contents of drawable the floating layer is attached to */
if (layer->fs.initial == FALSE)
floating_sel_restore (layer, layer->offset_x, layer->offset_y, layer->width, layer->height);
floating_sel_restore (layer, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
layer->fs.initial = TRUE;
if (undo)
undo_push_fs_relax (gimage, layer->ID);
undo_push_fs_relax (gimage, GIMP_DRAWABLE(layer)->ID);
}
void
@ -358,7 +362,7 @@ floating_sel_composite (Layer *layer,
d_layer = NULL;
if (! (gimage = drawable_gimage (layer->ID)))
if (! (gimage = drawable_gimage (GIMP_DRAWABLE(layer))))
return;
/* What this function does is composite the specified area of the
@ -369,18 +373,18 @@ floating_sel_composite (Layer *layer,
/* If this isn't the first composite, restore the image underneath */
if (! layer->fs.initial)
floating_sel_restore (layer, x, y, w, h);
else if (layer->visible)
else if (GIMP_DRAWABLE(layer)->visible)
layer->fs.initial = FALSE;
/* First restore what's behind the image if necessary, then check for visibility */
if (layer->visible)
if (GIMP_DRAWABLE(layer)->visible)
{
/* Find the minimum area we need to composite -- in gimage space */
drawable_offsets (layer->fs.drawable, &offx, &offy);
x1 = MAXIMUM (layer->offset_x, offx);
y1 = MAXIMUM (layer->offset_y, offy);
x2 = MINIMUM (layer->offset_x + layer->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (layer->offset_y + layer->height, offy + drawable_height (layer->fs.drawable));
x1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_x, offx);
y1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_y, offy);
x2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, offy + drawable_height (layer->fs.drawable));
x1 = BOUNDS (x, x1, x2);
y1 = BOUNDS (y, y1, y2);
@ -390,8 +394,8 @@ floating_sel_composite (Layer *layer,
if ((x2 - x1) > 0 && (y2 - y1) > 0)
{
/* composite the area from the layer to the drawable */
pixel_region_init (&fsPR, layer->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
pixel_region_init (&fsPR, GIMP_DRAWABLE(layer)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
/* a kludge here to prevent the case of the drawable
@ -400,7 +404,7 @@ floating_sel_composite (Layer *layer,
*/
if (drawable_layer (layer->fs.drawable))
{
d_layer = layer_get_ID (layer->fs.drawable);
d_layer = GIMP_LAYER (layer->fs.drawable);
if ((preserve_trans = d_layer->preserve_trans))
d_layer->preserve_trans = FALSE;
}
@ -450,18 +454,18 @@ floating_sel_boundary (Layer *layer,
g_free (layer->fs.segs);
/* find the segments */
pixel_region_init (&bPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
layer->fs.segs = find_mask_boundary (&bPR, &layer->fs.num_segs,
WithinBounds, 0, 0,
layer->width, layer->height);
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* offset the segments */
for (i = 0; i < layer->fs.num_segs; i++)
{
layer->fs.segs[i].x1 += layer->offset_x;
layer->fs.segs[i].y1 += layer->offset_y;
layer->fs.segs[i].x2 += layer->offset_x;
layer->fs.segs[i].y2 += layer->offset_y;
layer->fs.segs[i].x1 += GIMP_DRAWABLE(layer)->offset_x;
layer->fs.segs[i].y1 += GIMP_DRAWABLE(layer)->offset_y;
layer->fs.segs[i].x2 += GIMP_DRAWABLE(layer)->offset_x;
layer->fs.segs[i].y2 += GIMP_DRAWABLE(layer)->offset_y;
}
layer->fs.boundary_known = TRUE;

View file

@ -22,7 +22,7 @@
/* Functions */
void floating_sel_attach (Layer *, int);
void floating_sel_attach (Layer *, GimpDrawable *);
void floating_sel_remove (Layer *);
void floating_sel_anchor (Layer *);
void floating_sel_reset (Layer *);

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,8 @@
#ifndef __LAYER_H__
#define __LAYER_H__
#include "drawable.h"
#include "boundary.h"
#include "channel.h"
#include "temp_buf.h"
@ -36,53 +38,24 @@ typedef enum
/* structure declarations */
typedef struct _Layer Layer;
#define GIMP_LAYER(obj) GTK_CHECK_CAST (obj, gimp_layer_get_type (), GimpLayer)
#define GIMP_LAYER_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_layer_get_type(), GimpLayerClass)
#define GIMP_IS_LAYER(obj) GTK_CHECK_TYPE (obj, gimp_layer_get_type())
struct _Layer
{
char * name; /* name of the layer */
#define GIMP_LAYER_MASK(obj) GTK_CHECK_CAST (obj, gimp_layer_mask_get_type (), GimpLayerMask)
#define GIMP_LAYER_MASK_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_layer_mask_get_type(), GimpLayerMaskClass)
#define GIMP_IS_LAYER_MASK(obj) GTK_CHECK_TYPE (obj, gimp_layer_mask_get_type())
TileManager * tiles; /* Tiles for layer data */
int visible; /* controls visibility */
int linked; /* control linkage */
int preserve_trans; /* preserve transparency? */
typedef struct _GimpLayer GimpLayer;
typedef struct _GimpLayerClass GimpLayerClass;
typedef struct _GimpLayerMask GimpLayerMask;
typedef struct _GimpLayerMaskClass GimpLayerMaskClass;
Channel * mask; /* possible layer mask */
int apply_mask; /* controls mask application */
int edit_mask; /* edit mask or layer? */
int show_mask; /* show mask or layer? */
int offset_x, offset_y; /* offset of layer in image */
int type; /* type of image */
int width, height; /* size of layer */
int bytes; /* bytes per pixel */
int opacity; /* layer opacity */
int mode; /* layer combination mode */
int dirty; /* dirty bit */
int ID; /* provides a unique ID */
int gimage_ID; /* ID of gimage owner */
/* Preview variables */
TempBuf *preview; /* preview of the channel */
int preview_valid; /* is the preview valid? */
/* Floating selections */
struct
{
TileManager *backing_store; /* for obscured regions */
int drawable; /* floating sel is attached to */
int initial; /* is fs composited yet? */
int boundary_known; /* is the current boundary valid*/
BoundSeg *segs; /* boundary of floating sel */
int num_segs; /* number of segs in boundary */
} fs;
};
typedef GimpLayer Layer; /* convenience */
typedef GimpLayerMask LayerMask; /* convenience */
guint gimp_layer_get_type (void);
guint gimp_layer_mask_get_type (void);
/* Special undo types */
@ -92,7 +65,7 @@ struct _layer_undo
{
Layer * layer; /* the actual layer */
int prev_position; /* former position in list */
int prev_layer; /* previous active layer */
Layer * prev_layer; /* previous active layer */
int undo_type; /* is this a new layer undo */
/* or a remove layer undo? */
};
@ -105,7 +78,7 @@ struct _layer_mask_undo
int apply_mask; /* apply mask? */
int edit_mask; /* edit mask or layer? */
int show_mask; /* show the mask? */
Channel *mask; /* the layer mask */
LayerMask *mask; /* the layer mask */
int mode; /* the application mode */
int undo_type; /* is this a new layer mask */
/* or a remove layer mask */
@ -116,23 +89,20 @@ typedef struct _fs_to_layer_undo FStoLayerUndo;
struct _fs_to_layer_undo
{
Layer * layer; /* the layer */
int drawable; /* drawable of floating sel */
GimpDrawable * drawable; /* drawable of floating sel */
};
/* function declarations */
void layer_allocate (Layer *, int, int, int);
void layer_deallocate (Layer *);
Layer * layer_new (int, int, int, int, char *, int, int);
Layer * layer_copy (Layer *, int);
Layer * layer_from_tiles (void *, int, TileManager *, char *, int, int);
Channel * layer_add_mask (Layer *, int);
Channel * layer_create_mask (Layer *, AddMaskType);
Layer * layer_from_tiles (void *, GimpDrawable *, TileManager *, char *, int, int);
LayerMask * layer_add_mask (Layer *, LayerMask *);
LayerMask * layer_create_mask (Layer *, AddMaskType);
Layer * layer_get_ID (int);
void layer_delete (Layer *);
void layer_apply_mask (Layer *, int);
void layer_translate (Layer *, int, int);
void layer_apply_image (Layer *, int, int, int, int, TileManager *, int);
void layer_add_alpha (Layer *);
void layer_scale (Layer *, int, int, int);
void layer_resize (Layer *, int, int, int, int);
@ -140,15 +110,31 @@ BoundSeg * layer_boundary (Layer *, int *);
void layer_invalidate_boundary (Layer *);
int layer_pick_correlate (Layer *, int, int);
LayerMask * layer_mask_new (int, int, int, char *,
int, unsigned char *);
LayerMask * layer_mask_copy (LayerMask *);
void layer_mask_delete (LayerMask *);
LayerMask * layer_mask_get_ID (int);
/* access functions */
unsigned char * layer_data (Layer *);
Channel * layer_mask (Layer *);
LayerMask * layer_mask (Layer *);
int layer_has_alpha (Layer *);
int layer_is_floating_sel (Layer *);
int layer_linked (Layer *);
TempBuf * layer_preview (Layer *, int, int);
TempBuf * layer_mask_preview (Layer *, int, int);
void layer_invalidate_previews (int);
/* from drawable.c */
Layer * drawable_layer (GimpDrawable *);
LayerMask * drawable_layer_mask (GimpDrawable *);
/* from channel.c */
void channel_layer_alpha (Channel *, Layer *);
void channel_layer_mask (Channel *, Layer *);
#endif /* __LAYER_H__ */

View file

@ -44,6 +44,7 @@
#include "undo.h"
#include "tools.h"
#include "layer_pvt.h" /* ick. */
#define OVERHEAD 25 /* in units of pixel area */
#define EPSILON 5
@ -778,23 +779,25 @@ gdisplay_mask_bounds (GDisplay *gdisp,
int *y2)
{
Layer *layer;
int off_x, off_y;
/* If there is a floating selection, handle things differently */
if ((layer = gimage_floating_sel (gdisp->gimage)))
{
drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
if (! channel_bounds (gimage_get_mask (gdisp->gimage), x1, y1, x2, y2))
{
*x1 = layer->offset_x;
*y1 = layer->offset_y;
*x2 = layer->offset_x + layer->width;
*y2 = layer->offset_y + layer->height;
*x1 = off_x;
*y1 = off_y;
*x2 = off_x + drawable_width (GIMP_DRAWABLE(layer));
*y2 = off_y + drawable_height (GIMP_DRAWABLE(layer));
}
else
{
*x1 = MINIMUM (layer->offset_x, *x1);
*y1 = MINIMUM (layer->offset_y, *y1);
*x2 = MAXIMUM (layer->offset_x + layer->width, *x2);
*y2 = MAXIMUM (layer->offset_y + layer->height, *y2);
*x1 = MINIMUM (off_x, *x1);
*y1 = MINIMUM (off_y, *y1);
*x2 = MAXIMUM (off_x + drawable_width (GIMP_DRAWABLE(layer)), *x2);
*y2 = MAXIMUM (off_y + drawable_height (GIMP_DRAWABLE(layer)), *y2);
}
}
else if (! channel_bounds (gimage_get_mask (gdisp->gimage), x1, y1, x2, y2))
@ -970,7 +973,7 @@ gdisplay_set_menu_sensitivity (GDisplay *gdisp)
gint aux;
gint lm;
gint lp;
gint drawable;
GimpDrawable *drawable;
gint base_type;
gint type;

View file

@ -563,6 +563,7 @@ crop_image (GImage *gimage,
link_ptr list;
int width, height;
int lx1, ly1, lx2, ly2;
int off_x, off_y;
width = x2 - x1;
height = y2 - y1;
@ -606,10 +607,12 @@ crop_image (GImage *gimage,
layer_translate (layer, -x1, -y1);
lx1 = BOUNDS (layer->offset_x, 0, gimage->width);
ly1 = BOUNDS (layer->offset_y, 0, gimage->height);
lx2 = BOUNDS ((layer->width + layer->offset_x), 0, gimage->width);
ly2 = BOUNDS ((layer->height + layer->offset_y), 0, gimage->height);
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
lx1 = BOUNDS (off_x, 0, gimage->width);
ly1 = BOUNDS (off_y, 0, gimage->height);
lx2 = BOUNDS ((drawable_width (GIMP_DRAWABLE (layer)) + off_x), 0, gimage->width);
ly2 = BOUNDS ((drawable_height (GIMP_DRAWABLE (layer)) + off_y), 0, gimage->height);
width = lx2 - lx1;
height = ly2 - ly1;
@ -617,10 +620,10 @@ crop_image (GImage *gimage,
if (width && height)
layer_resize (layer, width, height,
-(lx1 - layer->offset_x),
-(ly1 - layer->offset_y));
-(lx1 - off_x),
-(ly1 - off_y));
else
gimage_remove_layer (gimage, layer->ID);
gimage_remove_layer (gimage, layer);
}
/* Make sure the projection matches the gimage size */

View file

@ -81,7 +81,7 @@ struct _CurvesDialog
GtkWidget * graph;
GdkPixmap * pixmap;
int drawable_id;
GimpDrawable * drawable;
ImageMap image_map;
int color;
int channel;
@ -367,12 +367,12 @@ curves_initialize (void *gdisp_ptr)
curves_dialog->points[i][16][1] = 255;
}
curves_dialog->drawable_id = gimage_active_drawable (gdisp->gimage);
curves_dialog->color = drawable_color (curves_dialog->drawable_id);
curves_dialog->image_map = image_map_create (gdisp_ptr, curves_dialog->drawable_id);
curves_dialog->drawable = gimage_active_drawable (gdisp->gimage);
curves_dialog->color = drawable_color ( (curves_dialog->drawable));
curves_dialog->image_map = image_map_create (gdisp_ptr, curves_dialog->drawable);
/* check for alpha channel */
if (drawable_has_alpha (curves_dialog->drawable_id))
if (drawable_has_alpha ( (curves_dialog->drawable)))
gtk_widget_set_sensitive( channel_items[4].widget, TRUE);
else
gtk_widget_set_sensitive( channel_items[4].widget, FALSE);
@ -1326,15 +1326,13 @@ curves_spline_invoker (Argument *args)
int int_value;
CurvesDialog cd;
GImage *gimage;
int drawable_id;
int channel;
int num_cp;
unsigned char *control_pts;
int x1, y1, x2, y2;
int i, j;
void *pr;
drawable_id = -1;
GimpDrawable *drawable;
/* the gimage */
if (success)
@ -1347,9 +1345,8 @@ curves_spline_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* channel */
@ -1358,10 +1355,10 @@ curves_spline_invoker (Argument *args)
int_value = args[2].value.pdb_int;
if (success)
{
if (drawable_gray (drawable_id))
if (drawable_gray (drawable))
if (int_value != 0)
success = FALSE;
else if (drawable_color (drawable_id))
else if (drawable_color (drawable))
if (int_value < 0 || int_value > 3)
success = FALSE;
else
@ -1396,7 +1393,7 @@ curves_spline_invoker (Argument *args)
}
cd.channel = channel;
cd.color = drawable_color (drawable_id);
cd.color = drawable_color (drawable);
cd.curve_type = SMOOTH;
for (j = 0; j < num_cp / 2; j++)
@ -1407,16 +1404,16 @@ curves_spline_invoker (Argument *args)
curves_calculate_curve (&cd);
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
curves (&srcPR, &destPR, (void *) &cd);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&curves_spline_proc, success);
@ -1478,14 +1475,12 @@ curves_explicit_invoker (Argument *args)
int int_value;
CurvesDialog cd;
GImage *gimage;
int drawable_id;
int channel;
unsigned char *curve;
int x1, y1, x2, y2;
int i, j;
void *pr;
drawable_id = -1;
GimpDrawable *drawable;
/* the gimage */
if (success)
@ -1498,9 +1493,8 @@ curves_explicit_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* channel */
@ -1509,10 +1503,10 @@ curves_explicit_invoker (Argument *args)
int_value = args[2].value.pdb_int;
if (success)
{
if (drawable_gray (drawable_id))
if (drawable_gray (drawable))
if (int_value != 0)
success = FALSE;
else if (drawable_color (drawable_id))
else if (drawable_color (drawable))
if (int_value < 0 || int_value > 3)
success = FALSE;
else
@ -1541,22 +1535,22 @@ curves_explicit_invoker (Argument *args)
cd.curve[i][j] = j;
cd.channel = channel;
cd.color = drawable_color (drawable_id);
cd.color = drawable_color (drawable);
for (j = 0; j < 256; j++)
cd.curve[cd.channel][j] = curve[j];
/* The application should occur only within selection bounds */
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
curves (&srcPR, &destPR, (void *) &cd);
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
return procedural_db_return_args (&curves_explicit_proc, success);

View file

@ -23,8 +23,9 @@
#include "desaturate.h"
#include "interface.h"
#include "paint_funcs.h"
#include "gimage.h"
static void desaturate (int);
static void desaturate (GimpDrawable *);
static Argument * desaturate_invoker (Argument *);
@ -33,25 +34,24 @@ image_desaturate (gimage_ptr)
void *gimage_ptr;
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
if (! drawable_color (drawable_id))
if (! drawable_color (drawable))
{
message_box ("Desaturate operates only on RGB color drawables.", NULL, NULL);
return;
}
desaturate (drawable_id);
desaturate (drawable);
}
/* Desaturateer */
static void
desaturate (drawable_id)
int drawable_id;
desaturate (GimpDrawable *drawable)
{
PixelRegion srcPR, destPR;
unsigned char *src, *s;
@ -62,10 +62,13 @@ desaturate (drawable_id)
void *pr;
int x1, y1, x2, y2;
has_alpha = drawable_has_alpha (drawable_id);
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
if (!drawable)
return;
has_alpha = drawable_has_alpha (drawable);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -103,8 +106,8 @@ desaturate (drawable_id)
}
}
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
@ -151,9 +154,9 @@ desaturate_invoker (args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
/* the gimage */
if (success)
@ -166,18 +169,17 @@ desaturate_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* check to make sure the drawable is color */
if (success)
success = drawable_color (drawable_id);
success = drawable_color (drawable);
if (success)
desaturate (drawable_id);
desaturate (drawable);
return procedural_db_return_args (&desaturate_proc, success);
}

View file

@ -44,6 +44,7 @@
#include "undo.h"
#include "tools.h"
#include "layer_pvt.h" /* ick. */
#define OVERHEAD 25 /* in units of pixel area */
#define EPSILON 5
@ -778,23 +779,25 @@ gdisplay_mask_bounds (GDisplay *gdisp,
int *y2)
{
Layer *layer;
int off_x, off_y;
/* If there is a floating selection, handle things differently */
if ((layer = gimage_floating_sel (gdisp->gimage)))
{
drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
if (! channel_bounds (gimage_get_mask (gdisp->gimage), x1, y1, x2, y2))
{
*x1 = layer->offset_x;
*y1 = layer->offset_y;
*x2 = layer->offset_x + layer->width;
*y2 = layer->offset_y + layer->height;
*x1 = off_x;
*y1 = off_y;
*x2 = off_x + drawable_width (GIMP_DRAWABLE(layer));
*y2 = off_y + drawable_height (GIMP_DRAWABLE(layer));
}
else
{
*x1 = MINIMUM (layer->offset_x, *x1);
*y1 = MINIMUM (layer->offset_y, *y1);
*x2 = MAXIMUM (layer->offset_x + layer->width, *x2);
*y2 = MAXIMUM (layer->offset_y + layer->height, *y2);
*x1 = MINIMUM (off_x, *x1);
*y1 = MINIMUM (off_y, *y1);
*x2 = MAXIMUM (off_x + drawable_width (GIMP_DRAWABLE(layer)), *x2);
*y2 = MAXIMUM (off_y + drawable_height (GIMP_DRAWABLE(layer)), *y2);
}
}
else if (! channel_bounds (gimage_get_mask (gdisp->gimage), x1, y1, x2, y2))
@ -970,7 +973,7 @@ gdisplay_set_menu_sensitivity (GDisplay *gdisp)
gint aux;
gint lm;
gint lp;
gint drawable;
GimpDrawable *drawable;
gint base_type;
gint type;

View file

@ -39,7 +39,7 @@ struct _LayerSelect {
GtkWidget *preview;
GImage *gimage;
int current_layer;
Layer *current_layer;
int dirty;
int image_width, image_height;
double ratio;
@ -193,7 +193,7 @@ layer_select_advance (LayerSelect *layer_select,
while (list)
{
layer = (Layer *) list->data;
if (layer->ID == layer_select->current_layer)
if (layer == layer_select->current_layer)
index = count;
count++;
list = next_item (list);
@ -211,7 +211,7 @@ layer_select_advance (LayerSelect *layer_select,
if (nth)
{
layer = (Layer *) nth->data;
layer_select->current_layer = layer->ID;
layer_select->current_layer = layer;
}
}
@ -296,11 +296,11 @@ layer_select_set_layer (LayerSelect *layer_select)
{
Layer *layer;
if (! (layer = layer_get_ID (layer_select->current_layer)))
if (! (layer = (layer_select->current_layer)))
return;
/* Set the layer label */
gtk_label_set (GTK_LABEL (layer_select->label), layer->name);
gtk_label_set (GTK_LABEL (layer_select->label), drawable_name (GIMP_DRAWABLE(layer)));
}
@ -404,7 +404,7 @@ preview_redraw (LayerSelect *layer_select)
int w, h;
int offx, offy;
if (! (layer = layer_get_ID (layer_select->current_layer)))
if (! (layer = (layer_select->current_layer)))
return;
if (! layer_select->layer_pixmap)
@ -417,11 +417,13 @@ preview_redraw (LayerSelect *layer_select)
render_fs_preview (layer_select->layer_preview, layer_select->layer_pixmap);
else
{
int off_x, off_y;
drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
/* determine width and height */
w = (int) (layer_select->ratio * layer->width);
h = (int) (layer_select->ratio * layer->height);
offx = (int) (layer_select->ratio * layer->offset_x);
offy = (int) (layer_select->ratio * layer->offset_y);
w = (int) (layer_select->ratio * drawable_width (GIMP_DRAWABLE(layer)));
h = (int) (layer_select->ratio * drawable_height (GIMP_DRAWABLE(layer)));
offx = (int) (layer_select->ratio * off_x);
offy = (int) (layer_select->ratio * off_y);
preview_buf = layer_preview (layer, w, h);
preview_buf->x = offx;

View file

@ -28,71 +28,159 @@
#include "gimage_mask.h"
#include "gdisplay.h"
#include "layer.h"
#include "linked.h"
#include "palette.h"
#include "undo.h"
#include "drawable_pvt.h"
enum {
INVALIDATE_PREVIEW,
LAST_SIGNAL
};
static void gimp_drawable_class_init (GimpDrawableClass *klass);
static void gimp_drawable_init (GimpDrawable *drawable);
static void gimp_drawable_destroy (GtkObject *object);
static gint drawable_signals[LAST_SIGNAL] = { 0 };
static GimpDrawableClass *parent_class = NULL;
guint
gimp_drawable_get_type ()
{
static guint drawable_type = 0;
if (!drawable_type)
{
GtkTypeInfo drawable_info =
{
"GimpDrawable",
sizeof (GimpDrawable),
sizeof (GimpDrawableClass),
(GtkClassInitFunc) gimp_drawable_class_init,
(GtkObjectInitFunc) gimp_drawable_init,
(GtkArgFunc) NULL,
};
drawable_type = gtk_type_unique (gtk_data_get_type (), &drawable_info);
}
return drawable_type;
}
static void
gimp_drawable_class_init (GimpDrawableClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gtk_data_get_type ());
drawable_signals[INVALIDATE_PREVIEW] =
gtk_signal_new ("invalidate_preview",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GimpDrawableClass, invalidate_preview),
gtk_signal_default_marshaller,
GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, drawable_signals, LAST_SIGNAL);
object_class->destroy = gimp_drawable_destroy;
}
/*
* Static variables
*/
int global_drawable_ID = 1;
static GHashTable *drawable_table = NULL;
/**************************/
/* Function definitions */
void
drawable_apply_image (drawable_id, x1, y1, x2, y2, tiles, sparse)
int drawable_id;
int x1, y1;
int x2, y2;
TileManager *tiles;
int sparse;
static guint
drawable_hash (gpointer v)
{
Channel *channel;
Layer *layer;
return (guint) v;
}
if ((channel = channel_get_ID (drawable_id)))
channel_apply_image (channel, x1, y1, x2, y2, tiles, sparse);
else if ((layer = layer_get_ID (drawable_id)))
layer_apply_image (layer, x1, y1, x2, y2, tiles, sparse);
static gint
drawable_hash_compare (gpointer v1, gpointer v2)
{
return ((guint) v1) == ((guint) v2);
}
GimpDrawable*
drawable_get_ID (int drawable_id)
{
if (drawable_table == NULL)
return NULL;
return (GimpDrawable*) g_hash_table_lookup (drawable_table,
(gpointer) drawable_id);
}
int
drawable_ID (GimpDrawable *drawable)
{
return drawable->ID;
}
void
drawable_apply_image (GimpDrawable *drawable,
int x1, int y1, int x2, int y2,
TileManager *tiles, int sparse)
{
if (drawable)
if (! tiles)
undo_push_image (gimage_get_ID (drawable->gimage_ID), drawable, x1, y1, x2, y2);
else
undo_push_image_mod (gimage_get_ID (drawable->gimage_ID), drawable, x1, y1, x2, y2, tiles, sparse);
}
void
drawable_merge_shadow (drawable_id, undo)
int drawable_id;
int undo;
drawable_merge_shadow (GimpDrawable *drawable, int undo)
{
GImage *gimage;
PixelRegion shadowPR;
int x1, y1, x2, y2;
if (! (gimage = drawable_gimage (drawable_id)))
if (! drawable)
return;
if (! (gimage = drawable_gimage (drawable)))
return;
/* A useful optimization here is to limit the update to the
* extents of the selection mask, as it cannot extend beyond
* them.
*/
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&shadowPR, gimage->shadow, x1, y1,
(x2 - x1), (y2 - y1), FALSE);
gimage_apply_image (gimage, drawable_id, &shadowPR, undo, OPAQUE,
gimage_apply_image (gimage, drawable, &shadowPR, undo, OPAQUE,
REPLACE_MODE, NULL, x1, y1);
}
void
drawable_fill (drawable_id, fill_type)
int drawable_id;
int fill_type;
drawable_fill (GimpDrawable *drawable, int fill_type)
{
GImage *gimage;
PixelRegion destPR;
unsigned char c[MAX_CHANNELS];
unsigned char i, r, g, b, a;
if (! (gimage = drawable_gimage (drawable_id)))
if (! drawable)
return;
if (! (gimage = drawable_gimage (drawable)))
return;
a = 255;
@ -115,27 +203,27 @@ drawable_fill (drawable_id, fill_type)
break;
}
switch (drawable_type (drawable_id))
switch (drawable_type (drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
c[RED_PIX] = r;
c[GREEN_PIX] = g;
c[BLUE_PIX] = b;
if (drawable_type (drawable_id) == RGBA_GIMAGE)
if (drawable_type (drawable) == RGBA_GIMAGE)
c[ALPHA_PIX] = a;
break;
case GRAY_GIMAGE: case GRAYA_GIMAGE:
c[GRAY_PIX] = r;
if (drawable_type (drawable_id) == GRAYA_GIMAGE)
if (drawable_type (drawable) == GRAYA_GIMAGE)
c[ALPHA_G_PIX] = a;
break;
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
c[RED_PIX] = r;
c[GREEN_PIX] = g;
c[BLUE_PIX] = b;
gimage_transform_color (gimage, drawable_id, c, &i, RGB);
gimage_transform_color (gimage, drawable, c, &i, RGB);
c[INDEXED_PIX] = i;
if (drawable_type (drawable_id) == INDEXEDA_GIMAGE)
if (drawable_type (drawable) == INDEXEDA_GIMAGE)
c[ALPHA_I_PIX] = a;
break;
default:
@ -144,91 +232,86 @@ drawable_fill (drawable_id, fill_type)
}
pixel_region_init (&destPR,
drawable_data (drawable_id),
drawable_data (drawable),
0, 0,
drawable_width (drawable_id),
drawable_height (drawable_id),
drawable_width (drawable),
drawable_height (drawable),
TRUE);
color_region (&destPR, c);
/* Update the filled area */
drawable_update (drawable_id, 0, 0,
drawable_width (drawable_id),
drawable_height (drawable_id));
drawable_update (drawable, 0, 0,
drawable_width (drawable),
drawable_height (drawable));
}
void
drawable_update (drawable_id, x, y, w, h)
int drawable_id;
int x, y;
int w, h;
drawable_update (GimpDrawable *drawable, int x, int y, int w, int h)
{
GImage *gimage;
int offset_x, offset_y;
if (! (gimage = drawable_gimage (drawable_id)))
if (! drawable)
return;
drawable_offsets (drawable_id, &offset_x, &offset_y);
if (! (gimage = drawable_gimage (drawable)))
return;
drawable_offsets (drawable, &offset_x, &offset_y);
x += offset_x;
y += offset_y;
gdisplays_update_area (gimage->ID, x, y, w, h);
/* invalidate the preview */
drawable_invalidate_preview (drawable_id);
drawable_invalidate_preview (drawable);
}
int
drawable_mask_bounds (drawable_id, x1, y1, x2, y2)
int drawable_id;
int *x1, *y1;
int *x2, *y2;
drawable_mask_bounds (GimpDrawable *drawable,
int *x1, int *y1, int *x2, int *y2)
{
GImage *gimage;
int off_x, off_y;
if (! (gimage = drawable_gimage (drawable_id)))
if (! drawable)
return FALSE;
if (! (gimage = drawable_gimage (drawable)))
return FALSE;
if (gimage_mask_bounds (gimage, x1, y1, x2, y2))
{
drawable_offsets (drawable_id, &off_x, &off_y);
*x1 = BOUNDS (*x1 - off_x, 0, drawable_width (drawable_id));
*y1 = BOUNDS (*y1 - off_y, 0, drawable_height (drawable_id));
*x2 = BOUNDS (*x2 - off_x, 0, drawable_width (drawable_id));
*y2 = BOUNDS (*y2 - off_y, 0, drawable_height (drawable_id));
drawable_offsets (drawable, &off_x, &off_y);
*x1 = BOUNDS (*x1 - off_x, 0, drawable_width (drawable));
*y1 = BOUNDS (*y1 - off_y, 0, drawable_height (drawable));
*x2 = BOUNDS (*x2 - off_x, 0, drawable_width (drawable));
*y2 = BOUNDS (*y2 - off_y, 0, drawable_height (drawable));
return TRUE;
}
else
{
*x2 = drawable_width (drawable_id);
*y2 = drawable_height (drawable_id);
*x2 = drawable_width (drawable);
*y2 = drawable_height (drawable);
return FALSE;
}
}
void
drawable_invalidate_preview (drawable_id)
int drawable_id;
drawable_invalidate_preview (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
GImage *gimage;
if ((channel = channel_get_ID (drawable_id)))
channel->preview_valid = FALSE;
else if ((layer = layer_get_ID (drawable_id)))
{
if (layer_is_floating_sel (layer))
floating_sel_invalidate (layer);
else
layer->preview_valid = FALSE;
}
if (! drawable)
return;
gimage = drawable_gimage (drawable_id);
drawable->preview_valid = FALSE;
gtk_signal_emit (GTK_OBJECT(drawable), drawable_signals[INVALIDATE_PREVIEW]);
gimage = drawable_gimage (drawable);
if (gimage)
{
gimage->comp_preview_valid[0] = FALSE;
@ -239,85 +322,71 @@ drawable_invalidate_preview (drawable_id)
int
drawable_dirty (int drawable_id)
drawable_dirty (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return channel->dirty = (channel->dirty < 0) ? 2 : channel->dirty + 1;
else if ((layer = layer_get_ID (drawable_id)))
return layer->dirty = (layer->dirty < 0) ? 2 : layer->dirty + 1;
if (drawable)
return drawable->dirty = (drawable->dirty < 0) ? 2 : drawable->dirty + 1;
else
return 0;
}
int
drawable_clean (int drawable_id)
drawable_clean (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return channel->dirty = (channel->dirty <= 0) ? 0 : channel->dirty - 1;
else if ((layer = layer_get_ID (drawable_id)))
return layer->dirty = (layer->dirty <= 0) ? 0 : layer->dirty - 1;
if (drawable)
return drawable->dirty = (drawable->dirty <= 0) ? 0 : drawable->dirty - 1;
else
return 0;
}
GImage *
drawable_gimage (int drawable_id)
drawable_gimage (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return gimage_get_ID (channel->gimage_ID);
else if ((layer = layer_get_ID (drawable_id)))
return gimage_get_ID (layer->gimage_ID);
if (drawable)
return gimage_get_ID (drawable->gimage_ID);
else
return NULL;
}
int
drawable_type (int drawable_id)
drawable_type (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return GRAY_GIMAGE;
else if ((layer = layer_get_ID (drawable_id)))
return layer->type;
if (drawable)
return drawable->type;
else
return -1;
}
int
drawable_has_alpha (int drawable_id)
drawable_has_alpha (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return FALSE;
else if ((layer = layer_get_ID (drawable_id)))
return layer_has_alpha (layer);
if (drawable)
return drawable->has_alpha;
else
return FALSE;
}
int
drawable_type_with_alpha (int drawable_id)
int
drawable_visible (GimpDrawable *drawable)
{
int type = drawable_type (drawable_id);
int has_alpha = drawable_has_alpha (drawable_id);
return drawable->visible;
}
char *
drawable_name (GimpDrawable *drawable)
{
return drawable->name;
}
int
drawable_type_with_alpha (GimpDrawable *drawable)
{
int type = drawable_type (drawable);
int has_alpha = drawable_has_alpha (drawable);
if (has_alpha)
return type;
@ -336,11 +405,10 @@ drawable_type_with_alpha (int drawable_id)
int
drawable_color (drawable_id)
int drawable_id;
drawable_color (GimpDrawable *drawable)
{
if (drawable_type (drawable_id) == RGBA_GIMAGE ||
drawable_type (drawable_id) == RGB_GIMAGE)
if (drawable_type (drawable) == RGBA_GIMAGE ||
drawable_type (drawable) == RGB_GIMAGE)
return 1;
else
return 0;
@ -348,11 +416,10 @@ drawable_color (drawable_id)
int
drawable_gray (drawable_id)
int drawable_id;
drawable_gray (GimpDrawable *drawable)
{
if (drawable_type (drawable_id) == GRAYA_GIMAGE ||
drawable_type (drawable_id) == GRAY_GIMAGE)
if (drawable_type (drawable) == GRAYA_GIMAGE ||
drawable_type (drawable) == GRAY_GIMAGE)
return 1;
else
return 0;
@ -360,11 +427,10 @@ drawable_gray (drawable_id)
int
drawable_indexed (drawable_id)
int drawable_id;
drawable_indexed (GimpDrawable *drawable)
{
if (drawable_type (drawable_id) == INDEXEDA_GIMAGE ||
drawable_type (drawable_id) == INDEXED_GIMAGE)
if (drawable_type (drawable) == INDEXEDA_GIMAGE ||
drawable_type (drawable) == INDEXED_GIMAGE)
return 1;
else
return 0;
@ -372,128 +438,79 @@ drawable_indexed (drawable_id)
TileManager *
drawable_data (int drawable_id)
drawable_data (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return channel->tiles;
else if ((layer = layer_get_ID (drawable_id)))
return layer->tiles;
if (drawable)
return drawable->tiles;
else
return NULL;
}
TileManager *
drawable_shadow (int drawable_id)
drawable_shadow (GimpDrawable *drawable)
{
GImage *gimage;
Channel *channel;
Layer *layer;
if (! (gimage = drawable_gimage (drawable_id)))
if (! (gimage = drawable_gimage (drawable)))
return NULL;
if ((channel = channel_get_ID (drawable_id)))
{
return gimage_shadow (gimage, channel->width, channel->height, 1);
}
else if ((layer = layer_get_ID (drawable_id)))
{
return gimage_shadow (gimage, layer->width, layer->height, layer->bytes);
}
if (drawable)
return gimage_shadow (gimage, drawable->width, drawable->height,
drawable->bytes);
else
return NULL;
}
int
drawable_bytes (int drawable_id)
drawable_bytes (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return channel->bytes;
else if ((layer = layer_get_ID (drawable_id)))
return layer->bytes;
if (drawable)
return drawable->bytes;
else
return -1;
}
int
drawable_width (int drawable_id)
drawable_width (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return channel->width;
else if ((layer = layer_get_ID (drawable_id)))
return layer->width;
if (drawable)
return drawable->width;
else
return -1;
}
int
drawable_height (int drawable_id)
drawable_height (GimpDrawable *drawable)
{
Channel *channel;
Layer *layer;
if ((channel = channel_get_ID (drawable_id)))
return channel->height;
else if ((layer = layer_get_ID (drawable_id)))
return layer->height;
if (drawable)
return drawable->height;
else
return -1;
}
void
drawable_offsets (drawable_id, off_x, off_y)
int drawable_id;
int *off_x;
int *off_y;
drawable_offsets (GimpDrawable *drawable, int *off_x, int *off_y)
{
Channel *channel;
Layer *layer;
/* return the active layer offsets */
if ((layer = layer_get_ID (drawable_id)))
if (drawable)
{
*off_x = layer->offset_x;
*off_y = layer->offset_y;
return;
*off_x = drawable->offset_x;
*off_y = drawable->offset_y;
}
/* The case of a layer mask */
else if ((channel = channel_get_ID (drawable_id)))
{
if (channel->layer_ID != -1)
if ((layer = layer_get_ID (channel->layer_ID)))
{
*off_x = layer->offset_x;
*off_y = layer->offset_y;
return;
}
}
*off_x = 0;
*off_y = 0;
else
*off_x = *off_y = 0;
}
unsigned char *
drawable_cmap (drawable_id)
int drawable_id;
drawable_cmap (GimpDrawable *drawable)
{
GImage *gimage;
if ((gimage = drawable_gimage (drawable_id)))
if ((gimage = drawable_gimage (drawable)))
return gimage->cmap;
else
return NULL;
@ -501,40 +518,140 @@ drawable_cmap (drawable_id)
Layer *
drawable_layer (drawable_id)
int drawable_id;
drawable_layer (GimpDrawable *drawable)
{
Layer *layer;
if ((layer = layer_get_ID (drawable_id)))
if (!layer->mask || (layer->mask && !layer->edit_mask))
return layer;
return NULL;
}
Channel *
drawable_layer_mask (drawable_id)
int drawable_id;
{
Channel *channel;
if ((channel = channel_get_ID (drawable_id)))
if (channel->layer_ID != -1)
return channel;
return NULL;
}
Channel *
drawable_channel (drawable_id)
int drawable_id;
{
Channel *channel;
if ((channel = channel_get_ID (drawable_id)))
return channel;
if (drawable && GIMP_IS_LAYER(drawable))
return GIMP_LAYER (drawable);
else
return NULL;
}
LayerMask *
drawable_layer_mask (GimpDrawable *drawable)
{
if (drawable && GIMP_IS_LAYER_MASK(drawable))
return GIMP_LAYER_MASK(drawable);
else
return NULL;
}
Channel *
drawable_channel (GimpDrawable *drawable)
{
if (drawable && GIMP_IS_CHANNEL(drawable))
return GIMP_CHANNEL(drawable);
else
return NULL;
}
void
drawable_deallocate (GimpDrawable *drawable)
{
if (drawable->tiles)
tile_manager_destroy (drawable->tiles);
}
static void
gimp_drawable_init (GimpDrawable *drawable)
{
drawable->name = NULL;
drawable->tiles = NULL;
drawable->visible = FALSE;
drawable->width = drawable->height = 0;
drawable->offset_x = drawable->offset_y = 0;
drawable->bytes = 0;
drawable->dirty = FALSE;
drawable->gimage_ID = -1;
drawable->type = -1;
drawable->has_alpha = FALSE;
drawable->preview = NULL;
drawable->preview_valid = FALSE;
drawable->ID = global_drawable_ID++;
if (drawable_table == NULL)
drawable_table = g_hash_table_new (drawable_hash,
drawable_hash_compare);
g_hash_table_insert (drawable_table, (gpointer) drawable->ID,
(gpointer) drawable);
}
static void
gimp_drawable_destroy (GtkObject *object)
{
GimpDrawable *drawable;
g_return_if_fail (object != NULL);
g_return_if_fail (GIMP_IS_DRAWABLE (object));
drawable = GIMP_DRAWABLE (object);
g_hash_table_remove (drawable_table, (gpointer) drawable->ID);
if (drawable->name)
g_free (drawable->name);
if (drawable->tiles)
tile_manager_destroy (drawable->tiles);
if (drawable->preview)
temp_buf_free (drawable->preview);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
void
gimp_drawable_configure (GimpDrawable *drawable,
int gimage_ID, int width, int height,
int type, char *name)
{
int bpp;
int alpha;
if (!name)
name = "unnamed";
switch (type)
{
case RGB_GIMAGE:
bpp = 3; alpha = 0; break;
case GRAY_GIMAGE:
bpp = 1; alpha = 0; break;
case RGBA_GIMAGE:
bpp = 4; alpha = 1; break;
case GRAYA_GIMAGE:
bpp = 2; alpha = 1; break;
case INDEXED_GIMAGE:
bpp = 1; alpha = 0; break;
case INDEXEDA_GIMAGE:
bpp = 2; alpha = 1; break;
default:
warning ("Layer type %d not supported.", type);
return;
}
if (drawable->name)
g_free (drawable->name);
drawable->name = g_strdup(name);
drawable->width = width;
drawable->height = height;
drawable->bytes = bpp;
drawable->type = type;
drawable->has_alpha = alpha;
drawable->offset_x = 0;
drawable->offset_y = 0;
if (drawable->tiles)
tile_manager_destroy (drawable->tiles);
drawable->tiles = tile_manager_new (width, height, bpp);
drawable->dirty = FALSE;
drawable->visible = TRUE;
drawable->gimage_ID = gimage_ID;
/* preview variables */
drawable->preview = NULL;
drawable->preview_valid = FALSE;
}

View file

@ -18,33 +18,52 @@
#ifndef __DRAWABLE_H__
#define __DRAWABLE_H__
#include "gimage.h"
#include <gtk/gtkdata.h>
#include "tile_manager.h"
#include "temp_buf.h"
/* Drawable access functions */
void drawable_apply_image (int, int, int, int, int, TileManager *, int);
void drawable_merge_shadow (int, int);
void drawable_fill (int, int);
void drawable_update (int, int, int, int, int);
int drawable_mask_bounds (int, int *, int *, int *, int *);
void drawable_invalidate_preview (int);
int drawable_dirty (int);
int drawable_clean (int);
GImage * drawable_gimage (int);
int drawable_type (int);
int drawable_has_alpha (int);
int drawable_type_with_alpha (int);
int drawable_color (int);
int drawable_gray (int);
int drawable_indexed (int);
TileManager * drawable_data (int);
TileManager * drawable_shadow (int);
int drawable_bytes (int);
int drawable_width (int);
int drawable_height (int);
void drawable_offsets (int, int *, int *);
unsigned char * drawable_cmap (int);
Layer * drawable_layer (int);
Channel * drawable_layer_mask (int);
Channel * drawable_channel (int);
#define GIMP_DRAWABLE(obj) GTK_CHECK_CAST (obj, gimp_drawable_get_type (), GimpDrawable)
#define GIMP_DRAWABLE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_drawable_get_type(), GimpDrawableClass)
#define GIMP_IS_DRAWABLE(obj) GTK_CHECK_TYPE (obj, gimp_drawable_get_type())
typedef struct _GimpDrawable GimpDrawable;
typedef struct _GimpDrawableClass GimpDrawableClass;
guint gimp_drawable_get_type (void);
/* drawable access functions */
int drawable_ID (GimpDrawable *);
void drawable_apply_image (GimpDrawable *,
int, int, int, int,
TileManager *, int);
void drawable_merge_shadow (GimpDrawable *, int);
void drawable_fill (GimpDrawable *, int);
void drawable_update (GimpDrawable *,
int, int, int, int);
int drawable_mask_bounds (GimpDrawable *,
int *, int *, int *, int *);
void drawable_invalidate_preview (GimpDrawable *);
int drawable_dirty (GimpDrawable *);
int drawable_clean (GimpDrawable *);
int drawable_type (GimpDrawable *);
int drawable_has_alpha (GimpDrawable *);
int drawable_type_with_alpha (GimpDrawable *);
int drawable_color (GimpDrawable *);
int drawable_gray (GimpDrawable *);
int drawable_indexed (GimpDrawable *);
TileManager * drawable_data (GimpDrawable *);
TileManager * drawable_shadow (GimpDrawable *);
int drawable_bytes (GimpDrawable *);
int drawable_width (GimpDrawable *);
int drawable_height (GimpDrawable *);
int drawable_visible (GimpDrawable *);
void drawable_offsets (GimpDrawable *, int *, int *);
unsigned char * drawable_cmap (GimpDrawable *);
char * drawable_name (GimpDrawable *);
GimpDrawable * drawable_get_ID (int);
void drawable_deallocate (GimpDrawable *);
void gimp_drawable_configure (GimpDrawable *,
int, int, int, int, char *);
#endif /* __DRAWABLE_H__ */

View file

@ -33,17 +33,18 @@ static int success;
static Argument *
drawable_merge_shadow_invoker (Argument *args)
{
int drawable_id;
GimpDrawable *drawable;
int undo;
success = TRUE;
if (success)
drawable_id = args[0].value.pdb_int;
if ((drawable = drawable_get_ID (args[0].value.pdb_int)) == NULL)
success = FALSE;
if (success)
undo = (args[1].value.pdb_int) ? TRUE : FALSE;
if (success)
drawable_merge_shadow (drawable_id, undo);
drawable_merge_shadow (drawable, undo);
return procedural_db_return_args (&drawable_merge_shadow_proc, success);
}
@ -90,14 +91,14 @@ ProcRecord drawable_merge_shadow_proc =
static Argument *
drawable_fill_invoker (Argument *args)
{
int drawable_id;
GimpDrawable *drawable;
int fill_type;
fill_type = WHITE_FILL;
success = TRUE;
if (success)
drawable_id = args[0].value.pdb_int;
drawable = drawable_get_ID (args[0].value.pdb_int);
if (success)
{
int_value = args[1].value.pdb_int;
@ -113,7 +114,7 @@ drawable_fill_invoker (Argument *args)
}
if (success)
drawable_fill (drawable_id, fill_type);
drawable_fill (drawable, fill_type);
return procedural_db_return_args (&drawable_fill_proc, success);
}
@ -175,7 +176,7 @@ drawable_update_invoker (Argument *args)
}
if (success)
drawable_update (drawable_id, x, y, w, h);
drawable_update (drawable_get_ID (drawable_id), x, y, w, h);
return procedural_db_return_args (&drawable_update_proc, success);
}
@ -244,7 +245,7 @@ drawable_mask_bounds_invoker (Argument *args)
drawable_id = args[0].value.pdb_int;
if (success)
non_empty = drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
non_empty = drawable_mask_bounds (drawable_get_ID (drawable_id), &x1, &y1, &x2, &y2);
return_args = procedural_db_return_args (&drawable_mask_bounds_proc, success);
@ -330,7 +331,7 @@ drawable_gimage_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
success = ((gimage = drawable_gimage (drawable_id)) != NULL);
success = ((gimage = drawable_gimage (drawable_get_ID (drawable_id))) != NULL);
return_args = procedural_db_return_args (&drawable_gimage_proc, success);
@ -386,15 +387,17 @@ ProcRecord drawable_gimage_proc =
static Argument *
drawable_type_invoker (Argument *args)
{
int drawable_id;
int type;
GimpDrawable *drawable;
int type = -1;
Argument *return_args;
success = TRUE;
if ((drawable = drawable_get_ID (args[0].value.pdb_int)) == NULL)
success = FALSE;
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
type = drawable_type (drawable_id);
type = drawable_type (drawable);
return_args = procedural_db_return_args (&drawable_type_proc, success);
@ -458,7 +461,7 @@ drawable_has_alpha_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
has_alpha = drawable_has_alpha (drawable_id);
has_alpha = drawable_has_alpha (drawable_get_ID (drawable_id));
return_args = procedural_db_return_args (&drawable_has_alpha_proc, success);
@ -514,15 +517,15 @@ ProcRecord drawable_has_alpha_proc =
static Argument *
drawable_type_with_alpha_invoker (Argument *args)
{
int drawable_id;
int type_with_alpha;
GimpDrawable *drawable;
int type_with_alpha = -1;
Argument *return_args;
success = TRUE;
if ((drawable = drawable_get_ID (args[0].value.pdb_int)) == NULL)
success = FALSE;
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
type_with_alpha = drawable_type_with_alpha (drawable_id);
type_with_alpha = drawable_type_with_alpha (drawable);
return_args = procedural_db_return_args (&drawable_type_with_alpha_proc, success);
@ -586,7 +589,7 @@ drawable_color_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
color = drawable_color (drawable_id);
color = drawable_color (drawable_get_ID (drawable_id));
return_args = procedural_db_return_args (&drawable_color_proc, success);
@ -650,7 +653,7 @@ drawable_gray_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
gray = drawable_gray (drawable_id);
gray = drawable_gray (drawable_get_ID (drawable_id));
return_args = procedural_db_return_args (&drawable_gray_proc, success);
@ -714,7 +717,7 @@ drawable_indexed_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
indexed = drawable_indexed (drawable_id);
indexed = drawable_indexed (drawable_get_ID (drawable_id));
return_args = procedural_db_return_args (&drawable_indexed_proc, success);
@ -777,7 +780,7 @@ drawable_bytes_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
bytes = drawable_bytes (drawable_id);
bytes = drawable_bytes (drawable_get_ID (drawable_id));
return_args = procedural_db_return_args (&drawable_bytes_proc, success);
@ -841,7 +844,7 @@ drawable_width_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
width = drawable_width (drawable_id);
width = drawable_width (drawable_get_ID (drawable_id));
return_args = procedural_db_return_args (&drawable_width_proc, success);
@ -904,7 +907,7 @@ drawable_height_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
height = drawable_height (drawable_id);
height = drawable_height (drawable_get_ID (drawable_id));
return_args = procedural_db_return_args (&drawable_height_proc, success);
@ -969,7 +972,7 @@ drawable_offsets_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
drawable_offsets (drawable_id, &offset_x, &offset_y);
drawable_offsets (drawable_get_ID (drawable_id), &offset_x, &offset_y);
return_args = procedural_db_return_args (&drawable_offsets_proc, success);
@ -1040,7 +1043,7 @@ drawable_layer_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
layer = (drawable_layer (drawable_id)) ? TRUE : FALSE;
layer = (drawable_layer (drawable_get_ID (drawable_id))) ? TRUE : FALSE;
return_args = procedural_db_return_args (&drawable_layer_proc, success);
@ -1104,7 +1107,7 @@ drawable_layer_mask_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
layer_mask = (drawable_layer_mask (drawable_id)) ? TRUE : FALSE;
layer_mask = (drawable_layer_mask (drawable_get_ID (drawable_id))) ? TRUE : FALSE;
return_args = procedural_db_return_args (&drawable_layer_mask_proc, success);
@ -1168,7 +1171,7 @@ drawable_channel_invoker (Argument *args)
if (success)
drawable_id = args[0].value.pdb_int;
if (success)
channel = (drawable_channel (drawable_id)) ? TRUE : FALSE;
channel = (drawable_channel (drawable_get_ID (drawable_id))) ? TRUE : FALSE;
return_args = procedural_db_return_args (&drawable_channel_proc, success);
@ -1223,7 +1226,7 @@ ProcRecord drawable_channel_proc =
static Argument *
drawable_set_pixel_invoker (Argument *args)
{
int drawable_id;
GimpDrawable *drawable;
int x, y;
int num_channels;
unsigned char *pixel, *p;
@ -1232,24 +1235,26 @@ drawable_set_pixel_invoker (Argument *args)
success = TRUE;
if (success)
drawable_id = args[0].value.pdb_int;
/* Make sure the drawable exists */
if (success)
success = (drawable_gimage (drawable_id) != NULL);
{
int_value = args[0].value.pdb_int;
drawable = drawable_get_ID (int_value);
if (drawable == NULL || drawable_gimage (drawable) == NULL)
success = FALSE;
}
if (success)
{
x = args[1].value.pdb_int;
y = args[2].value.pdb_int;
if (x < 0 || x >= drawable_width (drawable_id))
if (x < 0 || x >= drawable_width (drawable))
success = FALSE;
if (y < 0 || y >= drawable_height (drawable_id))
if (y < 0 || y >= drawable_height (drawable))
success = FALSE;
}
if (success)
{
num_channels = args[3].value.pdb_int;
if (num_channels != drawable_bytes (drawable_id))
if (num_channels != drawable_bytes (drawable))
success = FALSE;
}
if (success)
@ -1257,7 +1262,7 @@ drawable_set_pixel_invoker (Argument *args)
if (success)
{
tile = tile_manager_get_tile (drawable_data (drawable_id), x, y, 0);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref (tile);
x %= TILE_WIDTH;
@ -1325,6 +1330,7 @@ static Argument *
drawable_get_pixel_invoker (Argument *args)
{
int drawable_id;
GimpDrawable *drawable;
int x, y;
int num_channels;
unsigned char *pixel, *p;
@ -1341,25 +1347,27 @@ drawable_get_pixel_invoker (Argument *args)
/* Make sure the drawable exists */
if (success)
{
success = (drawable_gimage (drawable_id) != NULL);
if (success)
num_channels = drawable_bytes (drawable_id);
drawable = drawable_get_ID (drawable_id);
if (drawable == NULL)
success = FALSE;
else
num_channels = drawable_bytes (drawable);
}
if (success)
{
x = args[1].value.pdb_int;
y = args[2].value.pdb_int;
if (x < 0 || x >= drawable_width (drawable_id))
if (x < 0 || x >= drawable_width (drawable))
success = FALSE;
if (y < 0 || y >= drawable_height (drawable_id))
if (y < 0 || y >= drawable_height (drawable))
success = FALSE;
}
if (success)
{
pixel = (unsigned char *) g_new (unsigned char, num_channels);
tile = tile_manager_get_tile (drawable_data (drawable_id), x, y, 0);
tile = tile_manager_get_tile (drawable_data (drawable), x, y, 0);
tile_ref (tile);
x %= TILE_WIDTH;

54
app/drawable_pvt.h Normal file
View file

@ -0,0 +1,54 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __DRAWABLE_PVT_H__
#define __DRAWABLE_PVT_H__
#include <gtk/gtkdata.h>
#include "tile_manager.h"
#include "temp_buf.h"
struct _GimpDrawable
{
GtkData data;
char *name; /* name of drawable */
TileManager *tiles; /* tiles for drawable data */
int visible; /* controls visibility */
int width, height; /* size of drawable */
int offset_x, offset_y; /* offset of layer in image */
int bytes; /* bytes per pixel */
int dirty; /* dirty bit */
int ID; /* provides a unique ID */
int gimage_ID; /* ID of gimage owner */
int type; /* type of drawable */
int has_alpha; /* drawable has alpha */
/* Preview variables */
TempBuf *preview; /* preview of the channel */
int preview_valid; /* is the preview valid? */
};
struct _GimpDrawableClass
{
GtkDataClass parent_class;
void (*invalidate_preview) (GtkObject *);
};
#endif /* __DRAWABLE_PVT_H__ */

View file

@ -39,9 +39,9 @@ static Argument *
edit_cut_invoker (Argument *args)
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
success = TRUE;
@ -54,15 +54,13 @@ edit_cut_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (drawable_gimage (int_value) != gimage)
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* create the new image */
if (success)
success = (edit_cut (gimage, drawable_id) != NULL);
success = (edit_cut (gimage, drawable) != NULL);
return procedural_db_return_args (&edit_cut_proc, success);
}
@ -110,9 +108,9 @@ static Argument *
edit_copy_invoker (Argument *args)
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
success = TRUE;
@ -125,15 +123,14 @@ edit_copy_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (drawable_gimage (int_value) != gimage)
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* create the new image */
if (success)
success = (edit_copy (gimage, drawable_id) != NULL);
success = (edit_copy (gimage, drawable) != NULL);
return procedural_db_return_args (&edit_copy_proc, success);
}
@ -181,10 +178,10 @@ static Argument *
edit_paste_invoker (Argument *args)
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int paste_into;
drawable_id = -1;
drawable = NULL;
success = TRUE;
@ -197,10 +194,9 @@ edit_paste_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (drawable_gimage (int_value) != gimage)
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
if (success)
{
@ -210,7 +206,7 @@ edit_paste_invoker (Argument *args)
/* create the new image */
if (success)
success = edit_paste (gimage, drawable_id, global_buf, paste_into);
success = edit_paste (gimage, drawable, global_buf, paste_into);
return_args = procedural_db_return_args (&edit_paste_proc, success);
@ -275,9 +271,9 @@ static Argument *
edit_clear_invoker (Argument *args)
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
success = TRUE;
@ -290,15 +286,14 @@ edit_clear_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (drawable_gimage (int_value) != gimage)
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* create the new image */
if (success)
success = edit_clear (gimage, drawable_id);
success = edit_clear (gimage, drawable);
return procedural_db_return_args (&edit_clear_proc, success);
}
@ -346,10 +341,9 @@ static Argument *
edit_fill_invoker (Argument *args)
{
GImage *gimage;
int drawable_id;
drawable_id = -1;
GimpDrawable *drawable;
drawable = NULL;
success = TRUE;
if (success)
@ -361,15 +355,14 @@ edit_fill_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (drawable_gimage (int_value) != gimage)
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* create the new image */
if (success)
success = edit_fill (gimage, drawable_id);
success = edit_fill (gimage, drawable);
return procedural_db_return_args (&edit_fill_proc, success);
}
@ -417,9 +410,9 @@ static Argument *
edit_stroke_invoker (Argument *args)
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
success = TRUE;
@ -432,15 +425,14 @@ edit_stroke_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (drawable_gimage (int_value) != gimage)
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* create the new image */
if (success)
success = gimage_mask_stroke (gimage, drawable_id);
success = gimage_mask_stroke (gimage, drawable);
return procedural_db_return_args (&edit_stroke_proc, success);
}

View file

@ -220,7 +220,8 @@ edit_selection_button_release (Tool *tool,
while (layer_list)
{
layer = (Layer *) layer_list->data;
if ((layer->ID == gdisp->gimage->active_layer) || layer->linked)
if (layer == gdisp->gimage->active_layer ||
layer_linked (layer))
layer_translate (layer, (x - edit_select.origx), (y - edit_select.origy));
layer_list = next_item (layer_list);
}
@ -299,6 +300,7 @@ edit_selection_draw (Tool *tool)
int floating_sel;
int x1, y1, x2, y2;
int x3, y3, x4, y4;
int off_x, off_y;
gdisp = (GDisplay *) tool->gdisp_ptr;
select = gdisp->select;
@ -376,8 +378,8 @@ edit_selection_draw (Tool *tool)
case LayerTranslate:
gdisplay_transform_coords (gdisp, 0, 0, &x1, &y1, TRUE);
gdisplay_transform_coords (gdisp,
drawable_width (gdisp->gimage->active_layer),
drawable_height (gdisp->gimage->active_layer),
drawable_width ( GIMP_DRAWABLE (gdisp->gimage->active_layer)),
drawable_height ( GIMP_DRAWABLE (gdisp->gimage->active_layer)),
&x2, &y2, TRUE);
/* Now, expand the rectangle to include all linked layers as well */
@ -385,15 +387,13 @@ edit_selection_draw (Tool *tool)
while (layer_list)
{
layer = (Layer *) layer_list->data;
if ((layer->ID != gdisp->gimage->active_layer) && layer->linked)
if (((layer) != gdisp->gimage->active_layer) && layer_linked (layer))
{
drawable_offsets (GIMP_DRAWABLE (layer), &off_x, &off_y);
gdisplay_transform_coords (gdisp, off_x, off_y, &x3, &y3, FALSE);
gdisplay_transform_coords (gdisp,
layer->offset_x,
layer->offset_y,
&x3, &y3, FALSE);
gdisplay_transform_coords (gdisp,
layer->offset_x + layer->width,
layer->offset_y + layer->height,
off_x + drawable_width (GIMP_DRAWABLE (layer)),
off_y + drawable_height (GIMP_DRAWABLE (layer)),
&x4, &y4, FALSE);
if (x3 < x1)
x1 = x3;
@ -545,7 +545,7 @@ edit_sel_arrow_keys_func (Tool *tool,
while (layer_list)
{
layer = (Layer *) layer_list->data;
if ((layer->ID == gdisp->gimage->active_layer) || layer->linked)
if (((layer) == gdisp->gimage->active_layer) || layer_linked (layer))
layer_translate (layer, inc_x, inc_y);
layer_list = next_item (layer_list);
}

View file

@ -22,8 +22,9 @@
#include "drawable.h"
#include "equalize.h"
#include "interface.h"
#include "gimage.h"
static void equalize (GImage *, int, int);
static void equalize (GImage *, GimpDrawable *, int);
static void eq_histogram (double [3][256], unsigned char [3][256], int, double);
static Argument * equalize_invoker (Argument *);
@ -33,25 +34,25 @@ image_equalize (gimage_ptr)
void *gimage_ptr;
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int mask_only = TRUE;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
if (drawable_indexed (drawable_id))
if (drawable_indexed (drawable))
{
message_box ("Equalize does not operate on indexed drawables.", NULL, NULL);
return;
}
equalize (gimage, drawable_id, mask_only);
equalize (gimage, drawable, mask_only);
}
static void
equalize(gimage, drawable_id, mask_only)
equalize(gimage, drawable, mask_only)
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int mask_only;
{
Channel *sel_mask;
@ -73,18 +74,18 @@ equalize(gimage, drawable_id, mask_only)
mask = NULL;
sel_mask = gimage_get_mask (gimage);
drawable_offsets (drawable_id, &off_x, &off_y);
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable_id);
drawable_offsets (drawable, &off_x, &off_y);
bytes = drawable_bytes (drawable);
has_alpha = drawable_has_alpha (drawable);
alpha = has_alpha ? (bytes - 1) : bytes;
count = 0.0;
/* Determine the histogram from the drawable data and the attendant mask */
no_mask = (drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
no_mask = (drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
sel_maskPR = (no_mask) ? NULL : &maskPR;
if (sel_maskPR)
pixel_region_init (sel_maskPR, sel_mask->tiles, x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (sel_maskPR, drawable_data (GIMP_DRAWABLE (sel_mask)), x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
/* Initialize histogram */
for (b = 0; b < alpha; b++)
@ -135,8 +136,8 @@ equalize(gimage, drawable_id, mask_only)
eq_histogram (hist, lut, alpha, count);
/* Apply the histogram */
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -166,8 +167,8 @@ equalize(gimage, drawable_id, mask_only)
}
}
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
@ -276,9 +277,9 @@ equalize_invoker (args)
int int_value;
int mask_only;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
/* the gimage */
if (success)
@ -291,10 +292,9 @@ equalize_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* the mask only option */
if (success)
@ -304,10 +304,10 @@ equalize_invoker (args)
}
/* make sure the drawable is not indexed color */
if (success)
success = ! drawable_indexed (drawable_id);
success = ! drawable_indexed (drawable);
if (success)
equalize (gimage, drawable_id, mask_only);
equalize (gimage, drawable, mask_only);
return procedural_db_return_args (&equalize_proc, success);
}

View file

@ -29,15 +29,15 @@
#include "tools.h"
/* forward function declarations */
static void eraser_motion (PaintCore *, int);
static void eraser_motion (PaintCore *, GimpDrawable *);
static Argument * eraser_invoker (Argument *);
static void * eraser_options = NULL;
void *
eraser_paint_func (paint_core, drawable_id, state)
eraser_paint_func (paint_core, drawable, state)
PaintCore *paint_core;
int drawable_id;
GimpDrawable *drawable;
int state;
{
switch (state)
@ -46,7 +46,7 @@ eraser_paint_func (paint_core, drawable_id, state)
break;
case MOTION_PAINT :
eraser_motion (paint_core, drawable_id);
eraser_motion (paint_core, drawable);
break;
case FINISH_PAINT :
@ -87,21 +87,21 @@ tools_free_eraser (tool)
void
eraser_motion (paint_core, drawable_id)
eraser_motion (paint_core, drawable)
PaintCore *paint_core;
int drawable_id;
GimpDrawable *drawable;
{
GImage *gimage;
TempBuf * area;
unsigned char col[MAX_CHANNELS];
if (! (gimage = drawable_gimage (drawable_id)))
if (! (gimage = drawable_gimage (drawable)))
return;
gimage_get_background (gimage, drawable_id, col);
gimage_get_background (gimage, drawable, col);
/* Get a region which can be used to paint to */
if (! (area = paint_core_get_paint_area (paint_core, drawable_id)))
if (! (area = paint_core_get_paint_area (paint_core, drawable)))
return;
/* set the alpha channel */
@ -112,16 +112,16 @@ eraser_motion (paint_core, drawable_id)
area->width * area->height, area->bytes);
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable_id, OPAQUE,
paint_core_paste_canvas (paint_core, drawable, OPAQUE,
(int) (get_brush_opacity () * 255),
ERASE_MODE, SOFT, CONSTANT);
}
static void *
eraser_non_gui_paint_func (PaintCore *paint_core, int drawable_id, int state)
eraser_non_gui_paint_func (PaintCore *paint_core, GimpDrawable *drawable, int state)
{
eraser_motion (paint_core, drawable_id);
eraser_motion (paint_core, drawable);
return NULL;
}
@ -178,13 +178,13 @@ eraser_invoker (args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int num_strokes;
double *stroke_array;
int int_value;
int i;
drawable_id = -1;
drawable = NULL;
num_strokes = 0;
/* the gimage */
@ -198,10 +198,9 @@ eraser_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (! (gimage == drawable_gimage (int_value)))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* num strokes */
if (success)
@ -219,7 +218,7 @@ eraser_invoker (args)
if (success)
/* init the paint core */
success = paint_core_init (&non_gui_paint_core, drawable_id,
success = paint_core_init (&non_gui_paint_core, drawable,
stroke_array[0], stroke_array[1]);
if (success)
@ -231,21 +230,21 @@ eraser_invoker (args)
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
if (num_strokes == 1)
eraser_non_gui_paint_func (&non_gui_paint_core, drawable_id, 0);
eraser_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
for (i = 1; i < num_strokes; i++)
{
non_gui_paint_core.curx = stroke_array[i * 2 + 0];
non_gui_paint_core.cury = stroke_array[i * 2 + 1];
paint_core_interpolate (&non_gui_paint_core, drawable_id);
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.lastx = non_gui_paint_core.curx;
non_gui_paint_core.lasty = non_gui_paint_core.cury;
}
/* finish the painting */
paint_core_finish (&non_gui_paint_core, drawable_id, -1);
paint_core_finish (&non_gui_paint_core, drawable, -1);
/* cleanup */
paint_core_cleanup ();

View file

@ -22,7 +22,7 @@
#include "procedural_db.h"
#include "tools.h"
void * eraser_paint_func (PaintCore *, int, int);
void * eraser_paint_func (PaintCore *, GimpDrawable *, int);
Tool * tools_new_eraser (void);
void tools_free_eraser (Tool *);

View file

@ -776,7 +776,7 @@ file_save (int image_ID,
args[0].value.pdb_int = 0;
args[1].value.pdb_int = image_ID;
args[2].value.pdb_int = gimage_active_drawable (gimage);
args[2].value.pdb_int = drawable_ID (gimage_active_drawable (gimage));
args[3].value.pdb_pointer = filename;
args[4].value.pdb_pointer = raw_filename;

View file

@ -24,6 +24,9 @@
#include "temp_buf.h"
#include "transform_core.h"
#include "undo.h"
#include "gimage.h"
#include "tile_manager_pvt.h" /* ick. */
#define FLIP 0
@ -37,8 +40,8 @@ struct _FlipOptions
/* forward function declarations */
static Tool * tools_new_flip_horz (void);
static Tool * tools_new_flip_vert (void);
static TileManager * flip_tool_flip_horz (GImage *, int, TileManager *, int);
static TileManager * flip_tool_flip_vert (GImage *, int, TileManager *, int);
static TileManager * flip_tool_flip_horz (GImage *, GimpDrawable *, TileManager *, int);
static TileManager * flip_tool_flip_vert (GImage *, GimpDrawable *, TileManager *, int);
static void flip_change_type (int);
static Argument * flip_invoker (Argument *);
@ -232,7 +235,7 @@ tools_new_flip_vert ()
static TileManager *
flip_tool_flip_horz (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
TileManager *orig,
int flip)
{
@ -273,7 +276,7 @@ flip_tool_flip_horz (GImage *gimage,
static TileManager *
flip_tool_flip_vert (GImage *gimage,
int drawable_id,
GimpDrawable *drawable,
TileManager *orig,
int flip)
{
@ -376,7 +379,7 @@ flip_invoker (Argument *args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int flip_type;
int int_value;
TileManager *float_tiles;
@ -385,7 +388,7 @@ flip_invoker (Argument *args)
Layer *layer;
Argument *return_args;
drawable_id = -1;
drawable = NULL;
flip_type = 0;
new_tiles = NULL;
layer = NULL;
@ -401,9 +404,8 @@ flip_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage == drawable_gimage (int_value))
drawable_id = int_value;
else
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
/* flip type */
@ -425,16 +427,16 @@ flip_invoker (Argument *args)
undo_push_group_start (gimage, TRANSFORM_CORE_UNDO);
/* Cut/Copy from the specified drawable */
float_tiles = transform_core_cut (gimage, drawable_id, &new_layer);
float_tiles = transform_core_cut (gimage, drawable, &new_layer);
/* flip the buffer */
switch (flip_type)
{
case 0: /* horz */
new_tiles = flip_tool_flip_horz (gimage, drawable_id, float_tiles, -1);
new_tiles = flip_tool_flip_horz (gimage, drawable, float_tiles, -1);
break;
case 1: /* vert */
new_tiles = flip_tool_flip_vert (gimage, drawable_id, float_tiles, -1);
new_tiles = flip_tool_flip_vert (gimage, drawable, float_tiles, -1);
break;
}
@ -442,7 +444,7 @@ flip_invoker (Argument *args)
tile_manager_destroy (float_tiles);
if (new_tiles)
success = (layer = transform_core_paste (gimage, drawable_id, new_tiles, new_layer)) != NULL;
success = (layer = transform_core_paste (gimage, drawable, new_tiles, new_layer)) != NULL;
else
success = FALSE;
@ -453,7 +455,7 @@ flip_invoker (Argument *args)
return_args = procedural_db_return_args (&flip_proc, success);
if (success)
return_args[1].value.pdb_int = layer->ID;
return_args[1].value.pdb_int = drawable_ID (GIMP_DRAWABLE(layer));
return return_args;
}

View file

@ -21,6 +21,7 @@
#include "appenv.h"
#include "channels_dialog.h"
#include "drawable.h"
#include "layer.h"
#include "errors.h"
#include "floating_sel.h"
#include "gimage.h"
@ -29,38 +30,40 @@
#include "paint_funcs.h"
#include "undo.h"
#include "layer_pvt.h"
#include "tile_manager_pvt.h" /* ick. */
void
floating_sel_attach (Layer *layer,
int drawable_id)
GimpDrawable *drawable)
{
GImage *gimage;
int floating_sel;
Layer *floating_sel;
if (! (gimage = drawable_gimage (drawable_id)))
if (! (gimage = drawable_gimage (drawable)))
return;
/* If there is already a floating selection, anchor it */
if (gimage->floating_sel != -1)
if (gimage->floating_sel != NULL)
{
floating_sel = gimage->floating_sel;
floating_sel_anchor (gimage_floating_sel (gimage));
/* if we were pasting to the old floating selection, paste now to the drawable */
if (drawable_id == floating_sel)
drawable_id = gimage_active_drawable (gimage);
if (drawable == GIMP_DRAWABLE(floating_sel))
drawable = gimage_active_drawable (gimage);
}
/* set the drawable and allocate a backing store */
layer->preserve_trans = TRUE;
layer->fs.drawable = drawable_id;
layer->fs.backing_store = tile_manager_new (layer->width, layer->height, drawable_bytes (drawable_id));
layer->fs.drawable = drawable;
layer->fs.backing_store = tile_manager_new (GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, drawable_bytes (drawable));
/* because setting the sensitivity in the layers_dialog lock call redraws the
* previews, we need to lock the dialogs before the floating sel is actually added.
* however, they won't lock unless we set the gimage's floating sel pointer
*/
gimage->floating_sel = layer->ID;
gimage->floating_sel = layer;
/* add the layer to the gimage */
gimage_add_layer (gimage, layer, 0);
@ -74,7 +77,7 @@ floating_sel_remove (Layer *layer)
{
GImage *gimage;
if (! (gimage = drawable_gimage (layer->fs.drawable)))
if (! (gimage = drawable_gimage ( (layer->fs.drawable))))
return;
/* store the affected area from the drawable in the backing store */
@ -84,10 +87,10 @@ floating_sel_remove (Layer *layer)
* because it will not be done until the floating selection is removed,
* at which point the obscured drawable's preview will not be declared invalid
*/
drawable_invalidate_preview (layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(layer));
/* remove the layer from the gimage */
gimage_remove_layer (gimage, layer->ID);
gimage_remove_layer (gimage, layer);
}
void
@ -95,7 +98,7 @@ floating_sel_anchor (Layer *layer)
{
GImage *gimage;
if (! (gimage = drawable_gimage (layer->ID)))
if (! (gimage = drawable_gimage (GIMP_DRAWABLE(layer))))
return;
if (! layer_is_floating_sel (layer))
{
@ -111,11 +114,11 @@ floating_sel_anchor (Layer *layer)
floating_sel_relax (layer, TRUE);
/* Composite the floating selection contents */
floating_sel_composite (layer, layer->offset_x, layer->offset_y,
layer->width, layer->height, TRUE);
floating_sel_composite (layer, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y,
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
/* remove the floating selection */
gimage_remove_layer (gimage, layer->ID);
gimage_remove_layer (gimage, layer);
/* end the group undo */
undo_push_group_end (gimage);
@ -129,23 +132,23 @@ floating_sel_reset (layer)
Layer *layer;
{
GImage *gimage;
Channel *lm;
LayerMask *lm;
if (! (gimage = drawable_gimage (layer->ID)))
if (! (gimage = drawable_gimage (GIMP_DRAWABLE(layer))))
return;
/* set the underlying drawable to active */
if (drawable_layer (layer->fs.drawable))
gimage_set_active_layer (gimage, layer->fs.drawable);
else if ((lm = drawable_layer_mask (layer->fs.drawable)))
gimage_set_active_layer (gimage, lm->layer_ID);
else if (drawable_channel (layer->fs.drawable))
if (drawable_layer ( (layer->fs.drawable)))
gimage_set_active_layer (gimage, GIMP_LAYER (layer->fs.drawable));
else if ((lm = drawable_layer_mask ( (layer->fs.drawable))))
gimage_set_active_layer (gimage, lm->layer);
else if (drawable_channel ( (layer->fs.drawable)))
{
gimage_set_active_channel (gimage, layer->fs.drawable);
gimage_set_active_channel (gimage, GIMP_CHANNEL(layer->fs.drawable));
if (gimage->layers)
gimage->active_layer = ((Layer *) gimage->layer_stack->data)->ID;
gimage->active_layer = (((Layer *) gimage->layer_stack->data));
else
gimage->active_layer = -1;
gimage->active_layer = NULL;
}
}
@ -159,7 +162,7 @@ floating_sel_to_layer (Layer *layer)
GImage *gimage;
if (! (gimage = drawable_gimage (layer->ID)))
if (! (gimage = drawable_gimage (GIMP_DRAWABLE(layer))))
return;
/* Check if the floating layer belongs to a channel... */
@ -173,21 +176,21 @@ floating_sel_to_layer (Layer *layer)
}
/* restore the contents of the drawable */
floating_sel_restore (layer, layer->offset_x, layer->offset_y, layer->width, layer->height);
floating_sel_restore (layer, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* determine whether the resulting layer needs an update */
drawable_offsets (layer->fs.drawable, &off_x, &off_y);
width = drawable_width (layer->fs.drawable);
height = drawable_height (layer->fs.drawable);
update = (update || ((layer->offset_x < off_x) ||
(layer->offset_y < off_y) ||
(layer->offset_x + layer->width > off_x + width) ||
(layer->offset_y + layer->height > off_y + height)) ? TRUE : FALSE);
update = (update || ((GIMP_DRAWABLE(layer)->offset_x < off_x) ||
(GIMP_DRAWABLE(layer)->offset_y < off_y) ||
(GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width > off_x + width) ||
(GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height > off_y + height)) ? TRUE : FALSE);
/* update the fs drawable--this updates the gimage composite preview
* as well as the underlying drawable's
*/
drawable_invalidate_preview (layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(layer));
/* allocate the undo structure */
fsu = (FStoLayerUndo *) g_malloc (sizeof (FStoLayerUndo));
@ -200,15 +203,15 @@ floating_sel_to_layer (Layer *layer)
layer_invalidate_boundary (layer);
/* Set pointers */
layer->fs.drawable = -1;
gimage->floating_sel = -1;
layer->fs.drawable = NULL;
gimage->floating_sel = NULL;
/* if the floating selection exceeds the attached layer's extents, update the new layer */
if (update)
drawable_update (layer->ID, 0, 0, layer->width, layer->height);
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* otherwise, just update the preview, because the image is valid as is */
else
drawable_invalidate_preview (layer->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(layer));
}
void
@ -223,14 +226,15 @@ floating_sel_store (Layer *layer,
int x1, y1, x2, y2;
/* Check the backing store & make sure it has the correct dimensions */
if (layer->fs.backing_store->levels[0].width != layer->width ||
layer->fs.backing_store->levels[0].height != layer->height ||
if (layer->fs.backing_store->levels[0].width != drawable_width (GIMP_DRAWABLE(layer)) ||
layer->fs.backing_store->levels[0].height != drawable_height (GIMP_DRAWABLE(layer)) ||
layer->fs.backing_store->levels[0].bpp != drawable_bytes (layer->fs.drawable))
{
/* free the backing store and allocate anew */
tile_manager_destroy (layer->fs.backing_store);
layer->fs.backing_store = tile_manager_new (layer->width, layer->height,
layer->fs.backing_store = tile_manager_new (GIMP_DRAWABLE(layer)->width,
GIMP_DRAWABLE(layer)->height,
drawable_bytes (layer->fs.drawable));
}
@ -241,10 +245,10 @@ floating_sel_store (Layer *layer,
drawable_offsets (layer->fs.drawable, &offx, &offy);
/* Find the minimum area we need to uncover -- in gimage space */
x1 = MAXIMUM (layer->offset_x, offx);
y1 = MAXIMUM (layer->offset_y, offy);
x2 = MINIMUM (layer->offset_x + layer->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (layer->offset_y + layer->height, offy + drawable_height (layer->fs.drawable));
x1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_x, offx);
y1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_y, offy);
x2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, offy + drawable_height (layer->fs.drawable));
x1 = BOUNDS (x, x1, x2);
y1 = BOUNDS (y, y1, y2);
@ -257,7 +261,7 @@ floating_sel_store (Layer *layer,
pixel_region_init (&srcPR, drawable_data (layer->fs.drawable),
(x1 - offx), (y1 - offy), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, layer->fs.backing_store,
(x1 - layer->offset_x), (y1 - layer->offset_y), (x2 - x1), (y2 - y1), TRUE);
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y), (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
}
@ -282,10 +286,10 @@ floating_sel_restore (Layer *layer,
/* Find the minimum area we need to uncover -- in gimage space */
drawable_offsets (layer->fs.drawable, &offx, &offy);
x1 = MAXIMUM (layer->offset_x, offx);
y1 = MAXIMUM (layer->offset_y, offy);
x2 = MINIMUM (layer->offset_x + layer->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (layer->offset_y + layer->height, offy + drawable_height (layer->fs.drawable));
x1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_x, offx);
y1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_y, offy);
x2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, offy + drawable_height (layer->fs.drawable));
x1 = BOUNDS (x, x1, x2);
y1 = BOUNDS (y, y1, y2);
@ -296,7 +300,7 @@ floating_sel_restore (Layer *layer,
{
/* Copy the area from the backing store to the drawable */
pixel_region_init (&srcPR, layer->fs.backing_store,
(x1 - layer->offset_x), (y1 - layer->offset_y), (x2 - x1), (y2 - y1), FALSE);
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_data (layer->fs.drawable),
(x1 - offx), (y1 - offy), (x2 - x1), (y2 - y1), TRUE);
@ -310,15 +314,15 @@ floating_sel_rigor (Layer *layer,
{
GImage *gimage;
if ((gimage = gimage_get_ID (layer->gimage_ID)) == NULL)
if ((gimage = gimage_get_ID (GIMP_DRAWABLE(layer)->gimage_ID)) == NULL)
return;
/* store the affected area from the drawable in the backing store */
floating_sel_store (layer, layer->offset_x, layer->offset_y, layer->width, layer->height);
floating_sel_store (layer, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
layer->fs.initial = TRUE;
if (undo)
undo_push_fs_rigor (gimage, layer->ID);
undo_push_fs_rigor (gimage, GIMP_DRAWABLE(layer)->ID);
}
void
@ -327,16 +331,16 @@ floating_sel_relax (Layer *layer,
{
GImage *gimage;
if ((gimage = gimage_get_ID (layer->gimage_ID)) == NULL)
if ((gimage = gimage_get_ID (GIMP_DRAWABLE(layer)->gimage_ID)) == NULL)
return;
/* restore the contents of drawable the floating layer is attached to */
if (layer->fs.initial == FALSE)
floating_sel_restore (layer, layer->offset_x, layer->offset_y, layer->width, layer->height);
floating_sel_restore (layer, GIMP_DRAWABLE(layer)->offset_x, GIMP_DRAWABLE(layer)->offset_y, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
layer->fs.initial = TRUE;
if (undo)
undo_push_fs_relax (gimage, layer->ID);
undo_push_fs_relax (gimage, GIMP_DRAWABLE(layer)->ID);
}
void
@ -358,7 +362,7 @@ floating_sel_composite (Layer *layer,
d_layer = NULL;
if (! (gimage = drawable_gimage (layer->ID)))
if (! (gimage = drawable_gimage (GIMP_DRAWABLE(layer))))
return;
/* What this function does is composite the specified area of the
@ -369,18 +373,18 @@ floating_sel_composite (Layer *layer,
/* If this isn't the first composite, restore the image underneath */
if (! layer->fs.initial)
floating_sel_restore (layer, x, y, w, h);
else if (layer->visible)
else if (GIMP_DRAWABLE(layer)->visible)
layer->fs.initial = FALSE;
/* First restore what's behind the image if necessary, then check for visibility */
if (layer->visible)
if (GIMP_DRAWABLE(layer)->visible)
{
/* Find the minimum area we need to composite -- in gimage space */
drawable_offsets (layer->fs.drawable, &offx, &offy);
x1 = MAXIMUM (layer->offset_x, offx);
y1 = MAXIMUM (layer->offset_y, offy);
x2 = MINIMUM (layer->offset_x + layer->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (layer->offset_y + layer->height, offy + drawable_height (layer->fs.drawable));
x1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_x, offx);
y1 = MAXIMUM (GIMP_DRAWABLE(layer)->offset_y, offy);
x2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, offx + drawable_width (layer->fs.drawable));
y2 = MINIMUM (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, offy + drawable_height (layer->fs.drawable));
x1 = BOUNDS (x, x1, x2);
y1 = BOUNDS (y, y1, y2);
@ -390,8 +394,8 @@ floating_sel_composite (Layer *layer,
if ((x2 - x1) > 0 && (y2 - y1) > 0)
{
/* composite the area from the layer to the drawable */
pixel_region_init (&fsPR, layer->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
pixel_region_init (&fsPR, GIMP_DRAWABLE(layer)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
/* a kludge here to prevent the case of the drawable
@ -400,7 +404,7 @@ floating_sel_composite (Layer *layer,
*/
if (drawable_layer (layer->fs.drawable))
{
d_layer = layer_get_ID (layer->fs.drawable);
d_layer = GIMP_LAYER (layer->fs.drawable);
if ((preserve_trans = d_layer->preserve_trans))
d_layer->preserve_trans = FALSE;
}
@ -450,18 +454,18 @@ floating_sel_boundary (Layer *layer,
g_free (layer->fs.segs);
/* find the segments */
pixel_region_init (&bPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
layer->fs.segs = find_mask_boundary (&bPR, &layer->fs.num_segs,
WithinBounds, 0, 0,
layer->width, layer->height);
GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
/* offset the segments */
for (i = 0; i < layer->fs.num_segs; i++)
{
layer->fs.segs[i].x1 += layer->offset_x;
layer->fs.segs[i].y1 += layer->offset_y;
layer->fs.segs[i].x2 += layer->offset_x;
layer->fs.segs[i].y2 += layer->offset_y;
layer->fs.segs[i].x1 += GIMP_DRAWABLE(layer)->offset_x;
layer->fs.segs[i].y1 += GIMP_DRAWABLE(layer)->offset_y;
layer->fs.segs[i].x2 += GIMP_DRAWABLE(layer)->offset_x;
layer->fs.segs[i].y2 += GIMP_DRAWABLE(layer)->offset_y;
}
layer->fs.boundary_known = TRUE;

View file

@ -22,7 +22,7 @@
/* Functions */
void floating_sel_attach (Layer *, int);
void floating_sel_attach (Layer *, GimpDrawable *);
void floating_sel_remove (Layer *);
void floating_sel_anchor (Layer *);
void floating_sel_reset (Layer *);

View file

@ -197,7 +197,9 @@ scan_convert (int gimage_ID, int num_pts, FreeSelectPoint *pts,
(int) pts[0].x, (int) pts[0].y);
}
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)), 0, 0,
drawable_width (GIMP_DRAWABLE(mask)),
drawable_height (GIMP_DRAWABLE(mask)), TRUE);
for (i = 0; i < height; i++)
{
list = scanlines[i];
@ -246,7 +248,8 @@ scan_convert (int gimage_ID, int num_pts, FreeSelectPoint *pts,
*b++ = (unsigned char) (val / SUPERSAMPLE2);
}
pixel_region_set_row (&maskPR, 0, (i / SUPERSAMPLE), mask->width, buf);
pixel_region_set_row (&maskPR, 0, (i / SUPERSAMPLE),
drawable_width (GIMP_DRAWABLE(mask)), buf);
}
free_list (scanlines[i]);

View file

@ -65,7 +65,7 @@ static int num_segs = 0;
static Channel * fuzzy_mask = NULL;
static SelectionOptions *fuzzy_options = NULL;
static void fuzzy_select (GImage *, int, int, int, double);
static void fuzzy_select (GImage *, GimpDrawable *, int, int, double);
static Argument *fuzzy_select_invoker (Argument *);
/*************************************/
@ -235,7 +235,7 @@ find_contiguous_region_helper (PixelRegion *mask, PixelRegion *src,
}
Channel *
find_contiguous_region (GImage *gimage, int drawable_id, int antialias,
find_contiguous_region (GImage *gimage, GimpDrawable *drawable, int antialias,
int threshold, int x, int y, int sample_merged)
{
PixelRegion srcPR, maskPR;
@ -256,13 +256,13 @@ find_contiguous_region (GImage *gimage, int drawable_id, int antialias,
}
else
{
pixel_region_init (&srcPR, drawable_data (drawable_id), 0, 0,
drawable_width (drawable_id), drawable_height (drawable_id), FALSE);
has_alpha = drawable_has_alpha (drawable_id);
pixel_region_init (&srcPR, drawable_data (drawable), 0, 0,
drawable_width (drawable), drawable_height (drawable), FALSE);
has_alpha = drawable_has_alpha (drawable);
}
mask = channel_new_mask (gimage->ID, srcPR.w, srcPR.h);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(mask)), 0, 0, drawable_width (GIMP_DRAWABLE(mask)), drawable_height (GIMP_DRAWABLE(mask)), TRUE);
tile = tile_manager_get_tile (srcPR.tiles, x, y, 0);
if (tile)
@ -281,7 +281,7 @@ find_contiguous_region (GImage *gimage, int drawable_id, int antialias,
}
static void
fuzzy_select (GImage *gimage, int drawable_id, int op, int feather,
fuzzy_select (GImage *gimage, GimpDrawable *drawable, int op, int feather,
double feather_radius)
{
int off_x, off_y;
@ -292,7 +292,7 @@ fuzzy_select (GImage *gimage, int drawable_id, int op, int feather,
else
gimage_mask_undo (gimage);
drawable_offsets (drawable_id, &off_x, &off_y);
drawable_offsets (drawable, &off_x, &off_y);
if (feather)
channel_feather (fuzzy_mask, gimage_get_mask (gimage),
feather_radius, op, off_x, off_y);
@ -366,7 +366,7 @@ fuzzy_select_button_release (Tool *tool, GdkEventButton *bevent,
{
FuzzySelect * fuzzy_sel;
GDisplay * gdisp;
int drawable_id;
GimpDrawable *drawable;
gdisp = (GDisplay *) gdisp_ptr;
fuzzy_sel = (FuzzySelect *) tool->private;
@ -380,8 +380,8 @@ fuzzy_select_button_release (Tool *tool, GdkEventButton *bevent,
/* First take care of the case where the user "cancels" the action */
if (! (bevent->state & GDK_BUTTON3_MASK))
{
drawable_id = (fuzzy_options->sample_merged) ? -1 : gimage_active_drawable (gdisp->gimage);
fuzzy_select (gdisp->gimage, drawable_id, fuzzy_sel->op,
drawable = (fuzzy_options->sample_merged) ? NULL : gimage_active_drawable (gdisp->gimage);
fuzzy_select (gdisp->gimage, drawable, fuzzy_sel->op,
fuzzy_options->feather, fuzzy_options->feather_radius);
gdisplays_flush ();
@ -446,19 +446,19 @@ fuzzy_select_calculate (Tool *tool, void *gdisp_ptr, int *nsegs)
GdkSegment *segs;
BoundSeg *bsegs;
int i, x, y;
int drawable_id;
GimpDrawable *drawable;
int use_offsets;
fuzzy_sel = (FuzzySelect *) tool->private;
gdisp = (GDisplay *) gdisp_ptr;
drawable_id = gimage_active_drawable (gdisp->gimage);
drawable = gimage_active_drawable (gdisp->gimage);
use_offsets = (fuzzy_options->sample_merged) ? FALSE : TRUE;
gdisplay_untransform_coords (gdisp, fuzzy_sel->x,
fuzzy_sel->y, &x, &y, FALSE, use_offsets);
new = find_contiguous_region (gdisp->gimage, drawable_id, fuzzy_options->antialias,
new = find_contiguous_region (gdisp->gimage, drawable, fuzzy_options->antialias,
fuzzy_sel->threshold, x, y, fuzzy_options->sample_merged);
if (fuzzy_mask)
@ -468,11 +468,11 @@ fuzzy_select_calculate (Tool *tool, void *gdisp_ptr, int *nsegs)
/* calculate and allocate a new XSegment array which represents the boundary
* of the color-contiguous region
*/
pixel_region_init (&maskPR, fuzzy_mask->tiles, 0, 0, fuzzy_mask->width, fuzzy_mask->height, FALSE);
pixel_region_init (&maskPR, drawable_data (GIMP_DRAWABLE(fuzzy_mask)), 0, 0, drawable_width (GIMP_DRAWABLE(fuzzy_mask)), drawable_height (GIMP_DRAWABLE(fuzzy_mask)), FALSE);
bsegs = find_mask_boundary (&maskPR, nsegs, WithinBounds,
0, 0,
fuzzy_mask->width,
fuzzy_mask->height);
drawable_width (GIMP_DRAWABLE(fuzzy_mask)),
drawable_height (GIMP_DRAWABLE(fuzzy_mask)));
segs = (GdkSegment *) g_malloc (sizeof (GdkSegment) * *nsegs);
@ -635,7 +635,7 @@ fuzzy_select_invoker (Argument *args)
{
int success = TRUE;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int op;
int threshold;
int antialias;
@ -645,7 +645,7 @@ fuzzy_select_invoker (Argument *args)
double feather_radius;
int int_value;
drawable_id = -1;
drawable = NULL;
op = REPLACE;
threshold = 0;
@ -660,10 +660,9 @@ fuzzy_select_invoker (Argument *args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* x, y */
if (success)
@ -723,12 +722,12 @@ fuzzy_select_invoker (Argument *args)
Channel *new;
Channel *old_fuzzy_mask;
new = find_contiguous_region (gimage, drawable_id, antialias, threshold, x, y, sample_merged);
new = find_contiguous_region (gimage, drawable, antialias, threshold, x, y, sample_merged);
old_fuzzy_mask = fuzzy_mask;
fuzzy_mask = new;
drawable_id = (sample_merged) ? -1 : drawable_id;
fuzzy_select (gimage, drawable_id, op, feather, feather_radius);
drawable = (sample_merged) ? NULL : drawable;
fuzzy_select (gimage, drawable, op, feather, feather_radius);
fuzzy_mask = old_fuzzy_mask;
}

View file

@ -29,7 +29,7 @@ void tools_free_fuzzy_select (Tool *);
/* functions */
Channel * find_contiguous_region (GImage *, int, int, int, int, int, int);
Channel * find_contiguous_region (GImage *, GimpDrawable *, int, int, int, int, int);
/* Procedure definition and marshalling function */
extern ProcRecord fuzzy_select_proc;

View file

@ -44,6 +44,7 @@
#include "undo.h"
#include "tools.h"
#include "layer_pvt.h" /* ick. */
#define OVERHEAD 25 /* in units of pixel area */
#define EPSILON 5
@ -778,23 +779,25 @@ gdisplay_mask_bounds (GDisplay *gdisp,
int *y2)
{
Layer *layer;
int off_x, off_y;
/* If there is a floating selection, handle things differently */
if ((layer = gimage_floating_sel (gdisp->gimage)))
{
drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
if (! channel_bounds (gimage_get_mask (gdisp->gimage), x1, y1, x2, y2))
{
*x1 = layer->offset_x;
*y1 = layer->offset_y;
*x2 = layer->offset_x + layer->width;
*y2 = layer->offset_y + layer->height;
*x1 = off_x;
*y1 = off_y;
*x2 = off_x + drawable_width (GIMP_DRAWABLE(layer));
*y2 = off_y + drawable_height (GIMP_DRAWABLE(layer));
}
else
{
*x1 = MINIMUM (layer->offset_x, *x1);
*y1 = MINIMUM (layer->offset_y, *y1);
*x2 = MAXIMUM (layer->offset_x + layer->width, *x2);
*y2 = MAXIMUM (layer->offset_y + layer->height, *y2);
*x1 = MINIMUM (off_x, *x1);
*y1 = MINIMUM (off_y, *y1);
*x2 = MAXIMUM (off_x + drawable_width (GIMP_DRAWABLE(layer)), *x2);
*y2 = MAXIMUM (off_y + drawable_height (GIMP_DRAWABLE(layer)), *y2);
}
}
else if (! channel_bounds (gimage_get_mask (gdisp->gimage), x1, y1, x2, y2))
@ -970,7 +973,7 @@ gdisplay_set_menu_sensitivity (GDisplay *gdisp)
gint aux;
gint lm;
gint lp;
gint drawable;
GimpDrawable *drawable;
gint base_type;
gint type;

File diff suppressed because it is too large Load diff

View file

@ -19,6 +19,7 @@
#define __GIMAGE_H__
#include "boundary.h"
#include "drawable.h"
#include "channel.h"
#include "layer.h"
#include "linked.h"
@ -34,6 +35,8 @@
#define INDEXED_GIMAGE 4
#define INDEXEDA_GIMAGE 5
#define TYPE_HAS_ALPHA(t) ((t)==RGBA_GIMAGE || (t)==GRAYA_GIMAGE || (t)==INDEXEDA_GIMAGE)
#define GRAY_PIX 0
#define ALPHA_G_PIX 1
#define RED_PIX 0
@ -126,9 +129,9 @@ struct _GImage
link_ptr channels; /* the list of masks */
link_ptr layer_stack; /* the layers in MRU order */
int active_layer; /* ID of active layer */
int active_channel; /* ID of active channel */
int floating_sel; /* ID of fs layer */
Layer * active_layer; /* ID of active layer */
Channel * active_channel; /* ID of active channel */
Layer * floating_sel; /* ID of fs layer */
Channel * selection_mask; /* selection mask channel */
int visible [MAX_CHANNELS]; /* visible channels */
@ -161,15 +164,15 @@ GImage * gimage_get_ID (int);
TileManager * gimage_shadow (GImage *, int, int, int);
void gimage_free_shadow (GImage *);
void gimage_delete (GImage *);
void gimage_apply_image (GImage *, int, PixelRegion *, int, int, int,
void gimage_apply_image (GImage *, GimpDrawable *, PixelRegion *, int, int, int,
TileManager *, int, int);
void gimage_replace_image (GImage *, int, PixelRegion *, int, int,
void gimage_replace_image (GImage *, GimpDrawable *, PixelRegion *, int, int,
PixelRegion *, int, int);
void gimage_get_foreground (GImage *, int, unsigned char *);
void gimage_get_background (GImage *, int, unsigned char *);
void gimage_get_foreground (GImage *, GimpDrawable *, unsigned char *);
void gimage_get_background (GImage *, GimpDrawable *, unsigned char *);
void gimage_get_color (GImage *, int, unsigned char *,
unsigned char *);
void gimage_transform_color (GImage *, int, unsigned char *,
void gimage_transform_color (GImage *, GimpDrawable *, unsigned char *,
unsigned char *, int);
Guide* gimage_add_hguide (GImage *);
Guide* gimage_add_vguide (GImage *);
@ -180,36 +183,36 @@ void gimage_delete_guide (GImage *, Guide *);
/* layer/channel functions */
int gimage_get_layer_index (GImage *, int);
int gimage_get_channel_index (GImage *, int);
int gimage_get_layer_index (GImage *, Layer *);
int gimage_get_channel_index (GImage *, Channel *);
Layer * gimage_get_active_layer (GImage *);
Channel * gimage_get_active_channel (GImage *);
Channel * gimage_get_mask (GImage *);
int gimage_get_component_active (GImage *, ChannelType);
int gimage_get_component_visible (GImage *, ChannelType);
int gimage_layer_boundary (GImage *, BoundSeg **, int *);
Layer * gimage_set_active_layer (GImage *, int);
Channel * gimage_set_active_channel (GImage *, int);
Layer * gimage_set_active_layer (GImage *, Layer *);
Channel * gimage_set_active_channel (GImage *, Channel *);
Channel * gimage_unset_active_channel (GImage *);
void gimage_set_component_active (GImage *, ChannelType, int);
void gimage_set_component_visible (GImage *, ChannelType, int);
Layer * gimage_pick_correlate_layer (GImage *, int, int);
void gimage_set_layer_mask_apply (GImage *, int);
void gimage_set_layer_mask_edit (GImage *, int, int);
void gimage_set_layer_mask_edit (GImage *, Layer *, int);
void gimage_set_layer_mask_show (GImage *, int);
Layer * gimage_raise_layer (GImage *, int);
Layer * gimage_lower_layer (GImage *, int);
Layer * gimage_raise_layer (GImage *, Layer *);
Layer * gimage_lower_layer (GImage *, Layer *);
Layer * gimage_merge_visible_layers (GImage *, MergeType);
Layer * gimage_flatten (GImage *);
Layer * gimage_merge_layers (GImage *, link_ptr, MergeType);
Layer * gimage_add_layer (GImage *, Layer *, int);
Layer * gimage_remove_layer (GImage *, int);
Channel * gimage_add_layer_mask (GImage *, int, int);
Channel * gimage_remove_layer_mask (GImage *, int, int);
Channel * gimage_raise_channel (GImage *, int);
Channel * gimage_lower_channel (GImage *, int);
Layer * gimage_remove_layer (GImage *, Layer *);
LayerMask * gimage_add_layer_mask (GImage *, Layer *, LayerMask *);
Channel * gimage_remove_layer_mask (GImage *, Layer *, int);
Channel * gimage_raise_channel (GImage *, Channel *);
Channel * gimage_lower_channel (GImage *, Channel *);
Channel * gimage_add_channel (GImage *, Channel *, int);
Channel * gimage_remove_channel (GImage *, int);
Channel * gimage_remove_channel (GImage *, Channel *);
void gimage_construct (GImage *, int, int, int, int);
void gimage_invalidate (GImage *, int, int, int, int, int, int, int, int);
void gimage_validate (TileManager *, Tile *, int);
@ -221,7 +224,7 @@ void gimage_deflate (GImage *);
int gimage_is_flat (GImage *);
int gimage_is_empty (GImage *);
int gimage_active_drawable (GImage *);
GimpDrawable * gimage_active_drawable (GImage *);
int gimage_base_type (GImage *);
int gimage_base_type_with_alpha (GImage *);
char * gimage_filename (GImage *);
@ -254,4 +257,7 @@ void gimage_invalidate_preview (GImage *);
void gimage_invalidate_previews (void);
/* from drawable.c */
GImage * drawable_gimage (GimpDrawable*);
#endif /* __GIMAGE_H__ */

View file

@ -24,6 +24,10 @@
#include "gdisplay.h"
#include "gimage.h"
#include "gimage_cmds.h"
#include "floating_sel.h"
#include "layer_pvt.h" /* ick. */
#include "drawable_pvt.h" /* ick ick. */
static int int_value;
static int success;
@ -31,6 +35,9 @@ static Argument *return_args;
extern link_ptr image_list;
static GImage * duplicate (GImage *gimage);
static Argument * channel_ops_duplicate_invoker (Argument *args);
/************************/
/* GIMAGE_LIST_IMAGES */
@ -498,7 +505,7 @@ gimage_get_layers_invoker (Argument *args)
layer_ids = (int *) g_malloc (sizeof (int) * num_layers);
for (i = 0; i < num_layers; i++, layer_list = next_item (layer_list))
layer_ids[i] = ((Layer *) layer_list->data)->ID;
layer_ids[i] = drawable_ID (GIMP_DRAWABLE(((Layer *) layer_list->data)));
}
return_args[1].value.pdb_int = num_layers;
@ -586,7 +593,7 @@ gimage_get_channels_invoker (Argument *args)
channel_ids = (int *) g_malloc (sizeof (int) * num_channels);
for (i = 0; i < num_channels; i++, channel_list = next_item (channel_list))
channel_ids[i] = ((Channel *) channel_list->data)->ID;
channel_ids[i] = drawable_ID (GIMP_DRAWABLE(((Channel *) channel_list->data)));
}
return_args[1].value.pdb_int = num_channels;
@ -665,7 +672,7 @@ gimage_get_active_layer_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_get_active_layer_proc, success);
if (success)
return_args[1].value.pdb_int = (layer) ? layer->ID : -1;
return_args[1].value.pdb_int = (layer) ? drawable_ID (GIMP_DRAWABLE(layer)) : -1;
return return_args;
}
@ -735,7 +742,7 @@ gimage_get_active_channel_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_get_active_channel_proc, success);
if (success)
return_args[1].value.pdb_int = (channel) ? channel->ID : -1;
return_args[1].value.pdb_int = (channel) ? drawable_ID (GIMP_DRAWABLE(channel)) : -1;
return return_args;
}
@ -805,7 +812,7 @@ gimage_get_selection_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_get_selection_proc, success);
if (success)
return_args[1].value.pdb_int = mask->ID;
return_args[1].value.pdb_int = drawable_ID (GIMP_DRAWABLE(mask));
return return_args;
}
@ -1074,7 +1081,7 @@ gimage_set_active_layer_invoker (Argument *args)
}
if (success)
gimage_set_active_layer (gimage, layer->ID);
gimage_set_active_layer (gimage, layer);
return procedural_db_return_args (&gimage_set_active_layer_proc, success);
}
@ -1139,7 +1146,7 @@ gimage_set_active_channel_invoker (Argument *args)
}
if (success)
gimage_set_active_channel (gimage, channel->ID);
gimage_set_active_channel (gimage, channel);
return procedural_db_return_args (&gimage_set_active_channel_proc, success);
}
@ -1455,7 +1462,7 @@ gimage_pick_correlate_layer_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_pick_correlate_layer_proc, success);
if (success)
return_args[1].value.pdb_int = layer->ID;
return_args[1].value.pdb_int = drawable_ID (GIMP_DRAWABLE(layer));
return return_args;
}
@ -1532,7 +1539,7 @@ gimage_raise_layer_invoker (Argument *args)
}
if (success)
success = ((gimage_raise_layer (gimage, layer->ID)) != NULL);
success = ((gimage_raise_layer (gimage, layer)) != NULL);
return procedural_db_return_args (&gimage_raise_layer_proc, success);
}
@ -1597,7 +1604,7 @@ gimage_lower_layer_invoker (Argument *args)
}
if (success)
success = ((gimage_lower_layer (gimage, layer->ID)) != NULL);
success = ((gimage_lower_layer (gimage, layer)) != NULL);
return procedural_db_return_args (&gimage_lower_layer_proc, success);
}
@ -1677,7 +1684,7 @@ gimage_merge_visible_layers_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_merge_visible_layers_proc, success);
if (success)
return_args[1].value.pdb_int = layer->ID;
return_args[1].value.pdb_int = drawable_ID (GIMP_DRAWABLE(layer));
return return_args;
}
@ -1752,7 +1759,7 @@ gimage_flatten_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_flatten_proc, success);
if (success)
return_args[1].value.pdb_int = layer->ID;
return_args[1].value.pdb_int = drawable_ID (GIMP_DRAWABLE(layer));
return return_args;
}
@ -1822,9 +1829,9 @@ gimage_add_layer_invoker (Argument *args)
/* make sure that this layer can be added to the specified image */
if ((!success) ||
(drawable_color (layer->ID) && gimage_base_type (gimage) != RGB) ||
(drawable_gray (layer->ID) && gimage_base_type (gimage) != GRAY) ||
(drawable_indexed (layer->ID) && gimage_base_type (gimage) != INDEXED))
(drawable_color (GIMP_DRAWABLE(layer)) && gimage_base_type (gimage) != RGB) ||
(drawable_gray (GIMP_DRAWABLE(layer)) && gimage_base_type (gimage) != GRAY) ||
(drawable_indexed (GIMP_DRAWABLE(layer)) && gimage_base_type (gimage) != INDEXED))
success = FALSE;
}
if (success)
@ -1903,7 +1910,7 @@ gimage_remove_layer_invoker (Argument *args)
}
if (success)
gimage_remove_layer (gimage, layer->ID);
gimage_remove_layer (gimage, layer);
return procedural_db_return_args (&gimage_remove_layer_proc, success);
}
@ -1952,7 +1959,7 @@ gimage_add_layer_mask_invoker (Argument *args)
{
GImage *gimage;
Layer *layer;
Channel *mask;
LayerMask *mask;
success = TRUE;
if (success)
@ -1970,12 +1977,12 @@ gimage_add_layer_mask_invoker (Argument *args)
if (success)
{
int_value = args[2].value.pdb_int;
if ((mask = channel_get_ID (int_value)) == NULL)
if ((mask = layer_mask_get_ID (int_value)) == NULL)
success = FALSE;
}
if (success)
success = ((mask = gimage_add_layer_mask (gimage, layer->ID, mask->ID)) != NULL);
success = ((mask = gimage_add_layer_mask (gimage, layer, mask)) != NULL);
return procedural_db_return_args (&gimage_add_layer_mask_proc, success);
}
@ -2057,7 +2064,7 @@ gimage_remove_layer_mask_invoker (Argument *args)
}
if (success)
gimage_remove_layer_mask (gimage, layer->ID, mode);
gimage_remove_layer_mask (gimage, layer, mode);
return procedural_db_return_args (&gimage_remove_layer_mask_proc, success);
}
@ -2126,7 +2133,7 @@ gimage_raise_channel_invoker (Argument *args)
}
if (success)
success = ((gimage_raise_channel (gimage, channel->ID)) != NULL);
success = ((gimage_raise_channel (gimage, channel)) != NULL);
return procedural_db_return_args (&gimage_raise_channel_proc, success);
}
@ -2191,7 +2198,7 @@ gimage_lower_channel_invoker (Argument *args)
}
if (success)
success = ((gimage_lower_channel (gimage, channel->ID)) != NULL);
success = ((gimage_lower_channel (gimage, channel)) != NULL);
return procedural_db_return_args (&gimage_lower_channel_proc, success);
}
@ -2331,7 +2338,7 @@ gimage_remove_channel_invoker (Argument *args)
}
if (success)
success = (gimage_remove_channel (gimage, channel->ID) != NULL);
success = (gimage_remove_channel (gimage, channel) != NULL);
return procedural_db_return_args (&gimage_remove_channel_proc, success);
}
@ -2379,17 +2386,17 @@ static Argument *
gimage_active_drawable_invoker (Argument *args)
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
Argument *return_args;
drawable_id = -1;
drawable = NULL;
success = TRUE;
if (success)
{
int_value = args[0].value.pdb_int;
if ((gimage = gimage_get_ID (int_value)))
success = ((drawable_id = gimage_active_drawable (gimage)) != -1);
success = ((drawable = gimage_active_drawable (gimage)) != NULL);
else
success = FALSE;
}
@ -2397,7 +2404,7 @@ gimage_active_drawable_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_active_drawable_proc, success);
if (success)
return_args[1].value.pdb_int = drawable_id;
return_args[1].value.pdb_int = drawable_ID (drawable);
return return_args;
}
@ -3164,7 +3171,7 @@ gimage_floating_sel_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_floating_sel_proc, success);
if (success)
return_args[1].value.pdb_int = (floating_sel) ? floating_sel->ID : -1;
return_args[1].value.pdb_int = (floating_sel) ? drawable_ID (GIMP_DRAWABLE(floating_sel)) : -1;
return return_args;
}
@ -3207,3 +3214,205 @@ ProcRecord gimage_floating_sel_proc =
/* Exec method */
{ { gimage_floating_sel_invoker } },
};
static GImage *
duplicate (GImage *gimage)
{
PixelRegion srcPR, destPR;
GImage *new_gimage;
Layer *layer, *new_layer;
Layer *floating_layer;
Channel *channel, *new_channel;
link_ptr list;
Layer *active_layer = NULL;
Channel *active_channel = NULL;
GimpDrawable *new_floating_sel_drawable = NULL;
GimpDrawable *floating_sel_drawable = NULL;
int count;
/* Create a new image */
new_gimage = gimage_new (gimage->width, gimage->height, gimage->base_type);
gimage_disable_undo (new_gimage);
floating_layer = gimage_floating_sel (gimage);
if (floating_layer)
{
floating_sel_relax (floating_layer, FALSE);
floating_sel_drawable = floating_layer->fs.drawable;
floating_layer = NULL;
}
/* Copy the layers */
list = gimage->layers;
count = 0;
layer = NULL;
while (list)
{
layer = (Layer *) list->data;
list = next_item (list);
new_layer = layer_copy (layer, FALSE);
GIMP_DRAWABLE(new_layer)->ID = new_gimage->ID;
/* Make sure the copied layer doesn't say: "<old layer> copy" */
g_free (drawable_name (GIMP_DRAWABLE(new_layer)));
GIMP_DRAWABLE(new_layer)-> name = g_strdup (drawable_name (GIMP_DRAWABLE(layer)));
/* Make sure if the layer has a layer mask, it's name isn't screwed up */
if (new_layer->mask)
{
g_free (drawable_name (GIMP_DRAWABLE(new_layer->mask)));
GIMP_DRAWABLE(new_layer->mask)->name = g_strdup (drawable_name (GIMP_DRAWABLE(layer->mask)));
}
if (gimage->active_layer == layer)
active_layer = new_layer;
if (gimage->floating_sel == layer)
floating_layer = new_layer;
if (floating_sel_drawable == GIMP_DRAWABLE(layer))
new_floating_sel_drawable = GIMP_DRAWABLE(new_layer);
/* Add the layer */
if (floating_layer != new_layer)
gimage_add_layer (new_gimage, new_layer, count++);
}
/* Copy the channels */
list = gimage->channels;
count = 0;
while (list)
{
channel = (Channel *) list->data;
list = next_item (list);
new_channel = channel_copy (channel);
/* Make sure the copied channel doesn't say: "<old channel> copy" */
g_free (drawable_name (GIMP_DRAWABLE(new_channel)));
GIMP_DRAWABLE(new_channel)->name = g_strdup (drawable_name (GIMP_DRAWABLE(channel)));
if (gimage->active_channel == channel)
active_channel = (new_channel);
if (floating_sel_drawable == GIMP_DRAWABLE(channel))
new_floating_sel_drawable = GIMP_DRAWABLE(new_channel);
/* Add the channel */
gimage_add_channel (new_gimage, new_channel, count++);
}
/* Copy the selection mask */
pixel_region_init (&srcPR, drawable_data (GIMP_DRAWABLE(gimage->selection_mask)), 0, 0, gimage->width, gimage->height, FALSE);
pixel_region_init (&destPR, drawable_data (GIMP_DRAWABLE(new_gimage->selection_mask)), 0, 0, gimage->width, gimage->height, TRUE);
copy_region (&srcPR, &destPR);
new_gimage->selection_mask->bounds_known = FALSE;
new_gimage->selection_mask->boundary_known = FALSE;
/* Set active layer, active channel */
new_gimage->active_layer = active_layer;
new_gimage->active_channel = active_channel;
if (floating_layer)
floating_sel_attach (floating_layer, new_floating_sel_drawable);
/* Copy the colormap if necessary */
if (new_gimage->base_type == INDEXED)
memcpy (new_gimage->cmap, gimage->cmap, gimage->num_cols * 3);
new_gimage->num_cols = gimage->num_cols;
/* copy state of all color channels */
for (count = 0; count < MAX_CHANNELS; count++)
{
new_gimage->visible[count] = gimage->visible[count];
new_gimage->active[count] = gimage->active[count];
}
gimage_enable_undo (new_gimage);
return new_gimage;
}
/* The duplicate procedure definition */
ProcArg channel_ops_duplicate_args[] =
{
{ PDB_IMAGE,
"image",
"the image"
}
};
ProcArg channel_ops_duplicate_out_args[] =
{
{ PDB_IMAGE,
"new_image",
"the new, duplicated image"
}
};
ProcRecord channel_ops_duplicate_proc =
{
"gimp_channel_ops_duplicate",
"Duplicate the specified image",
"This procedure duplicates the specified image, copying all layers, channels, and image information.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1997",
PDB_INTERNAL,
/* Input arguments */
1,
channel_ops_duplicate_args,
/* Output arguments */
1,
channel_ops_duplicate_out_args,
/* Exec method */
{ { channel_ops_duplicate_invoker } },
};
static Argument *
channel_ops_duplicate_invoker (Argument *args)
{
Argument *return_args;
int success = TRUE;
int int_value;
GImage *gimage, *new_gimage;
new_gimage = NULL;
/* the gimage */
if (success)
{
int_value = args[0].value.pdb_int;
if (! (gimage = gimage_get_ID (int_value)))
success = FALSE;
}
if (success)
success = ((new_gimage = duplicate ((void *) gimage)) != NULL);
return_args = procedural_db_return_args (&channel_ops_duplicate_proc, success);
if (success)
return_args[1].value.pdb_int = new_gimage->ID;
return return_args;
}
void
channel_ops_duplicate (void *gimage_ptr)
{
GImage *gimage;
GImage *new_gimage;
gimage = (GImage *) gimage_ptr;
new_gimage = duplicate (gimage);
gdisplay_new (new_gimage, 0x0101);
}

View file

@ -20,6 +20,8 @@
#include "procedural_db.h"
void channel_ops_duplicate (void *);
extern ProcRecord gimage_list_images_proc;
extern ProcRecord gimage_new_proc;
extern ProcRecord gimage_resize_proc;
@ -63,5 +65,6 @@ extern ProcRecord gimage_enable_undo_proc;
extern ProcRecord gimage_disable_undo_proc;
extern ProcRecord gimage_clean_all_proc;
extern ProcRecord gimage_floating_sel_proc;
extern ProcRecord channel_ops_duplicate_proc;
#endif /* __GIMAGE_CMDS_H__ */

View file

@ -31,6 +31,10 @@
#include "paint_core.h"
#include "undo.h"
#include "layer_pvt.h"
#include "tile_manager_pvt.h"
#include "drawable_pvt.h"
/* feathering variables */
double gimage_mask_feather_radius = 5;
int gimage_mask_border_radius = 5;
@ -39,7 +43,7 @@ int gimage_mask_shrink_pixels = 1;
int gimage_mask_stroking = FALSE;
/* local functions */
static void * gimage_mask_stroke_paint_func (PaintCore *, int, int);
static void * gimage_mask_stroke_paint_func (PaintCore *, GimpDrawable *, int);
/* functions */
int
@ -86,10 +90,12 @@ gimage_mask_boundary (gimage, segs_in, segs_out, num_segs_in, num_segs_out)
/* if a layer is active, we return multiple boundaries based on the extents */
else if ((layer = gimage_get_active_layer (gimage)))
{
x1 = BOUNDS (layer->offset_x, 0, gimage->width);
y1 = BOUNDS (layer->offset_y, 0, gimage->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, gimage->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, gimage->height);
int off_x, off_y;
drawable_offsets (GIMP_DRAWABLE(layer), &off_x, &off_y);
x1 = BOUNDS (off_x, 0, gimage->width);
y1 = BOUNDS (off_y, 0, gimage->height);
x2 = BOUNDS (off_x + drawable_width (GIMP_DRAWABLE(layer)), 0, gimage->width);
y2 = BOUNDS (off_y + drawable_height (GIMP_DRAWABLE(layer)), 0, gimage->height);
return channel_boundary (gimage_get_mask (gimage),
segs_in, segs_out,
@ -135,7 +141,7 @@ gimage_mask_invalidate (gimage)
*/
layer = gimage_get_active_layer (gimage);
if (layer && layer_is_floating_sel (layer))
drawable_update (layer->ID, 0, 0, layer->width, layer->height);
drawable_update (GIMP_DRAWABLE(layer), 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height);
}
@ -174,15 +180,14 @@ gimage_mask_translate (gimage, off_x, off_y)
TileManager *
gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
gimage_mask_extract (gimage, drawable, cut_gimage, keep_indexed)
GImage * gimage;
int drawable_id;
GimpDrawable *drawable;
int cut_gimage;
int keep_indexed;
{
TileManager * tiles;
Channel * sel_mask;
Channel * channel;
PixelRegion srcPR, destPR, maskPR;
unsigned char bg[MAX_CHANNELS];
int bytes, type;
@ -190,13 +195,16 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
int off_x, off_y;
int non_empty;
if (!drawable)
return NULL;
/* If there are no bounds, then just extract the entire image
* This may not be the correct behavior, but after getting rid
* of floating selections, it's still tempting to "cut" or "copy"
* a small layer and expect it to work, even though there is no
* actual selection mask
*/
non_empty = drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
non_empty = drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
if (non_empty && (!(x2 - x1) || !(y2 - y1)))
{
message_box ("Unable to cut/copy because the selected\nregion is empty.", NULL, NULL);
@ -204,7 +212,7 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
}
/* How many bytes in the temp buffer? */
switch (drawable_type (drawable_id))
switch (drawable_type (drawable))
{
case RGB_GIMAGE: case RGBA_GIMAGE:
bytes = 4; type = RGB; break;
@ -232,13 +240,13 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
else
sel_mask = NULL;
gimage_get_background (gimage, drawable_id, bg);
gimage_get_background (gimage, drawable, bg);
/* If a cut was specified, and the selection mask is not empty, push an undo */
if (cut_gimage && non_empty)
drawable_apply_image (drawable_id, x1, y1, x2, y2, NULL, FALSE);
drawable_apply_image (drawable, x1, y1, x2, y2, NULL, FALSE);
drawable_offsets (drawable_id, &off_x, &off_y);
drawable_offsets (drawable, &off_x, &off_y);
/* Allocate the temp buffer */
tiles = tile_manager_new ((x2 - x1), (y2 - y1), bytes);
@ -246,16 +254,16 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
tiles->y = y1 + off_y;
/* configure the pixel regions */
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), cut_gimage);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), cut_gimage);
pixel_region_init (&destPR, tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
/* If there is a selection, extract from it */
if (non_empty)
{
pixel_region_init (&maskPR, sel_mask->tiles, (x1 + off_x), (y1 + off_y), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(sel_mask)->tiles, (x1 + off_x), (y1 + off_y), (x2 - x1), (y2 - y1), FALSE);
extract_from_region (&srcPR, &destPR, &maskPR, drawable_cmap (drawable_id),
bg, type, drawable_has_alpha (drawable_id), cut_gimage);
extract_from_region (&srcPR, &destPR, &maskPR, drawable_cmap (drawable),
bg, type, drawable_has_alpha (drawable), cut_gimage);
if (cut_gimage)
{
@ -267,7 +275,7 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
tiles->levels[0].width, tiles->levels[0].height);
/* Invalidate the preview */
drawable_invalidate_preview (drawable_id);
drawable_invalidate_preview (drawable);
}
}
/* Otherwise, get the entire active layer */
@ -275,8 +283,8 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
{
/* If the layer is indexed...we need to extract pixels */
if (type == INDEXED && !keep_indexed)
extract_from_region (&srcPR, &destPR, NULL, drawable_cmap (drawable_id),
bg, type, drawable_has_alpha (drawable_id), FALSE);
extract_from_region (&srcPR, &destPR, NULL, drawable_cmap (drawable),
bg, type, drawable_has_alpha (drawable), FALSE);
/* If the layer doesn't have an alpha channel, add one */
else if (bytes > srcPR.bytes)
add_alpha_region (&srcPR, &destPR);
@ -287,20 +295,19 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
/* If we're cutting, remove either the layer (or floating selection),
* the layer mask, or the channel
*/
if (cut_gimage && drawable_layer (drawable_id))
if (cut_gimage && drawable_layer (drawable))
{
if (layer_is_floating_sel (drawable_layer (drawable_id)))
floating_sel_remove (drawable_layer (drawable_id));
if (layer_is_floating_sel (drawable_layer (drawable)))
floating_sel_remove (drawable_layer (drawable));
else
gimage_remove_layer (gimage, drawable_id);
gimage_remove_layer (gimage, GIMP_LAYER (drawable));
}
else if (cut_gimage && drawable_layer_mask (drawable_id))
else if (cut_gimage && drawable_layer_mask (drawable))
{
if ((channel = channel_get_ID (drawable_id)))
gimage_remove_layer_mask (gimage, channel->layer_ID, DISCARD);
gimage_remove_layer_mask (gimage, GIMP_LAYER_MASK(drawable)->layer, DISCARD);
}
else if (cut_gimage && drawable_channel (drawable_id))
gimage_remove_channel (gimage, drawable_id);
else if (cut_gimage && drawable_channel (drawable))
gimage_remove_channel (gimage, GIMP_CHANNEL(drawable));
}
return tiles;
@ -308,9 +315,9 @@ gimage_mask_extract (gimage, drawable_id, cut_gimage, keep_indexed)
Layer *
gimage_mask_float (gimage, drawable_id, off_x, off_y)
gimage_mask_float (gimage, drawable, off_x, off_y)
GImage * gimage;
int drawable_id;
GimpDrawable* drawable;
int off_x, off_y; /* optional offset */
{
Layer *layer;
@ -320,7 +327,7 @@ gimage_mask_float (gimage, drawable_id, off_x, off_y)
int x1, y1, x2, y2;
/* Make sure there is a region to float... */
non_empty = drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
non_empty = drawable_mask_bounds ( (drawable), &x1, &y1, &x2, &y2);
if (! non_empty || (x2 - x1) == 0 || (y2 - y1) == 0)
{
message_box ("Float Selection: No selection to float.", NULL, NULL);
@ -331,20 +338,20 @@ gimage_mask_float (gimage, drawable_id, off_x, off_y)
undo_push_group_start (gimage, FLOAT_MASK_UNDO);
/* Cut the selected region */
tiles = gimage_mask_extract (gimage, drawable_id, TRUE, FALSE);
tiles = gimage_mask_extract (gimage, drawable, TRUE, FALSE);
/* Create a new layer from the buffer */
layer = layer_from_tiles (gimage, drawable_id, tiles, "Floated Layer", OPAQUE, NORMAL);
layer = layer_from_tiles (gimage, drawable, tiles, "Floated Layer", OPAQUE, NORMAL);
/* Set the offsets */
layer->offset_x = tiles->x + off_x;
layer->offset_y = tiles->y + off_y;
GIMP_DRAWABLE(layer)->offset_x = tiles->x + off_x;
GIMP_DRAWABLE(layer)->offset_y = tiles->y + off_y;
/* Free the temp buffer */
tile_manager_destroy (tiles);
/* Add the floating layer to the gimage */
floating_sel_attach (layer, drawable_id);
floating_sel_attach (layer, drawable);
/* End an undo group */
undo_push_group_end (gimage);
@ -465,15 +472,15 @@ gimage_mask_shrink (gimage, shrink_pixels)
void
gimage_mask_layer_alpha (gimage, layer_id)
gimage_mask_layer_alpha (gimage, layer)
GImage *gimage;
int layer_id;
Layer *layer;
{
/* extract the layer's alpha channel */
if (drawable_has_alpha (layer_id))
if (drawable_has_alpha (GIMP_DRAWABLE (layer)))
{
/* load the mask with the given layer's alpha channel */
channel_layer_alpha (gimage_get_mask (gimage), layer_id);
channel_layer_alpha (gimage_get_mask (gimage), layer);
}
else
{
@ -484,20 +491,15 @@ gimage_mask_layer_alpha (gimage, layer_id)
void
gimage_mask_layer_mask (gimage, layer_id)
gimage_mask_layer_mask (gimage, layer)
GImage *gimage;
int layer_id;
Layer *layer;
{
Layer *layer;
if ((layer = layer_get_ID (layer_id)) == NULL)
return;
/* extract the layer's alpha channel */
if (layer->mask)
{
/* load the mask with the given layer's alpha channel */
channel_layer_mask (gimage_get_mask (gimage), layer_id);
channel_layer_mask (gimage_get_mask (gimage), layer);
}
else
{
@ -508,12 +510,12 @@ gimage_mask_layer_mask (gimage, layer_id)
void
gimage_mask_load (gimage, channel_id)
gimage_mask_load (gimage, channel)
GImage *gimage;
int channel_id;
Channel *channel;
{
/* Load the specified channel to the gimage mask */
channel_load (gimage_get_mask (gimage), channel_get_ID (channel_id));
channel_load (gimage_get_mask (gimage), (channel));
}
@ -526,7 +528,7 @@ gimage_mask_save (gimage)
new_channel = channel_copy (gimage_get_mask (gimage));
/* saved selections are not visible by default */
new_channel->visible = FALSE;
GIMP_DRAWABLE(new_channel)->visible = FALSE;
gimage_add_channel (gimage, new_channel, -1);
return new_channel;
@ -534,9 +536,9 @@ gimage_mask_save (gimage)
int
gimage_mask_stroke (gimage, drawable_id)
gimage_mask_stroke (gimage, drawable)
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
{
BoundSeg *bs_in;
BoundSeg *bs_out;
@ -559,10 +561,10 @@ gimage_mask_stroke (gimage, drawable_id)
return TRUE;
/* find the drawable offsets */
drawable_offsets (drawable_id, &offx, &offy);
drawable_offsets (drawable, &offx, &offy);
/* init the paint core */
if (! paint_core_init (&non_gui_paint_core, drawable_id,
if (! paint_core_init (&non_gui_paint_core, drawable,
(stroke_segs[0].x1 - offx),
(stroke_segs[0].y1 - offy)))
return FALSE;
@ -582,7 +584,7 @@ gimage_mask_stroke (gimage, drawable_id)
non_gui_paint_core.curx = (stroke_segs[seg].x2 - offx);
non_gui_paint_core.cury = (stroke_segs[seg].y2 - offy);
paint_core_interpolate (&non_gui_paint_core, drawable_id);
paint_core_interpolate (&non_gui_paint_core, drawable);
non_gui_paint_core.lastx = non_gui_paint_core.curx;
non_gui_paint_core.lasty = non_gui_paint_core.cury;
@ -596,7 +598,7 @@ gimage_mask_stroke (gimage, drawable_id)
}
/* finish the painting */
paint_core_finish (&non_gui_paint_core, drawable_id, -1);
paint_core_finish (&non_gui_paint_core, drawable, -1);
/* cleanup */
gimage_mask_stroking = FALSE;
@ -607,22 +609,22 @@ gimage_mask_stroke (gimage, drawable_id)
}
static void *
gimage_mask_stroke_paint_func (paint_core, drawable_id, state)
gimage_mask_stroke_paint_func (paint_core, drawable, state)
PaintCore *paint_core;
int drawable_id;
GimpDrawable *drawable;
int state;
{
GImage *gimage;
TempBuf * area;
unsigned char col[MAX_CHANNELS];
if (! (gimage = drawable_gimage (drawable_id)))
if (! (gimage = drawable_gimage (drawable)))
return NULL;
gimage_get_foreground (gimage, drawable_id, col);
gimage_get_foreground (gimage, drawable, col);
/* Get a region which can be used to paint to */
if (! (area = paint_core_get_paint_area (paint_core, drawable_id)))
if (! (area = paint_core_get_paint_area (paint_core, drawable)))
return NULL;
/* set the alpha channel */
@ -633,7 +635,7 @@ gimage_mask_stroke_paint_func (paint_core, drawable_id, state)
area->width * area->height, area->bytes);
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable_id, OPAQUE,
paint_core_paste_canvas (paint_core, drawable, OPAQUE,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);

View file

@ -28,8 +28,8 @@ void gimage_mask_invalidate (GImage *);
int gimage_mask_value (GImage *, int, int);
int gimage_mask_is_empty (GImage *);
void gimage_mask_translate (GImage *, int, int);
TileManager * gimage_mask_extract (GImage *, int, int, int);
Layer * gimage_mask_float (GImage *, int, int, int);
TileManager * gimage_mask_extract (GImage *, GimpDrawable *, int, int);
Layer * gimage_mask_float (GImage *, GimpDrawable *, int, int);
void gimage_mask_clear (GImage *);
void gimage_mask_undo (GImage *);
void gimage_mask_invert (GImage *);
@ -40,10 +40,10 @@ void gimage_mask_feather (GImage *, double);
void gimage_mask_border (GImage *, int);
void gimage_mask_grow (GImage *, int);
void gimage_mask_shrink (GImage *, int);
void gimage_mask_layer_alpha (GImage *, int);
void gimage_mask_layer_mask (GImage *, int);
void gimage_mask_load (GImage *, int);
void gimage_mask_layer_alpha (GImage *, Layer *);
void gimage_mask_layer_mask (GImage *, Layer *);
void gimage_mask_load (GImage *, Channel *);
Channel * gimage_mask_save (GImage *);
int gimage_mask_stroke (GImage *, int);
int gimage_mask_stroke (GImage *, GimpDrawable *);
#endif /* __GIMAGE_MASK_H__ */

View file

@ -349,7 +349,7 @@ static Argument *
gimage_mask_float_invoker (Argument *args)
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int offx, offy;
Layer *layer;
@ -364,17 +364,21 @@ gimage_mask_float_invoker (Argument *args)
}
if (success)
{
drawable_id = args[1].value.pdb_int;
int_value = args[1].value.pdb_int;
drawable = drawable_get_ID (int_value);
}
if (success)
{
offx = args[2].value.pdb_int;
offy = args[3].value.pdb_int;
}
if (success)
success = ((layer = gimage_mask_float (gimage, drawable_id, offx, offy)) != NULL);
success = ((layer = gimage_mask_float (gimage, drawable, offx, offy)) != NULL);
return_args = procedural_db_return_args (&gimage_mask_float_proc, success);
if (success)
return_args[1].value.pdb_int = layer->ID;
return_args[1].value.pdb_int = drawable_ID (GIMP_DRAWABLE(layer));
return return_args;
}
@ -981,7 +985,7 @@ gimage_mask_layer_alpha_invoker (Argument *args)
success = FALSE;
}
if (success)
gimage_mask_layer_alpha (gimage, layer->ID);
gimage_mask_layer_alpha (gimage, layer);
return procedural_db_return_args (&gimage_mask_layer_alpha_proc, success);
}
@ -1044,11 +1048,12 @@ gimage_mask_load_invoker (Argument *args)
if ((channel = channel_get_ID (int_value)) == NULL)
success = FALSE;
else
success = (channel->width == gimage->width && channel->height == gimage->height);
success = (drawable_width (GIMP_DRAWABLE(channel)) == gimage->width &&
drawable_height (GIMP_DRAWABLE(channel)) == gimage->height);
}
if (success)
gimage_mask_load (gimage, channel->ID);
gimage_mask_load (gimage, channel);
return procedural_db_return_args (&gimage_mask_load_proc, success);
}
@ -1114,7 +1119,7 @@ gimage_mask_save_invoker (Argument *args)
return_args = procedural_db_return_args (&gimage_mask_save_proc, success);
if (success)
return_args[1].value.pdb_int = channel->ID;
return_args[1].value.pdb_int = drawable_ID (GIMP_DRAWABLE(channel));
return return_args;
}

View file

@ -31,6 +31,61 @@
#include "temp_buf.h"
#include "undo.h"
#include "channel_pvt.h"
enum {
LAST_SIGNAL
};
static void gimp_channel_class_init (GimpChannelClass *klass);
static void gimp_channel_init (GimpChannel *channel);
static void gimp_channel_destroy (GtkObject *object);
static gint channel_signals[LAST_SIGNAL] = { 0 };
static GimpDrawableClass *parent_class = NULL;
guint
gimp_channel_get_type ()
{
static guint channel_type = 0;
if (!channel_type)
{
GtkTypeInfo channel_info =
{
"GimpChannel",
sizeof (GimpChannel),
sizeof (GimpChannelClass),
(GtkClassInitFunc) gimp_channel_class_init,
(GtkObjectInitFunc) gimp_channel_init,
(GtkArgFunc) NULL,
};
channel_type = gtk_type_unique (gimp_drawable_get_type (), &channel_info);
}
return channel_type;
}
static void
gimp_channel_class_init (GimpChannelClass *class)
{
GtkObjectClass *object_class;
object_class = (GtkObjectClass*) class;
parent_class = gtk_type_class (gimp_drawable_get_type ());
gtk_object_class_add_signals (object_class, channel_signals, LAST_SIGNAL);
object_class->destroy = gimp_channel_destroy;
}
static void
gimp_channel_init (GimpChannel *channel)
{
}
#define ROUND(x) ((int) (x + 0.5))
@ -38,8 +93,8 @@
* Static variables
*/
extern int global_drawable_ID;
static link_ptr channel_list = NULL;
int channel_get_count = 0;
/**************************/
@ -53,19 +108,6 @@ channel_validate (TileManager *tm, Tile *tile, int level)
}
void
channel_allocate (Channel *channel, int width, int height)
{
channel->tiles = tile_manager_new (width, height, 1);
}
void
channel_deallocate (Channel *channel)
{
if (channel->tiles)
tile_manager_destroy (channel->tiles);
}
Channel *
@ -75,37 +117,16 @@ channel_new (int gimage_ID, int width, int height, char *name, int opacity,
Channel * channel;
int i;
channel = (Channel *) g_malloc (sizeof (Channel));
channel = gtk_type_new (gimp_channel_get_type ());
if (!name)
name = "unnamed";
channel->name = (char *) g_malloc (strlen (name) + 1);
strcpy (channel->name, name);
/* set size information */
channel->width = width;
channel->height = height;
channel->bytes = 1;
/* allocate the memory for this channel */
channel_allocate (channel, width, height);
channel->visible = 1;
gimp_drawable_configure (GIMP_DRAWABLE(channel),
gimage_ID, width, height, GRAY_GIMAGE, name);
/* set the channel color and opacity */
for (i = 0; i < 3; i++)
channel->col[i] = col[i];
channel->opacity = opacity;
channel->show_masked = 1;
channel->dirty = 0;
/* give this channel an ID */
channel->ID = global_drawable_ID++;
channel->layer_ID = -1;
channel->gimage_ID = gimage_ID;
/* add the new channel to the global list */
channel_list = append_to_list (channel_list, (void *) channel);
/* selection mask variables */
channel->empty = TRUE;
@ -119,10 +140,6 @@ channel_new (int gimage_ID, int width, int height, char *name, int opacity,
channel->x2 = width;
channel->y2 = height;
/* preview variables */
channel->preview = NULL;
channel->preview_valid = FALSE;
return channel;
}
@ -135,18 +152,22 @@ channel_copy (Channel *channel)
PixelRegion srcPR, destPR;
/* formulate the new channel name */
channel_name = (char *) g_malloc (strlen (channel->name) + 6);
sprintf (channel_name, "%s copy", channel->name);
channel_name = (char *) g_malloc (strlen (GIMP_DRAWABLE(channel)->name) + 6);
sprintf (channel_name, "%s copy", GIMP_DRAWABLE(channel)->name);
/* allocate a new channel object */
new_channel = channel_new (channel->gimage_ID, channel->width, channel->height, channel_name,
channel->opacity, channel->col);
new_channel->visible = channel->visible;
new_channel = channel_new (GIMP_DRAWABLE(channel)->gimage_ID,
GIMP_DRAWABLE(channel)->width,
GIMP_DRAWABLE(channel)->height,
channel_name, channel->opacity, channel->col);
GIMP_DRAWABLE(new_channel)->visible = GIMP_DRAWABLE(channel)->visible;
new_channel->show_masked = channel->show_masked;
/* copy the contents across channels */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&destPR, new_channel->tiles, 0, 0, channel->width, channel->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0,
GIMP_DRAWABLE(channel)->width,
GIMP_DRAWABLE(channel)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(new_channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, TRUE);
copy_region (&srcPR, &destPR);
/* free up the channel_name memory */
@ -159,56 +180,42 @@ channel_copy (Channel *channel)
Channel *
channel_get_ID (int ID)
{
link_ptr tmp = channel_list;
Channel * channel;
while (tmp)
{
channel = (Channel *) tmp->data;
if (channel->ID == ID)
return channel;
tmp = next_item (tmp);
}
return NULL;
GimpDrawable *drawable;
drawable = drawable_get_ID (ID);
if (drawable && GIMP_IS_CHANNEL (drawable))
return GIMP_CHANNEL (drawable);
else
return NULL;
}
void
channel_delete (Channel *channel)
{
gtk_object_destroy (GTK_OBJECT (channel));
}
static void
gimp_channel_destroy (GtkObject *object)
{
GimpChannel *channel;
g_return_if_fail (object != NULL);
g_return_if_fail (GIMP_IS_CHANNEL (object));
channel = GIMP_CHANNEL (object);
/* free the segments? */
if (channel->segs_in)
g_free (channel->segs_in);
if (channel->segs_out)
g_free (channel->segs_out);
/* remove this image from the global list */
channel_list = remove_from_list (channel_list, (void *) channel);
/* deallocate the channel mem */
channel_deallocate (channel);
/* free the channel name buffer */
g_free (channel->name);
g_free (channel);
if (GTK_OBJECT_CLASS (parent_class)->destroy)
(*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
}
void
channel_apply_image (Channel *channel, int x1, int y1, int x2, int y2,
TileManager *tiles, int sparse)
{
/* Need to push an undo operation */
if (! tiles)
undo_push_image (gimage_get_ID (channel->gimage_ID), channel->ID, x1, y1, x2, y2);
else
undo_push_image_mod (gimage_get_ID (channel->gimage_ID), channel->ID, x1, y1, x2, y2, tiles, sparse);
}
void
channel_scale (Channel *channel, int new_width, int new_height)
{
@ -219,10 +226,10 @@ channel_scale (Channel *channel, int new_width, int new_height)
return;
/* Update the old channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
/* Allocate the new channel, configure dest region */
new_tiles = tile_manager_new (new_width, new_height, 1);
@ -232,18 +239,18 @@ channel_scale (Channel *channel, int new_width, int new_height)
scale_region (&srcPR, &destPR);
/* Push the channel on the undo stack */
undo_push_channel_mod (gimage_get_ID (channel->gimage_ID), channel);
undo_push_channel_mod (gimage_get_ID (GIMP_DRAWABLE(channel)->gimage_ID), channel);
/* Configure the new channel */
channel->tiles = new_tiles;
channel->width = new_width;
channel->height = new_height;
GIMP_DRAWABLE(channel)->tiles = new_tiles;
GIMP_DRAWABLE(channel)->width = new_width;
GIMP_DRAWABLE(channel)->height = new_height;
/* bounds are now unknown */
channel->bounds_known = FALSE;
/* Update the new channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
}
@ -263,8 +270,8 @@ channel_resize (Channel *channel, int new_width, int new_height,
x1 = BOUNDS (offx, 0, new_width);
y1 = BOUNDS (offy, 0, new_height);
x2 = BOUNDS ((offx + channel->width), 0, new_width);
y2 = BOUNDS ((offy + channel->height), 0, new_height);
x2 = BOUNDS ((offx + GIMP_DRAWABLE(channel)->width), 0, new_width);
y2 = BOUNDS ((offy + GIMP_DRAWABLE(channel)->height), 0, new_height);
w = x2 - x1;
h = y2 - y1;
@ -291,14 +298,14 @@ channel_resize (Channel *channel, int new_width, int new_height,
}
/* Update the old channel position */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
/* Configure the pixel regions */
pixel_region_init (&srcPR, channel->tiles, x1, y1, w, h, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, x1, y1, w, h, FALSE);
/* Determine whether the new channel needs to be initially cleared */
if ((new_width > channel->width) ||
(new_height > channel->height) ||
if ((new_width > GIMP_DRAWABLE(channel)->width) ||
(new_height > GIMP_DRAWABLE(channel)->height) ||
(x2 || y2))
clear = TRUE;
else
@ -320,18 +327,18 @@ channel_resize (Channel *channel, int new_width, int new_height,
copy_region (&srcPR, &destPR);
/* Push the channel on the undo stack */
undo_push_channel_mod (gimage_get_ID (channel->gimage_ID), channel);
undo_push_channel_mod (gimage_get_ID (GIMP_DRAWABLE(channel)->gimage_ID), channel);
/* Configure the new channel */
channel->tiles = new_tiles;
channel->width = new_width;
channel->height = new_height;
GIMP_DRAWABLE(channel)->tiles = new_tiles;
GIMP_DRAWABLE(channel)->width = new_width;
GIMP_DRAWABLE(channel)->height = new_height;
/* bounds are now unknown */
channel->bounds_known = FALSE;
/* update the new channel area */
drawable_update (channel->ID, 0, 0, channel->width, channel->height);
drawable_update (GIMP_DRAWABLE(channel), 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height);
}
@ -348,9 +355,9 @@ channel_data (Channel *channel)
int
channel_toggle_visibility (Channel *channel)
{
channel->visible = !channel->visible;
GIMP_DRAWABLE(channel)->visible = !GIMP_DRAWABLE(channel)->visible;
return channel->visible;
return GIMP_DRAWABLE(channel)->visible;
}
@ -362,10 +369,10 @@ channel_preview (Channel *channel, int width, int height)
int subsample;
/* The easy way */
if (channel->preview_valid &&
channel->preview->width == width &&
channel->preview->height == height)
return channel->preview;
if (GIMP_DRAWABLE(channel)->preview_valid &&
GIMP_DRAWABLE(channel)->preview->width == width &&
GIMP_DRAWABLE(channel)->preview->height == height)
return GIMP_DRAWABLE(channel)->preview;
/* The hard way */
else
{
@ -373,11 +380,11 @@ channel_preview (Channel *channel, int width, int height)
subsample = 1;
if (width < 1) width = 1;
if (height < 1) height = 1;
while ((width * (subsample + 1) * 2 < channel->width) &&
(height * (subsample + 1) * 2 < channel->height))
while ((width * (subsample + 1) * 2 < GIMP_DRAWABLE(channel)->width) &&
(height * (subsample + 1) * 2 < GIMP_DRAWABLE(channel)->height))
subsample = subsample + 1;
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
preview_buf = mask_buf_new (width, height);
destPR.bytes = 1;
@ -390,13 +397,13 @@ channel_preview (Channel *channel, int width, int height)
subsample_region (&srcPR, &destPR, subsample);
if (channel->preview_valid)
mask_buf_free (channel->preview);
if (GIMP_DRAWABLE(channel)->preview_valid)
mask_buf_free (GIMP_DRAWABLE(channel)->preview);
channel->preview = preview_buf;
channel->preview_valid = 1;
GIMP_DRAWABLE(channel)->preview = preview_buf;
GIMP_DRAWABLE(channel)->preview_valid = 1;
return channel->preview;
return GIMP_DRAWABLE(channel)->preview;
}
}
@ -404,14 +411,19 @@ channel_preview (Channel *channel, int width, int height)
void
channel_invalidate_previews (int gimage_id)
{
link_ptr tmp = channel_list;
link_ptr tmp;
Channel * channel;
GImage * gimage;
if (! (gimage = gimage_get_ID (gimage_id)))
return;
tmp = gimage->channels;
while (tmp)
{
channel = (Channel *) tmp->data;
if (gimage_id == -1 || (channel->gimage_ID == gimage_id))
drawable_invalidate_preview (channel->ID);
drawable_invalidate_preview (GIMP_DRAWABLE(channel));
tmp = next_item (tmp);
}
}
@ -431,7 +443,7 @@ channel_new_mask (int gimage_ID, int width, int height)
new_channel = channel_new (gimage_ID, width, height, "Selection Mask", 127, black);
/* Set the validate procedure */
tile_manager_set_validate_proc (new_channel->tiles, channel_validate);
tile_manager_set_validate_proc (GIMP_DRAWABLE(new_channel)->tiles, channel_validate);
return new_channel;
}
@ -455,7 +467,7 @@ channel_boundary (Channel *mask, BoundSeg **segs_in, BoundSeg **segs_out,
if (channel_bounds (mask, &x3, &y3, &x4, &y4))
{
pixel_region_init (&bPR, mask->tiles, x3, y3, (x4 - x3), (y4 - y3), FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x3, y3, (x4 - x3), (y4 - y3), FALSE);
mask->segs_out = find_mask_boundary (&bPR, &mask->num_segs_out,
IgnoreBounds,
x1, y1,
@ -467,7 +479,7 @@ channel_boundary (Channel *mask, BoundSeg **segs_in, BoundSeg **segs_out,
if (x2 > x1 && y2 > y1)
{
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
mask->segs_in = find_mask_boundary (&bPR, &mask->num_segs_in,
WithinBounds,
x1, y1,
@ -514,11 +526,11 @@ channel_value (Channel *mask, int x, int y)
}
else
{
if (x < 0 || x >= mask->width || y < 0 || y >= mask->height)
if (x < 0 || x >= GIMP_DRAWABLE(mask)->width || y < 0 || y >= GIMP_DRAWABLE(mask)->height)
return 0;
}
tile = tile_manager_get_tile (mask->tiles, x, y, 0);
tile = tile_manager_get_tile (GIMP_DRAWABLE(mask)->tiles, x, y, 0);
tile_ref (tile);
val = tile->data[(y % TILE_HEIGHT) * TILE_WIDTH + (x % TILE_WIDTH)];
tile_unref (tile, FALSE);
@ -549,12 +561,12 @@ channel_bounds (Channel *mask, int *x1, int *y1, int *x2, int *y2)
}
/* go through and calculate the bounds */
*x1 = mask->width;
*y1 = mask->height;
*x1 = GIMP_DRAWABLE(mask)->width;
*y1 = GIMP_DRAWABLE(mask)->height;
*x2 = 0;
*y2 = 0;
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -583,15 +595,15 @@ channel_bounds (Channel *mask, int *x1, int *y1, int *x2, int *y2)
}
}
*x2 = BOUNDS (*x2 + 1, 0, mask->width);
*y2 = BOUNDS (*y2 + 1, 0, mask->height);
*x2 = BOUNDS (*x2 + 1, 0, GIMP_DRAWABLE(mask)->width);
*y2 = BOUNDS (*y2 + 1, 0, GIMP_DRAWABLE(mask)->height);
if (*x1 == mask->width && *y1 == mask->height)
if (*x1 == GIMP_DRAWABLE(mask)->width && *y1 == GIMP_DRAWABLE(mask)->height)
{
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
else
{
@ -618,7 +630,7 @@ channel_is_empty (Channel *mask)
if (mask->bounds_known)
return mask->empty;
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, FALSE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, FALSE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* check if any pixel in the mask is non-zero */
@ -646,8 +658,8 @@ channel_is_empty (Channel *mask)
mask->bounds_known = TRUE;
mask->boundary_known = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
return TRUE;
}
@ -665,16 +677,16 @@ channel_add_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -702,16 +714,16 @@ channel_sub_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -739,16 +751,16 @@ channel_inter_segment (Channel *mask, int x, int y, int width, int value)
/* check horizontal extents... */
x2 = x + width;
if (x2 < 0) x2 = 0;
if (x2 > mask->width) x2 = mask->width;
if (x2 > GIMP_DRAWABLE(mask)->width) x2 = GIMP_DRAWABLE(mask)->width;
if (x < 0) x = 0;
if (x > mask->width) x = mask->width;
if (x > GIMP_DRAWABLE(mask)->width) x = GIMP_DRAWABLE(mask)->width;
width = x2 - x;
if (!width) return;
if (y < 0 || y > mask->height)
if (y < 0 || y > GIMP_DRAWABLE(mask)->height)
return;
pixel_region_init (&maskPR, mask->tiles, x, y, width, 1, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, x, y, width, 1, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
data = maskPR.data;
@ -768,7 +780,7 @@ channel_combine_rect (Channel *mask, int op, int x, int y, int w, int h)
for (i = y; i < y + h; i++)
{
if (i >= 0 && i < mask->height)
if (i >= 0 && i < GIMP_DRAWABLE(mask)->height)
switch (op)
{
case ADD: case REPLACE:
@ -806,10 +818,10 @@ channel_combine_rect (Channel *mask, int op, int x, int y, int w, int h)
else
mask->bounds_known = FALSE;
mask->x1 = BOUNDS (mask->x1, 0, mask->width);
mask->y1 = BOUNDS (mask->y1, 0, mask->height);
mask->x2 = BOUNDS (mask->x2, 0, mask->width);
mask->y2 = BOUNDS (mask->y2, 0, mask->height);
mask->x1 = BOUNDS (mask->x1, 0, GIMP_DRAWABLE(mask)->width);
mask->y1 = BOUNDS (mask->y1, 0, GIMP_DRAWABLE(mask)->height);
mask->x2 = BOUNDS (mask->x2, 0, GIMP_DRAWABLE(mask)->width);
mask->y2 = BOUNDS (mask->y2, 0, GIMP_DRAWABLE(mask)->height);
}
@ -842,7 +854,7 @@ channel_combine_ellipse (Channel *mask, int op, int x, int y, int w, int h,
for (i = y; i < (y + h); i++)
{
if (i >= 0 && i < mask->height)
if (i >= 0 && i < GIMP_DRAWABLE(mask)->height)
{
/* Non-antialiased code */
if (!aa)
@ -952,10 +964,10 @@ channel_combine_ellipse (Channel *mask, int op, int x, int y, int w, int h,
else
mask->bounds_known = FALSE;
mask->x1 = BOUNDS (mask->x1, 0, mask->width);
mask->y1 = BOUNDS (mask->y1, 0, mask->height);
mask->x2 = BOUNDS (mask->x2, 0, mask->width);
mask->y2 = BOUNDS (mask->y2, 0, mask->height);
mask->x1 = BOUNDS (mask->x1, 0, GIMP_DRAWABLE(mask)->width);
mask->y1 = BOUNDS (mask->y1, 0, GIMP_DRAWABLE(mask)->height);
mask->x2 = BOUNDS (mask->x2, 0, GIMP_DRAWABLE(mask)->width);
mask->y2 = BOUNDS (mask->y2, 0, GIMP_DRAWABLE(mask)->height);
}
@ -972,16 +984,16 @@ channel_combine_mask (Channel *mask, Channel *add_on, int op,
int w, h;
void * pr;
x1 = BOUNDS (off_x, 0, mask->width);
y1 = BOUNDS (off_y, 0, mask->height);
x2 = BOUNDS (off_x + add_on->width, 0, mask->width);
y2 = BOUNDS (off_y + add_on->height, 0, mask->height);
x1 = BOUNDS (off_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS (off_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS (off_x + GIMP_DRAWABLE(add_on)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS (off_y + GIMP_DRAWABLE(add_on)->height, 0, GIMP_DRAWABLE(mask)->height);
w = (x2 - x1);
h = (y2 - y1);
pixel_region_init (&srcPR, add_on->tiles, (x1 - off_x), (y1 - off_y), w, h, FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, w, h, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(add_on)->tiles, (x1 - off_x), (y1 - off_y), w, h, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, w, h, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -1027,12 +1039,12 @@ channel_feather (Channel *input, Channel *output, double radius,
int x1, y1, x2, y2;
PixelRegion srcPR;
x1 = BOUNDS (off_x, 0, output->width);
y1 = BOUNDS (off_y, 0, output->height);
x2 = BOUNDS (off_x + input->width, 0, output->width);
y2 = BOUNDS (off_y + input->height, 0, output->height);
x1 = BOUNDS (off_x, 0, GIMP_DRAWABLE(output)->width);
y1 = BOUNDS (off_y, 0, GIMP_DRAWABLE(output)->height);
x2 = BOUNDS (off_x + GIMP_DRAWABLE(input)->width, 0, GIMP_DRAWABLE(output)->width);
y2 = BOUNDS (off_y + GIMP_DRAWABLE(input)->height, 0, GIMP_DRAWABLE(output)->height);
pixel_region_init (&srcPR, input->tiles, (x1 - off_x), (y1 - off_y), (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(input)->tiles, (x1 - off_x), (y1 - off_y), (x2 - x1), (y2 - y1), FALSE);
gaussian_blur_region (&srcPR, radius);
if (input != output)
@ -1055,7 +1067,7 @@ channel_push_undo (Channel *mask)
if (channel_bounds (mask, &x1, &y1, &x2, &y2))
{
undo_tiles = tile_manager_new ((x2 - x1), (y2 - y1), 1);
pixel_region_init (&srcPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, undo_tiles, 0, 0, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
}
@ -1067,12 +1079,12 @@ channel_push_undo (Channel *mask)
mask_undo->y = y1;
/* push the undo buffer onto the undo stack */
gimage = gimage_get_ID (mask->gimage_ID);
gimage = gimage_get_ID (GIMP_DRAWABLE(mask)->gimage_ID);
undo_push_mask (gimage, mask_undo);
gimage_mask_invalidate (gimage);
/* invalidate the preview */
mask->preview_valid = 0;
GIMP_DRAWABLE(mask)->preview_valid = 0;
}
@ -1087,14 +1099,14 @@ channel_clear (Channel *mask)
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&maskPR, mask->tiles, mask->x1, mask->y1,
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&maskPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&maskPR, &bg);
}
@ -1102,8 +1114,8 @@ channel_clear (Channel *mask)
mask->bounds_known = TRUE;
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
@ -1118,7 +1130,7 @@ channel_invert (Channel *mask)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* subtract each pixel in the mask from 255 */
@ -1146,7 +1158,7 @@ channel_sharpen (Channel *mask)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
for (pr = pixel_regions_register (1, &maskPR); pr != NULL; pr = pixel_regions_process (pr))
{
/* if a pixel in the mask has a non-zero value, make it 255 */
@ -1175,15 +1187,15 @@ channel_all (Channel *mask)
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&maskPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&maskPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&maskPR, &bg);
/* we know the bounds */
mask->bounds_known = TRUE;
mask->empty = FALSE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
@ -1202,25 +1214,25 @@ channel_border (Channel *mask, int radius)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), FALSE);
bs = find_mask_boundary (&bPR, &num_segs, WithinBounds, x1, y1, x2, y2);
/* clear the channel */
if (mask->bounds_known && !mask->empty)
{
pixel_region_init (&bPR, mask->tiles, mask->x1, mask->y1,
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, mask->x1, mask->y1,
(mask->x2 - mask->x1), (mask->y2 - mask->y1), TRUE);
color_region (&bPR, &bg);
}
else
{
/* clear the mask */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&bPR, &bg);
}
/* calculate a border of specified radius based on the boundary segments */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
border_region (&bPR, bs, num_segs, radius);
g_free (bs);
@ -1241,7 +1253,7 @@ channel_grow (Channel *mask, int steps)
channel_push_undo (mask);
/* need full extents for grow */
pixel_region_init (&bPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
while (steps--)
thin_region (&bPR, GROW_REGION);
@ -1262,7 +1274,7 @@ channel_shrink (Channel *mask, int steps)
/* push the current channel onto the undo stack */
channel_push_undo (mask);
pixel_region_init (&bPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&bPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
while (steps--)
thin_region (&bPR, SHRINK_REGION);
@ -1286,10 +1298,10 @@ channel_translate (Channel *mask, int off_x, int off_y)
channel_push_undo (mask);
channel_bounds (mask, &x1, &y1, &x2, &y2);
x1 = BOUNDS ((x1 + off_x), 0, mask->width);
y1 = BOUNDS ((y1 + off_y), 0, mask->height);
x2 = BOUNDS ((x2 + off_x), 0, mask->width);
y2 = BOUNDS ((y2 + off_y), 0, mask->height);
x1 = BOUNDS ((x1 + off_x), 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS ((y1 + off_y), 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS ((x2 + off_x), 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS ((y2 + off_y), 0, GIMP_DRAWABLE(mask)->height);
width = x2 - x1;
height = y2 - y1;
@ -1300,22 +1312,22 @@ channel_translate (Channel *mask, int off_x, int off_y)
/* copy the portion of the mask we will keep to a
* temporary buffer
*/
tmp_mask = channel_new_mask (mask->gimage_ID, width, height);
tmp_mask = channel_new_mask (GIMP_DRAWABLE(mask)->gimage_ID, width, height);
pixel_region_init (&srcPR, mask->tiles, x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, tmp_mask->tiles, 0, 0, width, height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, x1 - off_x, y1 - off_y, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(tmp_mask)->tiles, 0, 0, width, height, TRUE);
copy_region (&srcPR, &destPR);
}
/* clear the mask */
pixel_region_init (&srcPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(mask)->width, GIMP_DRAWABLE(mask)->height, TRUE);
color_region (&srcPR, &empty);
if (width != 0 && height != 0)
{
/* copy the temp mask back to the mask */
pixel_region_init (&srcPR, tmp_mask->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, width, height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(tmp_mask)->tiles, 0, 0, width, height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, width, height, TRUE);
copy_region (&srcPR, &destPR);
/* free the temporary mask */
@ -1327,8 +1339,8 @@ channel_translate (Channel *mask, int off_x, int off_y)
{
mask->empty = TRUE;
mask->x1 = 0; mask->y1 = 0;
mask->x2 = mask->width;
mask->y2 = mask->height;
mask->x2 = GIMP_DRAWABLE(mask)->width;
mask->y2 = GIMP_DRAWABLE(mask)->height;
}
else
{
@ -1341,10 +1353,9 @@ channel_translate (Channel *mask, int off_x, int off_y)
void
channel_layer_alpha (Channel *mask, int layer_id)
channel_layer_alpha (Channel *mask, Layer *layer)
{
PixelRegion srcPR, destPR;
Layer *layer;
unsigned char empty = 0;
int x1, y1, x2, y2;
@ -1352,54 +1363,24 @@ channel_layer_alpha (Channel *mask, int layer_id)
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, mask->tiles, 0, 0, mask->width, 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);
layer = layer_get_ID (layer_id);
x1 = BOUNDS (layer->offset_x, 0, mask->width);
y1 = BOUNDS (layer->offset_y, 0, mask->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, mask->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, mask->height);
x1 = BOUNDS (GIMP_DRAWABLE(layer)->offset_x, 0, GIMP_DRAWABLE(mask)->width);
y1 = BOUNDS (GIMP_DRAWABLE(layer)->offset_y, 0, GIMP_DRAWABLE(mask)->height);
x2 = BOUNDS (GIMP_DRAWABLE(layer)->offset_x + GIMP_DRAWABLE(layer)->width, 0, GIMP_DRAWABLE(mask)->width);
y2 = BOUNDS (GIMP_DRAWABLE(layer)->offset_y + GIMP_DRAWABLE(layer)->height, 0, GIMP_DRAWABLE(mask)->height);
pixel_region_init (&srcPR, layer->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles,
(x1 - GIMP_DRAWABLE(layer)->offset_x), (y1 - GIMP_DRAWABLE(layer)->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
extract_alpha_region (&srcPR, NULL, &destPR);
mask->bounds_known = FALSE;
}
void
channel_layer_mask (Channel *mask, int layer_id)
{
PixelRegion srcPR, destPR;
Layer *layer;
unsigned char empty = 0;
int x1, y1, x2, y2;
/* push the current mask onto the undo stack */
channel_push_undo (mask);
/* clear the mask */
pixel_region_init (&destPR, mask->tiles, 0, 0, mask->width, mask->height, TRUE);
color_region (&destPR, &empty);
layer = layer_get_ID (layer_id);
x1 = BOUNDS (layer->offset_x, 0, mask->width);
y1 = BOUNDS (layer->offset_y, 0, mask->height);
x2 = BOUNDS (layer->offset_x + layer->width, 0, mask->width);
y2 = BOUNDS (layer->offset_y + layer->height, 0, mask->height);
pixel_region_init (&srcPR, layer->mask->tiles,
(x1 - layer->offset_x), (y1 - layer->offset_y),
(x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, mask->tiles, x1, y1, (x2 - x1), (y2 - y1), TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;
}
void
@ -1411,9 +1392,15 @@ channel_load (Channel *mask, Channel *channel)
channel_push_undo (mask);
/* copy the channel to the mask */
pixel_region_init (&srcPR, channel->tiles, 0, 0, channel->width, channel->height, FALSE);
pixel_region_init (&destPR, mask->tiles, 0, 0, channel->width, channel->height, TRUE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(channel)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE(mask)->tiles, 0, 0, GIMP_DRAWABLE(channel)->width, GIMP_DRAWABLE(channel)->height, TRUE);
copy_region (&srcPR, &destPR);
mask->bounds_known = FALSE;
}
void
channel_invalidate_bounds (Channel *channel)
{
channel->bounds_known = FALSE;
}

View file

@ -18,6 +18,8 @@
#ifndef __CHANNEL_H__
#define __CHANNEL_H__
#include "drawable.h"
#include "boundary.h"
#include "temp_buf.h"
#include "tile_manager.h"
@ -34,45 +36,16 @@
/* structure declarations */
typedef struct _Channel Channel;
#define GIMP_CHANNEL(obj) GTK_CHECK_CAST (obj, gimp_channel_get_type (), GimpChannel)
#define GIMP_CHANNEL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gimp_channel_get_type(), GimpChannelClass)
#define GIMP_IS_CHANNEL(obj) GTK_CHECK_TYPE (obj, gimp_channel_get_type())
struct _Channel
{
char * name; /* name of the channel */
typedef struct _GimpChannel GimpChannel;
typedef struct _GimpChannelClass GimpChannelClass;
TileManager *tiles; /* tiles for channel data */
int visible; /* controls visibility */
int width, height; /* size of channel */
int bytes; /* bytes per pixel */
unsigned char col[3]; /* RGB triplet for channel color*/
int opacity; /* Channel opacity */
int show_masked; /* Show masked areas--as */
/* opposed to selected areas */
int dirty; /* dirty bit */
int ID; /* provides a unique ID */
int layer_ID; /* ID of layer-if a layer mask */
int gimage_ID; /* ID of gimage owner */
/* Selection mask variables */
int boundary_known; /* is the current boundary valid*/
BoundSeg *segs_in; /* outline of selected region */
BoundSeg *segs_out; /* outline of selected region */
int num_segs_in; /* number of lines in boundary */
int num_segs_out; /* number of lines in boundary */
int empty; /* is the region empty? */
int bounds_known; /* recalculate the bounds? */
int x1, y1; /* coordinates for bounding box */
int x2, y2; /* lower right hand coordinate */
/* Preview variables */
TempBuf *preview; /* preview of the channel */
int preview_valid; /* is the preview valid? */
};
typedef GimpChannel Channel; /* convenience */
guint gimp_channel_get_type (void);
/* Special undo type */
typedef struct _channel_undo ChannelUndo;
@ -81,7 +54,7 @@ struct _channel_undo
{
Channel * channel; /* the actual channel */
int prev_position; /* former position in list */
int prev_channel; /* previous active channel */
Channel * prev_channel; /* previous active channel */
int undo_type; /* is this a new channel undo */
/* or a remove channel undo? */
};
@ -98,13 +71,10 @@ struct _mask_undo
/* function declarations */
void channel_allocate (Channel *, int, int);
void channel_deallocate (Channel *);
Channel * channel_new (int, int, int, char *, int, unsigned char *);
Channel * channel_copy (Channel *);
Channel * channel_get_ID (int);
void channel_delete (Channel *);
void channel_apply_image (Channel *, int, int, int, int, TileManager *, int);
void channel_scale (Channel *, int, int);
void channel_resize (Channel *, int, int, int, int);
@ -140,8 +110,12 @@ void channel_border (Channel *, int);
void channel_grow (Channel *, int);
void channel_shrink (Channel *, int);
void channel_translate (Channel *, int, int);
void channel_layer_alpha (Channel *, int);
void channel_layer_mask (Channel *, int);
void channel_load (Channel *, Channel *);
void channel_invalidate_bounds (Channel *);
extern int channel_get_count;
/* from drawable.c */
Channel * drawable_channel (GimpDrawable *);
#endif /* __CHANNEL_H__ */

View file

@ -23,8 +23,9 @@
#include "desaturate.h"
#include "interface.h"
#include "paint_funcs.h"
#include "gimage.h"
static void desaturate (int);
static void desaturate (GimpDrawable *);
static Argument * desaturate_invoker (Argument *);
@ -33,25 +34,24 @@ image_desaturate (gimage_ptr)
void *gimage_ptr;
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
if (! drawable_color (drawable_id))
if (! drawable_color (drawable))
{
message_box ("Desaturate operates only on RGB color drawables.", NULL, NULL);
return;
}
desaturate (drawable_id);
desaturate (drawable);
}
/* Desaturateer */
static void
desaturate (drawable_id)
int drawable_id;
desaturate (GimpDrawable *drawable)
{
PixelRegion srcPR, destPR;
unsigned char *src, *s;
@ -62,10 +62,13 @@ desaturate (drawable_id)
void *pr;
int x1, y1, x2, y2;
has_alpha = drawable_has_alpha (drawable_id);
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
if (!drawable)
return;
has_alpha = drawable_has_alpha (drawable);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -103,8 +106,8 @@ desaturate (drawable_id)
}
}
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
@ -151,9 +154,9 @@ desaturate_invoker (args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
/* the gimage */
if (success)
@ -166,18 +169,17 @@ desaturate_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* check to make sure the drawable is color */
if (success)
success = drawable_color (drawable_id);
success = drawable_color (drawable);
if (success)
desaturate (drawable_id);
desaturate (drawable);
return procedural_db_return_args (&desaturate_proc, success);
}

View file

@ -22,8 +22,9 @@
#include "drawable.h"
#include "equalize.h"
#include "interface.h"
#include "gimage.h"
static void equalize (GImage *, int, int);
static void equalize (GImage *, GimpDrawable *, int);
static void eq_histogram (double [3][256], unsigned char [3][256], int, double);
static Argument * equalize_invoker (Argument *);
@ -33,25 +34,25 @@ image_equalize (gimage_ptr)
void *gimage_ptr;
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int mask_only = TRUE;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
if (drawable_indexed (drawable_id))
if (drawable_indexed (drawable))
{
message_box ("Equalize does not operate on indexed drawables.", NULL, NULL);
return;
}
equalize (gimage, drawable_id, mask_only);
equalize (gimage, drawable, mask_only);
}
static void
equalize(gimage, drawable_id, mask_only)
equalize(gimage, drawable, mask_only)
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int mask_only;
{
Channel *sel_mask;
@ -73,18 +74,18 @@ equalize(gimage, drawable_id, mask_only)
mask = NULL;
sel_mask = gimage_get_mask (gimage);
drawable_offsets (drawable_id, &off_x, &off_y);
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable_id);
drawable_offsets (drawable, &off_x, &off_y);
bytes = drawable_bytes (drawable);
has_alpha = drawable_has_alpha (drawable);
alpha = has_alpha ? (bytes - 1) : bytes;
count = 0.0;
/* Determine the histogram from the drawable data and the attendant mask */
no_mask = (drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
no_mask = (drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2) == FALSE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
sel_maskPR = (no_mask) ? NULL : &maskPR;
if (sel_maskPR)
pixel_region_init (sel_maskPR, sel_mask->tiles, x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (sel_maskPR, drawable_data (GIMP_DRAWABLE (sel_mask)), x1 + off_x, y1 + off_y, (x2 - x1), (y2 - y1), FALSE);
/* Initialize histogram */
for (b = 0; b < alpha; b++)
@ -135,8 +136,8 @@ equalize(gimage, drawable_id, mask_only)
eq_histogram (hist, lut, alpha, count);
/* Apply the histogram */
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -166,8 +167,8 @@ equalize(gimage, drawable_id, mask_only)
}
}
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
@ -276,9 +277,9 @@ equalize_invoker (args)
int int_value;
int mask_only;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
/* the gimage */
if (success)
@ -291,10 +292,9 @@ equalize_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* the mask only option */
if (success)
@ -304,10 +304,10 @@ equalize_invoker (args)
}
/* make sure the drawable is not indexed color */
if (success)
success = ! drawable_indexed (drawable_id);
success = ! drawable_indexed (drawable);
if (success)
equalize (gimage, drawable_id, mask_only);
equalize (gimage, drawable, mask_only);
return procedural_db_return_args (&equalize_proc, success);
}

View file

@ -22,8 +22,9 @@
#include "drawable.h"
#include "interface.h"
#include "invert.h"
#include "gimage.h"
static void invert (int);
static void invert (GimpDrawable *);
static Argument * invert_invoker (Argument *);
@ -32,14 +33,14 @@ image_invert (gimage_ptr)
void *gimage_ptr;
{
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
Argument *return_vals;
int nreturn_vals;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
if (drawable_indexed (drawable_id))
if (drawable_indexed (drawable))
{
message_box ("Invert does not operate on indexed drawables.", NULL, NULL);
return;
@ -48,7 +49,7 @@ image_invert (gimage_ptr)
return_vals = procedural_db_run_proc ("gimp_invert",
&nreturn_vals,
PDB_IMAGE, gimage->ID,
PDB_DRAWABLE, drawable_id,
PDB_DRAWABLE, drawable_ID (drawable),
PDB_END);
if (return_vals[0].value.pdb_int != PDB_SUCCESS)
@ -61,8 +62,8 @@ image_invert (gimage_ptr)
/* Inverter */
static void
invert (drawable_id)
int drawable_id;
invert (drawable)
GimpDrawable *drawable;
{
PixelRegion srcPR, destPR;
unsigned char *src, *s;
@ -73,12 +74,12 @@ invert (drawable_id)
void *pr;
int x1, y1, x2, y2;
bytes = drawable_bytes (drawable_id);
has_alpha = drawable_has_alpha (drawable_id);
bytes = drawable_bytes (drawable);
has_alpha = drawable_has_alpha (drawable);
alpha = has_alpha ? (bytes - 1) : bytes;
drawable_mask_bounds (drawable_id, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable_id), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable_id), x1, y1, (x2 - x1), (y2 - y1), TRUE);
drawable_mask_bounds (drawable, &x1, &y1, &x2, &y2);
pixel_region_init (&srcPR, drawable_data (drawable), x1, y1, (x2 - x1), (y2 - y1), FALSE);
pixel_region_init (&destPR, drawable_shadow (drawable), x1, y1, (x2 - x1), (y2 - y1), TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -108,8 +109,8 @@ invert (drawable_id)
}
}
drawable_merge_shadow (drawable_id, TRUE);
drawable_update (drawable_id, x1, y1, (x2 - x1), (y2 - y1));
drawable_merge_shadow (drawable, TRUE);
drawable_update (drawable, x1, y1, (x2 - x1), (y2 - y1));
}
@ -156,9 +157,9 @@ invert_invoker (args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
drawable_id = -1;
drawable = NULL;
/* the gimage */
if (success)
@ -171,17 +172,16 @@ invert_invoker (args)
if (success)
{
int_value = args[1].value.pdb_int;
if (gimage != drawable_gimage (int_value))
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
else
drawable_id = int_value;
}
/* make sure the drawable is not indexed color */
if (success)
success = ! drawable_indexed (drawable_id);
success = ! drawable_indexed (drawable);
if (success)
invert (drawable_id);
invert (drawable);
return procedural_db_return_args (&invert_proc, success);
}

View file

@ -28,6 +28,8 @@
#include "interface.h"
#include "palette.h"
#include "channel_pvt.h"
#define ENTRY_WIDTH 60
#define OFFSET_BACKGROUND 0
#define OFFSET_TRANSPARENT 1
@ -47,9 +49,8 @@ typedef struct
} OffsetDialog;
/* Local procedures */
static GImage * duplicate (GImage *gimage);
static void offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
@ -71,22 +72,9 @@ static void offset_wraparound_update (GtkWidget *widget,
static void offset_halfheight_update (GtkWidget *widget,
gpointer data);
static Argument * channel_ops_duplicate_invoker (Argument *args);
static Argument * channel_ops_offset_invoker (Argument *args);
void
channel_ops_duplicate (void *gimage_ptr)
{
GImage *gimage;
GImage *new_gimage;
gimage = (GImage *) gimage_ptr;
new_gimage = duplicate (gimage);
gdisplay_new (new_gimage, 0x0101);
}
void
channel_ops_offset (void *gimage_ptr)
{
@ -100,15 +88,15 @@ channel_ops_offset (void *gimage_ptr)
GtkWidget *toggle_vbox;
GtkWidget *table;
GSList *group = NULL;
int drawable_id;
GimpDrawable *drawable;
GImage *gimage;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
off_d = g_new (OffsetDialog, 1);
off_d->wrap_around = TRUE;
off_d->transparent = drawable_has_alpha (drawable_id);
off_d->transparent = drawable_has_alpha (drawable);
off_d->background = !off_d->transparent;
off_d->gimage_id = gimage->ID;
@ -190,7 +178,7 @@ channel_ops_offset (void *gimage_ptr)
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), off_d->background);
gtk_widget_show (toggle);
if (drawable_has_alpha (drawable_id))
if (drawable_has_alpha (drawable))
{
toggle = gtk_radio_button_new_with_label (group, "Transparent");
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
@ -224,142 +212,25 @@ channel_ops_offset (void *gimage_ptr)
off_d);
}
static GImage *
duplicate (GImage *gimage)
{
PixelRegion srcPR, destPR;
GImage *new_gimage;
Layer *layer, *new_layer;
Layer *floating_layer;
Channel *channel, *new_channel;
link_ptr list;
int active_layer = -1;
int active_channel = -1;
int new_floating_sel_drawable = -1;
int floating_sel_drawable = -1;
int count;
/* Create a new image */
new_gimage = gimage_new (gimage->width, gimage->height, gimage->base_type);
gimage_disable_undo (new_gimage);
floating_layer = gimage_floating_sel (gimage);
if (floating_layer)
{
floating_sel_relax (floating_layer, FALSE);
floating_sel_drawable = floating_layer->fs.drawable;
floating_layer = NULL;
}
/* Copy the layers */
list = gimage->layers;
count = 0;
layer = NULL;
while (list)
{
layer = (Layer *) list->data;
list = next_item (list);
new_layer = layer_copy (layer, FALSE);
new_layer->gimage_ID = new_gimage->ID;
/* Make sure the copied layer doesn't say: "<old layer> copy" */
g_free (new_layer->name);
new_layer->name = g_strdup (layer->name);
/* Make sure if the layer has a layer mask, it's name isn't screwed up */
if (new_layer->mask)
{
g_free (new_layer->mask->name);
new_layer->mask->name = g_strdup (layer->mask->name);
}
if (gimage->active_layer == layer->ID)
active_layer = new_layer->ID;
if (gimage->floating_sel == layer->ID)
floating_layer = new_layer;
if (floating_sel_drawable == layer->ID)
new_floating_sel_drawable = new_layer->ID;
/* Add the layer */
if (floating_layer != new_layer)
gimage_add_layer (new_gimage, new_layer, count++);
}
/* Copy the channels */
list = gimage->channels;
count = 0;
while (list)
{
channel = (Channel *) list->data;
list = next_item (list);
new_channel = channel_copy (channel);
/* Make sure the copied channel doesn't say: "<old channel> copy" */
g_free (new_channel->name);
new_channel->name = g_strdup (channel->name);
if (gimage->active_channel == layer->ID)
active_channel = new_channel->ID;
if (floating_sel_drawable == channel->ID)
new_floating_sel_drawable = new_channel->ID;
/* Add the channel */
gimage_add_channel (new_gimage, new_channel, count++);
}
/* Copy the selection mask */
pixel_region_init (&srcPR, gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, FALSE);
pixel_region_init (&destPR, new_gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, TRUE);
copy_region (&srcPR, &destPR);
new_gimage->selection_mask->bounds_known = FALSE;
new_gimage->selection_mask->boundary_known = FALSE;
/* Set active layer, active channel */
new_gimage->active_layer = active_layer;
new_gimage->active_channel = active_channel;
if (floating_layer)
floating_sel_attach (floating_layer, new_floating_sel_drawable);
/* Copy the colormap if necessary */
if (new_gimage->base_type == INDEXED)
memcpy (new_gimage->cmap, gimage->cmap, gimage->num_cols * 3);
new_gimage->num_cols = gimage->num_cols;
/* copy state of all color channels */
for (count = 0; count < MAX_CHANNELS; count++)
{
new_gimage->visible[count] = gimage->visible[count];
new_gimage->active[count] = gimage->active[count];
}
gimage_enable_undo (new_gimage);
return new_gimage;
}
static void
offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
int offset_y)
{
PixelRegion srcPR, destPR;
Channel *channel;
Layer *layer;
TileManager *new_tiles;
int width, height;
int src_x, src_y;
int dest_x, dest_y;
unsigned char fill[MAX_CHANNELS] = { 0 };
if (!drawable)
return;
width = drawable_width (drawable);
height = drawable_height (drawable);
@ -565,10 +436,7 @@ offset (GImage *gimage,
drawable_data (drawable), FALSE);
/* swap the tiles */
if ((channel = channel_get_ID (drawable)))
channel->tiles = new_tiles;
else if ((layer = layer_get_ID (drawable)))
layer->tiles = new_tiles;
drawable->tiles = new_tiles;
/* update the drawable */
drawable_update (drawable, 0, 0, drawable_width (drawable), drawable_height (drawable));
@ -584,14 +452,14 @@ offset_ok_callback (GtkWidget *widget,
{
OffsetDialog *off_d;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int offset_x, offset_y;
int fill_type;
off_d = (OffsetDialog *) data;
if ((gimage = gimage_get_ID (off_d->gimage_id)) != NULL)
{
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
offset_x = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_x_entry)));
offset_y = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_y_entry)));
@ -601,7 +469,7 @@ offset_ok_callback (GtkWidget *widget,
else
fill_type = OFFSET_BACKGROUND;
offset (gimage, drawable_id, off_d->wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, off_d->wrap_around, fill_type, offset_x, offset_y);
gdisplays_flush ();
}
@ -684,76 +552,6 @@ offset_halfheight_update (GtkWidget *widget,
* Procedure database functions and data structures
*/
/* The duplicate procedure definition */
ProcArg channel_ops_duplicate_args[] =
{
{ PDB_IMAGE,
"image",
"the image"
}
};
ProcArg channel_ops_duplicate_out_args[] =
{
{ PDB_IMAGE,
"new_image",
"the new, duplicated image"
}
};
ProcRecord channel_ops_duplicate_proc =
{
"gimp_channel_ops_duplicate",
"Duplicate the specified image",
"This procedure duplicates the specified image, copying all layers, channels, and image information.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1997",
PDB_INTERNAL,
/* Input arguments */
1,
channel_ops_duplicate_args,
/* Output arguments */
1,
channel_ops_duplicate_out_args,
/* Exec method */
{ { channel_ops_duplicate_invoker } },
};
static Argument *
channel_ops_duplicate_invoker (Argument *args)
{
Argument *return_args;
int success = TRUE;
int int_value;
GImage *gimage, *new_gimage;
new_gimage = NULL;
/* the gimage */
if (success)
{
int_value = args[0].value.pdb_int;
if (! (gimage = gimage_get_ID (int_value)))
success = FALSE;
}
if (success)
success = ((new_gimage = duplicate ((void *) gimage)) != NULL);
return_args = procedural_db_return_args (&channel_ops_duplicate_proc, success);
if (success)
return_args[1].value.pdb_int = new_gimage->ID;
return return_args;
}
/*
* Procedure database functions and data structures
*/
@ -816,7 +614,7 @@ channel_ops_offset_invoker (Argument *args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int wrap_around;
int fill_type;
int offset_x;
@ -831,8 +629,9 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
{
drawable_id = args[1].value.pdb_int;
if (gimage != drawable_gimage (drawable_id))
int_value = args[1].value.pdb_int;
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
if (success)
@ -852,7 +651,7 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
offset (gimage, drawable_id, wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, wrap_around, fill_type, offset_x, offset_y);
return procedural_db_return_args (&channel_ops_offset_proc, success);
}

View file

@ -21,11 +21,9 @@
#include "procedural_db.h"
/* channel_ops functions */
void channel_ops_duplicate (void *);
void channel_ops_offset (void *);
/* Procedure definition and marshalling function */
extern ProcRecord channel_ops_duplicate_proc;
extern ProcRecord channel_ops_offset_proc;
#endif /* __CHANNEL_OPS_H__ */

View file

@ -66,6 +66,10 @@
#include "undo.h"
#include "palette.h"
#include "layer_pvt.h" /* ick. */
#include "drawable_pvt.h" /* ick ick. */
#include "tile_manager_pvt.h" /* ick ick ick. */
#define MAXNUMCOLORS 256
#define NODITHER 0
@ -738,7 +742,7 @@ convert_image (GImage *gimage,
break;
}
new_tiles = tile_manager_new (layer->width, layer->height, new_layer_bytes);
new_tiles = tile_manager_new (GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, new_layer_bytes);
switch (new_type)
{
@ -758,9 +762,10 @@ convert_image (GImage *gimage,
/* Push the layer on the undo stack */
undo_push_layer_mod (gimage, layer);
layer->tiles = new_tiles;
layer->bytes = new_layer_bytes;
layer->type = new_layer_type;
GIMP_DRAWABLE(layer)->tiles = new_tiles;
GIMP_DRAWABLE(layer)->bytes = new_layer_bytes;
GIMP_DRAWABLE(layer)->type = new_layer_type;
GIMP_DRAWABLE(layer)->has_alpha = TYPE_HAS_ALPHA(new_layer_type);
}
/* Delete the quantizer object, if there is one */
@ -800,8 +805,8 @@ rgb_converter (Layer *layer,
void *pr;
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -832,7 +837,7 @@ rgb_converter (Layer *layer,
}
break;
case INDEXED:
cmap = drawable_cmap (layer->ID);
cmap = drawable_cmap (GIMP_DRAWABLE(layer));
for (row = 0; row < srcPR.h; row++)
{
s = src;
@ -874,8 +879,8 @@ grayscale_converter (Layer *layer,
void *pr;
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
@ -903,7 +908,7 @@ grayscale_converter (Layer *layer,
}
break;
case INDEXED:
cmap = drawable_cmap (layer->ID);
cmap = drawable_cmap (GIMP_DRAWABLE(layer));
for (row = 0; row < srcPR.h; row++)
{
s = src;
@ -966,7 +971,7 @@ generate_histogram_gray (Histogram histogram,
has_alpha = (gboolean) layer_has_alpha(layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
for (pr = pixel_regions_register (1, &srcPR);
pr != NULL;
pr = pixel_regions_process (pr))
@ -999,7 +1004,7 @@ generate_histogram_rgb (Histogram histogram,
g_print ("col_limit = %d, nfc = %d\n", col_limit, num_found_cols);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
for (pr = pixel_regions_register (1, &srcPR);
pr != NULL;
pr = pixel_regions_process (pr))
@ -2057,8 +2062,8 @@ median_cut_pass2_no_dither_gray (QuantizeObj *quantobj,
zero_histogram_gray (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2107,14 +2112,14 @@ median_cut_pass2_no_dither_rgb (QuantizeObj *quantobj,
/* In the case of web/mono palettes, we actually force
* grayscale drawables through the rgb pass2 functions
*/
if (drawable_gray (layer->ID))
if (drawable_gray (GIMP_DRAWABLE(layer)))
red_pix = green_pix = blue_pix = GRAY_PIX;
zero_histogram_rgb (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2167,8 +2172,8 @@ median_cut_pass2_nodestruct_dither_rgb (QuantizeObj *quantobj,
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, 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, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
for (pr = pixel_regions_register (2, &srcPR, &destPR); pr != NULL; pr = pixel_regions_process (pr))
{
src = srcPR.data;
@ -2322,12 +2327,12 @@ median_cut_pass2_fs_dither_gray (QuantizeObj *quantobj,
zero_histogram_gray (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, layer->height, TRUE);
src_bytes = layer->bytes;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
src_bytes = GIMP_DRAWABLE(layer)->bytes;
dest_bytes = new_tiles->levels[0].bpp;
width = layer->width;
height = layer->height;
width = GIMP_DRAWABLE(layer)->width;
height = GIMP_DRAWABLE(layer)->height;
error_limiter = init_error_limit ();
range_limiter = range_array + 256;
@ -2472,18 +2477,18 @@ median_cut_pass2_fs_dither_rgb (QuantizeObj *quantobj,
/* In the case of web/mono palettes, we actually force
* grayscale drawables through the rgb pass2 functions
*/
if (drawable_gray (layer->ID))
if (drawable_gray (GIMP_DRAWABLE(layer)))
red_pix = green_pix = blue_pix = GRAY_PIX;
zero_histogram_rgb (histogram);
has_alpha = layer_has_alpha (layer);
pixel_region_init (&srcPR, layer->tiles, 0, 0, layer->width, layer->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, layer->width, layer->height, TRUE);
src_bytes = layer->bytes;
pixel_region_init (&srcPR, GIMP_DRAWABLE(layer)->tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, FALSE);
pixel_region_init (&destPR, new_tiles, 0, 0, GIMP_DRAWABLE(layer)->width, GIMP_DRAWABLE(layer)->height, TRUE);
src_bytes = GIMP_DRAWABLE(layer)->bytes;
dest_bytes = new_tiles->levels[0].bpp;
width = layer->width;
height = layer->height;
width = GIMP_DRAWABLE(layer)->width;
height = GIMP_DRAWABLE(layer)->height;
error_limiter = init_error_limit ();
range_limiter = range_array + 256;

View file

@ -28,6 +28,8 @@
#include "interface.h"
#include "palette.h"
#include "channel_pvt.h"
#define ENTRY_WIDTH 60
#define OFFSET_BACKGROUND 0
#define OFFSET_TRANSPARENT 1
@ -47,9 +49,8 @@ typedef struct
} OffsetDialog;
/* Local procedures */
static GImage * duplicate (GImage *gimage);
static void offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
@ -71,22 +72,9 @@ static void offset_wraparound_update (GtkWidget *widget,
static void offset_halfheight_update (GtkWidget *widget,
gpointer data);
static Argument * channel_ops_duplicate_invoker (Argument *args);
static Argument * channel_ops_offset_invoker (Argument *args);
void
channel_ops_duplicate (void *gimage_ptr)
{
GImage *gimage;
GImage *new_gimage;
gimage = (GImage *) gimage_ptr;
new_gimage = duplicate (gimage);
gdisplay_new (new_gimage, 0x0101);
}
void
channel_ops_offset (void *gimage_ptr)
{
@ -100,15 +88,15 @@ channel_ops_offset (void *gimage_ptr)
GtkWidget *toggle_vbox;
GtkWidget *table;
GSList *group = NULL;
int drawable_id;
GimpDrawable *drawable;
GImage *gimage;
gimage = (GImage *) gimage_ptr;
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
off_d = g_new (OffsetDialog, 1);
off_d->wrap_around = TRUE;
off_d->transparent = drawable_has_alpha (drawable_id);
off_d->transparent = drawable_has_alpha (drawable);
off_d->background = !off_d->transparent;
off_d->gimage_id = gimage->ID;
@ -190,7 +178,7 @@ channel_ops_offset (void *gimage_ptr)
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (toggle), off_d->background);
gtk_widget_show (toggle);
if (drawable_has_alpha (drawable_id))
if (drawable_has_alpha (drawable))
{
toggle = gtk_radio_button_new_with_label (group, "Transparent");
group = gtk_radio_button_group (GTK_RADIO_BUTTON (toggle));
@ -224,142 +212,25 @@ channel_ops_offset (void *gimage_ptr)
off_d);
}
static GImage *
duplicate (GImage *gimage)
{
PixelRegion srcPR, destPR;
GImage *new_gimage;
Layer *layer, *new_layer;
Layer *floating_layer;
Channel *channel, *new_channel;
link_ptr list;
int active_layer = -1;
int active_channel = -1;
int new_floating_sel_drawable = -1;
int floating_sel_drawable = -1;
int count;
/* Create a new image */
new_gimage = gimage_new (gimage->width, gimage->height, gimage->base_type);
gimage_disable_undo (new_gimage);
floating_layer = gimage_floating_sel (gimage);
if (floating_layer)
{
floating_sel_relax (floating_layer, FALSE);
floating_sel_drawable = floating_layer->fs.drawable;
floating_layer = NULL;
}
/* Copy the layers */
list = gimage->layers;
count = 0;
layer = NULL;
while (list)
{
layer = (Layer *) list->data;
list = next_item (list);
new_layer = layer_copy (layer, FALSE);
new_layer->gimage_ID = new_gimage->ID;
/* Make sure the copied layer doesn't say: "<old layer> copy" */
g_free (new_layer->name);
new_layer->name = g_strdup (layer->name);
/* Make sure if the layer has a layer mask, it's name isn't screwed up */
if (new_layer->mask)
{
g_free (new_layer->mask->name);
new_layer->mask->name = g_strdup (layer->mask->name);
}
if (gimage->active_layer == layer->ID)
active_layer = new_layer->ID;
if (gimage->floating_sel == layer->ID)
floating_layer = new_layer;
if (floating_sel_drawable == layer->ID)
new_floating_sel_drawable = new_layer->ID;
/* Add the layer */
if (floating_layer != new_layer)
gimage_add_layer (new_gimage, new_layer, count++);
}
/* Copy the channels */
list = gimage->channels;
count = 0;
while (list)
{
channel = (Channel *) list->data;
list = next_item (list);
new_channel = channel_copy (channel);
/* Make sure the copied channel doesn't say: "<old channel> copy" */
g_free (new_channel->name);
new_channel->name = g_strdup (channel->name);
if (gimage->active_channel == layer->ID)
active_channel = new_channel->ID;
if (floating_sel_drawable == channel->ID)
new_floating_sel_drawable = new_channel->ID;
/* Add the channel */
gimage_add_channel (new_gimage, new_channel, count++);
}
/* Copy the selection mask */
pixel_region_init (&srcPR, gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, FALSE);
pixel_region_init (&destPR, new_gimage->selection_mask->tiles, 0, 0, gimage->width, gimage->height, TRUE);
copy_region (&srcPR, &destPR);
new_gimage->selection_mask->bounds_known = FALSE;
new_gimage->selection_mask->boundary_known = FALSE;
/* Set active layer, active channel */
new_gimage->active_layer = active_layer;
new_gimage->active_channel = active_channel;
if (floating_layer)
floating_sel_attach (floating_layer, new_floating_sel_drawable);
/* Copy the colormap if necessary */
if (new_gimage->base_type == INDEXED)
memcpy (new_gimage->cmap, gimage->cmap, gimage->num_cols * 3);
new_gimage->num_cols = gimage->num_cols;
/* copy state of all color channels */
for (count = 0; count < MAX_CHANNELS; count++)
{
new_gimage->visible[count] = gimage->visible[count];
new_gimage->active[count] = gimage->active[count];
}
gimage_enable_undo (new_gimage);
return new_gimage;
}
static void
offset (GImage *gimage,
int drawable,
GimpDrawable *drawable,
int wrap_around,
int fill_type,
int offset_x,
int offset_y)
{
PixelRegion srcPR, destPR;
Channel *channel;
Layer *layer;
TileManager *new_tiles;
int width, height;
int src_x, src_y;
int dest_x, dest_y;
unsigned char fill[MAX_CHANNELS] = { 0 };
if (!drawable)
return;
width = drawable_width (drawable);
height = drawable_height (drawable);
@ -565,10 +436,7 @@ offset (GImage *gimage,
drawable_data (drawable), FALSE);
/* swap the tiles */
if ((channel = channel_get_ID (drawable)))
channel->tiles = new_tiles;
else if ((layer = layer_get_ID (drawable)))
layer->tiles = new_tiles;
drawable->tiles = new_tiles;
/* update the drawable */
drawable_update (drawable, 0, 0, drawable_width (drawable), drawable_height (drawable));
@ -584,14 +452,14 @@ offset_ok_callback (GtkWidget *widget,
{
OffsetDialog *off_d;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int offset_x, offset_y;
int fill_type;
off_d = (OffsetDialog *) data;
if ((gimage = gimage_get_ID (off_d->gimage_id)) != NULL)
{
drawable_id = gimage_active_drawable (gimage);
drawable = gimage_active_drawable (gimage);
offset_x = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_x_entry)));
offset_y = (int) atof (gtk_entry_get_text (GTK_ENTRY (off_d->off_y_entry)));
@ -601,7 +469,7 @@ offset_ok_callback (GtkWidget *widget,
else
fill_type = OFFSET_BACKGROUND;
offset (gimage, drawable_id, off_d->wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, off_d->wrap_around, fill_type, offset_x, offset_y);
gdisplays_flush ();
}
@ -684,76 +552,6 @@ offset_halfheight_update (GtkWidget *widget,
* Procedure database functions and data structures
*/
/* The duplicate procedure definition */
ProcArg channel_ops_duplicate_args[] =
{
{ PDB_IMAGE,
"image",
"the image"
}
};
ProcArg channel_ops_duplicate_out_args[] =
{
{ PDB_IMAGE,
"new_image",
"the new, duplicated image"
}
};
ProcRecord channel_ops_duplicate_proc =
{
"gimp_channel_ops_duplicate",
"Duplicate the specified image",
"This procedure duplicates the specified image, copying all layers, channels, and image information.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1997",
PDB_INTERNAL,
/* Input arguments */
1,
channel_ops_duplicate_args,
/* Output arguments */
1,
channel_ops_duplicate_out_args,
/* Exec method */
{ { channel_ops_duplicate_invoker } },
};
static Argument *
channel_ops_duplicate_invoker (Argument *args)
{
Argument *return_args;
int success = TRUE;
int int_value;
GImage *gimage, *new_gimage;
new_gimage = NULL;
/* the gimage */
if (success)
{
int_value = args[0].value.pdb_int;
if (! (gimage = gimage_get_ID (int_value)))
success = FALSE;
}
if (success)
success = ((new_gimage = duplicate ((void *) gimage)) != NULL);
return_args = procedural_db_return_args (&channel_ops_duplicate_proc, success);
if (success)
return_args[1].value.pdb_int = new_gimage->ID;
return return_args;
}
/*
* Procedure database functions and data structures
*/
@ -816,7 +614,7 @@ channel_ops_offset_invoker (Argument *args)
int success = TRUE;
int int_value;
GImage *gimage;
int drawable_id;
GimpDrawable *drawable;
int wrap_around;
int fill_type;
int offset_x;
@ -831,8 +629,9 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
{
drawable_id = args[1].value.pdb_int;
if (gimage != drawable_gimage (drawable_id))
int_value = args[1].value.pdb_int;
drawable = drawable_get_ID (int_value);
if (drawable == NULL || gimage != drawable_gimage (drawable))
success = FALSE;
}
if (success)
@ -852,7 +651,7 @@ channel_ops_offset_invoker (Argument *args)
}
if (success)
offset (gimage, drawable_id, wrap_around, fill_type, offset_x, offset_y);
offset (gimage, drawable, wrap_around, fill_type, offset_x, offset_y);
return procedural_db_return_args (&channel_ops_offset_proc, success);
}

Some files were not shown because too many files have changed in this diff Show more