mirror of https://github.com/GNOME/gimp.git
indentation, no real changes
2000-06-05 Sven Neumann <sven@gimp.org> * app/paint_core.[ch]: indentation, no real changes * plug-ins/gap/README * plug-ins/gap/gap_mov_dialog.c * plug-ins/gap/gap_mov_exec.c: applied a patch from Wolfgang Hofer * plug-ins/imagemap/imap_csim.y: applied a patch from Maurits Rijk which promises to fix bug #10090. Yosh, could you regenerate the C code, please...?! * tips/gimp_tips.txt: applied gimp-quinet-20000508-0.patch, an update to the english tips file provided by Raphael Quinet.
This commit is contained in:
parent
f65440e78d
commit
a43f448b9d
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2000-06-05 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/paint_core.[ch]: indentation, no real changes
|
||||
|
||||
* plug-ins/gap/README
|
||||
* plug-ins/gap/gap_mov_dialog.c
|
||||
* plug-ins/gap/gap_mov_exec.c: applied a patch from Wolfgang
|
||||
Hofer
|
||||
|
||||
* plug-ins/imagemap/imap_csim.y: applied a patch from
|
||||
Maurits Rijk which promises to fix bug #10090.
|
||||
Yosh, could you regenerate the C code, please...?!
|
||||
|
||||
* tips/gimp_tips.txt: applied gimp-quinet-20000508-0.patch,
|
||||
an update to the english tips file provided by Raphael Quinet.
|
||||
|
||||
2000-06-05 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* plug-ins/common/xbm.c: Don't save the mask inverted.
|
||||
|
|
392
app/paint_core.c
392
app/paint_core.c
|
@ -56,26 +56,75 @@
|
|||
PaintCore non_gui_paint_core;
|
||||
|
||||
/* local function prototypes */
|
||||
static void paint_core_calculate_brush_size (MaskBuf *, double, int *, int *);
|
||||
static MaskBuf * paint_core_subsample_mask (MaskBuf *, double, double);
|
||||
static MaskBuf * paint_core_pressurize_mask (MaskBuf *, double, double, double);
|
||||
static MaskBuf * paint_core_solidify_mask (MaskBuf *);
|
||||
static MaskBuf * paint_core_scale_mask (MaskBuf *, gdouble);
|
||||
static MaskBuf * paint_core_scale_pixmap (MaskBuf *, gdouble);
|
||||
static MaskBuf * paint_core_get_brush_mask (PaintCore *, BrushApplicationMode, gdouble);
|
||||
static void paint_core_paste (PaintCore *, MaskBuf *,
|
||||
GimpDrawable *, int, int,
|
||||
LayerModeEffects,
|
||||
PaintApplicationMode);
|
||||
static void paint_core_replace (PaintCore *, MaskBuf *,
|
||||
GimpDrawable *, int, int,
|
||||
PaintApplicationMode);
|
||||
static void brush_to_canvas_tiles (PaintCore *, MaskBuf *, int);
|
||||
static void canvas_tiles_to_canvas_buf (PaintCore *);
|
||||
static void brush_to_canvas_buf (PaintCore *, MaskBuf *, int);
|
||||
static void set_undo_tiles (GimpDrawable *, int, int, int, int);
|
||||
static void set_canvas_tiles (int, int, int, int);
|
||||
static void paint_core_invalidate_cache (GimpBrush *brush, gpointer *blah);
|
||||
static void paint_core_calculate_brush_size (MaskBuf *mask,
|
||||
gdouble scale,
|
||||
gint *width,
|
||||
gint *height);
|
||||
static MaskBuf * paint_core_subsample_mask (MaskBuf *mask,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
static MaskBuf * paint_core_pressurize_mask (MaskBuf *brush_mask,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble pressure);
|
||||
static MaskBuf * paint_core_solidify_mask (MaskBuf *brush_mask);
|
||||
static MaskBuf * paint_core_scale_mask (MaskBuf *brush_mask,
|
||||
gdouble scale);
|
||||
static MaskBuf * paint_core_scale_pixmap (MaskBuf *brush_mask,
|
||||
gdouble scale);
|
||||
|
||||
static MaskBuf * paint_core_get_brush_mask (PaintCore *paint_core,
|
||||
BrushApplicationMode brush_hardness,
|
||||
gdouble scale);
|
||||
static void paint_core_paste (PaintCore *paint_core,
|
||||
MaskBuf *brush_mask,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
LayerModeEffects paint_mode,
|
||||
PaintApplicationMode mode);
|
||||
static void paint_core_replace (PaintCore *paint_core,
|
||||
MaskBuf *brush_mask,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
PaintApplicationMode mode);
|
||||
|
||||
static void brush_to_canvas_tiles (PaintCore *paint_core,
|
||||
MaskBuf *brush_mask,
|
||||
gint brush_opacity);
|
||||
static void brush_to_canvas_buf (PaintCore *paint_core,
|
||||
MaskBuf *brush_mask,
|
||||
gint brush_opacity);
|
||||
static void canvas_tiles_to_canvas_buf (PaintCore *paint_core);
|
||||
|
||||
static void set_undo_tiles (GimpDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
static void set_canvas_tiles (gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
static void paint_core_invalidate_cache (GimpBrush *brush,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/* paint buffers utility functions */
|
||||
static void free_paint_buffers (void);
|
||||
|
||||
/* brush pipe utility functions */
|
||||
static void paint_line_pixmap_mask (GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *pixmap_mask,
|
||||
TempBuf *brush_mask,
|
||||
guchar *d,
|
||||
gint x,
|
||||
gint y,
|
||||
gint bytes,
|
||||
gint width,
|
||||
BrushApplicationMode mode);
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
|
@ -100,24 +149,17 @@ static MaskBuf * scale_brush = NULL;
|
|||
static MaskBuf *scale_pixmap = NULL;
|
||||
static MaskBuf *kernel_brushes[SUBSAMPLE + 1][SUBSAMPLE + 1];
|
||||
|
||||
static MaskBuf *last_brush_mask = NULL;
|
||||
static gboolean cache_invalid = FALSE;
|
||||
|
||||
/* paint buffers utility functions */
|
||||
static void free_paint_buffers (void);
|
||||
|
||||
/* brush pipe utility functions */
|
||||
static void paint_line_pixmap_mask (GImage *, GimpDrawable *,
|
||||
TempBuf *, TempBuf *, guchar *,
|
||||
int, int, int, int, int);
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
|
||||
static void
|
||||
paint_core_sample_color (GimpDrawable *drawable,
|
||||
int x,
|
||||
int y,
|
||||
int state)
|
||||
gint x,
|
||||
gint y,
|
||||
gint state)
|
||||
{
|
||||
guchar *color;
|
||||
|
||||
|
@ -277,6 +319,7 @@ paint_core_button_press (Tool *tool,
|
|||
{
|
||||
draw_core_pause (paint_core->core, tool);
|
||||
paint_core_interpolate (paint_core, drawable);
|
||||
|
||||
paint_core->lastx = paint_core->curx;
|
||||
paint_core->lasty = paint_core->cury;
|
||||
paint_core->lastpressure = paint_core->curpressure;
|
||||
|
@ -302,12 +345,16 @@ paint_core_button_press (Tool *tool,
|
|||
paint_core->brush =
|
||||
(* GIMP_BRUSH_CLASS (GTK_OBJECT (paint_core->brush)
|
||||
->klass)->select_brush) (paint_core);
|
||||
|
||||
(* paint_core->paint_func) (paint_core, drawable, MOTION_PAINT);
|
||||
}
|
||||
}
|
||||
|
||||
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
|
||||
(* paint_core->paint_func) (paint_core, drawable, PRETRACE_PAINT);
|
||||
|
||||
gdisplay_flush_now (gdisp);
|
||||
|
||||
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
|
||||
(* paint_core->paint_func) (paint_core, drawable, POSTTRACE_PAINT);
|
||||
}
|
||||
|
@ -332,7 +379,9 @@ paint_core_button_release (Tool *tool,
|
|||
gdk_flush ();
|
||||
|
||||
/* Let the specific painting function finish up */
|
||||
(* paint_core->paint_func) (paint_core, gimage_active_drawable (gdisp->gimage), FINISH_PAINT);
|
||||
(* paint_core->paint_func) (paint_core,
|
||||
gimage_active_drawable (gdisp->gimage),
|
||||
FINISH_PAINT);
|
||||
|
||||
/* Set tool state to inactive -- no longer painting */
|
||||
draw_core_stop (paint_core->core, tool);
|
||||
|
@ -377,10 +426,16 @@ paint_core_motion (Tool *tool,
|
|||
paint_core_interpolate (paint_core, gimage_active_drawable (gdisp->gimage));
|
||||
|
||||
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
|
||||
(* paint_core->paint_func) (paint_core, gimage_active_drawable (gdisp->gimage), PRETRACE_PAINT);
|
||||
(* paint_core->paint_func) (paint_core,
|
||||
gimage_active_drawable (gdisp->gimage),
|
||||
PRETRACE_PAINT);
|
||||
|
||||
gdisplay_flush_now (gdisp);
|
||||
|
||||
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
|
||||
(* paint_core->paint_func) (paint_core, gimage_active_drawable (gdisp->gimage), POSTTRACE_PAINT);
|
||||
(* paint_core->paint_func) (paint_core,
|
||||
gimage_active_drawable (gdisp->gimage),
|
||||
POSTTRACE_PAINT);
|
||||
|
||||
paint_core->lastx = paint_core->curx;
|
||||
paint_core->lasty = paint_core->cury;
|
||||
|
@ -400,9 +455,9 @@ paint_core_cursor_update (Tool *tool,
|
|||
GDisplay *gdisp;
|
||||
Layer *layer;
|
||||
PaintCore *paint_core;
|
||||
GdkCursorType ctype = GDK_TOP_LEFT_ARROW;
|
||||
gint x, y;
|
||||
gchar status_str[STATUSBAR_SIZE];
|
||||
GdkCursorType ctype = GDK_TOP_LEFT_ARROW;
|
||||
|
||||
gdisp = (GDisplay *) gdisp_ptr;
|
||||
paint_core = (PaintCore *) tool->private;
|
||||
|
@ -639,7 +694,6 @@ paint_core_new (ToolType type)
|
|||
private->context_id = 0;
|
||||
|
||||
tool->private = (void *) private;
|
||||
|
||||
tool->button_press_func = paint_core_button_press;
|
||||
tool->button_release_func = paint_core_button_release;
|
||||
tool->motion_func = paint_core_motion;
|
||||
|
@ -706,6 +760,7 @@ paint_core_init (PaintCore *paint_core,
|
|||
g_message (_("No brushes available for use with this tool."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_object_ref (GTK_OBJECT (brush));
|
||||
gtk_signal_connect (GTK_OBJECT (brush), "dirty",
|
||||
GTK_SIGNAL_FUNC (paint_core_invalidate_cache),
|
||||
|
@ -739,39 +794,10 @@ paint_core_init (PaintCore *paint_core,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
paint_core_get_color_from_gradient (PaintCore *paint_core,
|
||||
gdouble gradient_length,
|
||||
gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b,
|
||||
gdouble *a,
|
||||
gint mode)
|
||||
{
|
||||
gdouble y;
|
||||
gdouble distance; /* distance in current brush stroke */
|
||||
|
||||
distance = paint_core->pixel_dist;
|
||||
y = ((double) distance / gradient_length);
|
||||
|
||||
/* for the once modes, set y close to 1.0 after the first chunk */
|
||||
if ( (mode == ONCE_FORWARD || mode == ONCE_BACKWARDS) && y >= 1.0 )
|
||||
y = 0.9999999;
|
||||
|
||||
if ( (((int)y & 1) && mode != LOOP_SAWTOOTH) || mode == ONCE_BACKWARDS )
|
||||
y = 1.0 - (y - (int)y);
|
||||
else
|
||||
y = y - (int)y;
|
||||
|
||||
gradient_get_color_at (gimp_context_get_gradient (NULL), y, r, g, b, a);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
paint_core_interpolate (PaintCore *paint_core,
|
||||
GimpDrawable *drawable)
|
||||
{
|
||||
gdouble n;
|
||||
GimpVector2 delta;
|
||||
#ifdef GTK_HAVE_SIX_VALUATORS
|
||||
gdouble dpressure, dxtilt, dytilt, dwheel;
|
||||
|
@ -780,6 +806,7 @@ paint_core_interpolate (PaintCore *paint_core,
|
|||
#endif /* GTK_HAVE_SIX_VALUATORS */
|
||||
/* double spacing; */
|
||||
/* double lastscale, curscale; */
|
||||
gdouble n;
|
||||
gdouble left;
|
||||
gdouble t;
|
||||
gdouble initial;
|
||||
|
@ -870,7 +897,7 @@ paint_core_interpolate (PaintCore *paint_core,
|
|||
void
|
||||
paint_core_finish (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint tool_id)
|
||||
gint tool_ID)
|
||||
{
|
||||
GImage *gimage;
|
||||
PaintUndo *pu;
|
||||
|
@ -882,13 +909,14 @@ paint_core_finish (PaintCore *paint_core,
|
|||
* if nothing has, then just return...
|
||||
*/
|
||||
|
||||
if ((paint_core->x2 == paint_core->x1) || (paint_core->y2 == paint_core->y1))
|
||||
if ((paint_core->x2 == paint_core->x1) ||
|
||||
(paint_core->y2 == paint_core->y1))
|
||||
return;
|
||||
|
||||
undo_push_group_start (gimage, PAINT_CORE_UNDO);
|
||||
|
||||
pu = g_new (PaintUndo, 1);
|
||||
pu->tool_ID = tool_id;
|
||||
pu->tool_ID = tool_ID;
|
||||
pu->lastx = paint_core->startx;
|
||||
pu->lasty = paint_core->starty;
|
||||
pu->lastpressure = paint_core->startpressure;
|
||||
|
@ -937,6 +965,33 @@ paint_core_cleanup (void)
|
|||
free_paint_buffers ();
|
||||
}
|
||||
|
||||
void
|
||||
paint_core_get_color_from_gradient (PaintCore *paint_core,
|
||||
gdouble gradient_length,
|
||||
gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b,
|
||||
gdouble *a,
|
||||
GradientPaintMode mode)
|
||||
{
|
||||
gdouble y;
|
||||
gdouble distance; /* distance in current brush stroke */
|
||||
|
||||
distance = paint_core->pixel_dist;
|
||||
y = ((double) distance / gradient_length);
|
||||
|
||||
/* for the once modes, set y close to 1.0 after the first chunk */
|
||||
if ( (mode == ONCE_FORWARD || mode == ONCE_BACKWARDS) && y >= 1.0 )
|
||||
y = 0.9999999;
|
||||
|
||||
if ( (((int)y & 1) && mode != LOOP_SAWTOOTH) || mode == ONCE_BACKWARDS )
|
||||
y = 1.0 - (y - (int)y);
|
||||
else
|
||||
y = y - (int)y;
|
||||
|
||||
gradient_get_color_at (gimp_context_get_gradient (NULL), y, r, g, b, a);
|
||||
}
|
||||
|
||||
|
||||
/************************/
|
||||
/* Painting functions */
|
||||
|
@ -960,8 +1015,8 @@ paint_core_get_paint_area (PaintCore *paint_core,
|
|||
&bwidth, &bheight);
|
||||
|
||||
/* adjust the x and y coordinates to the upper left corner of the brush */
|
||||
x = (int) paint_core->curx - (bwidth >> 1);
|
||||
y = (int) paint_core->cury - (bheight >> 1);
|
||||
x = (gint) paint_core->curx - (bwidth >> 1);
|
||||
y = (gint) paint_core->cury - (bheight >> 1);
|
||||
|
||||
dwidth = drawable_width (drawable);
|
||||
dheight = drawable_height (drawable);
|
||||
|
@ -989,14 +1044,17 @@ paint_core_get_orig_image (PaintCore *paint_core,
|
|||
gint x2,
|
||||
gint y2)
|
||||
{
|
||||
PixelRegion srcPR, destPR;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion destPR;
|
||||
Tile *undo_tile;
|
||||
gint h;
|
||||
gint refd;
|
||||
gint pixelwidth;
|
||||
gint dwidth, dheight;
|
||||
guchar *s, *d;
|
||||
void * pr;
|
||||
gint dwidth;
|
||||
gint dheight;
|
||||
guchar *s;
|
||||
guchar *d;
|
||||
gpointer pr;
|
||||
|
||||
orig_buf = temp_buf_resize (orig_buf, drawable_bytes (drawable),
|
||||
x1, y1, (x2 - x1), (y2 - y1));
|
||||
|
@ -1093,19 +1151,18 @@ paint_core_replace_canvas (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask;
|
||||
|
||||
/* get the brush mask */
|
||||
brush_mask = paint_core_get_brush_mask (paint_core, brush_hardness, brush_scale);
|
||||
brush_mask =
|
||||
paint_core_get_brush_mask (paint_core, brush_hardness, brush_scale);
|
||||
|
||||
/* paste the canvas buf */
|
||||
paint_core_replace (paint_core, brush_mask, drawable,
|
||||
brush_opacity, image_opacity, mode);
|
||||
}
|
||||
|
||||
static MaskBuf *last_brush_mask = NULL;
|
||||
static gboolean cache_invalid = FALSE;
|
||||
|
||||
static void
|
||||
paint_core_invalidate_cache (GimpBrush *brush,
|
||||
gpointer *blah)
|
||||
gpointer data)
|
||||
{
|
||||
/* Make sure we don't cache data for a brush that has changed */
|
||||
if (last_brush_mask == brush->mask)
|
||||
|
@ -1136,8 +1193,8 @@ paint_core_calculate_brush_size (MaskBuf *mask,
|
|||
else
|
||||
ratio = sqrt (scale);
|
||||
|
||||
*width = MAX ((int)(mask->width * ratio + 0.5), 1);
|
||||
*height = MAX ((int)(mask->height * ratio + 0.5), 1);
|
||||
*width = MAX ((gint)(mask->width * ratio + 0.5), 1);
|
||||
*height = MAX ((gint)(mask->height * ratio + 0.5), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1148,9 +1205,11 @@ paint_core_subsample_mask (MaskBuf *mask,
|
|||
{
|
||||
MaskBuf *dest;
|
||||
gdouble left;
|
||||
guchar *m, *d;
|
||||
guchar *m;
|
||||
guchar *d;
|
||||
const gint *k;
|
||||
gint index1, index2;
|
||||
gint index1;
|
||||
gint index2;
|
||||
const gint *kernel;
|
||||
gint new_val;
|
||||
gint i, j;
|
||||
|
@ -1166,23 +1225,28 @@ paint_core_subsample_mask (MaskBuf *mask,
|
|||
|
||||
kernel = subsample[index2][index1];
|
||||
|
||||
if ((mask == last_brush_mask) && kernel_brushes[index2][index1] &&
|
||||
!cache_invalid)
|
||||
if (mask == last_brush_mask && !cache_invalid)
|
||||
{
|
||||
if (kernel_brushes[index2][index1])
|
||||
return kernel_brushes[index2][index1];
|
||||
else if (mask != last_brush_mask || cache_invalid)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i <= SUBSAMPLE; i++)
|
||||
for (j = 0; j <= SUBSAMPLE; j++)
|
||||
{
|
||||
if (kernel_brushes[i][j])
|
||||
mask_buf_free (kernel_brushes[i][j]);
|
||||
|
||||
kernel_brushes[i][j] = NULL;
|
||||
}
|
||||
|
||||
last_brush_mask = mask;
|
||||
cache_invalid = FALSE;
|
||||
kernel_brushes[index2][index1] =
|
||||
mask_buf_new (mask->width + 2, mask->height + 2);
|
||||
dest = kernel_brushes[index2][index1];
|
||||
}
|
||||
|
||||
dest = kernel_brushes[index2][index1] = mask_buf_new (mask->width + 2,
|
||||
mask->height + 2);
|
||||
|
||||
m = mask_buf_data (mask);
|
||||
for (i = 0; i < mask->height; i++)
|
||||
|
@ -1238,6 +1302,7 @@ paint_core_pressurize_mask (MaskBuf *brush_mask,
|
|||
{
|
||||
if (pressure_brush)
|
||||
mask_buf_free (pressure_brush);
|
||||
|
||||
pressure_brush = mask_buf_new (brush_mask->width + 2,
|
||||
brush_mask->height + 2);
|
||||
}
|
||||
|
@ -1317,11 +1382,14 @@ static MaskBuf *
|
|||
paint_core_solidify_mask (MaskBuf *brush_mask)
|
||||
{
|
||||
static MaskBuf *last_brush = NULL;
|
||||
gint i, j;
|
||||
guchar * data, * src;
|
||||
gint i;
|
||||
gint j;
|
||||
guchar *data;
|
||||
guchar *src;
|
||||
|
||||
if (brush_mask == last_brush && !cache_invalid)
|
||||
return solid_brush;
|
||||
|
||||
last_brush = brush_mask;
|
||||
|
||||
if (solid_brush)
|
||||
|
@ -1353,7 +1421,8 @@ paint_core_scale_mask (MaskBuf *brush_mask,
|
|||
static MaskBuf *last_brush = NULL;
|
||||
static gint last_width = 0.0;
|
||||
static gint last_height = 0.0;
|
||||
gint dest_width, dest_height;
|
||||
gint dest_width;
|
||||
gint dest_height;
|
||||
|
||||
if (scale == 0.0)
|
||||
return NULL;
|
||||
|
@ -1388,7 +1457,8 @@ paint_core_scale_pixmap (MaskBuf *brush_mask,
|
|||
static MaskBuf *last_brush = NULL;
|
||||
static gint last_width = 0.0;
|
||||
static gint last_height = 0.0;
|
||||
gint dest_width, dest_height;
|
||||
gint dest_width;
|
||||
gint dest_height;
|
||||
|
||||
if (scale == 0.0)
|
||||
return NULL;
|
||||
|
@ -1456,10 +1526,11 @@ paint_core_paste (PaintCore *paint_core,
|
|||
LayerModeEffects paint_mode,
|
||||
PaintApplicationMode mode)
|
||||
{
|
||||
GImage *gimage;
|
||||
GimpImage *gimage;
|
||||
PixelRegion srcPR;
|
||||
TileManager *alt = NULL;
|
||||
gint offx, offy;
|
||||
gint offx;
|
||||
gint offy;
|
||||
|
||||
if (! (gimage = drawable_gimage (drawable)))
|
||||
return;
|
||||
|
@ -1533,10 +1604,12 @@ paint_core_replace (PaintCore *paint_core,
|
|||
gint image_opacity,
|
||||
PaintApplicationMode mode)
|
||||
{
|
||||
GImage *gimage;
|
||||
PixelRegion srcPR, maskPR;
|
||||
GimpImage *gimage;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
TileManager *alt = NULL;
|
||||
gint offx, offy;
|
||||
gint offx;
|
||||
gint offy;
|
||||
|
||||
if (!drawable_has_alpha (drawable))
|
||||
{
|
||||
|
@ -1575,7 +1648,8 @@ paint_core_replace (PaintCore *paint_core,
|
|||
{
|
||||
/* The mask is just the brush mask */
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = canvas_buf->width;
|
||||
maskPR.h = canvas_buf->height;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1584,7 +1658,8 @@ paint_core_replace (PaintCore *paint_core,
|
|||
|
||||
/* intialize canvas buf source pixel regions */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
|
@ -1614,11 +1689,13 @@ paint_core_replace (PaintCore *paint_core,
|
|||
static void
|
||||
canvas_tiles_to_canvas_buf (PaintCore *paint_core)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
|
||||
/* combine the canvas tiles and the canvas buf */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
|
@ -1637,22 +1714,26 @@ brush_to_canvas_tiles (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask,
|
||||
gint brush_opacity)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
gint x, y;
|
||||
gint xoff, yoff;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
gint x;
|
||||
gint y;
|
||||
gint xoff;
|
||||
gint yoff;
|
||||
|
||||
/* combine the brush mask and the canvas tiles */
|
||||
pixel_region_init (&srcPR, canvas_tiles,
|
||||
canvas_buf->x, canvas_buf->y,
|
||||
canvas_buf->width, canvas_buf->height, TRUE);
|
||||
|
||||
x = (int) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (int) paint_core->cury - (brush_mask->height >> 1);
|
||||
x = (gint) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (gint) paint_core->cury - (brush_mask->height >> 1);
|
||||
xoff = (x < 0) ? -x : 0;
|
||||
yoff = (y < 0) ? -y : 0;
|
||||
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = srcPR.w;
|
||||
maskPR.h = srcPR.h;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1667,25 +1748,30 @@ brush_to_canvas_buf (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask,
|
||||
gint brush_opacity)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
gint x, y;
|
||||
gint xoff, yoff;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
gint x;
|
||||
gint y;
|
||||
gint xoff;
|
||||
gint yoff;
|
||||
|
||||
x = (int) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (int) paint_core->cury - (brush_mask->height >> 1);
|
||||
x = (gint) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (gint) paint_core->cury - (brush_mask->height >> 1);
|
||||
xoff = (x < 0) ? -x : 0;
|
||||
yoff = (y < 0) ? -y : 0;
|
||||
|
||||
/* combine the canvas buf and the brush mask to the canvas buf */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
srcPR.data = temp_buf_data (canvas_buf);
|
||||
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = srcPR.w;
|
||||
maskPR.h = srcPR.h;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1701,22 +1787,26 @@ paint_to_canvas_tiles (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask,
|
||||
gint brush_opacity)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
gint x, y;
|
||||
gint xoff, yoff;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
gint x;
|
||||
gint y;
|
||||
gint xoff;
|
||||
gint yoff;
|
||||
|
||||
/* combine the brush mask and the canvas tiles */
|
||||
pixel_region_init (&srcPR, canvas_tiles,
|
||||
canvas_buf->x, canvas_buf->y,
|
||||
canvas_buf->width, canvas_buf->height, TRUE);
|
||||
|
||||
x = (int) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (int) paint_core->cury - (brush_mask->height >> 1);
|
||||
x = (gint) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (gint) paint_core->cury - (brush_mask->height >> 1);
|
||||
xoff = (x < 0) ? -x : 0;
|
||||
yoff = (y < 0) ? -y : 0;
|
||||
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = srcPR.w;
|
||||
maskPR.h = srcPR.h;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1727,7 +1817,8 @@ paint_to_canvas_tiles (PaintCore *paint_core,
|
|||
|
||||
/* combine the canvas tiles and the canvas buf */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
|
@ -1746,26 +1837,31 @@ paint_to_canvas_buf (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask,
|
||||
gint brush_opacity)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
gint x, y;
|
||||
gint xoff, yoff;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
gint x;
|
||||
gint y;
|
||||
gint xoff;
|
||||
gint yoff;
|
||||
|
||||
x = (int) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (int) paint_core->cury - (brush_mask->height >> 1);
|
||||
x = (gint) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (gint) paint_core->cury - (brush_mask->height >> 1);
|
||||
xoff = (x < 0) ? -x : 0;
|
||||
yoff = (y < 0) ? -y : 0;
|
||||
|
||||
|
||||
/* combine the canvas buf and the brush mask to the canvas buf */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
srcPR.data = temp_buf_data (canvas_buf);
|
||||
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = srcPR.w;
|
||||
maskPR.h = srcPR.h;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1783,7 +1879,8 @@ set_undo_tiles (GimpDrawable *drawable,
|
|||
gint w,
|
||||
gint h)
|
||||
{
|
||||
gint i, j;
|
||||
gint i;
|
||||
gint j;
|
||||
Tile *src_tile;
|
||||
Tile *dest_tile;
|
||||
|
||||
|
@ -1814,7 +1911,8 @@ set_canvas_tiles (gint x,
|
|||
gint w,
|
||||
gint h)
|
||||
{
|
||||
gint i, j;
|
||||
gint i;
|
||||
gint j;
|
||||
Tile *tile;
|
||||
|
||||
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
|
||||
|
@ -1825,8 +1923,7 @@ set_canvas_tiles (gint x,
|
|||
if (tile_is_valid (tile) == FALSE)
|
||||
{
|
||||
tile = tile_manager_get_tile (canvas_tiles, j, i, TRUE, TRUE);
|
||||
memset (tile_data_pointer (tile, 0, 0), 0,
|
||||
tile_size (tile));
|
||||
memset (tile_data_pointer (tile, 0, 0), 0, tile_size (tile));
|
||||
tile_release (tile, TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -1858,16 +1955,20 @@ free_paint_buffers (void)
|
|||
|
||||
void
|
||||
paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
||||
GImage *dest,
|
||||
GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *area,
|
||||
gdouble scale,
|
||||
gint mode)
|
||||
BrushApplicationMode mode)
|
||||
{
|
||||
PixelRegion destPR;
|
||||
void *pr;
|
||||
guchar *d;
|
||||
gint ulx, uly, offsetx, offsety, y;
|
||||
gint ulx;
|
||||
gint uly;
|
||||
gint offsetx;
|
||||
gint offsety;
|
||||
gint y;
|
||||
TempBuf *pixmap_mask;
|
||||
TempBuf *brush_mask;
|
||||
|
||||
|
@ -1876,13 +1977,15 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
|||
/* scale the brushes */
|
||||
pixmap_mask =
|
||||
paint_core_scale_pixmap (gimp_brush_pixmap_pixmap (GIMP_BRUSH_PIXMAP (paint_core->brush)), scale);
|
||||
|
||||
if (mode == SOFT)
|
||||
brush_mask = paint_core_scale_mask (paint_core->brush->mask, scale);
|
||||
else
|
||||
brush_mask = NULL;
|
||||
|
||||
destPR.bytes = area->bytes;
|
||||
destPR.x = 0; destPR.y = 0;
|
||||
destPR.x = 0;
|
||||
destPR.y = 0;
|
||||
destPR.w = area->width;
|
||||
destPR.h = area->height;
|
||||
destPR.rowstride = destPR.bytes * area->width;
|
||||
|
@ -1894,8 +1997,8 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
|||
* paint_core_get_paint_area. Ugly to have to do this here, too.
|
||||
*/
|
||||
|
||||
ulx = (int) paint_core->curx - (pixmap_mask->width >> 1);
|
||||
uly = (int) paint_core->cury - (pixmap_mask->height >> 1);
|
||||
ulx = (gint) paint_core->curx - (pixmap_mask->width >> 1);
|
||||
uly = (gint) paint_core->cury - (pixmap_mask->height >> 1);
|
||||
|
||||
offsetx = area->x - ulx;
|
||||
offsety = area->y - uly;
|
||||
|
@ -1914,7 +2017,7 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
|||
}
|
||||
|
||||
static void
|
||||
paint_line_pixmap_mask (GImage *dest,
|
||||
paint_line_pixmap_mask (GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *pixmap_mask,
|
||||
TempBuf *brush_mask,
|
||||
|
@ -1923,14 +2026,15 @@ paint_line_pixmap_mask (GImage *dest,
|
|||
gint y,
|
||||
gint bytes,
|
||||
gint width,
|
||||
gint mode)
|
||||
BrushApplicationMode mode)
|
||||
{
|
||||
guchar *b, *p;
|
||||
gint x_index;
|
||||
guchar *b;
|
||||
guchar *p;
|
||||
guchar *mask;
|
||||
gdouble alpha;
|
||||
gdouble factor = 0.00392156986; /* 1.0 / 255.0 */
|
||||
gint x_index;
|
||||
gint i;
|
||||
guchar *mask;
|
||||
|
||||
/* Make sure x, y are positive */
|
||||
while (x < 0)
|
||||
|
|
|
@ -119,42 +119,68 @@ struct _paint_undo
|
|||
};
|
||||
|
||||
/* paint tool action functions */
|
||||
void paint_core_button_press (Tool *, GdkEventButton *, gpointer);
|
||||
void paint_core_button_release (Tool *, GdkEventButton *, gpointer);
|
||||
void paint_core_motion (Tool *, GdkEventMotion *, gpointer);
|
||||
void paint_core_cursor_update (Tool *, GdkEventMotion *, gpointer);
|
||||
void paint_core_control (Tool *, ToolAction, gpointer);
|
||||
void paint_core_button_press (Tool *tool, GdkEventButton *bevent, gpointer gdisp_ptr);
|
||||
void paint_core_button_release (Tool *tool, GdkEventButton *bevent, gpointer gdisp_ptr);
|
||||
void paint_core_motion (Tool *tool, GdkEventMotion *mevent, gpointer gdisp_ptr);
|
||||
void paint_core_cursor_update (Tool *tool, GdkEventMotion *mevent, gpointer gdisp_ptr);
|
||||
|
||||
void paint_core_control (Tool *tool,
|
||||
ToolAction action,
|
||||
gpointer gdisp_ptr);
|
||||
|
||||
/* paint tool functions */
|
||||
void paint_core_no_draw (Tool *);
|
||||
Tool * paint_core_new (ToolType);
|
||||
void paint_core_free (Tool *);
|
||||
int paint_core_init (PaintCore *, GimpDrawable *, double, double);
|
||||
void paint_core_interpolate (PaintCore *, GimpDrawable *);
|
||||
void paint_core_get_color_from_gradient (PaintCore *, double, double*, double*, double*,double *,int);
|
||||
void paint_core_finish (PaintCore *, GimpDrawable *, int);
|
||||
void paint_core_no_draw (Tool *tool);
|
||||
Tool * paint_core_new (ToolType type);
|
||||
void paint_core_free (Tool *tool);
|
||||
int paint_core_init (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
void paint_core_interpolate (PaintCore *paint_core,
|
||||
GimpDrawable *drawable);
|
||||
void paint_core_finish (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint tool_ID);
|
||||
void paint_core_cleanup (void);
|
||||
|
||||
void paint_core_get_color_from_gradient (PaintCore *paint_core,
|
||||
gdouble gradient_length,
|
||||
gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b,
|
||||
gdouble *a,
|
||||
GradientPaintMode mode);
|
||||
|
||||
/* paint tool painting functions */
|
||||
TempBuf * paint_core_get_paint_area (PaintCore *,
|
||||
GimpDrawable *,
|
||||
gdouble);
|
||||
TempBuf * paint_core_get_orig_image (PaintCore *,
|
||||
GimpDrawable *,
|
||||
int, int, int, int);
|
||||
void paint_core_paste_canvas (PaintCore *,
|
||||
GimpDrawable *, int, int,
|
||||
LayerModeEffects,
|
||||
BrushApplicationMode,
|
||||
gdouble,
|
||||
PaintApplicationMode);
|
||||
void paint_core_replace_canvas (PaintCore *,
|
||||
GimpDrawable *, int, int,
|
||||
BrushApplicationMode,
|
||||
gdouble,
|
||||
PaintApplicationMode);
|
||||
void paint_core_color_area_with_pixmap (PaintCore *,
|
||||
GImage *, GimpDrawable *,
|
||||
TempBuf *, gdouble, int);
|
||||
TempBuf * paint_core_get_paint_area (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gdouble scale);
|
||||
TempBuf * paint_core_get_orig_image (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2);
|
||||
void paint_core_paste_canvas (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
LayerModeEffects paint_mode,
|
||||
BrushApplicationMode brush_hardness,
|
||||
gdouble brush_scale,
|
||||
PaintApplicationMode mode);
|
||||
void paint_core_replace_canvas (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
BrushApplicationMode brush_hardness,
|
||||
gdouble brush_scale,
|
||||
PaintApplicationMode mode);
|
||||
void paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
||||
GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *area,
|
||||
gdouble scale,
|
||||
BrushApplicationMode mode);
|
||||
|
||||
#endif /* __PAINT_CORE_H__ */
|
||||
|
|
|
@ -56,26 +56,75 @@
|
|||
PaintCore non_gui_paint_core;
|
||||
|
||||
/* local function prototypes */
|
||||
static void paint_core_calculate_brush_size (MaskBuf *, double, int *, int *);
|
||||
static MaskBuf * paint_core_subsample_mask (MaskBuf *, double, double);
|
||||
static MaskBuf * paint_core_pressurize_mask (MaskBuf *, double, double, double);
|
||||
static MaskBuf * paint_core_solidify_mask (MaskBuf *);
|
||||
static MaskBuf * paint_core_scale_mask (MaskBuf *, gdouble);
|
||||
static MaskBuf * paint_core_scale_pixmap (MaskBuf *, gdouble);
|
||||
static MaskBuf * paint_core_get_brush_mask (PaintCore *, BrushApplicationMode, gdouble);
|
||||
static void paint_core_paste (PaintCore *, MaskBuf *,
|
||||
GimpDrawable *, int, int,
|
||||
LayerModeEffects,
|
||||
PaintApplicationMode);
|
||||
static void paint_core_replace (PaintCore *, MaskBuf *,
|
||||
GimpDrawable *, int, int,
|
||||
PaintApplicationMode);
|
||||
static void brush_to_canvas_tiles (PaintCore *, MaskBuf *, int);
|
||||
static void canvas_tiles_to_canvas_buf (PaintCore *);
|
||||
static void brush_to_canvas_buf (PaintCore *, MaskBuf *, int);
|
||||
static void set_undo_tiles (GimpDrawable *, int, int, int, int);
|
||||
static void set_canvas_tiles (int, int, int, int);
|
||||
static void paint_core_invalidate_cache (GimpBrush *brush, gpointer *blah);
|
||||
static void paint_core_calculate_brush_size (MaskBuf *mask,
|
||||
gdouble scale,
|
||||
gint *width,
|
||||
gint *height);
|
||||
static MaskBuf * paint_core_subsample_mask (MaskBuf *mask,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
static MaskBuf * paint_core_pressurize_mask (MaskBuf *brush_mask,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
gdouble pressure);
|
||||
static MaskBuf * paint_core_solidify_mask (MaskBuf *brush_mask);
|
||||
static MaskBuf * paint_core_scale_mask (MaskBuf *brush_mask,
|
||||
gdouble scale);
|
||||
static MaskBuf * paint_core_scale_pixmap (MaskBuf *brush_mask,
|
||||
gdouble scale);
|
||||
|
||||
static MaskBuf * paint_core_get_brush_mask (PaintCore *paint_core,
|
||||
BrushApplicationMode brush_hardness,
|
||||
gdouble scale);
|
||||
static void paint_core_paste (PaintCore *paint_core,
|
||||
MaskBuf *brush_mask,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
LayerModeEffects paint_mode,
|
||||
PaintApplicationMode mode);
|
||||
static void paint_core_replace (PaintCore *paint_core,
|
||||
MaskBuf *brush_mask,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
PaintApplicationMode mode);
|
||||
|
||||
static void brush_to_canvas_tiles (PaintCore *paint_core,
|
||||
MaskBuf *brush_mask,
|
||||
gint brush_opacity);
|
||||
static void brush_to_canvas_buf (PaintCore *paint_core,
|
||||
MaskBuf *brush_mask,
|
||||
gint brush_opacity);
|
||||
static void canvas_tiles_to_canvas_buf (PaintCore *paint_core);
|
||||
|
||||
static void set_undo_tiles (GimpDrawable *drawable,
|
||||
gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
static void set_canvas_tiles (gint x,
|
||||
gint y,
|
||||
gint w,
|
||||
gint h);
|
||||
static void paint_core_invalidate_cache (GimpBrush *brush,
|
||||
gpointer data);
|
||||
|
||||
|
||||
/* paint buffers utility functions */
|
||||
static void free_paint_buffers (void);
|
||||
|
||||
/* brush pipe utility functions */
|
||||
static void paint_line_pixmap_mask (GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *pixmap_mask,
|
||||
TempBuf *brush_mask,
|
||||
guchar *d,
|
||||
gint x,
|
||||
gint y,
|
||||
gint bytes,
|
||||
gint width,
|
||||
BrushApplicationMode mode);
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
|
@ -100,24 +149,17 @@ static MaskBuf * scale_brush = NULL;
|
|||
static MaskBuf *scale_pixmap = NULL;
|
||||
static MaskBuf *kernel_brushes[SUBSAMPLE + 1][SUBSAMPLE + 1];
|
||||
|
||||
static MaskBuf *last_brush_mask = NULL;
|
||||
static gboolean cache_invalid = FALSE;
|
||||
|
||||
/* paint buffers utility functions */
|
||||
static void free_paint_buffers (void);
|
||||
|
||||
/* brush pipe utility functions */
|
||||
static void paint_line_pixmap_mask (GImage *, GimpDrawable *,
|
||||
TempBuf *, TempBuf *, guchar *,
|
||||
int, int, int, int, int);
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
|
||||
|
||||
static void
|
||||
paint_core_sample_color (GimpDrawable *drawable,
|
||||
int x,
|
||||
int y,
|
||||
int state)
|
||||
gint x,
|
||||
gint y,
|
||||
gint state)
|
||||
{
|
||||
guchar *color;
|
||||
|
||||
|
@ -277,6 +319,7 @@ paint_core_button_press (Tool *tool,
|
|||
{
|
||||
draw_core_pause (paint_core->core, tool);
|
||||
paint_core_interpolate (paint_core, drawable);
|
||||
|
||||
paint_core->lastx = paint_core->curx;
|
||||
paint_core->lasty = paint_core->cury;
|
||||
paint_core->lastpressure = paint_core->curpressure;
|
||||
|
@ -302,12 +345,16 @@ paint_core_button_press (Tool *tool,
|
|||
paint_core->brush =
|
||||
(* GIMP_BRUSH_CLASS (GTK_OBJECT (paint_core->brush)
|
||||
->klass)->select_brush) (paint_core);
|
||||
|
||||
(* paint_core->paint_func) (paint_core, drawable, MOTION_PAINT);
|
||||
}
|
||||
}
|
||||
|
||||
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
|
||||
(* paint_core->paint_func) (paint_core, drawable, PRETRACE_PAINT);
|
||||
|
||||
gdisplay_flush_now (gdisp);
|
||||
|
||||
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
|
||||
(* paint_core->paint_func) (paint_core, drawable, POSTTRACE_PAINT);
|
||||
}
|
||||
|
@ -332,7 +379,9 @@ paint_core_button_release (Tool *tool,
|
|||
gdk_flush ();
|
||||
|
||||
/* Let the specific painting function finish up */
|
||||
(* paint_core->paint_func) (paint_core, gimage_active_drawable (gdisp->gimage), FINISH_PAINT);
|
||||
(* paint_core->paint_func) (paint_core,
|
||||
gimage_active_drawable (gdisp->gimage),
|
||||
FINISH_PAINT);
|
||||
|
||||
/* Set tool state to inactive -- no longer painting */
|
||||
draw_core_stop (paint_core->core, tool);
|
||||
|
@ -377,10 +426,16 @@ paint_core_motion (Tool *tool,
|
|||
paint_core_interpolate (paint_core, gimage_active_drawable (gdisp->gimage));
|
||||
|
||||
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
|
||||
(* paint_core->paint_func) (paint_core, gimage_active_drawable (gdisp->gimage), PRETRACE_PAINT);
|
||||
(* paint_core->paint_func) (paint_core,
|
||||
gimage_active_drawable (gdisp->gimage),
|
||||
PRETRACE_PAINT);
|
||||
|
||||
gdisplay_flush_now (gdisp);
|
||||
|
||||
if (paint_core->flags & TOOL_TRACES_ON_WINDOW)
|
||||
(* paint_core->paint_func) (paint_core, gimage_active_drawable (gdisp->gimage), POSTTRACE_PAINT);
|
||||
(* paint_core->paint_func) (paint_core,
|
||||
gimage_active_drawable (gdisp->gimage),
|
||||
POSTTRACE_PAINT);
|
||||
|
||||
paint_core->lastx = paint_core->curx;
|
||||
paint_core->lasty = paint_core->cury;
|
||||
|
@ -400,9 +455,9 @@ paint_core_cursor_update (Tool *tool,
|
|||
GDisplay *gdisp;
|
||||
Layer *layer;
|
||||
PaintCore *paint_core;
|
||||
GdkCursorType ctype = GDK_TOP_LEFT_ARROW;
|
||||
gint x, y;
|
||||
gchar status_str[STATUSBAR_SIZE];
|
||||
GdkCursorType ctype = GDK_TOP_LEFT_ARROW;
|
||||
|
||||
gdisp = (GDisplay *) gdisp_ptr;
|
||||
paint_core = (PaintCore *) tool->private;
|
||||
|
@ -639,7 +694,6 @@ paint_core_new (ToolType type)
|
|||
private->context_id = 0;
|
||||
|
||||
tool->private = (void *) private;
|
||||
|
||||
tool->button_press_func = paint_core_button_press;
|
||||
tool->button_release_func = paint_core_button_release;
|
||||
tool->motion_func = paint_core_motion;
|
||||
|
@ -706,6 +760,7 @@ paint_core_init (PaintCore *paint_core,
|
|||
g_message (_("No brushes available for use with this tool."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gtk_object_ref (GTK_OBJECT (brush));
|
||||
gtk_signal_connect (GTK_OBJECT (brush), "dirty",
|
||||
GTK_SIGNAL_FUNC (paint_core_invalidate_cache),
|
||||
|
@ -739,39 +794,10 @@ paint_core_init (PaintCore *paint_core,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
paint_core_get_color_from_gradient (PaintCore *paint_core,
|
||||
gdouble gradient_length,
|
||||
gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b,
|
||||
gdouble *a,
|
||||
gint mode)
|
||||
{
|
||||
gdouble y;
|
||||
gdouble distance; /* distance in current brush stroke */
|
||||
|
||||
distance = paint_core->pixel_dist;
|
||||
y = ((double) distance / gradient_length);
|
||||
|
||||
/* for the once modes, set y close to 1.0 after the first chunk */
|
||||
if ( (mode == ONCE_FORWARD || mode == ONCE_BACKWARDS) && y >= 1.0 )
|
||||
y = 0.9999999;
|
||||
|
||||
if ( (((int)y & 1) && mode != LOOP_SAWTOOTH) || mode == ONCE_BACKWARDS )
|
||||
y = 1.0 - (y - (int)y);
|
||||
else
|
||||
y = y - (int)y;
|
||||
|
||||
gradient_get_color_at (gimp_context_get_gradient (NULL), y, r, g, b, a);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
paint_core_interpolate (PaintCore *paint_core,
|
||||
GimpDrawable *drawable)
|
||||
{
|
||||
gdouble n;
|
||||
GimpVector2 delta;
|
||||
#ifdef GTK_HAVE_SIX_VALUATORS
|
||||
gdouble dpressure, dxtilt, dytilt, dwheel;
|
||||
|
@ -780,6 +806,7 @@ paint_core_interpolate (PaintCore *paint_core,
|
|||
#endif /* GTK_HAVE_SIX_VALUATORS */
|
||||
/* double spacing; */
|
||||
/* double lastscale, curscale; */
|
||||
gdouble n;
|
||||
gdouble left;
|
||||
gdouble t;
|
||||
gdouble initial;
|
||||
|
@ -870,7 +897,7 @@ paint_core_interpolate (PaintCore *paint_core,
|
|||
void
|
||||
paint_core_finish (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint tool_id)
|
||||
gint tool_ID)
|
||||
{
|
||||
GImage *gimage;
|
||||
PaintUndo *pu;
|
||||
|
@ -882,13 +909,14 @@ paint_core_finish (PaintCore *paint_core,
|
|||
* if nothing has, then just return...
|
||||
*/
|
||||
|
||||
if ((paint_core->x2 == paint_core->x1) || (paint_core->y2 == paint_core->y1))
|
||||
if ((paint_core->x2 == paint_core->x1) ||
|
||||
(paint_core->y2 == paint_core->y1))
|
||||
return;
|
||||
|
||||
undo_push_group_start (gimage, PAINT_CORE_UNDO);
|
||||
|
||||
pu = g_new (PaintUndo, 1);
|
||||
pu->tool_ID = tool_id;
|
||||
pu->tool_ID = tool_ID;
|
||||
pu->lastx = paint_core->startx;
|
||||
pu->lasty = paint_core->starty;
|
||||
pu->lastpressure = paint_core->startpressure;
|
||||
|
@ -937,6 +965,33 @@ paint_core_cleanup (void)
|
|||
free_paint_buffers ();
|
||||
}
|
||||
|
||||
void
|
||||
paint_core_get_color_from_gradient (PaintCore *paint_core,
|
||||
gdouble gradient_length,
|
||||
gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b,
|
||||
gdouble *a,
|
||||
GradientPaintMode mode)
|
||||
{
|
||||
gdouble y;
|
||||
gdouble distance; /* distance in current brush stroke */
|
||||
|
||||
distance = paint_core->pixel_dist;
|
||||
y = ((double) distance / gradient_length);
|
||||
|
||||
/* for the once modes, set y close to 1.0 after the first chunk */
|
||||
if ( (mode == ONCE_FORWARD || mode == ONCE_BACKWARDS) && y >= 1.0 )
|
||||
y = 0.9999999;
|
||||
|
||||
if ( (((int)y & 1) && mode != LOOP_SAWTOOTH) || mode == ONCE_BACKWARDS )
|
||||
y = 1.0 - (y - (int)y);
|
||||
else
|
||||
y = y - (int)y;
|
||||
|
||||
gradient_get_color_at (gimp_context_get_gradient (NULL), y, r, g, b, a);
|
||||
}
|
||||
|
||||
|
||||
/************************/
|
||||
/* Painting functions */
|
||||
|
@ -960,8 +1015,8 @@ paint_core_get_paint_area (PaintCore *paint_core,
|
|||
&bwidth, &bheight);
|
||||
|
||||
/* adjust the x and y coordinates to the upper left corner of the brush */
|
||||
x = (int) paint_core->curx - (bwidth >> 1);
|
||||
y = (int) paint_core->cury - (bheight >> 1);
|
||||
x = (gint) paint_core->curx - (bwidth >> 1);
|
||||
y = (gint) paint_core->cury - (bheight >> 1);
|
||||
|
||||
dwidth = drawable_width (drawable);
|
||||
dheight = drawable_height (drawable);
|
||||
|
@ -989,14 +1044,17 @@ paint_core_get_orig_image (PaintCore *paint_core,
|
|||
gint x2,
|
||||
gint y2)
|
||||
{
|
||||
PixelRegion srcPR, destPR;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion destPR;
|
||||
Tile *undo_tile;
|
||||
gint h;
|
||||
gint refd;
|
||||
gint pixelwidth;
|
||||
gint dwidth, dheight;
|
||||
guchar *s, *d;
|
||||
void * pr;
|
||||
gint dwidth;
|
||||
gint dheight;
|
||||
guchar *s;
|
||||
guchar *d;
|
||||
gpointer pr;
|
||||
|
||||
orig_buf = temp_buf_resize (orig_buf, drawable_bytes (drawable),
|
||||
x1, y1, (x2 - x1), (y2 - y1));
|
||||
|
@ -1093,19 +1151,18 @@ paint_core_replace_canvas (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask;
|
||||
|
||||
/* get the brush mask */
|
||||
brush_mask = paint_core_get_brush_mask (paint_core, brush_hardness, brush_scale);
|
||||
brush_mask =
|
||||
paint_core_get_brush_mask (paint_core, brush_hardness, brush_scale);
|
||||
|
||||
/* paste the canvas buf */
|
||||
paint_core_replace (paint_core, brush_mask, drawable,
|
||||
brush_opacity, image_opacity, mode);
|
||||
}
|
||||
|
||||
static MaskBuf *last_brush_mask = NULL;
|
||||
static gboolean cache_invalid = FALSE;
|
||||
|
||||
static void
|
||||
paint_core_invalidate_cache (GimpBrush *brush,
|
||||
gpointer *blah)
|
||||
gpointer data)
|
||||
{
|
||||
/* Make sure we don't cache data for a brush that has changed */
|
||||
if (last_brush_mask == brush->mask)
|
||||
|
@ -1136,8 +1193,8 @@ paint_core_calculate_brush_size (MaskBuf *mask,
|
|||
else
|
||||
ratio = sqrt (scale);
|
||||
|
||||
*width = MAX ((int)(mask->width * ratio + 0.5), 1);
|
||||
*height = MAX ((int)(mask->height * ratio + 0.5), 1);
|
||||
*width = MAX ((gint)(mask->width * ratio + 0.5), 1);
|
||||
*height = MAX ((gint)(mask->height * ratio + 0.5), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1148,9 +1205,11 @@ paint_core_subsample_mask (MaskBuf *mask,
|
|||
{
|
||||
MaskBuf *dest;
|
||||
gdouble left;
|
||||
guchar *m, *d;
|
||||
guchar *m;
|
||||
guchar *d;
|
||||
const gint *k;
|
||||
gint index1, index2;
|
||||
gint index1;
|
||||
gint index2;
|
||||
const gint *kernel;
|
||||
gint new_val;
|
||||
gint i, j;
|
||||
|
@ -1166,23 +1225,28 @@ paint_core_subsample_mask (MaskBuf *mask,
|
|||
|
||||
kernel = subsample[index2][index1];
|
||||
|
||||
if ((mask == last_brush_mask) && kernel_brushes[index2][index1] &&
|
||||
!cache_invalid)
|
||||
if (mask == last_brush_mask && !cache_invalid)
|
||||
{
|
||||
if (kernel_brushes[index2][index1])
|
||||
return kernel_brushes[index2][index1];
|
||||
else if (mask != last_brush_mask || cache_invalid)
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i <= SUBSAMPLE; i++)
|
||||
for (j = 0; j <= SUBSAMPLE; j++)
|
||||
{
|
||||
if (kernel_brushes[i][j])
|
||||
mask_buf_free (kernel_brushes[i][j]);
|
||||
|
||||
kernel_brushes[i][j] = NULL;
|
||||
}
|
||||
|
||||
last_brush_mask = mask;
|
||||
cache_invalid = FALSE;
|
||||
kernel_brushes[index2][index1] =
|
||||
mask_buf_new (mask->width + 2, mask->height + 2);
|
||||
dest = kernel_brushes[index2][index1];
|
||||
}
|
||||
|
||||
dest = kernel_brushes[index2][index1] = mask_buf_new (mask->width + 2,
|
||||
mask->height + 2);
|
||||
|
||||
m = mask_buf_data (mask);
|
||||
for (i = 0; i < mask->height; i++)
|
||||
|
@ -1238,6 +1302,7 @@ paint_core_pressurize_mask (MaskBuf *brush_mask,
|
|||
{
|
||||
if (pressure_brush)
|
||||
mask_buf_free (pressure_brush);
|
||||
|
||||
pressure_brush = mask_buf_new (brush_mask->width + 2,
|
||||
brush_mask->height + 2);
|
||||
}
|
||||
|
@ -1317,11 +1382,14 @@ static MaskBuf *
|
|||
paint_core_solidify_mask (MaskBuf *brush_mask)
|
||||
{
|
||||
static MaskBuf *last_brush = NULL;
|
||||
gint i, j;
|
||||
guchar * data, * src;
|
||||
gint i;
|
||||
gint j;
|
||||
guchar *data;
|
||||
guchar *src;
|
||||
|
||||
if (brush_mask == last_brush && !cache_invalid)
|
||||
return solid_brush;
|
||||
|
||||
last_brush = brush_mask;
|
||||
|
||||
if (solid_brush)
|
||||
|
@ -1353,7 +1421,8 @@ paint_core_scale_mask (MaskBuf *brush_mask,
|
|||
static MaskBuf *last_brush = NULL;
|
||||
static gint last_width = 0.0;
|
||||
static gint last_height = 0.0;
|
||||
gint dest_width, dest_height;
|
||||
gint dest_width;
|
||||
gint dest_height;
|
||||
|
||||
if (scale == 0.0)
|
||||
return NULL;
|
||||
|
@ -1388,7 +1457,8 @@ paint_core_scale_pixmap (MaskBuf *brush_mask,
|
|||
static MaskBuf *last_brush = NULL;
|
||||
static gint last_width = 0.0;
|
||||
static gint last_height = 0.0;
|
||||
gint dest_width, dest_height;
|
||||
gint dest_width;
|
||||
gint dest_height;
|
||||
|
||||
if (scale == 0.0)
|
||||
return NULL;
|
||||
|
@ -1456,10 +1526,11 @@ paint_core_paste (PaintCore *paint_core,
|
|||
LayerModeEffects paint_mode,
|
||||
PaintApplicationMode mode)
|
||||
{
|
||||
GImage *gimage;
|
||||
GimpImage *gimage;
|
||||
PixelRegion srcPR;
|
||||
TileManager *alt = NULL;
|
||||
gint offx, offy;
|
||||
gint offx;
|
||||
gint offy;
|
||||
|
||||
if (! (gimage = drawable_gimage (drawable)))
|
||||
return;
|
||||
|
@ -1533,10 +1604,12 @@ paint_core_replace (PaintCore *paint_core,
|
|||
gint image_opacity,
|
||||
PaintApplicationMode mode)
|
||||
{
|
||||
GImage *gimage;
|
||||
PixelRegion srcPR, maskPR;
|
||||
GimpImage *gimage;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
TileManager *alt = NULL;
|
||||
gint offx, offy;
|
||||
gint offx;
|
||||
gint offy;
|
||||
|
||||
if (!drawable_has_alpha (drawable))
|
||||
{
|
||||
|
@ -1575,7 +1648,8 @@ paint_core_replace (PaintCore *paint_core,
|
|||
{
|
||||
/* The mask is just the brush mask */
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = canvas_buf->width;
|
||||
maskPR.h = canvas_buf->height;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1584,7 +1658,8 @@ paint_core_replace (PaintCore *paint_core,
|
|||
|
||||
/* intialize canvas buf source pixel regions */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
|
@ -1614,11 +1689,13 @@ paint_core_replace (PaintCore *paint_core,
|
|||
static void
|
||||
canvas_tiles_to_canvas_buf (PaintCore *paint_core)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
|
||||
/* combine the canvas tiles and the canvas buf */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
|
@ -1637,22 +1714,26 @@ brush_to_canvas_tiles (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask,
|
||||
gint brush_opacity)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
gint x, y;
|
||||
gint xoff, yoff;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
gint x;
|
||||
gint y;
|
||||
gint xoff;
|
||||
gint yoff;
|
||||
|
||||
/* combine the brush mask and the canvas tiles */
|
||||
pixel_region_init (&srcPR, canvas_tiles,
|
||||
canvas_buf->x, canvas_buf->y,
|
||||
canvas_buf->width, canvas_buf->height, TRUE);
|
||||
|
||||
x = (int) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (int) paint_core->cury - (brush_mask->height >> 1);
|
||||
x = (gint) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (gint) paint_core->cury - (brush_mask->height >> 1);
|
||||
xoff = (x < 0) ? -x : 0;
|
||||
yoff = (y < 0) ? -y : 0;
|
||||
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = srcPR.w;
|
||||
maskPR.h = srcPR.h;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1667,25 +1748,30 @@ brush_to_canvas_buf (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask,
|
||||
gint brush_opacity)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
gint x, y;
|
||||
gint xoff, yoff;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
gint x;
|
||||
gint y;
|
||||
gint xoff;
|
||||
gint yoff;
|
||||
|
||||
x = (int) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (int) paint_core->cury - (brush_mask->height >> 1);
|
||||
x = (gint) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (gint) paint_core->cury - (brush_mask->height >> 1);
|
||||
xoff = (x < 0) ? -x : 0;
|
||||
yoff = (y < 0) ? -y : 0;
|
||||
|
||||
/* combine the canvas buf and the brush mask to the canvas buf */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
srcPR.data = temp_buf_data (canvas_buf);
|
||||
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = srcPR.w;
|
||||
maskPR.h = srcPR.h;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1701,22 +1787,26 @@ paint_to_canvas_tiles (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask,
|
||||
gint brush_opacity)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
gint x, y;
|
||||
gint xoff, yoff;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
gint x;
|
||||
gint y;
|
||||
gint xoff;
|
||||
gint yoff;
|
||||
|
||||
/* combine the brush mask and the canvas tiles */
|
||||
pixel_region_init (&srcPR, canvas_tiles,
|
||||
canvas_buf->x, canvas_buf->y,
|
||||
canvas_buf->width, canvas_buf->height, TRUE);
|
||||
|
||||
x = (int) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (int) paint_core->cury - (brush_mask->height >> 1);
|
||||
x = (gint) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (gint) paint_core->cury - (brush_mask->height >> 1);
|
||||
xoff = (x < 0) ? -x : 0;
|
||||
yoff = (y < 0) ? -y : 0;
|
||||
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = srcPR.w;
|
||||
maskPR.h = srcPR.h;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1727,7 +1817,8 @@ paint_to_canvas_tiles (PaintCore *paint_core,
|
|||
|
||||
/* combine the canvas tiles and the canvas buf */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
|
@ -1746,26 +1837,31 @@ paint_to_canvas_buf (PaintCore *paint_core,
|
|||
MaskBuf *brush_mask,
|
||||
gint brush_opacity)
|
||||
{
|
||||
PixelRegion srcPR, maskPR;
|
||||
gint x, y;
|
||||
gint xoff, yoff;
|
||||
PixelRegion srcPR;
|
||||
PixelRegion maskPR;
|
||||
gint x;
|
||||
gint y;
|
||||
gint xoff;
|
||||
gint yoff;
|
||||
|
||||
x = (int) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (int) paint_core->cury - (brush_mask->height >> 1);
|
||||
x = (gint) paint_core->curx - (brush_mask->width >> 1);
|
||||
y = (gint) paint_core->cury - (brush_mask->height >> 1);
|
||||
xoff = (x < 0) ? -x : 0;
|
||||
yoff = (y < 0) ? -y : 0;
|
||||
|
||||
|
||||
/* combine the canvas buf and the brush mask to the canvas buf */
|
||||
srcPR.bytes = canvas_buf->bytes;
|
||||
srcPR.x = 0; srcPR.y = 0;
|
||||
srcPR.x = 0;
|
||||
srcPR.y = 0;
|
||||
srcPR.w = canvas_buf->width;
|
||||
srcPR.h = canvas_buf->height;
|
||||
srcPR.rowstride = canvas_buf->width * canvas_buf->bytes;
|
||||
srcPR.data = temp_buf_data (canvas_buf);
|
||||
|
||||
maskPR.bytes = 1;
|
||||
maskPR.x = 0; maskPR.y = 0;
|
||||
maskPR.x = 0;
|
||||
maskPR.y = 0;
|
||||
maskPR.w = srcPR.w;
|
||||
maskPR.h = srcPR.h;
|
||||
maskPR.rowstride = maskPR.bytes * brush_mask->width;
|
||||
|
@ -1783,7 +1879,8 @@ set_undo_tiles (GimpDrawable *drawable,
|
|||
gint w,
|
||||
gint h)
|
||||
{
|
||||
gint i, j;
|
||||
gint i;
|
||||
gint j;
|
||||
Tile *src_tile;
|
||||
Tile *dest_tile;
|
||||
|
||||
|
@ -1814,7 +1911,8 @@ set_canvas_tiles (gint x,
|
|||
gint w,
|
||||
gint h)
|
||||
{
|
||||
gint i, j;
|
||||
gint i;
|
||||
gint j;
|
||||
Tile *tile;
|
||||
|
||||
for (i = y; i < (y + h); i += (TILE_HEIGHT - (i % TILE_HEIGHT)))
|
||||
|
@ -1825,8 +1923,7 @@ set_canvas_tiles (gint x,
|
|||
if (tile_is_valid (tile) == FALSE)
|
||||
{
|
||||
tile = tile_manager_get_tile (canvas_tiles, j, i, TRUE, TRUE);
|
||||
memset (tile_data_pointer (tile, 0, 0), 0,
|
||||
tile_size (tile));
|
||||
memset (tile_data_pointer (tile, 0, 0), 0, tile_size (tile));
|
||||
tile_release (tile, TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -1858,16 +1955,20 @@ free_paint_buffers (void)
|
|||
|
||||
void
|
||||
paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
||||
GImage *dest,
|
||||
GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *area,
|
||||
gdouble scale,
|
||||
gint mode)
|
||||
BrushApplicationMode mode)
|
||||
{
|
||||
PixelRegion destPR;
|
||||
void *pr;
|
||||
guchar *d;
|
||||
gint ulx, uly, offsetx, offsety, y;
|
||||
gint ulx;
|
||||
gint uly;
|
||||
gint offsetx;
|
||||
gint offsety;
|
||||
gint y;
|
||||
TempBuf *pixmap_mask;
|
||||
TempBuf *brush_mask;
|
||||
|
||||
|
@ -1876,13 +1977,15 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
|||
/* scale the brushes */
|
||||
pixmap_mask =
|
||||
paint_core_scale_pixmap (gimp_brush_pixmap_pixmap (GIMP_BRUSH_PIXMAP (paint_core->brush)), scale);
|
||||
|
||||
if (mode == SOFT)
|
||||
brush_mask = paint_core_scale_mask (paint_core->brush->mask, scale);
|
||||
else
|
||||
brush_mask = NULL;
|
||||
|
||||
destPR.bytes = area->bytes;
|
||||
destPR.x = 0; destPR.y = 0;
|
||||
destPR.x = 0;
|
||||
destPR.y = 0;
|
||||
destPR.w = area->width;
|
||||
destPR.h = area->height;
|
||||
destPR.rowstride = destPR.bytes * area->width;
|
||||
|
@ -1894,8 +1997,8 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
|||
* paint_core_get_paint_area. Ugly to have to do this here, too.
|
||||
*/
|
||||
|
||||
ulx = (int) paint_core->curx - (pixmap_mask->width >> 1);
|
||||
uly = (int) paint_core->cury - (pixmap_mask->height >> 1);
|
||||
ulx = (gint) paint_core->curx - (pixmap_mask->width >> 1);
|
||||
uly = (gint) paint_core->cury - (pixmap_mask->height >> 1);
|
||||
|
||||
offsetx = area->x - ulx;
|
||||
offsety = area->y - uly;
|
||||
|
@ -1914,7 +2017,7 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
|||
}
|
||||
|
||||
static void
|
||||
paint_line_pixmap_mask (GImage *dest,
|
||||
paint_line_pixmap_mask (GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *pixmap_mask,
|
||||
TempBuf *brush_mask,
|
||||
|
@ -1923,14 +2026,15 @@ paint_line_pixmap_mask (GImage *dest,
|
|||
gint y,
|
||||
gint bytes,
|
||||
gint width,
|
||||
gint mode)
|
||||
BrushApplicationMode mode)
|
||||
{
|
||||
guchar *b, *p;
|
||||
gint x_index;
|
||||
guchar *b;
|
||||
guchar *p;
|
||||
guchar *mask;
|
||||
gdouble alpha;
|
||||
gdouble factor = 0.00392156986; /* 1.0 / 255.0 */
|
||||
gint x_index;
|
||||
gint i;
|
||||
guchar *mask;
|
||||
|
||||
/* Make sure x, y are positive */
|
||||
while (x < 0)
|
||||
|
|
|
@ -119,42 +119,68 @@ struct _paint_undo
|
|||
};
|
||||
|
||||
/* paint tool action functions */
|
||||
void paint_core_button_press (Tool *, GdkEventButton *, gpointer);
|
||||
void paint_core_button_release (Tool *, GdkEventButton *, gpointer);
|
||||
void paint_core_motion (Tool *, GdkEventMotion *, gpointer);
|
||||
void paint_core_cursor_update (Tool *, GdkEventMotion *, gpointer);
|
||||
void paint_core_control (Tool *, ToolAction, gpointer);
|
||||
void paint_core_button_press (Tool *tool, GdkEventButton *bevent, gpointer gdisp_ptr);
|
||||
void paint_core_button_release (Tool *tool, GdkEventButton *bevent, gpointer gdisp_ptr);
|
||||
void paint_core_motion (Tool *tool, GdkEventMotion *mevent, gpointer gdisp_ptr);
|
||||
void paint_core_cursor_update (Tool *tool, GdkEventMotion *mevent, gpointer gdisp_ptr);
|
||||
|
||||
void paint_core_control (Tool *tool,
|
||||
ToolAction action,
|
||||
gpointer gdisp_ptr);
|
||||
|
||||
/* paint tool functions */
|
||||
void paint_core_no_draw (Tool *);
|
||||
Tool * paint_core_new (ToolType);
|
||||
void paint_core_free (Tool *);
|
||||
int paint_core_init (PaintCore *, GimpDrawable *, double, double);
|
||||
void paint_core_interpolate (PaintCore *, GimpDrawable *);
|
||||
void paint_core_get_color_from_gradient (PaintCore *, double, double*, double*, double*,double *,int);
|
||||
void paint_core_finish (PaintCore *, GimpDrawable *, int);
|
||||
void paint_core_no_draw (Tool *tool);
|
||||
Tool * paint_core_new (ToolType type);
|
||||
void paint_core_free (Tool *tool);
|
||||
int paint_core_init (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gdouble x,
|
||||
gdouble y);
|
||||
void paint_core_interpolate (PaintCore *paint_core,
|
||||
GimpDrawable *drawable);
|
||||
void paint_core_finish (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint tool_ID);
|
||||
void paint_core_cleanup (void);
|
||||
|
||||
void paint_core_get_color_from_gradient (PaintCore *paint_core,
|
||||
gdouble gradient_length,
|
||||
gdouble *r,
|
||||
gdouble *g,
|
||||
gdouble *b,
|
||||
gdouble *a,
|
||||
GradientPaintMode mode);
|
||||
|
||||
/* paint tool painting functions */
|
||||
TempBuf * paint_core_get_paint_area (PaintCore *,
|
||||
GimpDrawable *,
|
||||
gdouble);
|
||||
TempBuf * paint_core_get_orig_image (PaintCore *,
|
||||
GimpDrawable *,
|
||||
int, int, int, int);
|
||||
void paint_core_paste_canvas (PaintCore *,
|
||||
GimpDrawable *, int, int,
|
||||
LayerModeEffects,
|
||||
BrushApplicationMode,
|
||||
gdouble,
|
||||
PaintApplicationMode);
|
||||
void paint_core_replace_canvas (PaintCore *,
|
||||
GimpDrawable *, int, int,
|
||||
BrushApplicationMode,
|
||||
gdouble,
|
||||
PaintApplicationMode);
|
||||
void paint_core_color_area_with_pixmap (PaintCore *,
|
||||
GImage *, GimpDrawable *,
|
||||
TempBuf *, gdouble, int);
|
||||
TempBuf * paint_core_get_paint_area (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gdouble scale);
|
||||
TempBuf * paint_core_get_orig_image (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint x1,
|
||||
gint y1,
|
||||
gint x2,
|
||||
gint y2);
|
||||
void paint_core_paste_canvas (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
LayerModeEffects paint_mode,
|
||||
BrushApplicationMode brush_hardness,
|
||||
gdouble brush_scale,
|
||||
PaintApplicationMode mode);
|
||||
void paint_core_replace_canvas (PaintCore *paint_core,
|
||||
GimpDrawable *drawable,
|
||||
gint brush_opacity,
|
||||
gint image_opacity,
|
||||
BrushApplicationMode brush_hardness,
|
||||
gdouble brush_scale,
|
||||
PaintApplicationMode mode);
|
||||
void paint_core_color_area_with_pixmap (PaintCore *paint_core,
|
||||
GimpImage *dest,
|
||||
GimpDrawable *drawable,
|
||||
TempBuf *area,
|
||||
gdouble scale,
|
||||
BrushApplicationMode mode);
|
||||
|
||||
#endif /* __PAINT_CORE_H__ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Project gap "Gimp Animation Package" 01. May 2000 release 1.1.20a
|
||||
Project gap "Gimp Animation Package" 04. June 2000 release 1.1.23a
|
||||
|
||||
--------------------------------------------------------------------
|
||||
Introduction
|
||||
|
@ -533,13 +533,35 @@ WebTip: My GIMP-page http://pages.hotbot.com/arts/hof/index.html
|
|||
you can step from point to point,
|
||||
and make other points to the curremt point.
|
||||
|
||||
"Clear Point"
|
||||
does reset Witdh, Height and Opacity of the point to 100%
|
||||
and Rotat to 0 degree.
|
||||
"Clear Point" "Clear All Points"
|
||||
does reset Width, Height and Opacity of the point to 100%
|
||||
and Rotation to 0 degree, and leaves the path (X/Y Values)
|
||||
unchanged.
|
||||
|
||||
"Reset Points"
|
||||
"Delete All Points"
|
||||
removes all controlpoints.
|
||||
|
||||
"Rotate Follow"
|
||||
Calculate Rotate values for all controlpoints
|
||||
to follow the path.
|
||||
An Object moving along a horizontal line
|
||||
from left to right results in an angle of 0 degree.
|
||||
(or a multiple of 360 degress if the path
|
||||
builds circular loops)
|
||||
A vertical Move from top to bottom gives 90 degrees.
|
||||
|
||||
SHIFT: If this Button is clicked while the
|
||||
Shift Key is pressed, a fix Rotation offset
|
||||
is added to all the calculated Rotation Values.
|
||||
The Rotation Offset is taken from the current
|
||||
Rotate Value of Controlpint 1.
|
||||
|
||||
If an Object moves from Right to Left
|
||||
the calculated Angle is 180 degree and the Object
|
||||
appears upside down.
|
||||
With a Startoffset of 180 (or -180)
|
||||
you can compensate this effect.
|
||||
|
||||
"Save Points"
|
||||
saves your controlpoints to file
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
*/
|
||||
|
||||
/* revision history:
|
||||
* gimp 1.1.23a; 2000/06/04 hof: new button: rotation follow path
|
||||
* gimp 1.1.20a; 2000/04/25 hof: support for keyframes, anim_preview (suggested by jakub steiner)
|
||||
* gimp 1.1.17b; 2000/02/23 hof: bugfix: dont flatten the preview, just merge visible layers
|
||||
* bugfix: for current frame never use diskfile for the preview
|
||||
|
@ -176,6 +177,18 @@ struct _MenuItem
|
|||
GtkWidget *widget;
|
||||
};
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
OPS_BUTTON_MODIFIER_NONE,
|
||||
OPS_BUTTON_MODIFIER_SHIFT,
|
||||
OPS_BUTTON_MODIFIER_CTRL,
|
||||
OPS_BUTTON_MODIFIER_ALT,
|
||||
OPS_BUTTON_MODIFIER_SHIFT_CTRL,
|
||||
OPS_BUTTON_MODIFIER_LAST
|
||||
} OpsButtonModifier;
|
||||
|
||||
|
||||
/* Declare a local function.
|
||||
*/
|
||||
GtkWidget * p_buildmenu (MenuItem *);
|
||||
|
@ -211,7 +224,9 @@ static void mov_path_prevw_cursor_update ( t_mov_path_preview *path_ptr );
|
|||
static gint mov_path_prevw_preview_expose ( GtkWidget *widget, GdkEvent *event );
|
||||
static gint mov_path_prevw_preview_events ( GtkWidget *widget, GdkEvent *event );
|
||||
static gint p_chk_keyframes(t_mov_path_preview *path_ptr);
|
||||
static gdouble p_calc_angle(gint p1x, gint p1y, gint p2x, gint p2y);
|
||||
|
||||
static void button_pressed_callback (GtkWidget *widget, GdkEventButton *bevent, gpointer client_data);
|
||||
static void mov_padd_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_pins_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_pdel_callback (GtkWidget *widget,gpointer data);
|
||||
|
@ -219,8 +234,10 @@ static void mov_pnext_callback (GtkWidget *widget,gpointer data);
|
|||
static void mov_pprev_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_pfirst_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_plast_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_pres_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_pdel_all_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_pclr_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_pclr_all_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_prot_follow_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_pload_callback (GtkWidget *widget,gpointer data);
|
||||
static void mov_psave_callback (GtkWidget *widget,gpointer data);
|
||||
static void p_points_load_from_file (GtkWidget *widget,gpointer data);
|
||||
|
@ -294,6 +311,7 @@ static t_mov_interface mov_int =
|
|||
FALSE /* run */
|
||||
};
|
||||
|
||||
OpsButtonModifier global_key_modifier = OPS_BUTTON_MODIFIER_NONE;
|
||||
|
||||
/* ============================================================================
|
||||
**********************
|
||||
|
@ -914,6 +932,79 @@ p_copy_point(gint to_idx, gint from_idx)
|
|||
pvals->point[to_idx].keyframe = 0;
|
||||
}
|
||||
|
||||
static gdouble
|
||||
p_calc_angle(gint p1x, gint p1y, gint p2x, gint p2y)
|
||||
{
|
||||
/* calculate angle in degree
|
||||
* how to rotate an object that follows the line between p1 and p2
|
||||
*/
|
||||
gdouble l_a;
|
||||
gdouble l_b;
|
||||
gdouble l_angle_rad;
|
||||
gdouble l_angle;
|
||||
|
||||
l_a = p2x - p1x;
|
||||
l_b = (p2y - p1y) * (-1.0);
|
||||
|
||||
if(l_a == 0)
|
||||
{
|
||||
if(l_b < 0) { l_angle = 90.0; }
|
||||
else { l_angle = 270.0; }
|
||||
}
|
||||
else
|
||||
{
|
||||
l_angle_rad = atan(l_b/l_a);
|
||||
l_angle = (l_angle_rad * 180.0) / 3.14159;
|
||||
|
||||
if(l_a < 0)
|
||||
{
|
||||
l_angle = 180 - l_angle;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_angle = l_angle * (-1.0);
|
||||
}
|
||||
}
|
||||
|
||||
if(gap_debug)
|
||||
{
|
||||
printf("p_calc_angle: p1(%d/%d) p2(%d/%d) a=%f, b=%f, angle=%f\n"
|
||||
, (int)p1x, (int)p1y, (int)p2x, (int)p2y
|
||||
, (float)l_a, (float)l_b, (float)l_angle);
|
||||
}
|
||||
return(l_angle);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
button_pressed_callback (GtkWidget *widget,
|
||||
GdkEventButton *bevent,
|
||||
gpointer client_data)
|
||||
{
|
||||
OpsButtonModifier *key_modifier;
|
||||
|
||||
g_return_if_fail (client_data != NULL);
|
||||
key_modifier = (OpsButtonModifier *)client_data;
|
||||
|
||||
if (bevent->state & GDK_SHIFT_MASK)
|
||||
{
|
||||
if (bevent->state & GDK_CONTROL_MASK)
|
||||
*key_modifier = OPS_BUTTON_MODIFIER_SHIFT_CTRL;
|
||||
else
|
||||
*key_modifier = OPS_BUTTON_MODIFIER_SHIFT;
|
||||
}
|
||||
else if (bevent->state & GDK_CONTROL_MASK)
|
||||
*key_modifier = OPS_BUTTON_MODIFIER_CTRL;
|
||||
else if (bevent->state & GDK_MOD1_MASK)
|
||||
*key_modifier = OPS_BUTTON_MODIFIER_ALT;
|
||||
else
|
||||
*key_modifier = OPS_BUTTON_MODIFIER_NONE;
|
||||
|
||||
if(gap_debug)
|
||||
{
|
||||
printf("button_pressed_callback %d\n", (int)*key_modifier);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mov_padd_callback (GtkWidget *widget,
|
||||
|
@ -1066,16 +1157,170 @@ mov_pclr_callback (GtkWidget *widget,
|
|||
}
|
||||
|
||||
static void
|
||||
mov_pres_callback (GtkWidget *widget,
|
||||
mov_pdel_all_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
t_mov_path_preview *path_ptr = data;
|
||||
|
||||
if(gap_debug) printf("mov_pres_callback\n");
|
||||
if(gap_debug) printf("mov_pdel_all_callback\n");
|
||||
p_reset_points();
|
||||
p_point_refresh(path_ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
mov_pclr_all_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
gint l_idx;
|
||||
t_mov_path_preview *path_ptr = data;
|
||||
|
||||
if(gap_debug) printf("mov_pclr_all_callback\n");
|
||||
|
||||
for(l_idx = 0; l_idx <= pvals->point_idx_max; l_idx++)
|
||||
{
|
||||
pvals->point[l_idx].rotation = 0; /* no rotation (0 degree) */
|
||||
}
|
||||
p_point_refresh(path_ptr);
|
||||
}
|
||||
|
||||
static gdouble
|
||||
p_rotatate_less_than_180(gdouble angle, gdouble angle_new, gint *turns)
|
||||
{
|
||||
/* if an object follows a circular path and does more than one turn
|
||||
* there comes a point where it flips from say 265 degree to -85 degree.
|
||||
*
|
||||
* if there are more (say 3) frames between the controlpoints,
|
||||
* the object performs an unexpected rotation effect because the iteration
|
||||
* from 265 to -85 is done in a sequence like this: 265.0, 148.6, 32.3, -85.0
|
||||
*
|
||||
* we can avoid this by preventing angle changes of more than 180 degree.
|
||||
* in such a case this procedure adjusts the new_angle from -85 to 275
|
||||
* that results in oterations like this: 265.0, 268.3, 271.6, 275.0
|
||||
*/
|
||||
gint l_diff;
|
||||
gint l_turns;
|
||||
|
||||
l_diff = angle - (angle_new + (*turns * 360));
|
||||
if((l_diff >= -180) && (l_diff < 180))
|
||||
{
|
||||
return(angle_new + (*turns * 360));
|
||||
}
|
||||
|
||||
l_diff = (angle - angle_new);
|
||||
if(l_diff < 0)
|
||||
{
|
||||
l_turns = (l_diff / 360) -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_turns = (l_diff / 360) +1;
|
||||
}
|
||||
|
||||
*turns = l_turns;
|
||||
|
||||
if(gap_debug)
|
||||
{
|
||||
printf("p_rotatate_less_than_180: turns %d angle_new:%f\n"
|
||||
, (int)l_turns, (float)angle_new);
|
||||
}
|
||||
|
||||
return( angle_new + (l_turns * 360));
|
||||
}
|
||||
|
||||
static void
|
||||
mov_prot_follow_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
gint l_idx;
|
||||
gdouble l_startangle;
|
||||
gdouble l_angle_1;
|
||||
gdouble l_angle_2;
|
||||
gdouble l_angle_new;
|
||||
gdouble l_angle;
|
||||
gint l_turns;
|
||||
|
||||
t_mov_path_preview *path_ptr = data;
|
||||
|
||||
if(gap_debug) printf("mov_prot_follow_callback\n");
|
||||
|
||||
if( pvals->point_idx_max > 1)
|
||||
{
|
||||
l_startangle = 0.0;
|
||||
l_angle = 0.0;
|
||||
l_turns = 0;
|
||||
if(global_key_modifier == OPS_BUTTON_MODIFIER_SHIFT)
|
||||
{
|
||||
p_points_to_tab(path_ptr);
|
||||
l_startangle = pvals->point[0].rotation;
|
||||
}
|
||||
|
||||
for(l_idx = 0; l_idx <= pvals->point_idx_max; l_idx++)
|
||||
{
|
||||
if(l_idx == 0)
|
||||
{
|
||||
l_angle = p_calc_angle(pvals->point[l_idx].p_x,
|
||||
pvals->point[l_idx].p_y,
|
||||
pvals->point[l_idx +1].p_x,
|
||||
pvals->point[l_idx +1].p_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(l_idx == pvals->point_idx_max)
|
||||
{
|
||||
l_angle_new = p_calc_angle(pvals->point[l_idx -1].p_x,
|
||||
pvals->point[l_idx -1].p_y,
|
||||
pvals->point[l_idx].p_x,
|
||||
pvals->point[l_idx].p_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
l_angle_1 = p_calc_angle(pvals->point[l_idx -1].p_x,
|
||||
pvals->point[l_idx -1].p_y,
|
||||
pvals->point[l_idx].p_x,
|
||||
pvals->point[l_idx].p_y);
|
||||
|
||||
l_angle_2 = p_calc_angle(pvals->point[l_idx].p_x,
|
||||
pvals->point[l_idx].p_y,
|
||||
pvals->point[l_idx +1].p_x,
|
||||
pvals->point[l_idx +1].p_y);
|
||||
|
||||
if((l_angle_1 == 0) && (l_angle_2 == 180))
|
||||
{
|
||||
l_angle_new = 270;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((l_angle_1 == 90) && (l_angle_2 == 270))
|
||||
{
|
||||
l_angle_new = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l_angle_new = (l_angle_1 + l_angle_2) / 2;
|
||||
}
|
||||
}
|
||||
if(((l_angle_1 < 0) && (l_angle_2 >= 180))
|
||||
|| ((l_angle_2 < 0) && (l_angle_1 >= 180)))
|
||||
{
|
||||
l_angle_new += 180;
|
||||
}
|
||||
}
|
||||
l_angle = p_rotatate_less_than_180(l_angle, l_angle_new, &l_turns);
|
||||
}
|
||||
|
||||
if(gap_debug)
|
||||
{
|
||||
printf("ROT Follow [%03d] angle = %f\n", (int)l_idx, (float)l_angle);
|
||||
}
|
||||
|
||||
pvals->point[l_idx].rotation = l_startangle + l_angle;
|
||||
}
|
||||
}
|
||||
|
||||
global_key_modifier = OPS_BUTTON_MODIFIER_NONE;
|
||||
p_point_refresh(path_ptr);
|
||||
}
|
||||
|
||||
static void
|
||||
p_filesel_close_cb(GtkWidget *widget,
|
||||
t_mov_path_preview *path_ptr)
|
||||
|
@ -2160,18 +2405,52 @@ mov_path_prevw_create ( GDrawable *drawable, t_mov_path_preview *path_ptr)
|
|||
, NULL);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label ( _("Reset Points"));
|
||||
button = gtk_button_new_with_label ( _("Clear All Points"));
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
||||
(GtkSignalFunc) mov_pres_callback,
|
||||
(GtkSignalFunc) mov_pclr_all_callback,
|
||||
path_ptr);
|
||||
gtk_table_attach( GTK_TABLE(button_table), button, 1, 2, row, row+1,
|
||||
GTK_FILL, 0, 0, 0 );
|
||||
gimp_help_set_help_data(button,
|
||||
_("Reset Controlpoints \nto one Defaultpoint")
|
||||
_("Reset all Controlpoints to default Values\n"
|
||||
"but dont change the path (X/Y Values)")
|
||||
, NULL);
|
||||
gtk_widget_show (button);
|
||||
|
||||
row++;
|
||||
|
||||
button = gtk_button_new_with_label ( _("Rotate Follow"));
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "button_press_event",
|
||||
(GtkSignalFunc) button_pressed_callback,
|
||||
&global_key_modifier);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
||||
(GtkSignalFunc) mov_prot_follow_callback,
|
||||
path_ptr);
|
||||
gtk_table_attach( GTK_TABLE(button_table), button, 0, 1, row, row+1,
|
||||
GTK_FILL, 0, 0, 0 );
|
||||
gimp_help_set_help_data(button,
|
||||
_("Set Rotation for all Controlpoints\n"
|
||||
"to follow the shape of the path.\n"
|
||||
"(Shift: use Rotation of contolpoint 1 as offset)")
|
||||
, NULL);
|
||||
gtk_widget_show (button);
|
||||
|
||||
|
||||
button = gtk_button_new_with_label ( _("Delete All Points"));
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
||||
(GtkSignalFunc) mov_pdel_all_callback,
|
||||
path_ptr);
|
||||
gtk_table_attach( GTK_TABLE(button_table), button, 1, 2, row, row+1,
|
||||
GTK_FILL, 0, 0, 0 );
|
||||
gimp_help_set_help_data(button,
|
||||
_("Delete all Controlpoints")
|
||||
, NULL);
|
||||
gtk_widget_show (button);
|
||||
|
||||
|
||||
row++;
|
||||
|
||||
button = gtk_button_new_with_label ( _("Load Points"));
|
||||
|
@ -2960,6 +3239,12 @@ p_mov_render(gint32 image_id, t_mov_values *val_ptr, t_mov_current *cur_ptr)
|
|||
val_ptr->src_force_visible);
|
||||
|
||||
|
||||
if(gap_debug)
|
||||
{
|
||||
printf("p_mov_render: Before p_my_layer_copy image_id:%d src_layer_id:%d\n"
|
||||
,(int)image_id, (int)cur_ptr->src_layers[cur_ptr->src_layer_idx]);
|
||||
}
|
||||
|
||||
|
||||
/* make a copy of the current source layer
|
||||
* (using current opacity & paintmode values)
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
*/
|
||||
|
||||
/* revision history:
|
||||
* gimp 1.1.23a; 2000/06/03 hof: bugfix anim_preview < 100% did not work
|
||||
* (the layer tattoos in a duplicated image may differ from the original !!)
|
||||
* gimp 1.1.20a; 2000/04/25 hof: support for keyframes, anim_preview
|
||||
* version 0.93.04 hof: Window with Info Message if no Source Image was selected in MovePath
|
||||
* version 0.90.00; hof: 1.st (pre) release 14.Dec.1997
|
||||
|
@ -601,7 +603,9 @@ p_mov_anim_preview(t_mov_values *pvals_orig, t_anim_info *ainfo_ptr, gint previe
|
|||
gint l_retvals;
|
||||
GImageType l_type;
|
||||
guint l_width, l_height;
|
||||
gint32 l_tattoo;
|
||||
gint32 l_stackpos;
|
||||
gint l_nlayers;
|
||||
gint32 *l_src_layers;
|
||||
gint l_rc;
|
||||
|
||||
l_mov_ptr = &apv_mov_data;
|
||||
|
@ -614,6 +618,7 @@ p_mov_anim_preview(t_mov_values *pvals_orig, t_anim_info *ainfo_ptr, gint previe
|
|||
|
||||
/* -1 assume no tmp_image (use unscaled original source) */
|
||||
l_tmp_image_id = -1;
|
||||
l_stackpos = 0;
|
||||
|
||||
/* Scale (down) needed ? */
|
||||
if((l_pvals->apv_scalex != 100.0) || (l_pvals->apv_scaley != 100.0))
|
||||
|
@ -638,9 +643,49 @@ p_mov_anim_preview(t_mov_values *pvals_orig, t_anim_info *ainfo_ptr, gint previe
|
|||
PARAM_INT32, l_size_y,
|
||||
PARAM_END);
|
||||
|
||||
/* find the selected src_layer by tattoo in the copy of src_image */
|
||||
l_tattoo = gimp_layer_get_tattoo(pvals_orig->src_layer_id);
|
||||
l_pvals->src_layer_id = gimp_image_get_layer_by_tattoo(l_tmp_image_id, l_tattoo);
|
||||
/* findout the src_layer id in the scaled copy by stackpos index */
|
||||
l_pvals->src_layer_id = -1;
|
||||
l_src_layers = gimp_image_get_layers (pvals_orig->src_image_id, &l_nlayers);
|
||||
if(l_src_layers == NULL)
|
||||
{
|
||||
printf("ERROR: p_mov_anim_preview GOT no src_layers (original image_id %d)\n",
|
||||
(int)pvals_orig->src_image_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(l_stackpos = 0;
|
||||
l_stackpos < l_nlayers;
|
||||
l_stackpos++)
|
||||
{
|
||||
if(l_src_layers[l_stackpos] == pvals_orig->src_layer_id)
|
||||
break;
|
||||
}
|
||||
g_free(l_src_layers);
|
||||
|
||||
l_src_layers = gimp_image_get_layers (l_tmp_image_id, &l_nlayers);
|
||||
if(l_src_layers == NULL)
|
||||
{
|
||||
printf("ERROR: p_mov_anim_preview GOT no src_layers (scaled copy image_id %d)\n",
|
||||
(int)l_tmp_image_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
l_pvals->src_layer_id = l_src_layers[l_stackpos];
|
||||
g_free(l_src_layers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(gap_debug)
|
||||
{
|
||||
printf("p_mov_anim_preview: orig src_image_id:%d src_layer:%d, stackpos:%d\n"
|
||||
,(int)pvals_orig->src_image_id
|
||||
,(int)pvals_orig->src_layer_id
|
||||
,(int)l_stackpos);
|
||||
printf(" Scaled src_image_id:%d scaled_src_layer:%d\n"
|
||||
,(int)l_tmp_image_id
|
||||
,(int)l_pvals->src_layer_id );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ coords_tag : COORDS '=' STRING
|
|||
}
|
||||
/* Remove last point if duplicate */
|
||||
first = (GdkPoint*) points->data;
|
||||
polygon->points = points;
|
||||
if (first->x == point->x && first->y == point->y)
|
||||
polygon_remove_last_point(polygon);
|
||||
polygon->points = points;
|
||||
|
|
|
@ -11,67 +11,68 @@
|
|||
# tips than with automatic word-wrapping, but this also means that
|
||||
# you have to avoid excessively long lines in this file.
|
||||
# - Tips should be concise: 3 lines or less.
|
||||
# - Advice for translators to other languages: keep the original tips
|
||||
# as comments before the translated tips. It will be easier for
|
||||
# other people to check for changes or additions.
|
||||
#
|
||||
# Tips in this file have been contributed by Zachary Beane, Mo Oishi,
|
||||
# Raphael Quinet, Sven Neumann and other people on the gimp mailing
|
||||
# lists.
|
||||
# Raphael Quinet, Sven Neumann, Carey Bunks and other people on the
|
||||
# gimp mailing lists and newsgroup (comp.graphics.apps.gimp).
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
# The first tip should be a welcome message, because this is the
|
||||
# first thing that a new user will see.
|
||||
#
|
||||
|
||||
# FIXME: re-write this welcome message:
|
||||
|
||||
Welcome to the GIMP !
|
||||
|
||||
Nearly all image operations are performed by right-clicking
|
||||
on the image. And don't worry, you can undo most mistakes...
|
||||
|
||||
# Tips for beginners start here
|
||||
# (for people who are not familiar yet with layers and image formats)
|
||||
#
|
||||
|
||||
You can get context-sensitive help for most of the GIMP's features by
|
||||
pressing the F1 key at any time. This also works inside the menus.
|
||||
|
||||
The GIMP uses layers to let you organize your image. Think of them
|
||||
as a stack of slides or filters, such that looking through them you
|
||||
see a composite of their contents.
|
||||
|
||||
You can perform many layer operations by right-clicking on the text
|
||||
label of a layer in the Layers dialog (Dialogs->Layers & Channels).
|
||||
label of a layer in the "Layers, Channels and Paths" dialog
|
||||
|
||||
When trying to save files as GIF, XPM, or any other indexed
|
||||
color format, you need to convert the image to indexed using
|
||||
the Image menu.
|
||||
When you save an image to work on it again later, try using XCF,
|
||||
the GIMP's native file format (use the file extension ".xcf").
|
||||
This preserves the layers and every aspect of your work-in-progress.
|
||||
Once a project is completed, you can save it as JPEG, PNG, GIF, ...
|
||||
|
||||
You can get the Tool Options menu to open by double-clicking
|
||||
any button in the toolbar.
|
||||
|
||||
You can change the name of a layer by double-clicking
|
||||
on its name in the Layers dialog box.
|
||||
|
||||
The layer named "Background" is special. You can't add
|
||||
transparency or a layer mask to it. To add transparency, you
|
||||
must first "add alpha" to the layer by right-clicking in the
|
||||
layers dialog and selecting "Add Alpha Channel".
|
||||
|
||||
When using a drawing tool (Paintbrush, Airbrush, or Pencil),
|
||||
Shift-click will draw a straight line from your last drawing
|
||||
point to your current cursor position.
|
||||
The layer named "Background" it special because it lacks transparency.
|
||||
This prevents you from adding a layer mask or moving the layer up in
|
||||
the stack. You may add transparency to it by right-clicking in the
|
||||
"Layers, Channels and Paths" dialog and selecting "Add Alpha Channel".
|
||||
|
||||
Most plug-ins work on the current layer of the current image. In
|
||||
some cases, you will have to merge all layers (Layers->Flatten Image)
|
||||
if you want the plug-in to work on the whole image.
|
||||
|
||||
Most file-formats can't handle layers and for that reason only
|
||||
the active layer is saved. Use XCF, the GIMP's native file format
|
||||
to keep layers, channels and guides when saving.
|
||||
|
||||
Not all effects can be applied to all kinds of images. This
|
||||
is indicated by a grayed-out menu-entry. You may need to
|
||||
change the image to RGB, add an alpha-channel or flatten it.
|
||||
Not all effects can be applied to all kinds of images. This is
|
||||
indicated by a grayed-out menu-entry. You may need to change
|
||||
the image mode to RGB (Image->Mode->RGB), add an alpha-channel
|
||||
(Layers->Add Alpha Channel) or flatten it (Layers->Flatten Image).
|
||||
|
||||
# Tips for intermediate users start here
|
||||
#
|
||||
|
||||
You can drag and drop many things in the GIMP. For example, dragging
|
||||
a color from the toolbox or from a color palette and dropping it into
|
||||
an image will fill the current image or selection with that color.
|
||||
|
||||
When using a drawing tool (Paintbrush, Airbrush, or Pencil),
|
||||
Shift-click will draw a straight line from your last drawing
|
||||
point to your current cursor position. If you also press Ctrl,
|
||||
the line will be constrained to 15 degree angles.
|
||||
|
||||
The file selection dialog box has command-line completion with
|
||||
Tab, just like the shell. Type part of a filename, hit tab, and voila!
|
||||
It's completed.
|
||||
|
@ -80,10 +81,6 @@ You can reassign shortcut keys on any menu by bringing up the menu,
|
|||
selecting a menu item, and pressing the new shortcut key combination.
|
||||
This is dynamic and is saved when you exit GIMP.
|
||||
|
||||
All the old channel operations have been replaced with the more
|
||||
powerful and flexible Layer and Layer Mode operations. They may
|
||||
take getting used to, but they are simply a better way to operate.
|
||||
|
||||
You can use the middle mouse button to pan around
|
||||
the image, if it's larger than its display window.
|
||||
|
||||
|
@ -91,8 +88,17 @@ Click and drag on a ruler to place a Guide on an image. All
|
|||
dragged selections will snap to the guides. You can remove
|
||||
guides by dragging them off the image with the Move tool.
|
||||
|
||||
You can drag a layer from the "Layers, Channels and Paths" dialog
|
||||
and drop it onto the toolbox. This will create a new image
|
||||
containing only that layer.
|
||||
|
||||
A Floating Selection must be anchored to a new layer or to the last
|
||||
active layer before doing other operations on the image. Click on the
|
||||
New Layer or Anchor Layer buttons in the "Layers, Channels and Paths"
|
||||
dialog, or use the menus to do the same.
|
||||
|
||||
The GIMP supports gzip compression on the fly. Just add
|
||||
'.gz' (or '.bz2', if you have bzip2 installed) to the filename
|
||||
".gz" (or ".bz2", if you have bzip2 installed) to the filename
|
||||
and your image will be saved compressed. Of course loading
|
||||
compressed images works too.
|
||||
|
||||
|
@ -104,9 +110,35 @@ You can press or release the Shift and Ctrl keys while you are
|
|||
making a selection in order to constrain it to a perfect square
|
||||
or circle, or to have it centered on its starting point.
|
||||
|
||||
Using Edit->Stroke allows you to draw simple squares or circles by
|
||||
painting the edge of your current selection with the active brush.
|
||||
More complex shapes can be drawn with Filters->Render->Gfig.
|
||||
|
||||
If you stroke a path (Edit->Stroke), the current drawing tool and its
|
||||
settings are used. You can use the Paintbrush in gradient mode, the
|
||||
Clone tool with a pattern or even the Eraser or the Smudge tool.
|
||||
|
||||
You can create and edit complex selections using the Bezier tool.
|
||||
The "Paths" tab in the "Layers, Channels and Paths" dialog allows
|
||||
you to work on multiple paths and to convert them to selections.
|
||||
|
||||
You can use the paint tools to change the selection. Click on the
|
||||
Quick Mask button at the bottom left of an image window. Change your
|
||||
selection by painting in the image and click on the button again to
|
||||
convert it back to a normal selection.
|
||||
|
||||
You can save a selection to a channel (Select->Save to Channel) and
|
||||
then modify this channel with any paint tools. Using the buttons in
|
||||
the "Channels" tab of the "Layers, Channels and Paths" dialog, you can
|
||||
toggle the visibility of this new channel or convert it to a selection.
|
||||
|
||||
# Tips for advanced users start here
|
||||
# (this is mostly for learning shortcut keys)
|
||||
#
|
||||
|
||||
If your screen is too cluttered, you can press Tab multiple times
|
||||
in an image window to hide or show the toolbox and other dialogs.
|
||||
|
||||
You can adjust the selection range for fuzzy select
|
||||
by clicking and dragging left and right.
|
||||
|
||||
|
@ -132,26 +164,18 @@ You can adjust and re-place a selection by using Alt-drag.
|
|||
|
||||
If your fonts turn out blocky, that's because they're not scalable
|
||||
fonts. Most X servers support scalable Type 1 Postscript fonts.
|
||||
Download and install them.
|
||||
|
||||
# FIXME: The next tip should disappear once we have solved the
|
||||
# problems of stale pluginrc files and plug-in directories.
|
||||
# All other files in ~/.gimp can be kept after an upgrade.
|
||||
# In particular, we should try to preserve gimprc. --Raphael
|
||||
|
||||
When installing a new version, be sure to delete your personal GIMP
|
||||
settings directory first (on Unix: ~/.gimp-1.1, on Windows: _gimp1.1
|
||||
in your home directory, or _gimp1.1.<username> in the GIMP
|
||||
installation directory).
|
||||
|
||||
Using Edit->Stroke allows you to draw simple squares or circles by
|
||||
painting the edge of your current selection with the active brush.
|
||||
More complex shapes can be drawn with Filters->Render->Gfig.
|
||||
Download and install them. Some font servers allow you to use
|
||||
TrueType (.ttf) fonts, which are also scalable.
|
||||
|
||||
To create a perfect circle, hold Shift while doing an ellipse select. To
|
||||
place a circle precisely, drag horizontal and vertical guides tangent to
|
||||
the circle you want to select, place your cursor at the intersection
|
||||
of the guides, and the resulting selection will just touch the guides.
|
||||
|
||||
If some of your scanned photos do not look colorful enough, you can
|
||||
easily improve their tonal range with the "Auto" button in the Levels
|
||||
tool (Image->Colors->Levels). If there are any color casts, you can
|
||||
correct them with the Curves tool (Image->Colors->Curves).
|
||||
|
||||
# (end of tips)
|
||||
|
||||
|
|
Loading…
Reference in New Issue