diff --git a/ChangeLog b/ChangeLog index 8db616f8ef..7debd3fd43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2000-06-05 Sven Neumann + + * 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 * plug-ins/common/xbm.c: Don't save the mask inverted. diff --git a/app/paint_core.c b/app/paint_core.c index 7ba2135f33..7504818f6f 100644 --- a/app/paint_core.c +++ b/app/paint_core.c @@ -56,68 +56,110 @@ 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); /***********************************************************************/ /* undo blocks variables */ -static TileManager * undo_tiles = NULL; -static TileManager * canvas_tiles = NULL; +static TileManager *undo_tiles = NULL; +static TileManager *canvas_tiles = NULL; /***********************************************************************/ /* paint buffers variables */ -static TempBuf * orig_buf = NULL; -static TempBuf * canvas_buf = NULL; +static TempBuf *orig_buf = NULL; +static TempBuf *canvas_buf = NULL; /* brush buffers */ -static MaskBuf * pressure_brush; -static MaskBuf * solid_brush; -static MaskBuf * scale_brush = NULL; -static MaskBuf * scale_pixmap = NULL; -static MaskBuf * kernel_brushes[SUBSAMPLE + 1][SUBSAMPLE + 1]; +static MaskBuf *pressure_brush; +static MaskBuf *solid_brush; +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; @@ -148,10 +190,10 @@ paint_core_button_press (Tool *tool, GdkEventButton *bevent, gpointer gdisp_ptr) { - PaintCore * paint_core; - GDisplay * gdisp; - gboolean draw_line; - gdouble x, y; + PaintCore *paint_core; + GDisplay *gdisp; + gboolean draw_line; + gdouble x, y; GimpDrawable *drawable; gdisp = (GDisplay *) gdisp_ptr; @@ -186,13 +228,13 @@ paint_core_button_press (Tool *tool, if ((gdisp_ptr != tool->gdisp_ptr) || ! (bevent->state & GDK_SHIFT_MASK)) { /* initialize some values */ - paint_core->startx = paint_core->lastx = paint_core->curx = x; - paint_core->starty = paint_core->lasty = paint_core->cury = y; + paint_core->startx = paint_core->lastx = paint_core->curx = x; + paint_core->starty = paint_core->lasty = paint_core->cury = y; paint_core->startpressure = paint_core->lastpressure = paint_core->curpressure; - paint_core->startytilt = paint_core->lastytilt = paint_core->curytilt; - paint_core->startxtilt = paint_core->lastxtilt = paint_core->curxtilt; + paint_core->startytilt = paint_core->lastytilt = paint_core->curytilt; + paint_core->startxtilt = paint_core->lastxtilt = paint_core->curxtilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->startwheel = paint_core->lastwheel = paint_core->curwheel; + paint_core->startwheel = paint_core->lastwheel = paint_core->curwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ } @@ -202,13 +244,13 @@ paint_core_button_press (Tool *tool, else if (bevent->state & GDK_SHIFT_MASK) { draw_line = TRUE; - paint_core->startx = paint_core->lastx; - paint_core->starty = paint_core->lasty; + paint_core->startx = paint_core->lastx; + paint_core->starty = paint_core->lasty; paint_core->startpressure = paint_core->lastpressure; - paint_core->startxtilt = paint_core->lastxtilt; - paint_core->startytilt = paint_core->lastytilt; + paint_core->startxtilt = paint_core->lastxtilt; + paint_core->startytilt = paint_core->lastytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->startwheel = paint_core->lastwheel; + paint_core->startwheel = paint_core->lastwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ /* Restrict to multiples of 15 degrees if ctrl is pressed */ @@ -231,15 +273,15 @@ paint_core_button_press (Tool *tool, break; } dx = dx > 0 ? (cosinus[6-i] * radius) >> 8 : - ((cosinus[6-i] * radius) >> 8); - dy = dy > 0 ? (cosinus[i] * radius) >> 8 : - ((cosinus[i] * radius) >> 8); + dy = dy > 0 ? (cosinus[i] * radius) >> 8 : - ((cosinus[i] * radius) >> 8); } paint_core->curx = paint_core->lastx + dx; paint_core->cury = paint_core->lasty + dy; } } - tool->state = ACTIVE; - tool->gdisp_ptr = gdisp_ptr; + tool->state = ACTIVE; + tool->gdisp_ptr = gdisp_ptr; tool->paused_count = 0; /* pause the current selection and grab the pointer */ @@ -277,13 +319,14 @@ 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->lastx = paint_core->curx; + paint_core->lasty = paint_core->cury; paint_core->lastpressure = paint_core->curpressure; - paint_core->lastxtilt = paint_core->curxtilt; - paint_core->lastytilt = paint_core->curytilt; + paint_core->lastxtilt = paint_core->curxtilt; + paint_core->lastytilt = paint_core->curytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->lastwheel = paint_core->curwheel; + paint_core->lastwheel = paint_core->curwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ } else @@ -302,14 +345,18 @@ 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); + (* 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); + (* paint_core->paint_func) (paint_core, drawable, POSTTRACE_PAINT); } void @@ -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); @@ -349,8 +398,8 @@ paint_core_motion (Tool *tool, GdkEventMotion *mevent, gpointer gdisp_ptr) { - GDisplay * gdisp; - PaintCore * paint_core; + GDisplay *gdisp; + PaintCore *paint_core; gdisp = (GDisplay *) gdisp_ptr; paint_core = (PaintCore *) tool->private; @@ -367,28 +416,34 @@ paint_core_motion (Tool *tool, } paint_core->curpressure = mevent->pressure; - paint_core->curxtilt = mevent->xtilt; - paint_core->curytilt = mevent->ytilt; + paint_core->curxtilt = mevent->xtilt; + paint_core->curytilt = mevent->ytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->curwheel = mevent->wheel; + paint_core->curwheel = mevent->wheel; #endif /* GTK_HAVE_SIX_VALUATORS */ - paint_core->state = mevent->state; + paint_core->state = mevent->state; 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); - 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), + PRETRACE_PAINT); - paint_core->lastx = paint_core->curx; - paint_core->lasty = paint_core->cury; + 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->lastx = paint_core->curx; + paint_core->lasty = paint_core->cury; paint_core->lastpressure = paint_core->curpressure; - paint_core->lastxtilt = paint_core->curxtilt; - paint_core->lastytilt = paint_core->curytilt; + paint_core->lastxtilt = paint_core->curxtilt; + paint_core->lastytilt = paint_core->curytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->lastwheel = paint_core->curwheel; + paint_core->lastwheel = paint_core->curwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ } @@ -397,12 +452,12 @@ paint_core_cursor_update (Tool *tool, GdkEventMotion *mevent, gpointer gdisp_ptr) { - GDisplay *gdisp; - Layer *layer; - PaintCore * paint_core; - GdkCursorType ctype = GDK_TOP_LEFT_ARROW; - gint x, y; - gchar status_str[STATUSBAR_SIZE]; + GDisplay *gdisp; + Layer *layer; + PaintCore *paint_core; + gint x, y; + gchar status_str[STATUSBAR_SIZE]; + GdkCursorType ctype = GDK_TOP_LEFT_ARROW; gdisp = (GDisplay *) gdisp_ptr; paint_core = (PaintCore *) tool->private; @@ -568,7 +623,7 @@ paint_core_draw (Tool *tool) { GDisplay *gdisp; PaintCore *paint_core; - gint tx1, ty1, tx2, ty2; + gint tx1, ty1, tx2, ty2; paint_core = (PaintCore *) tool->private; @@ -626,8 +681,8 @@ paint_core_draw (Tool *tool) Tool * paint_core_new (ToolType type) { - Tool * tool; - PaintCore * private; + Tool *tool; + PaintCore *private; tool = tools_new_tool (type); private = g_new (PaintCore, 1); @@ -635,11 +690,10 @@ paint_core_new (ToolType type) private->core = draw_core_new (paint_core_draw); private->pick_colors = FALSE; - private->flags = 0; - private->context_id = 0; - - tool->private = (void *) private; + private->flags = 0; + 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), @@ -731,47 +786,18 @@ paint_core_init (PaintCore *paint_core, drawable_height (drawable), 1); /* Get the initial undo extents */ - paint_core->x1 = paint_core->x2 = paint_core->curx; - paint_core->y1 = paint_core->y2 = paint_core->cury; - paint_core->distance = 0.0; + paint_core->x1 = paint_core->x2 = paint_core->curx; + paint_core->y1 = paint_core->y2 = paint_core->cury; + paint_core->distance = 0.0; paint_core->pixel_dist = 0.0; 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; @@ -790,13 +817,13 @@ paint_core_interpolate (PaintCore *paint_core, gdouble xd, yd; gdouble mag; - delta.x = paint_core->curx - paint_core->lastx; - delta.y = paint_core->cury - paint_core->lasty; + delta.x = paint_core->curx - paint_core->lastx; + delta.y = paint_core->cury - paint_core->lasty; dpressure = paint_core->curpressure - paint_core->lastpressure; - dxtilt = paint_core->curxtilt - paint_core->lastxtilt; - dytilt = paint_core->curytilt - paint_core->lastytilt; + dxtilt = paint_core->curxtilt - paint_core->lastxtilt; + dytilt = paint_core->curytilt - paint_core->lastytilt; #ifdef GTK_HAVE_SIX_VALUATORS - dwheel = paint_core->curwheel - paint_core->lastwheel; + dwheel = paint_core->curwheel - paint_core->lastwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ /* return if there has been no motion */ @@ -839,38 +866,38 @@ paint_core_interpolate (PaintCore *paint_core, { t = (paint_core->distance - initial) / dist; - paint_core->curx = paint_core->lastx + delta.x * t; - paint_core->cury = paint_core->lasty + delta.y * t; - paint_core->pixel_dist = pixel_initial + pixel_dist * t; + paint_core->curx = paint_core->lastx + delta.x * t; + paint_core->cury = paint_core->lasty + delta.y * t; + paint_core->pixel_dist = pixel_initial + pixel_dist * t; paint_core->curpressure = paint_core->lastpressure + dpressure * t; - paint_core->curxtilt = paint_core->lastxtilt + dxtilt * t; - paint_core->curytilt = paint_core->lastytilt + dytilt * t; + paint_core->curxtilt = paint_core->lastxtilt + dxtilt * t; + paint_core->curytilt = paint_core->lastytilt + dytilt * t; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->curwheel = paint_core->lastwheel + dwheel * t; + paint_core->curwheel = paint_core->lastwheel + dwheel * t; #endif /* GTK_HAVE_SIX_VALUATORS */ if (paint_core->flags & TOOL_CAN_HANDLE_CHANGING_BRUSH) - paint_core->brush = + 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); } } - paint_core->distance = total; - paint_core->pixel_dist = pixel_initial + pixel_dist; - paint_core->curx = paint_core->lastx + delta.x; - paint_core->cury = paint_core->lasty + delta.y; + paint_core->distance = total; + paint_core->pixel_dist = pixel_initial + pixel_dist; + paint_core->curx = paint_core->lastx + delta.x; + paint_core->cury = paint_core->lasty + delta.y; paint_core->curpressure = paint_core->lastpressure + dpressure; - paint_core->curxtilt = paint_core->lastxtilt + dxtilt; - paint_core->curytilt = paint_core->lastytilt + dytilt; + paint_core->curxtilt = paint_core->lastxtilt + dxtilt; + paint_core->curytilt = paint_core->lastytilt + dytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->curwheel = paint_core->lastwheel + dwheel; + paint_core->curwheel = paint_core->lastwheel + dwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ } void paint_core_finish (PaintCore *paint_core, GimpDrawable *drawable, - gint tool_id) + gint tool_ID) { GImage *gimage; PaintUndo *pu; @@ -882,20 +909,21 @@ 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->lastx = paint_core->startx; - pu->lasty = paint_core->starty; + pu->tool_ID = tool_ID; + pu->lastx = paint_core->startx; + pu->lasty = paint_core->starty; pu->lastpressure = paint_core->startpressure; - pu->lastxtilt = paint_core->startxtilt; - pu->lastytilt = paint_core->startytilt; + pu->lastxtilt = paint_core->startxtilt; + pu->lastytilt = paint_core->startytilt; #ifdef GTK_HAVE_SIX_VALUATORS - pu->lastwheel = paint_core->startwheel; + pu->lastwheel = paint_core->startwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ /* Push a paint undo */ @@ -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,10 +1015,10 @@ 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); + dwidth = drawable_width (drawable); dheight = drawable_height (drawable); x1 = CLAMP (x - 1, 0, dwidth); @@ -989,19 +1044,22 @@ paint_core_get_orig_image (PaintCore *paint_core, gint x2, gint y2) { - PixelRegion srcPR, destPR; - Tile *undo_tile; - gint h; - gint refd; - gint pixelwidth; - gint dwidth, dheight; - guchar *s, *d; - void * pr; + PixelRegion srcPR; + PixelRegion destPR; + Tile *undo_tile; + gint h; + gint refd; + gint pixelwidth; + 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)); - dwidth = drawable_width (drawable); + dwidth = drawable_width (drawable); dheight = drawable_height (drawable); x1 = CLAMP (x1, 0, dwidth); @@ -1059,14 +1117,14 @@ paint_core_get_orig_image (PaintCore *paint_core, } 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) +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) { MaskBuf *brush_mask; @@ -1082,31 +1140,30 @@ paint_core_paste_canvas (PaintCore *paint_core, rather than using it to composite (i.e. transparent over opaque becomes transparent rather than opauqe. */ void -paint_core_replace_canvas (PaintCore *paint_core, - GimpDrawable *drawable, - gint brush_opacity, - gint image_opacity, - BrushApplicationMode brush_hardness, - gdouble brush_scale, - PaintApplicationMode mode) +paint_core_replace_canvas (PaintCore *paint_core, + GimpDrawable *drawable, + gint brush_opacity, + gint image_opacity, + BrushApplicationMode brush_hardness, + gdouble brush_scale, + PaintApplicationMode mode) { 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) cache_invalid = TRUE; @@ -1131,13 +1188,13 @@ paint_core_calculate_brush_size (MaskBuf *mask, { gdouble ratio; - if (scale < 1/256) - ratio = 1/16; + if (scale < 1 / 256) + ratio = 1 / 16; 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); } } @@ -1146,15 +1203,17 @@ paint_core_subsample_mask (MaskBuf *mask, gdouble x, gdouble y) { - MaskBuf *dest; - gdouble left; - guchar *m, *d; + MaskBuf *dest; + gdouble left; + guchar *m; + guchar *d; const gint *k; - gint index1, index2; + gint index1; + gint index2; const gint *kernel; - gint new_val; - gint i, j; - gint r, s; + gint new_val; + gint i, j; + gint r, s; x += (x < 0) ? mask->width : 0; left = x - floor(x); @@ -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) - return kernel_brushes[index2][index1]; - else if (mask != last_brush_mask || cache_invalid) - 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; - } + if (mask == last_brush_mask && !cache_invalid) + { + if (kernel_brushes[index2][index1]) + return kernel_brushes[index2][index1]; + } + 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]); - 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]; + kernel_brushes[i][j] = NULL; + } + + last_brush_mask = mask; + cache_invalid = FALSE; + } + + 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++) @@ -1216,21 +1280,21 @@ paint_core_pressurize_mask (MaskBuf *brush_mask, gdouble pressure) { static MaskBuf *last_brush = NULL; - static guchar mapi[256]; - guchar *source; - guchar *dest; + static guchar mapi[256]; + guchar *source; + guchar *dest; MaskBuf *subsample_mask; - gint i; + gint i; #ifdef FANCY_PRESSURE static gdouble map[256]; - gdouble ds, s, c; + gdouble ds, s, c; #endif /* Get the raw subsampled mask */ subsample_mask = paint_core_subsample_mask (brush_mask, x, y); /* Special case pressure = 0.5 */ - if ((int)(pressure*100+0.5) == 50) + if ((int)(pressure * 100 + 0.5) == 50) return subsample_mask; /* Make sure we have the right sized buffer */ @@ -1238,8 +1302,9 @@ 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); + + pressure_brush = mask_buf_new (brush_mask->width + 2, + brush_mask->height + 2); } #ifdef FANCY_PRESSURE @@ -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) @@ -1331,7 +1399,7 @@ paint_core_solidify_mask (MaskBuf *brush_mask) /* get the data and advance one line into it */ data = mask_buf_data (solid_brush) + solid_brush->width; - src = mask_buf_data (brush_mask); + src = mask_buf_data (brush_mask); for (i = 0; i < brush_mask->height; i++) { @@ -1350,10 +1418,11 @@ static MaskBuf * paint_core_scale_mask (MaskBuf *brush_mask, gdouble scale) { - static MaskBuf *last_brush = NULL; - static gint last_width = 0.0; - static gint last_height = 0.0; - gint dest_width, dest_height; + static MaskBuf *last_brush = NULL; + static gint last_width = 0.0; + static gint last_height = 0.0; + gint dest_width; + gint dest_height; if (scale == 0.0) return NULL; @@ -1385,10 +1454,11 @@ static MaskBuf * paint_core_scale_pixmap (MaskBuf *brush_mask, gdouble scale) { - static MaskBuf *last_brush = NULL; - static gint last_width = 0.0; - static gint last_height = 0.0; - gint dest_width, dest_height; + static MaskBuf *last_brush = NULL; + static gint last_width = 0.0; + static gint last_height = 0.0; + gint dest_width; + gint dest_height; if (scale == 0.0) return NULL; @@ -1417,9 +1487,9 @@ paint_core_scale_pixmap (MaskBuf *brush_mask, } static MaskBuf * -paint_core_get_brush_mask (PaintCore *paint_core, - BrushApplicationMode brush_hardness, - gdouble scale) +paint_core_get_brush_mask (PaintCore *paint_core, + BrushApplicationMode brush_hardness, + gdouble scale) { MaskBuf *mask; @@ -1448,18 +1518,19 @@ paint_core_get_brush_mask (PaintCore *paint_core, } static void -paint_core_paste (PaintCore *paint_core, - MaskBuf *brush_mask, - GimpDrawable *drawable, - gint brush_opacity, - gint image_opacity, - LayerModeEffects paint_mode, - PaintApplicationMode mode) +paint_core_paste (PaintCore *paint_core, + MaskBuf *brush_mask, + GimpDrawable *drawable, + gint brush_opacity, + gint image_opacity, + LayerModeEffects paint_mode, + PaintApplicationMode mode) { - GImage *gimage; - PixelRegion srcPR; + GimpImage *gimage; + PixelRegion srcPR; TileManager *alt = NULL; - gint offx, offy; + gint offx; + gint offy; if (! (gimage = drawable_gimage (drawable))) return; @@ -1526,17 +1597,19 @@ paint_core_paste (PaintCore *paint_core, mode. */ static void -paint_core_replace (PaintCore *paint_core, - MaskBuf *brush_mask, - GimpDrawable *drawable, - gint brush_opacity, - gint image_opacity, - PaintApplicationMode mode) +paint_core_replace (PaintCore *paint_core, + MaskBuf *brush_mask, + GimpDrawable *drawable, + gint brush_opacity, + 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)) { @@ -1574,21 +1647,23 @@ paint_core_replace (PaintCore *paint_core, else { /* The mask is just the brush mask */ - maskPR.bytes = 1; - maskPR.x = 0; maskPR.y = 0; - maskPR.w = canvas_buf->width; - maskPR.h = canvas_buf->height; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = canvas_buf->width; + maskPR.h = canvas_buf->height; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask); + maskPR.data = mask_buf_data (brush_mask); } /* intialize canvas buf source pixel regions */ - srcPR.bytes = canvas_buf->bytes; - srcPR.x = 0; srcPR.y = 0; - srcPR.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); /* apply the paint area to the gimage */ gimage_replace_image (gimage, drawable, &srcPR, @@ -1612,17 +1687,19 @@ paint_core_replace (PaintCore *paint_core, } static void -canvas_tiles_to_canvas_buf(PaintCore *paint_core) +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.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); pixel_region_init (&maskPR, canvas_tiles, canvas_buf->x, canvas_buf->y, @@ -1637,26 +1714,30 @@ 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.w = srcPR.w; - maskPR.h = srcPR.h; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = srcPR.w; + maskPR.h = srcPR.h; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; + maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; /* combine the mask to the canvas tiles */ combine_mask_and_region (&srcPR, &maskPR, brush_opacity); @@ -1667,29 +1748,34 @@ 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.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); - maskPR.bytes = 1; - maskPR.x = 0; maskPR.y = 0; - maskPR.w = srcPR.w; - maskPR.h = srcPR.h; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = srcPR.w; + maskPR.h = srcPR.h; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; + maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; /* apply the mask */ apply_mask_to_region (&srcPR, &maskPR, brush_opacity); @@ -1701,37 +1787,42 @@ 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.w = srcPR.w; - maskPR.h = srcPR.h; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = srcPR.w; + maskPR.h = srcPR.h; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; + maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; /* combine the mask and canvas tiles */ combine_mask_and_region (&srcPR, &maskPR, brush_opacity); /* combine the canvas tiles and the canvas buf */ - srcPR.bytes = canvas_buf->bytes; - srcPR.x = 0; srcPR.y = 0; - srcPR.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); pixel_region_init (&maskPR, canvas_tiles, canvas_buf->x, canvas_buf->y, @@ -1746,30 +1837,35 @@ 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.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); - maskPR.bytes = 1; - maskPR.x = 0; maskPR.y = 0; - maskPR.w = srcPR.w; - maskPR.h = srcPR.h; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = srcPR.w; + maskPR.h = srcPR.h; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; + maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; /* apply the mask */ apply_mask_to_region (&srcPR, &maskPR, brush_opacity); @@ -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); } } @@ -1857,17 +1954,21 @@ free_paint_buffers (void) /**************************************************/ void -paint_core_color_area_with_pixmap (PaintCore *paint_core, - GImage *dest, - GimpDrawable *drawable, - TempBuf *area, - gdouble scale, - gint mode) +paint_core_color_area_with_pixmap (PaintCore *paint_core, + GimpImage *dest, + GimpDrawable *drawable, + TempBuf *area, + gdouble scale, + BrushApplicationMode mode) { PixelRegion destPR; - void *pr; - guchar *d; - gint ulx, uly, offsetx, offsety, y; + void *pr; + guchar *d; + gint ulx; + gint uly; + gint offsetx; + gint offsety; + gint y; TempBuf *pixmap_mask; TempBuf *brush_mask; @@ -1876,17 +1977,19 @@ 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.w = area->width; - destPR.h = area->height; + destPR.bytes = area->bytes; + destPR.x = 0; + destPR.y = 0; + destPR.w = area->width; + destPR.h = area->height; destPR.rowstride = destPR.bytes * area->width; - destPR.data = temp_buf_data (area); + destPR.data = temp_buf_data (area); pr = pixel_regions_register (1, &destPR); @@ -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,23 +2017,24 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core, } static void -paint_line_pixmap_mask (GImage *dest, - GimpDrawable *drawable, - TempBuf *pixmap_mask, - TempBuf *brush_mask, - guchar *d, - gint x, - gint y, - gint bytes, - gint width, - gint mode) +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) { - guchar *b, *p; - gint x_index; - gdouble alpha; - gdouble factor = 0.00392156986; /* 1.0/255.0 */ - gint i; - guchar *mask; + guchar *b; + guchar *p; + guchar *mask; + gdouble alpha; + gdouble factor = 0.00392156986; /* 1.0 / 255.0 */ + gint x_index; + gint i; /* Make sure x, y are positive */ while (x < 0) @@ -1960,9 +2064,9 @@ paint_line_pixmap_mask (GImage *dest, alpha = d[bytes-1] * factor; if (alpha) { - d[0] *= alpha; - d[1] *= alpha; - d[2] *= alpha; + d[0] *= alpha; + d[1] *= alpha; + d[2] *= alpha; } /* printf("i: %i d->r: %i d->g: %i d->b: %i d->a: %i\n",i,(int)d[0], (int)d[1], (int)d[2], (int)d[3]); */ gimage_transform_color (dest, drawable, p, d, RGB); diff --git a/app/paint_core.h b/app/paint_core.h index 1b1947ce2a..076f4e5af3 100644 --- a/app/paint_core.h +++ b/app/paint_core.h @@ -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_cleanup (void); +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__ */ diff --git a/app/tools/paint_core.c b/app/tools/paint_core.c index 7ba2135f33..7504818f6f 100644 --- a/app/tools/paint_core.c +++ b/app/tools/paint_core.c @@ -56,68 +56,110 @@ 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); /***********************************************************************/ /* undo blocks variables */ -static TileManager * undo_tiles = NULL; -static TileManager * canvas_tiles = NULL; +static TileManager *undo_tiles = NULL; +static TileManager *canvas_tiles = NULL; /***********************************************************************/ /* paint buffers variables */ -static TempBuf * orig_buf = NULL; -static TempBuf * canvas_buf = NULL; +static TempBuf *orig_buf = NULL; +static TempBuf *canvas_buf = NULL; /* brush buffers */ -static MaskBuf * pressure_brush; -static MaskBuf * solid_brush; -static MaskBuf * scale_brush = NULL; -static MaskBuf * scale_pixmap = NULL; -static MaskBuf * kernel_brushes[SUBSAMPLE + 1][SUBSAMPLE + 1]; +static MaskBuf *pressure_brush; +static MaskBuf *solid_brush; +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; @@ -148,10 +190,10 @@ paint_core_button_press (Tool *tool, GdkEventButton *bevent, gpointer gdisp_ptr) { - PaintCore * paint_core; - GDisplay * gdisp; - gboolean draw_line; - gdouble x, y; + PaintCore *paint_core; + GDisplay *gdisp; + gboolean draw_line; + gdouble x, y; GimpDrawable *drawable; gdisp = (GDisplay *) gdisp_ptr; @@ -186,13 +228,13 @@ paint_core_button_press (Tool *tool, if ((gdisp_ptr != tool->gdisp_ptr) || ! (bevent->state & GDK_SHIFT_MASK)) { /* initialize some values */ - paint_core->startx = paint_core->lastx = paint_core->curx = x; - paint_core->starty = paint_core->lasty = paint_core->cury = y; + paint_core->startx = paint_core->lastx = paint_core->curx = x; + paint_core->starty = paint_core->lasty = paint_core->cury = y; paint_core->startpressure = paint_core->lastpressure = paint_core->curpressure; - paint_core->startytilt = paint_core->lastytilt = paint_core->curytilt; - paint_core->startxtilt = paint_core->lastxtilt = paint_core->curxtilt; + paint_core->startytilt = paint_core->lastytilt = paint_core->curytilt; + paint_core->startxtilt = paint_core->lastxtilt = paint_core->curxtilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->startwheel = paint_core->lastwheel = paint_core->curwheel; + paint_core->startwheel = paint_core->lastwheel = paint_core->curwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ } @@ -202,13 +244,13 @@ paint_core_button_press (Tool *tool, else if (bevent->state & GDK_SHIFT_MASK) { draw_line = TRUE; - paint_core->startx = paint_core->lastx; - paint_core->starty = paint_core->lasty; + paint_core->startx = paint_core->lastx; + paint_core->starty = paint_core->lasty; paint_core->startpressure = paint_core->lastpressure; - paint_core->startxtilt = paint_core->lastxtilt; - paint_core->startytilt = paint_core->lastytilt; + paint_core->startxtilt = paint_core->lastxtilt; + paint_core->startytilt = paint_core->lastytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->startwheel = paint_core->lastwheel; + paint_core->startwheel = paint_core->lastwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ /* Restrict to multiples of 15 degrees if ctrl is pressed */ @@ -231,15 +273,15 @@ paint_core_button_press (Tool *tool, break; } dx = dx > 0 ? (cosinus[6-i] * radius) >> 8 : - ((cosinus[6-i] * radius) >> 8); - dy = dy > 0 ? (cosinus[i] * radius) >> 8 : - ((cosinus[i] * radius) >> 8); + dy = dy > 0 ? (cosinus[i] * radius) >> 8 : - ((cosinus[i] * radius) >> 8); } paint_core->curx = paint_core->lastx + dx; paint_core->cury = paint_core->lasty + dy; } } - tool->state = ACTIVE; - tool->gdisp_ptr = gdisp_ptr; + tool->state = ACTIVE; + tool->gdisp_ptr = gdisp_ptr; tool->paused_count = 0; /* pause the current selection and grab the pointer */ @@ -277,13 +319,14 @@ 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->lastx = paint_core->curx; + paint_core->lasty = paint_core->cury; paint_core->lastpressure = paint_core->curpressure; - paint_core->lastxtilt = paint_core->curxtilt; - paint_core->lastytilt = paint_core->curytilt; + paint_core->lastxtilt = paint_core->curxtilt; + paint_core->lastytilt = paint_core->curytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->lastwheel = paint_core->curwheel; + paint_core->lastwheel = paint_core->curwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ } else @@ -302,14 +345,18 @@ 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); + (* 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); + (* paint_core->paint_func) (paint_core, drawable, POSTTRACE_PAINT); } void @@ -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); @@ -349,8 +398,8 @@ paint_core_motion (Tool *tool, GdkEventMotion *mevent, gpointer gdisp_ptr) { - GDisplay * gdisp; - PaintCore * paint_core; + GDisplay *gdisp; + PaintCore *paint_core; gdisp = (GDisplay *) gdisp_ptr; paint_core = (PaintCore *) tool->private; @@ -367,28 +416,34 @@ paint_core_motion (Tool *tool, } paint_core->curpressure = mevent->pressure; - paint_core->curxtilt = mevent->xtilt; - paint_core->curytilt = mevent->ytilt; + paint_core->curxtilt = mevent->xtilt; + paint_core->curytilt = mevent->ytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->curwheel = mevent->wheel; + paint_core->curwheel = mevent->wheel; #endif /* GTK_HAVE_SIX_VALUATORS */ - paint_core->state = mevent->state; + paint_core->state = mevent->state; 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); - 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), + PRETRACE_PAINT); - paint_core->lastx = paint_core->curx; - paint_core->lasty = paint_core->cury; + 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->lastx = paint_core->curx; + paint_core->lasty = paint_core->cury; paint_core->lastpressure = paint_core->curpressure; - paint_core->lastxtilt = paint_core->curxtilt; - paint_core->lastytilt = paint_core->curytilt; + paint_core->lastxtilt = paint_core->curxtilt; + paint_core->lastytilt = paint_core->curytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->lastwheel = paint_core->curwheel; + paint_core->lastwheel = paint_core->curwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ } @@ -397,12 +452,12 @@ paint_core_cursor_update (Tool *tool, GdkEventMotion *mevent, gpointer gdisp_ptr) { - GDisplay *gdisp; - Layer *layer; - PaintCore * paint_core; - GdkCursorType ctype = GDK_TOP_LEFT_ARROW; - gint x, y; - gchar status_str[STATUSBAR_SIZE]; + GDisplay *gdisp; + Layer *layer; + PaintCore *paint_core; + gint x, y; + gchar status_str[STATUSBAR_SIZE]; + GdkCursorType ctype = GDK_TOP_LEFT_ARROW; gdisp = (GDisplay *) gdisp_ptr; paint_core = (PaintCore *) tool->private; @@ -568,7 +623,7 @@ paint_core_draw (Tool *tool) { GDisplay *gdisp; PaintCore *paint_core; - gint tx1, ty1, tx2, ty2; + gint tx1, ty1, tx2, ty2; paint_core = (PaintCore *) tool->private; @@ -626,8 +681,8 @@ paint_core_draw (Tool *tool) Tool * paint_core_new (ToolType type) { - Tool * tool; - PaintCore * private; + Tool *tool; + PaintCore *private; tool = tools_new_tool (type); private = g_new (PaintCore, 1); @@ -635,11 +690,10 @@ paint_core_new (ToolType type) private->core = draw_core_new (paint_core_draw); private->pick_colors = FALSE; - private->flags = 0; - private->context_id = 0; - - tool->private = (void *) private; + private->flags = 0; + 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), @@ -731,47 +786,18 @@ paint_core_init (PaintCore *paint_core, drawable_height (drawable), 1); /* Get the initial undo extents */ - paint_core->x1 = paint_core->x2 = paint_core->curx; - paint_core->y1 = paint_core->y2 = paint_core->cury; - paint_core->distance = 0.0; + paint_core->x1 = paint_core->x2 = paint_core->curx; + paint_core->y1 = paint_core->y2 = paint_core->cury; + paint_core->distance = 0.0; paint_core->pixel_dist = 0.0; 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; @@ -790,13 +817,13 @@ paint_core_interpolate (PaintCore *paint_core, gdouble xd, yd; gdouble mag; - delta.x = paint_core->curx - paint_core->lastx; - delta.y = paint_core->cury - paint_core->lasty; + delta.x = paint_core->curx - paint_core->lastx; + delta.y = paint_core->cury - paint_core->lasty; dpressure = paint_core->curpressure - paint_core->lastpressure; - dxtilt = paint_core->curxtilt - paint_core->lastxtilt; - dytilt = paint_core->curytilt - paint_core->lastytilt; + dxtilt = paint_core->curxtilt - paint_core->lastxtilt; + dytilt = paint_core->curytilt - paint_core->lastytilt; #ifdef GTK_HAVE_SIX_VALUATORS - dwheel = paint_core->curwheel - paint_core->lastwheel; + dwheel = paint_core->curwheel - paint_core->lastwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ /* return if there has been no motion */ @@ -839,38 +866,38 @@ paint_core_interpolate (PaintCore *paint_core, { t = (paint_core->distance - initial) / dist; - paint_core->curx = paint_core->lastx + delta.x * t; - paint_core->cury = paint_core->lasty + delta.y * t; - paint_core->pixel_dist = pixel_initial + pixel_dist * t; + paint_core->curx = paint_core->lastx + delta.x * t; + paint_core->cury = paint_core->lasty + delta.y * t; + paint_core->pixel_dist = pixel_initial + pixel_dist * t; paint_core->curpressure = paint_core->lastpressure + dpressure * t; - paint_core->curxtilt = paint_core->lastxtilt + dxtilt * t; - paint_core->curytilt = paint_core->lastytilt + dytilt * t; + paint_core->curxtilt = paint_core->lastxtilt + dxtilt * t; + paint_core->curytilt = paint_core->lastytilt + dytilt * t; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->curwheel = paint_core->lastwheel + dwheel * t; + paint_core->curwheel = paint_core->lastwheel + dwheel * t; #endif /* GTK_HAVE_SIX_VALUATORS */ if (paint_core->flags & TOOL_CAN_HANDLE_CHANGING_BRUSH) - paint_core->brush = + 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); } } - paint_core->distance = total; - paint_core->pixel_dist = pixel_initial + pixel_dist; - paint_core->curx = paint_core->lastx + delta.x; - paint_core->cury = paint_core->lasty + delta.y; + paint_core->distance = total; + paint_core->pixel_dist = pixel_initial + pixel_dist; + paint_core->curx = paint_core->lastx + delta.x; + paint_core->cury = paint_core->lasty + delta.y; paint_core->curpressure = paint_core->lastpressure + dpressure; - paint_core->curxtilt = paint_core->lastxtilt + dxtilt; - paint_core->curytilt = paint_core->lastytilt + dytilt; + paint_core->curxtilt = paint_core->lastxtilt + dxtilt; + paint_core->curytilt = paint_core->lastytilt + dytilt; #ifdef GTK_HAVE_SIX_VALUATORS - paint_core->curwheel = paint_core->lastwheel + dwheel; + paint_core->curwheel = paint_core->lastwheel + dwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ } void paint_core_finish (PaintCore *paint_core, GimpDrawable *drawable, - gint tool_id) + gint tool_ID) { GImage *gimage; PaintUndo *pu; @@ -882,20 +909,21 @@ 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->lastx = paint_core->startx; - pu->lasty = paint_core->starty; + pu->tool_ID = tool_ID; + pu->lastx = paint_core->startx; + pu->lasty = paint_core->starty; pu->lastpressure = paint_core->startpressure; - pu->lastxtilt = paint_core->startxtilt; - pu->lastytilt = paint_core->startytilt; + pu->lastxtilt = paint_core->startxtilt; + pu->lastytilt = paint_core->startytilt; #ifdef GTK_HAVE_SIX_VALUATORS - pu->lastwheel = paint_core->startwheel; + pu->lastwheel = paint_core->startwheel; #endif /* GTK_HAVE_SIX_VALUATORS */ /* Push a paint undo */ @@ -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,10 +1015,10 @@ 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); + dwidth = drawable_width (drawable); dheight = drawable_height (drawable); x1 = CLAMP (x - 1, 0, dwidth); @@ -989,19 +1044,22 @@ paint_core_get_orig_image (PaintCore *paint_core, gint x2, gint y2) { - PixelRegion srcPR, destPR; - Tile *undo_tile; - gint h; - gint refd; - gint pixelwidth; - gint dwidth, dheight; - guchar *s, *d; - void * pr; + PixelRegion srcPR; + PixelRegion destPR; + Tile *undo_tile; + gint h; + gint refd; + gint pixelwidth; + 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)); - dwidth = drawable_width (drawable); + dwidth = drawable_width (drawable); dheight = drawable_height (drawable); x1 = CLAMP (x1, 0, dwidth); @@ -1059,14 +1117,14 @@ paint_core_get_orig_image (PaintCore *paint_core, } 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) +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) { MaskBuf *brush_mask; @@ -1082,31 +1140,30 @@ paint_core_paste_canvas (PaintCore *paint_core, rather than using it to composite (i.e. transparent over opaque becomes transparent rather than opauqe. */ void -paint_core_replace_canvas (PaintCore *paint_core, - GimpDrawable *drawable, - gint brush_opacity, - gint image_opacity, - BrushApplicationMode brush_hardness, - gdouble brush_scale, - PaintApplicationMode mode) +paint_core_replace_canvas (PaintCore *paint_core, + GimpDrawable *drawable, + gint brush_opacity, + gint image_opacity, + BrushApplicationMode brush_hardness, + gdouble brush_scale, + PaintApplicationMode mode) { 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) cache_invalid = TRUE; @@ -1131,13 +1188,13 @@ paint_core_calculate_brush_size (MaskBuf *mask, { gdouble ratio; - if (scale < 1/256) - ratio = 1/16; + if (scale < 1 / 256) + ratio = 1 / 16; 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); } } @@ -1146,15 +1203,17 @@ paint_core_subsample_mask (MaskBuf *mask, gdouble x, gdouble y) { - MaskBuf *dest; - gdouble left; - guchar *m, *d; + MaskBuf *dest; + gdouble left; + guchar *m; + guchar *d; const gint *k; - gint index1, index2; + gint index1; + gint index2; const gint *kernel; - gint new_val; - gint i, j; - gint r, s; + gint new_val; + gint i, j; + gint r, s; x += (x < 0) ? mask->width : 0; left = x - floor(x); @@ -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) - return kernel_brushes[index2][index1]; - else if (mask != last_brush_mask || cache_invalid) - 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; - } + if (mask == last_brush_mask && !cache_invalid) + { + if (kernel_brushes[index2][index1]) + return kernel_brushes[index2][index1]; + } + 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]); - 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]; + kernel_brushes[i][j] = NULL; + } + + last_brush_mask = mask; + cache_invalid = FALSE; + } + + 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++) @@ -1216,21 +1280,21 @@ paint_core_pressurize_mask (MaskBuf *brush_mask, gdouble pressure) { static MaskBuf *last_brush = NULL; - static guchar mapi[256]; - guchar *source; - guchar *dest; + static guchar mapi[256]; + guchar *source; + guchar *dest; MaskBuf *subsample_mask; - gint i; + gint i; #ifdef FANCY_PRESSURE static gdouble map[256]; - gdouble ds, s, c; + gdouble ds, s, c; #endif /* Get the raw subsampled mask */ subsample_mask = paint_core_subsample_mask (brush_mask, x, y); /* Special case pressure = 0.5 */ - if ((int)(pressure*100+0.5) == 50) + if ((int)(pressure * 100 + 0.5) == 50) return subsample_mask; /* Make sure we have the right sized buffer */ @@ -1238,8 +1302,9 @@ 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); + + pressure_brush = mask_buf_new (brush_mask->width + 2, + brush_mask->height + 2); } #ifdef FANCY_PRESSURE @@ -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) @@ -1331,7 +1399,7 @@ paint_core_solidify_mask (MaskBuf *brush_mask) /* get the data and advance one line into it */ data = mask_buf_data (solid_brush) + solid_brush->width; - src = mask_buf_data (brush_mask); + src = mask_buf_data (brush_mask); for (i = 0; i < brush_mask->height; i++) { @@ -1350,10 +1418,11 @@ static MaskBuf * paint_core_scale_mask (MaskBuf *brush_mask, gdouble scale) { - static MaskBuf *last_brush = NULL; - static gint last_width = 0.0; - static gint last_height = 0.0; - gint dest_width, dest_height; + static MaskBuf *last_brush = NULL; + static gint last_width = 0.0; + static gint last_height = 0.0; + gint dest_width; + gint dest_height; if (scale == 0.0) return NULL; @@ -1385,10 +1454,11 @@ static MaskBuf * paint_core_scale_pixmap (MaskBuf *brush_mask, gdouble scale) { - static MaskBuf *last_brush = NULL; - static gint last_width = 0.0; - static gint last_height = 0.0; - gint dest_width, dest_height; + static MaskBuf *last_brush = NULL; + static gint last_width = 0.0; + static gint last_height = 0.0; + gint dest_width; + gint dest_height; if (scale == 0.0) return NULL; @@ -1417,9 +1487,9 @@ paint_core_scale_pixmap (MaskBuf *brush_mask, } static MaskBuf * -paint_core_get_brush_mask (PaintCore *paint_core, - BrushApplicationMode brush_hardness, - gdouble scale) +paint_core_get_brush_mask (PaintCore *paint_core, + BrushApplicationMode brush_hardness, + gdouble scale) { MaskBuf *mask; @@ -1448,18 +1518,19 @@ paint_core_get_brush_mask (PaintCore *paint_core, } static void -paint_core_paste (PaintCore *paint_core, - MaskBuf *brush_mask, - GimpDrawable *drawable, - gint brush_opacity, - gint image_opacity, - LayerModeEffects paint_mode, - PaintApplicationMode mode) +paint_core_paste (PaintCore *paint_core, + MaskBuf *brush_mask, + GimpDrawable *drawable, + gint brush_opacity, + gint image_opacity, + LayerModeEffects paint_mode, + PaintApplicationMode mode) { - GImage *gimage; - PixelRegion srcPR; + GimpImage *gimage; + PixelRegion srcPR; TileManager *alt = NULL; - gint offx, offy; + gint offx; + gint offy; if (! (gimage = drawable_gimage (drawable))) return; @@ -1526,17 +1597,19 @@ paint_core_paste (PaintCore *paint_core, mode. */ static void -paint_core_replace (PaintCore *paint_core, - MaskBuf *brush_mask, - GimpDrawable *drawable, - gint brush_opacity, - gint image_opacity, - PaintApplicationMode mode) +paint_core_replace (PaintCore *paint_core, + MaskBuf *brush_mask, + GimpDrawable *drawable, + gint brush_opacity, + 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)) { @@ -1574,21 +1647,23 @@ paint_core_replace (PaintCore *paint_core, else { /* The mask is just the brush mask */ - maskPR.bytes = 1; - maskPR.x = 0; maskPR.y = 0; - maskPR.w = canvas_buf->width; - maskPR.h = canvas_buf->height; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = canvas_buf->width; + maskPR.h = canvas_buf->height; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask); + maskPR.data = mask_buf_data (brush_mask); } /* intialize canvas buf source pixel regions */ - srcPR.bytes = canvas_buf->bytes; - srcPR.x = 0; srcPR.y = 0; - srcPR.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); /* apply the paint area to the gimage */ gimage_replace_image (gimage, drawable, &srcPR, @@ -1612,17 +1687,19 @@ paint_core_replace (PaintCore *paint_core, } static void -canvas_tiles_to_canvas_buf(PaintCore *paint_core) +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.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); pixel_region_init (&maskPR, canvas_tiles, canvas_buf->x, canvas_buf->y, @@ -1637,26 +1714,30 @@ 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.w = srcPR.w; - maskPR.h = srcPR.h; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = srcPR.w; + maskPR.h = srcPR.h; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; + maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; /* combine the mask to the canvas tiles */ combine_mask_and_region (&srcPR, &maskPR, brush_opacity); @@ -1667,29 +1748,34 @@ 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.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); - maskPR.bytes = 1; - maskPR.x = 0; maskPR.y = 0; - maskPR.w = srcPR.w; - maskPR.h = srcPR.h; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = srcPR.w; + maskPR.h = srcPR.h; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; + maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; /* apply the mask */ apply_mask_to_region (&srcPR, &maskPR, brush_opacity); @@ -1701,37 +1787,42 @@ 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.w = srcPR.w; - maskPR.h = srcPR.h; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = srcPR.w; + maskPR.h = srcPR.h; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; + maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; /* combine the mask and canvas tiles */ combine_mask_and_region (&srcPR, &maskPR, brush_opacity); /* combine the canvas tiles and the canvas buf */ - srcPR.bytes = canvas_buf->bytes; - srcPR.x = 0; srcPR.y = 0; - srcPR.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); pixel_region_init (&maskPR, canvas_tiles, canvas_buf->x, canvas_buf->y, @@ -1746,30 +1837,35 @@ 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.w = canvas_buf->width; - srcPR.h = canvas_buf->height; + srcPR.bytes = canvas_buf->bytes; + 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); + srcPR.data = temp_buf_data (canvas_buf); - maskPR.bytes = 1; - maskPR.x = 0; maskPR.y = 0; - maskPR.w = srcPR.w; - maskPR.h = srcPR.h; + maskPR.bytes = 1; + maskPR.x = 0; + maskPR.y = 0; + maskPR.w = srcPR.w; + maskPR.h = srcPR.h; maskPR.rowstride = maskPR.bytes * brush_mask->width; - maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; + maskPR.data = mask_buf_data (brush_mask) + yoff * maskPR.rowstride + xoff * maskPR.bytes; /* apply the mask */ apply_mask_to_region (&srcPR, &maskPR, brush_opacity); @@ -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); } } @@ -1857,17 +1954,21 @@ free_paint_buffers (void) /**************************************************/ void -paint_core_color_area_with_pixmap (PaintCore *paint_core, - GImage *dest, - GimpDrawable *drawable, - TempBuf *area, - gdouble scale, - gint mode) +paint_core_color_area_with_pixmap (PaintCore *paint_core, + GimpImage *dest, + GimpDrawable *drawable, + TempBuf *area, + gdouble scale, + BrushApplicationMode mode) { PixelRegion destPR; - void *pr; - guchar *d; - gint ulx, uly, offsetx, offsety, y; + void *pr; + guchar *d; + gint ulx; + gint uly; + gint offsetx; + gint offsety; + gint y; TempBuf *pixmap_mask; TempBuf *brush_mask; @@ -1876,17 +1977,19 @@ 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.w = area->width; - destPR.h = area->height; + destPR.bytes = area->bytes; + destPR.x = 0; + destPR.y = 0; + destPR.w = area->width; + destPR.h = area->height; destPR.rowstride = destPR.bytes * area->width; - destPR.data = temp_buf_data (area); + destPR.data = temp_buf_data (area); pr = pixel_regions_register (1, &destPR); @@ -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,23 +2017,24 @@ paint_core_color_area_with_pixmap (PaintCore *paint_core, } static void -paint_line_pixmap_mask (GImage *dest, - GimpDrawable *drawable, - TempBuf *pixmap_mask, - TempBuf *brush_mask, - guchar *d, - gint x, - gint y, - gint bytes, - gint width, - gint mode) +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) { - guchar *b, *p; - gint x_index; - gdouble alpha; - gdouble factor = 0.00392156986; /* 1.0/255.0 */ - gint i; - guchar *mask; + guchar *b; + guchar *p; + guchar *mask; + gdouble alpha; + gdouble factor = 0.00392156986; /* 1.0 / 255.0 */ + gint x_index; + gint i; /* Make sure x, y are positive */ while (x < 0) @@ -1960,9 +2064,9 @@ paint_line_pixmap_mask (GImage *dest, alpha = d[bytes-1] * factor; if (alpha) { - d[0] *= alpha; - d[1] *= alpha; - d[2] *= alpha; + d[0] *= alpha; + d[1] *= alpha; + d[2] *= alpha; } /* printf("i: %i d->r: %i d->g: %i d->b: %i d->a: %i\n",i,(int)d[0], (int)d[1], (int)d[2], (int)d[3]); */ gimage_transform_color (dest, drawable, p, d, RGB); diff --git a/app/tools/paint_core.h b/app/tools/paint_core.h index 1b1947ce2a..076f4e5af3 100644 --- a/app/tools/paint_core.h +++ b/app/tools/paint_core.h @@ -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_cleanup (void); +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__ */ diff --git a/plug-ins/gap/README b/plug-ins/gap/README index b205eb9008..060f60c575 100644 --- a/plug-ins/gap/README +++ b/plug-ins/gap/README @@ -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 diff --git a/plug-ins/gap/gap_mov_dialog.c b/plug-ins/gap/gap_mov_dialog.c index f58dac7fcb..ff8a9848cf 100644 --- a/plug-ins/gap/gap_mov_dialog.c +++ b/plug-ins/gap/gap_mov_dialog.c @@ -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) diff --git a/plug-ins/gap/gap_mov_exec.c b/plug-ins/gap/gap_mov_exec.c index 874ae0ee06..4004e13b70 100644 --- a/plug-ins/gap/gap_mov_exec.c +++ b/plug-ins/gap/gap_mov_exec.c @@ -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 ); + } } diff --git a/plug-ins/imagemap/imap_csim.y b/plug-ins/imagemap/imap_csim.y index 38e1fb4c59..aca8b71db1 100755 --- a/plug-ins/imagemap/imap_csim.y +++ b/plug-ins/imagemap/imap_csim.y @@ -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; diff --git a/tips/gimp_tips.txt b/tips/gimp_tips.txt index e93093b99e..70cb3bec62 100644 --- a/tips/gimp_tips.txt +++ b/tips/gimp_tips.txt @@ -11,68 +11,69 @@ # 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) # -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 +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. +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". -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. - -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) +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 # -The file selection dialog box has command-line completion with +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,20 +81,25 @@ 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 +You can use the middle mouse button to pan around the image, if it's larger than its display window. -Click and drag on a ruler to place a Guide on an image. All -dragged selections will snap to the guides. You can remove +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. -The GIMP supports gzip compression on the fly. Just add -'.gz' (or '.bz2', if you have bzip2 installed) to the filename -and your image will be saved compressed. Of course loading +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 +and your image will be saved compressed. Of course loading compressed images works too. Pressing and holding the Shift key before making a selection allows @@ -101,16 +107,42 @@ you to add to the current selection instead of replacing it. Using Ctrl before making a selection subtracts from the current one. 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 +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) # -You can adjust the selection range for fuzzy select +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. -Shift-click on the eye icon in the Layers dialog to hide all +Shift-click on the eye icon in the Layers dialog to hide all layers but that one. Shift-click again to show all layers. Ctrl-click on the layer mask's preview in the Layers dialog @@ -130,28 +162,20 @@ will constrain the rotation to 15 degree angles. 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. 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. - -To create a perfect circle, hold Shift while doing an ellipse select. To -place a circle precisely, drag horizontal and vertical guides tangent to +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. 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)