--- gimp-2.4.3-/app/paint/gimpbrushcore.c Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/paint/gimpbrushcore.c Thu Jan 10 07:10:23 2008 @@ -808,7 +808,8 @@ gdouble image_opacity, GimpLayerModeEffects paint_mode, GimpBrushApplicationMode brush_hardness, - GimpPaintApplicationMode mode) + GimpPaintApplicationMode mode, + gboolean reduce_update_freq) { TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core, brush_hardness); @@ -836,7 +837,7 @@ gimp_paint_core_paste (paint_core, &brush_maskPR, drawable, brush_opacity, image_opacity, paint_mode, - mode); + mode, reduce_update_freq); } } @@ -850,7 +851,8 @@ gdouble brush_opacity, gdouble image_opacity, GimpBrushApplicationMode brush_hardness, - GimpPaintApplicationMode mode) + GimpPaintApplicationMode mode, + gboolean reduce_update_freq) { TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core, brush_hardness); @@ -878,7 +880,7 @@ gimp_paint_core_replace (paint_core, &brush_maskPR, drawable, brush_opacity, image_opacity, - mode); + mode, reduce_update_freq); } } --- gimp-2.4.3-/app/paint/gimpbrushcore.h Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/paint/gimpbrushcore.h Thu Jan 10 07:10:23 2008 @@ -112,13 +112,15 @@ gdouble image_opacity, GimpLayerModeEffects paint_mode, GimpBrushApplicationMode brush_hardness, - GimpPaintApplicationMode mode); + GimpPaintApplicationMode mode, + gboolean reduce_update_freq); void gimp_brush_core_replace_canvas (GimpBrushCore *core, GimpDrawable *drawable, gdouble brush_opacity, gdouble image_opacity, GimpBrushApplicationMode brush_hardness, - GimpPaintApplicationMode mode); + GimpPaintApplicationMode mode, + gboolean reduce_update_freq); void gimp_brush_core_color_area_with_pixmap (GimpBrushCore *core, --- gimp-2.4.3-/app/paint/gimpclone.c Tue Nov 20 18:31:16 2007 +++ gimp-painter--2.4.3/app/paint/gimpclone.c Thu Jan 10 07:14:32 2008 @@ -253,7 +253,8 @@ */ source_options->align_mode == GIMP_SOURCE_ALIGN_FIXED ? - GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT); + GIMP_PAINT_INCREMENTAL : GIMP_PAINT_CONSTANT, + paint_options->reduce_update_freq); } static void --- gimp-2.4.3-/app/paint/gimpconvolve.c Tue Nov 20 18:31:16 2007 +++ gimp-painter--2.4.3/app/paint/gimpconvolve.c Thu Jan 10 07:22:15 2008 @@ -211,7 +211,8 @@ MIN (opacity, GIMP_OPACITY_OPAQUE), gimp_context_get_opacity (context), gimp_paint_options_get_brush_mode (paint_options), - GIMP_PAINT_INCREMENTAL); + GIMP_PAINT_INCREMENTAL, + paint_options->reduce_update_freq); } static void --- gimp-2.4.3-/app/paint/gimpdodgeburn.c Tue Nov 20 18:31:16 2007 +++ gimp-painter--2.4.3/app/paint/gimpdodgeburn.c Thu Jan 10 07:22:49 2008 @@ -242,7 +242,8 @@ MIN (opacity, GIMP_OPACITY_OPAQUE), gimp_context_get_opacity (context), gimp_paint_options_get_brush_mode (paint_options), - GIMP_PAINT_CONSTANT); + GIMP_PAINT_CONSTANT, + paint_options->reduce_update_freq); g_free (temp_data); } --- gimp-2.4.3-/app/paint/gimperaser.c Tue Nov 20 18:31:16 2007 +++ gimp-painter--2.4.3/app/paint/gimperaser.c Thu Jan 10 07:14:55 2008 @@ -140,5 +140,6 @@ (options->anti_erase ? GIMP_ANTI_ERASE_MODE : GIMP_ERASE_MODE), gimp_paint_options_get_brush_mode (paint_options), - paint_options->application_mode); + paint_options->application_mode, + paint_options->reduce_update_freq); } --- gimp-2.4.3-/app/paint/gimpheal.c Tue Dec 11 16:31:24 2007 +++ gimp-painter--2.4.3/app/paint/gimpheal.c Thu Jan 10 07:23:11 2008 @@ -505,7 +505,8 @@ MIN (opacity, GIMP_OPACITY_OPAQUE), gimp_context_get_opacity (context), gimp_paint_options_get_brush_mode (paint_options), - GIMP_PAINT_INCREMENTAL); + GIMP_PAINT_INCREMENTAL, + paint_options->reduce_update_freq); temp_buf_free (src); temp_buf_free (temp); --- gimp-2.4.3-/app/paint/gimpink.c Tue Nov 20 18:31:16 2007 +++ gimp-painter--2.4.3/app/paint/gimpink.c Thu Jan 10 07:11:54 2008 @@ -385,7 +385,8 @@ GIMP_OPACITY_OPAQUE, gimp_context_get_opacity (context), gimp_context_get_paint_mode (context), - GIMP_PAINT_CONSTANT); + GIMP_PAINT_CONSTANT, + paint_options->reduce_update_freq); if (blob_union) g_free (blob_union); --- gimp-2.4.3-/app/paint/gimpink2.c Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/paint/gimpink2.c Thu Jan 10 07:12:10 2008 @@ -425,7 +425,8 @@ GIMP_OPACITY_OPAQUE, gimp_context_get_opacity (context), gimp_context_get_paint_mode (context), - GIMP_PAINT_CONSTANT); + GIMP_PAINT_CONSTANT, + paint_options->reduce_update_freq); if (blob_union) g_free (blob_union); --- gimp-2.4.3-/app/paint/gimpmixbrush.c Fri Jan 11 06:06:46 2008 +++ gimp-painter--2.4.3/app/paint/gimpmixbrush.c Fri Jan 11 05:38:53 2008 @@ -17,7 +17,7 @@ */ /*#define CHECK_TIME*/ -#define LOWER_UPDATE + #include "config.h" #include @@ -61,7 +61,6 @@ gdouble pixel_dist; GimpRGB color; gdouble opacity; - guint32 time; } CoordsHistory; @@ -73,24 +72,13 @@ GimpPaintState paint_state, guint32 time); -#ifdef LOWER_UPDATE static void gimp_mixbrush_motion (GimpPaintCore *paint_core, GimpDrawable *drawable, - GimpPaintOptions *paint_options, - guint32 time); -static void gimp_mixbrush_start (GimpPaintCore *paint_core, - GimpDrawable *drawable, - GimpPaintOptions *paint_options, - guint32 time); -#else -static void gimp_mixbrush_start (GimpPaintCore *paint_core, - GimpDrawable *drawable, GimpPaintOptions *paint_options); -static void gimp_mixbrush_motion (GimpPaintCore *paint_core, +static void gimp_mixbrush_start (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options); -#endif static void gimp_mixbrush_finish (GimpPaintCore *paint_core, GimpDrawable *drawable, @@ -104,14 +92,14 @@ static void coords_history_free (CoordsHistory *history, gpointer dummy); -static inline gboolean get_canvas_color (GimpImage *image, - GimpDrawable *drawable, - GimpPaintCore *paint_core, - gint x, - gint y, - guint sample_size_limit, - gboolean merged, - GimpRGB *color); +static inline gboolean get_canvas_color (GimpImage *image, + GimpDrawable *drawable, + GimpPaintCore *paint_core, + gint x, + gint y, + guint sample_size_limit, + gboolean merged, + GimpRGB *color); static inline gboolean pick_up_avarage_color (GimpPickable *pickable, GimpBrushCore *brush_core, @@ -150,12 +138,8 @@ void paste_canvas (GimpPaintCore *core, GimpDrawable *drawable, GimpRGB *paint_color, - gdouble opacity); -#endif - -#ifdef LOWER_UPDATE -static inline void update_drawable (GimpMixbrush *mixbrush, - GimpDrawable *drawable); + gdouble opacity, + gboolean reduce_update_freq); #endif @@ -233,11 +217,7 @@ total_time = 0; count = 0; #endif -#ifdef LOWER_UPDATE - gimp_mixbrush_start (paint_core, drawable, paint_options, time); -#else gimp_mixbrush_start (paint_core, drawable, paint_options); -#endif GIMP_PAINT_CORE_CLASS (parent_class)->paint (paint_core, drawable, paint_options, paint_state, time); @@ -247,22 +227,14 @@ #ifdef CHECK_TIME timer = g_timer_new (); g_timer_start (timer); -#ifdef LOWER_UPDATE - gimp_mixbrush_motion (paint_core, drawable, paint_options, time); -#else gimp_mixbrush_motion (paint_core, drawable, paint_options); -#endif g_timer_stop (timer); total_time += g_timer_elapsed (timer, NULL); g_timer_destroy (timer); count++; #else -#ifdef LOWER_UPDATE - gimp_mixbrush_motion (paint_core, drawable, paint_options, time); -#else gimp_mixbrush_motion (paint_core, drawable, paint_options); #endif -#endif break; case GIMP_PAINT_STATE_FINISH: @@ -280,18 +252,10 @@ } } -#ifdef LOWER_UPDATE -static void -gimp_mixbrush_start (GimpPaintCore *paint_core, - GimpDrawable *drawable, - GimpPaintOptions *paint_options, - guint32 time) -#else static void gimp_mixbrush_start (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options) -#endif { GimpMixbrush *mixbrush = GIMP_MIXBRUSH (paint_core); GimpMixbrushOptions *mixbrush_options = GIMP_MIXBRUSH_OPTIONS (paint_options); @@ -401,15 +365,6 @@ /* Reset the rounding error */ gimp_rgba_set (&mixbrush->error, 0, 0, 0, 0); - -#ifdef LOWER_UPDATE - mixbrush->update_count = 0; - mixbrush->update_is_done = FALSE; - mixbrush->_x1 = mixbrush->_x2 = paint_core->cur_coords.x; - mixbrush->_y1 = mixbrush->_y2 = paint_core->cur_coords.y; - mixbrush->time = 100; - mixbrush->last_time = time; -#endif } static void @@ -429,11 +384,6 @@ while (mixbrush->history) gimp_mixbrush_paste_canvas (paint_core, drawable, paint_options); -#ifdef LOWER_UPDATE - if (! mixbrush->update_is_done) - update_drawable (mixbrush, drawable); -#endif - if (mixbrush->mask) { temp_buf_free (mixbrush->mask); @@ -441,18 +391,10 @@ } } -#ifdef LOWER_UPDATE -static void -gimp_mixbrush_motion (GimpPaintCore *paint_core, - GimpDrawable *drawable, - GimpPaintOptions *paint_options, - guint32 time) -#else static void gimp_mixbrush_motion (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options) -#endif { GimpImage *image; GimpMixbrush *mixbrush = GIMP_MIXBRUSH (paint_core); @@ -470,9 +412,6 @@ history->coords = paint_core->cur_coords; history->prev_coords = paint_core->last_coords; history->pixel_dist = paint_core->pixel_dist; -#ifdef LOWER_UPDATE - history->time = time; -#endif /* Pick up the raw canvas color */ get_canvas_color (image, drawable, paint_core, @@ -513,12 +452,6 @@ history = mixbrush->history->data; mixbrush->history = g_list_delete_link (mixbrush->history, mixbrush->history); - -#ifdef LOWER_UPDATE - mixbrush->time = (mixbrush->time + history->time - mixbrush->last_time) / 2; - mixbrush->last_time = history->time; - //g_printerr ("time = %d\n", mixbrush->time); -#endif if (history->opacity != 0.0) { @@ -669,7 +602,7 @@ paint_appl_mode == GIMP_PAINT_INCREMENTAL) { gdouble op = MIN (history->opacity, GIMP_OPACITY_OPAQUE) * gimp_context_get_opacity (context); - paste_canvas (paint_core, drawable, last_color, op); + paste_canvas (paint_core, drawable, last_color, op, paint_options->reduce_update_freq); } else { @@ -698,7 +631,8 @@ gimp_context_get_opacity (context), gimp_context_get_paint_mode (context), gimp_paint_options_get_brush_mode (paint_options), - paint_appl_mode); + paint_appl_mode, + paint_options->reduce_update_freq); } } paint_core->cur_coords = orig_coords; @@ -1033,7 +967,8 @@ paste_canvas (GimpPaintCore *core, GimpDrawable *drawable, GimpRGB *paint_color, - gdouble opacity) + gdouble opacity, + gboolean reduce_update_freq) { TempBuf *brush_mask = gimp_brush_core_get_brush_mask (GIMP_BRUSH_CORE (core), GIMP_BRUSH_SOFT); TempBuf *canvas_buf = core->canvas_buf; @@ -1222,54 +1157,45 @@ core->y2 = MAX (core->y2, c_y + c_h) ; /* Update the drawable */ -#ifdef LOWER_UPDATE + if (reduce_update_freq) { - GimpMixbrush *mixbrush = GIMP_MIXBRUSH (core); - gfloat n; + gdouble n; + gdouble s = (c_w + c_h) / 2.0 / 30.0; - n = MAX (2.0 - log10f (mixbrush->time), 0) * 2.0; - n *= log10f ((c_w + c_h) / 2) + 1.0; - //g_printerr ("time = %d, size = %d, n = %d\n\n", mixbrush->time, c_w, (gint)n); + n = MAX (1.6 - log10 (core->interval + 1.0), 0) * 1.5; + n *= faster_pow (s, 1.35); - if (mixbrush->update_count) + if (core->update_count) { - mixbrush->_x1 = MIN (mixbrush->_x1, c_x); - mixbrush->_y1 = MIN (mixbrush->_y1, c_y); - mixbrush->_x2 = MAX (mixbrush->_x2, c_x + c_w - 1) ; - mixbrush->_y2 = MAX (mixbrush->_y2, c_y + c_h - 1) ; + core->_x1 = MIN (core->_x1, c_x); + core->_y1 = MIN (core->_y1, c_y); + core->_x2 = MAX (core->_x2, c_x + c_w - 1) ; + core->_y2 = MAX (core->_y2, c_y + c_h - 1) ; } else { - mixbrush->_x1 = c_x; - mixbrush->_x2 = c_x + c_w - 1; - mixbrush->_y1 = c_y; - mixbrush->_y2 = c_y + c_h - 1; + core->_x1 = c_x; + core->_x2 = c_x + c_w - 1; + core->_y1 = c_y; + core->_y2 = c_y + c_h - 1; } - if (++mixbrush->update_count >= (gint)n) + if (++core->update_count >= MIN ((gint)n, 15)) { - mixbrush->update_count = 0; - mixbrush->update_is_done = TRUE; + core->update_count = 0; + core->updated = TRUE; - update_drawable (mixbrush, drawable); + gimp_drawable_update (drawable, + core->_x1, + core->_y1, + core->_x2 - core->_x1 + 1, + core->_y2 - core->_y1 + 1); } else - mixbrush->update_is_done = FALSE; + core->updated = FALSE; } -#else - gimp_drawable_update (drawable, c_x, c_y, c_w, c_h); -#endif -} -#endif + else + gimp_drawable_update (drawable, c_x, c_y, c_w, c_h); -#ifdef LOWER_UPDATE -static inline void update_drawable (GimpMixbrush *mixbrush, - GimpDrawable *drawable) -{ - gimp_drawable_update (drawable, - mixbrush->_x1, - mixbrush->_y1, - mixbrush->_x2 - mixbrush->_x1 + 1, - mixbrush->_y2 - mixbrush->_y1 + 1); } #endif --- gimp-2.4.3-/app/paint/gimpmixbrush.h Fri Jan 11 06:06:46 2008 +++ gimp-painter--2.4.3/app/paint/gimpmixbrush.h Tue Jan 8 05:06:59 2008 @@ -63,16 +63,6 @@ GimpRGB error; GList *history; gboolean use_alt_alpha_op; -#ifdef LOWER_UPDATE - guint32 time; - guint32 last_time; - gint update_count; - gboolean update_is_done; - gint _x1; - gint _x2; - gint _y1; - gint _y2; -#endif }; struct _GimpMixbrushClass --- gimp-2.4.3-/app/paint/gimppaintbrush.c Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/paint/gimppaintbrush.c Thu Jan 10 07:15:20 2008 @@ -179,5 +179,6 @@ gimp_context_get_opacity (context), gimp_context_get_paint_mode (context), gimp_paint_options_get_brush_mode (paint_options), - paint_appl_mode); + paint_appl_mode, + paint_options->reduce_update_freq); } --- gimp-2.4.3-/app/paint/gimppaintcore.c Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/paint/gimppaintcore.c Fri Jan 11 05:38:52 2008 @@ -310,17 +310,63 @@ paint_options, paint_state, time)) { - if (paint_state == GIMP_PAINT_STATE_MOTION) + gint i; + guint interval; + + switch (paint_state) { + case GIMP_PAINT_STATE_INIT: + core->interval = INTERVAL_INITIAL_VALUE; + core->last_time = time; + core->interval_index = 0; + core->update_count = 0; + core->interval_buf_initialized = TRUE; + core->updated = FALSE; + core->_x1 = core->_x2 = core->cur_coords.x; + core->_y1 = core->_y2 = core->cur_coords.y; + break; + + case GIMP_PAINT_STATE_MOTION: /* Save coordinates for gimp_paint_core_interpolate() */ core->last_paint.x = core->cur_coords.x; core->last_paint.y = core->cur_coords.y; + + case GIMP_PAINT_STATE_FINISH: /* fall through */ + interval = time - core->last_time; + if (core->interval_buf_initialized) + { + for (i = 0; i < INTERVAL_BUFFER_LENGTH; i++) + core->interval_buf[i] = interval; + core->interval = interval; + core->interval_buf_initialized = FALSE; + } + else + { + core->interval_index = (core->interval_index + 1) % INTERVAL_BUFFER_LENGTH; + core->interval_buf[core->interval_index] = interval; + interval = 0; + for (i = 0; i < INTERVAL_BUFFER_LENGTH; i++) + interval += core->interval_buf[i]; + core->interval = interval / (gdouble)INTERVAL_BUFFER_LENGTH; + } + core->last_time = time; + break; + + default: + break; } core_class->paint (core, drawable, paint_options, paint_state, time); + if (paint_state == GIMP_PAINT_STATE_FINISH && ! core->updated) + gimp_drawable_update (drawable, + core->_x1, + core->_y1, + core->_x2 - core->_x1 + 1, + core->_y2 - core->_y1 + 1); + core_class->post_paint (core, drawable, paint_options, paint_state, time); @@ -798,7 +844,8 @@ gdouble paint_opacity, gdouble image_opacity, GimpLayerModeEffects paint_mode, - GimpPaintApplicationMode mode) + GimpPaintApplicationMode mode, + gboolean reduce_update_freq) { TileManager *alt = NULL; PixelRegion srcPR; @@ -992,11 +1039,49 @@ core->y2 = MAX (core->y2, core->canvas_buf->y + core->canvas_buf->height); /* Update the drawable */ - gimp_drawable_update (drawable, - core->canvas_buf->x, - core->canvas_buf->y, - core->canvas_buf->width, - core->canvas_buf->height); + if (reduce_update_freq) + { + gdouble n; + gdouble s = (core->canvas_buf->width + core->canvas_buf->height) / 2.0 / 30.0; + + n = MAX (1.6 - log10 (core->interval + 1.0), 0) * 1.5; + n *= faster_pow (s, 1.35); + + if (core->update_count) + { + core->_x1 = MIN (core->_x1, core->canvas_buf->x); + core->_y1 = MIN (core->_y1, core->canvas_buf->y); + core->_x2 = MAX (core->_x2, core->canvas_buf->x + core->canvas_buf->width - 1) ; + core->_y2 = MAX (core->_y2, core->canvas_buf->y + core->canvas_buf->height - 1) ; + } + else + { + core->_x1 = core->canvas_buf->x; + core->_x2 = core->canvas_buf->x + core->canvas_buf->width - 1; + core->_y1 = core->canvas_buf->y; + core->_y2 = core->canvas_buf->y + core->canvas_buf->height - 1; + } + + if (++core->update_count >= MIN ((gint)n, 15)) + { + core->update_count = 0; + core->updated = TRUE; + + gimp_drawable_update (drawable, + core->_x1, + core->_y1, + core->_x2 - core->_x1 + 1, + core->_y2 - core->_y1 + 1); + } + else + core->updated = FALSE; + } + else + gimp_drawable_update (drawable, + core->canvas_buf->x, + core->canvas_buf->y, + core->canvas_buf->width, + core->canvas_buf->height); } /* This works similarly to gimp_paint_core_paste. However, instead of @@ -1013,7 +1098,8 @@ GimpDrawable *drawable, gdouble paint_opacity, gdouble image_opacity, - GimpPaintApplicationMode mode) + GimpPaintApplicationMode mode, + gboolean reduce_update_freq) { PixelRegion srcPR; @@ -1022,7 +1108,8 @@ gimp_paint_core_paste (core, paint_maskPR, drawable, paint_opacity, image_opacity, GIMP_NORMAL_MODE, - mode); + mode, + reduce_update_freq); return; } @@ -1081,15 +1168,54 @@ /* Update the undo extents */ core->x1 = MIN (core->x1, core->canvas_buf->x); core->y1 = MIN (core->y1, core->canvas_buf->y); - core->x2 = MAX (core->x2, core->canvas_buf->x + core->canvas_buf->width) ; - core->y2 = MAX (core->y2, core->canvas_buf->y + core->canvas_buf->height) ; + core->x2 = MAX (core->x2, core->canvas_buf->x + core->canvas_buf->width); + core->y2 = MAX (core->y2, core->canvas_buf->y + core->canvas_buf->height); /* Update the drawable */ - gimp_drawable_update (drawable, - core->canvas_buf->x, - core->canvas_buf->y, - core->canvas_buf->width, - core->canvas_buf->height); + if (reduce_update_freq) + { + gdouble n; + gdouble s = (core->canvas_buf->width + core->canvas_buf->height) / 2.0 / 30.0; + + n = MAX (1.6 - log10 (core->interval + 1.0), 0) * 1.5; + n *= faster_pow (s, 1.35); + + if (core->update_count) + { + core->_x1 = MIN (core->_x1, core->canvas_buf->x); + core->_y1 = MIN (core->_y1, core->canvas_buf->y); + core->_x2 = MAX (core->_x2, core->canvas_buf->x + core->canvas_buf->width - 1) ; + core->_y2 = MAX (core->_y2, core->canvas_buf->y + core->canvas_buf->height - 1) ; + } + else + { + core->_x1 = core->canvas_buf->x; + core->_x2 = core->canvas_buf->x + core->canvas_buf->width - 1; + core->_y1 = core->canvas_buf->y; + core->_y2 = core->canvas_buf->y + core->canvas_buf->height - 1; + } + + if (++core->update_count >= MIN ((gint)n, 15)) + { + core->update_count = 0; + core->updated = TRUE; + + gimp_drawable_update (drawable, + core->_x1, + core->_y1, + core->_x2 - core->_x1 + 1, + core->_y2 - core->_y1 + 1); + } + else + core->updated = FALSE; + } + else + gimp_drawable_update (drawable, + core->canvas_buf->x, + core->canvas_buf->y, + core->canvas_buf->width, + core->canvas_buf->height); + } static void --- gimp-2.4.3-/app/paint/gimppaintcore.h Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/paint/gimppaintcore.h Fri Jan 11 03:57:50 2008 @@ -24,6 +24,10 @@ #include "core/gimpobject.h" +#define INTERVAL_INITIAL_VALUE 100 +#define INTERVAL_BUFFER_LENGTH 5 + + #define GIMP_TYPE_PAINT_CORE (gimp_paint_core_get_type ()) #define GIMP_PAINT_CORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_PAINT_CORE, GimpPaintCore)) #define GIMP_PAINT_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_PAINT_CORE, GimpPaintCoreClass)) @@ -66,6 +70,17 @@ TempBuf *orig_buf; /* the unmodified drawable pixels */ TempBuf *orig_proj_buf; /* the unmodified projection pixels */ TempBuf *canvas_buf; /* the buffer to paint pixels to */ + + /* to reduce update frequency */ + gdouble interval; + guint32 last_time; + guint32 interval_buf[INTERVAL_BUFFER_LENGTH]; + gint interval_index; + gint update_count; + gboolean interval_buf_initialized; + gboolean updated; + gint _x1, _y1; + gint _x2, _y2; }; struct _GimpPaintCoreClass @@ -159,13 +174,15 @@ gdouble paint_opacity, gdouble image_opacity, GimpLayerModeEffects paint_mode, - GimpPaintApplicationMode mode); + GimpPaintApplicationMode mode, + gboolean reduce_update_freq); void gimp_paint_core_replace (GimpPaintCore *core, PixelRegion *paint_maskPR, GimpDrawable *drawable, gdouble paint_opacity, gdouble image_opacity, - GimpPaintApplicationMode mode); + GimpPaintApplicationMode mode, + gboolean reduce_update_freq); void gimp_paint_core_validate_undo_tiles (GimpPaintCore *core, GimpDrawable *drawable, @@ -184,6 +201,22 @@ gint y, gint w, gint h); + + +/* Utility function(s) */ +static inline gdouble faster_pow (gdouble a, gdouble b) +{ + guchar n[8] = "\0\0\0\0\0\0\0\0"; + guint32 i; + + (*((gdouble *)n)) = a; + i = (*((guint64 *)n)) >> 32; + + i = (guint32)(b * ((gint32)i - 1072632447) + 1072632447); + (*((guint64 *)n)) = (guint64)i << 32; + + return (*((gdouble *)n)); +} #endif /* __GIMP_PAINT_CORE_H__ */ --- gimp-2.4.3-/app/paint/gimppaintoptions.c Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/paint/gimppaintoptions.c Thu Jan 10 02:50:26 2008 @@ -60,6 +60,8 @@ #define DEFAULT_GRADIENT_LENGTH 100.0 #define DEFAULT_GRADIENT_UNIT GIMP_UNIT_PIXEL +#define DEFAULT_REDUCE_UPDATE_FREQ FALSE + enum { @@ -92,7 +94,9 @@ PROP_PATTERN_VIEW_TYPE, PROP_PATTERN_VIEW_SIZE, PROP_GRADIENT_VIEW_TYPE, - PROP_GRADIENT_VIEW_SIZE + PROP_GRADIENT_VIEW_SIZE, + + PROP_REDUCE_UPDATE_FREQ }; @@ -257,6 +261,11 @@ GIMP_VIEWABLE_MAX_BUTTON_SIZE, GIMP_VIEW_SIZE_LARGE, GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_REDUCE_UPDATE_FREQ, + "reduce-update-frequency", NULL, + DEFAULT_REDUCE_UPDATE_FREQ, + GIMP_PARAM_STATIC_STRINGS); } static void @@ -398,6 +407,10 @@ options->gradient_view_size = g_value_get_int (value); break; + case PROP_REDUCE_UPDATE_FREQ: + options->reduce_update_freq = g_value_get_boolean (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -514,6 +527,10 @@ break; case PROP_GRADIENT_VIEW_SIZE: g_value_set_int (value, options->gradient_view_size); + break; + + case PROP_REDUCE_UPDATE_FREQ: + g_value_set_boolean (value, options->reduce_update_freq); break; default: --- gimp-2.4.3-/app/paint/gimppaintoptions.h Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/paint/gimppaintoptions.h Thu Jan 10 02:41:43 2008 @@ -104,6 +104,8 @@ GimpViewSize pattern_view_size; GimpViewType gradient_view_type; GimpViewSize gradient_view_size; + + gboolean reduce_update_freq; }; struct _GimpPaintOptionsClass --- gimp-2.4.3-/app/paint/gimpsmudge.c Tue Nov 20 18:31:16 2007 +++ gimp-painter--2.4.3/app/paint/gimpsmudge.c Thu Jan 10 07:23:35 2008 @@ -312,7 +312,8 @@ MIN (opacity, GIMP_OPACITY_OPAQUE), gimp_context_get_opacity (context), gimp_paint_options_get_brush_mode (paint_options), - GIMP_PAINT_INCREMENTAL); + GIMP_PAINT_INCREMENTAL, + paint_options->reduce_update_freq); } static void --- gimp-2.4.3-/app/tools/gimppaintoptions-gui.c Thu Jan 3 20:16:18 2008 +++ gimp-painter--2.4.3/app/tools/gimppaintoptions-gui.c Thu Jan 10 03:00:10 2008 @@ -212,6 +212,11 @@ gtk_widget_show (frame); } + button = gimp_prop_check_button_new (config, "reduce-update-frequency", + _("Reduce update frequency")); + gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + return vbox; }