--- gimp-painter--2.4.3/app/paint/gimpmixbrush.c.orig Sat Dec 22 15:01:16 2007 +++ gimp-painter--2.4.3/app/paint/gimpmixbrush.c Wed Dec 26 05:33:37 2007 @@ -17,6 +17,7 @@ */ /*#define CHECK_TIME*/ +#define LOWER_UPDATE #include "config.h" #include @@ -60,28 +61,40 @@ gdouble pixel_dist; GimpRGB color; gdouble opacity; + guint32 time; } CoordsHistory; static void gimp_mixbrush_finalize (GObject *object); -static void gimp_mixbrush_start (GimpPaintCore *paint_core, +static void gimp_mixbrush_paint (GimpPaintCore *paint_core, GimpDrawable *drawable, - GimpPaintOptions *paint_options); + GimpPaintOptions *paint_options, + GimpPaintState paint_state, + guint32 time); -static void gimp_mixbrush_finish (GimpPaintCore *paint_core, +#ifdef LOWER_UPDATE +static void gimp_mixbrush_motion (GimpPaintCore *paint_core, GimpDrawable *drawable, - GimpPaintOptions *paint_options); - -static void gimp_mixbrush_paint (GimpPaintCore *paint_core, + GimpPaintOptions *paint_options, + guint32 time); +static void gimp_mixbrush_start (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options, - GimpPaintState paint_state, guint32 time); +#else +static void gimp_mixbrush_start (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options); static void gimp_mixbrush_motion (GimpPaintCore *paint_core, GimpDrawable *drawable, GimpPaintOptions *paint_options); +#endif + +static void gimp_mixbrush_finish (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options); static void gimp_mixbrush_paste_canvas (GimpPaintCore *paint_core, @@ -140,6 +153,10 @@ gdouble opacity); #endif +#ifdef LOWER_UPDATE +static inline void update_drawable (GimpMixbrush *mixbrush, + GimpDrawable *drawable); +#endif G_DEFINE_TYPE (GimpMixbrush, gimp_mixbrush, GIMP_TYPE_PAINTBRUSH) @@ -216,7 +233,11 @@ 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); @@ -226,14 +247,22 @@ #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: @@ -251,10 +280,18 @@ } } +#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); @@ -364,6 +401,15 @@ /* 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 @@ -378,13 +424,16 @@ g_list_foreach (mixbrush->history, (GFunc)coords_history_free, NULL); g_list_free (mixbrush->history); mixbrush->history = NULL; - - return; } 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); @@ -392,10 +441,18 @@ } } +#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); @@ -413,6 +470,9 @@ 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, @@ -422,6 +482,7 @@ &history->color); history->opacity = opacity; + mixbrush->history = g_list_append (mixbrush->history, history); /* Process a history item */ @@ -453,6 +514,12 @@ 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) { image = gimp_item_get_image (GIMP_ITEM (drawable)); @@ -960,7 +1027,7 @@ return CLAMP (value * params->out_factor + params->out_min, 0.0, 1.0); } -#if 1 + #ifndef GIMP_MIXBRUSH_COMPOSITE void paste_canvas (GimpPaintCore *core, @@ -970,6 +1037,7 @@ { TempBuf *brush_mask = gimp_brush_core_get_brush_mask (GIMP_BRUSH_CORE (core), GIMP_BRUSH_SOFT); TempBuf *canvas_buf = core->canvas_buf; + gint c_x = canvas_buf->x, c_y = canvas_buf->y, c_w = canvas_buf->width, c_h = canvas_buf->height; PixelRegion srcPR, maskPR; gint x, y, off_x, off_y; @@ -978,10 +1046,7 @@ /* set undo blocks */ gimp_paint_core_validate_undo_tiles (core, drawable, - canvas_buf->x, - canvas_buf->y, - canvas_buf->width, - canvas_buf->height); + c_x, c_y, c_w, c_h); /* init the pixel regions */ x = (gint) floor (core->cur_coords.x) - (brush_mask->width >> 1); @@ -991,8 +1056,7 @@ off_y = (y < 0) ? -y : 0; pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable), - canvas_buf->x, canvas_buf->y, - canvas_buf->width, canvas_buf->height, + c_x, c_y, c_w, c_h, TRUE); pixel_region_init_temp_buf (&maskPR, brush_mask, @@ -1047,7 +1111,7 @@ gdouble factor1, factor2; gdouble component; #if 0 - if (j == canvas_buf->width / 2 && i == canvas_buf->height / 2) + if (j == c_w / 2 && i == c_h / 2) { g_printerr ( "\nPos : %d %d\n", j, i); g_printerr ( "Paint color: %f %f %f %f\n", _paint_color.r, _paint_color.g, _paint_color.b, paint_color->a); @@ -1104,7 +1168,7 @@ } } #if 0 - if (j == canvas_buf->width / 2 && i == canvas_buf->height / 2) + if (j == c_w / 2 && i == c_h / 2) { g_printerr ( "Result color: %d %d %d %d\n", _src_data[0], _src_data[1], _src_data[2], _src_data[3]); } @@ -1152,211 +1216,60 @@ #endif /* Update the undo extents */ - core->x1 = MIN (core->x1, canvas_buf->x); - core->y1 = MIN (core->y1, canvas_buf->y); - core->x2 = MAX (core->x2, canvas_buf->x + canvas_buf->width) ; - core->y2 = MAX (core->y2, canvas_buf->y + canvas_buf->height) ; + core->x1 = MIN (core->x1, c_x); + core->y1 = MIN (core->y1, c_y); + core->x2 = MAX (core->x2, c_x + c_w) ; + core->y2 = MAX (core->y2, c_y + c_h) ; /* Update the drawable */ - gimp_drawable_update (drawable, - canvas_buf->x, - canvas_buf->y, - canvas_buf->width, - canvas_buf->height); -} -#endif -#else -void -paste_canvas (GimpPaintCore *core, - GimpDrawable *drawable, - GimpRGB *paint_color, - gdouble opacity) -{ - GimpMixbrush *mixbrush = GIMP_MIXBRUSH (core); - TempBuf *brush_mask = gimp_brush_core_get_brush_mask (GIMP_BRUSH_CORE (core), GIMP_BRUSH_SOFT); - TempBuf *canvas_buf = core->canvas_buf; - PixelRegion srcPR, destPR, maskPR; - gpointer iter; - gint x, y, off_x, off_y; - const guchar opaque_value = OPAQUE_OPACITY; - - if (!brush_mask || !canvas_buf || opacity == 0.0) - return; - - x = (gint) floor (core->cur_coords.x) - (brush_mask->width >> 1); - y = (gint) floor (core->cur_coords.y) - (brush_mask->height >> 1); - - off_x = (x < 0) ? -x : 0; - off_y = (y < 0) ? -y : 0; - - pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable), - canvas_buf->x, canvas_buf->y, - canvas_buf->width, canvas_buf->height, - FALSE); - pixel_region_init_temp_buf (&destPR, canvas_buf, - 0, 0, - canvas_buf->width, canvas_buf->height); - - if (!gimp_drawable_has_alpha (drawable)) - add_alpha_region (&srcPR, &destPR); - else - copy_region (&srcPR, &destPR); - - pixel_region_init_temp_buf (&destPR, canvas_buf, - 0, 0, - canvas_buf->width, canvas_buf->height); - pixel_region_init_temp_buf (&maskPR, brush_mask, - off_x, off_y, - brush_mask->width, brush_mask->height); - - for (iter = pixel_regions_register (2, &destPR, &maskPR); iter != NULL; iter = pixel_regions_process (iter)) - { - guchar *dest_data = destPR.data; - guchar *mask_data = maskPR.data; - gint i, j; +#ifdef LOWER_UPDATE + { + GimpMixbrush *mixbrush = GIMP_MIXBRUSH (core); + gfloat n; - for (i = 0; i < destPR.h; i++) - { - guchar *_dest_data = dest_data; - guchar *_mask_data = mask_data; + 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); - for (j = 0; j < destPR.w; j++) - { - GimpRGB src_color, dest_color; - gdouble op, paint_color_op, canvas_color_op; - gdouble factor1, factor2; - - op = opacity * (_mask_data[0] / 255.0); - if (!op) - goto label1; - - switch (srcPR.bytes) - { - case 1: - src_color.r = src_color.g = src_color.b = _dest_data[0] / 255.0; - src_color.a = 1.0; - break; - case 2: - src_color.r = src_color.g = src_color.b = _dest_data[0] / 255.0; - src_color.a = _dest_data[1] / 255.0; - break; - case 3: - src_color.r = _dest_data[0] / 255.0; - src_color.g = _dest_data[1] / 255.0; - src_color.b = _dest_data[2] / 255.0; - src_color.a = 1.0; - break; - case 4: - src_color.r = _dest_data[0] / 255.0; - src_color.g = _dest_data[1] / 255.0; - src_color.b = _dest_data[2] / 255.0; - src_color.a = _dest_data[3] / 255.0; - break; - default: - return; - } - - paint_color_op = paint_color->a * op; - canvas_color_op = (1.0 - paint_color_op) * src_color.a; - - factor1 = paint_color_op / (paint_color_op + canvas_color_op); - factor2 = 1.0 - factor1; - - dest_color.r = paint_color->r * factor1 + src_color.r * factor2; - if (srcPR.bytes > 2) - { - dest_color.g = paint_color->g * factor1 + src_color.g * factor2; - dest_color.b = paint_color->b * factor1 + src_color.b * factor2; - } - if (gimp_drawable_has_alpha (drawable)) - /*dest_color.a = paint_color->a + ((src_color.a - paint_color->a) * (1.0 - op));*/ - { - /* workaround against insufficiency of opacity */ - if (paint_color->a > src_color.a) - op = pow (opacity, 1.0 / 1.5) * (_mask_data[0] / 255.0); - dest_color.a = paint_color->a * op + src_color.a * (1.0 - op); - } - else - dest_color.a = 1.0; + if (mixbrush->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) ; + } + else + { + mixbrush->_x1 = c_x; + mixbrush->_x2 = c_x + c_w - 1; + mixbrush->_y1 = c_y; + mixbrush->_y2 = c_y + c_h - 1; + } -#if 0 - if (i == destPR.h / 2 && j == destPR.w / 2) - { - g_printerr ("original canvas color:\n %d %d %d %d / %f %f %f %f\n", - _dest_data[0], _dest_data[1], _dest_data[2], _dest_data[3], - src_color.r, src_color.g, src_color.b, src_color.a); - g_printerr ("paint color:\n %f %f %f %f\n", - paint_color->r, paint_color->g, paint_color->b, paint_color->a); - g_printerr ("op:\n %f / %f / %f / %f\n", opacity, op, paint_color_op, canvas_color_op); - g_printerr ("factor:\n %f / %f\n", factor1, factor2); - g_printerr ("result color:\n %f %f %f %f\n\n", - dest_color.r, dest_color.g, dest_color.b, dest_color.a); - } -#endif - - switch (srcPR.bytes) - { - case 1: - _dest_data[0] = MIN (dest_color.r * 255.0 + 0.5, 255); - _dest_data[1] = 255; - break; - case 2: - _dest_data[0] = MIN (dest_color.r * 255.0 + 0.5, 255); - _dest_data[1] = MIN (dest_color.a * 255.0 + 0.5, 255); - break; - case 3: - _dest_data[0] = MIN (dest_color.r * 255.0 + 0.5, 255); - _dest_data[1] = MIN (dest_color.g * 255.0 + 0.5, 255); - _dest_data[2] = MIN (dest_color.b * 255.0 + 0.5, 255); - _dest_data[3] = 255; - break; - case 4: - _dest_data[0] = MIN (dest_color.r * 255.0 + 0.5, 255); - _dest_data[1] = MIN (dest_color.g * 255.0 + 0.5, 255); - _dest_data[2] = MIN (dest_color.b * 255.0 + 0.5, 255); - _dest_data[3] = MIN (dest_color.a * 255.0 + 0.5, 255); - } - - label1: - _dest_data += destPR.bytes; - _mask_data++; - } - dest_data += destPR.rowstride; - mask_data += maskPR.rowstride; - } - } /* end of iteration */ -#if 0 - { - static int c = 0; - if (++c == 50) + if (++mixbrush->update_count >= (gint)n) { - g_file_set_contents ("r:\\out_canvas_buf_00.raw", temp_buf_data (canvas_buf), - canvas_buf->width * canvas_buf->height * canvas_buf->bytes, - NULL); - g_file_set_contents ("r:\\out_brush_mask_00.raw", temp_buf_data (brush_mask), - brush_mask->width * brush_mask->height * brush_mask->bytes, - NULL); + mixbrush->update_count = 0; + mixbrush->update_is_done = TRUE; + + update_drawable (mixbrush, drawable); } + else + mixbrush->update_is_done = FALSE; } +#else + gimp_drawable_update (drawable, c_x, c_y, c_w, c_h); +#endif +} #endif - if (! mixbrush->mask) - mixbrush->mask = temp_buf_new (canvas_buf->width, - canvas_buf->height, - 1, 0, 0, &opaque_value); - else if (mixbrush->mask->width < canvas_buf->width || - mixbrush->mask->height < canvas_buf->height) - { - temp_buf_free (mixbrush->mask); - mixbrush->mask = temp_buf_new (canvas_buf->width, - canvas_buf->height, - 1, 0, 0, &opaque_value); - } - - pixel_region_init_temp_buf (&maskPR, mixbrush->mask, - 0, 0,/*off_x, off_y,*/ - canvas_buf->width, canvas_buf->height); - - gimp_paint_core_replace (core, &maskPR, drawable, 1.0, 1.0, GIMP_PAINT_INCREMENTAL); +#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-painter--2.4.3/app/paint/gimpmixbrush.h.orig Mon Dec 17 20:20:00 2007 +++ gimp-painter--2.4.3/app/paint/gimpmixbrush.h Sun Dec 23 22:03:48 2007 @@ -63,6 +63,16 @@ 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