--- gimp-2.4.2_gpen_mixbrush/app/paint/gimpmixbrush.c.orig Mon Dec 3 05:31:38 2007 +++ gimp-2.4.2_gpen_mixbrush/app/paint/gimpmixbrush.c Thu Dec 6 12:11:19 2007 @@ -86,13 +86,14 @@ static void coords_history_free (CoordsHistory *history, gpointer dummy); -static inline void get_canvas_color (GimpImage *image, - GimpDrawable *drawable, - GimpPaintCore *paint_core, - CoordsHistory *history, - guint sample_size_limit, - gboolean merged, - GimpRGB *color_uchar); +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, @@ -167,6 +168,7 @@ gimp_mixbrush_init (GimpMixbrush *mixbrush) { mixbrush->history = NULL; + mixbrush->mask = NULL; } static void @@ -178,6 +180,8 @@ g_list_foreach (mixbrush->history, (GFunc)coords_history_free, NULL); g_list_free (mixbrush->history); } + if (mixbrush->mask) + temp_buf_free (mixbrush->mask); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -229,6 +233,28 @@ mixbrush->use_alt_alpha_op = (mixbrush_options->use_alt_composite_op && gimp_drawable_has_alpha (drawable)); + /* Init the pressure params */ + calc_pressure_params (&mixbrush->pr_main_density, + mixbrush_options->main_color_density_pressure_in1, + mixbrush_options->main_color_density_pressure_in2, + mixbrush_options->main_color_density_pressure_out1, + mixbrush_options->main_color_density_pressure_out2); + calc_pressure_params (&mixbrush->pr_main_rate, + mixbrush_options->main_color_pressure_in1, + mixbrush_options->main_color_pressure_in2, + mixbrush_options->main_color_pressure_out1, + mixbrush_options->main_color_pressure_out2); + calc_pressure_params (&mixbrush->pr_canvas_density, + mixbrush_options->canvas_color_density_pressure_in1, + mixbrush_options->canvas_color_density_pressure_in2, + mixbrush_options->canvas_color_density_pressure_out1, + mixbrush_options->canvas_color_density_pressure_out2); + calc_pressure_params (&mixbrush->pr_canvas_rate, + mixbrush_options->canvas_color_pressure_in1, + mixbrush_options->canvas_color_pressure_in2, + mixbrush_options->canvas_color_pressure_out1, + mixbrush_options->canvas_color_pressure_out2); + /* Get the index of the alpha component */ switch (gimp_drawable_type_without_alpha (drawable)) { @@ -263,8 +289,19 @@ mixbrush->paint_color.a = 1.0; - /* Reset the last color */ - mixbrush->last_color.a = 0.0; + /* Setup the last color */ + if (mixbrush->use_alt_alpha_op) + { + get_canvas_color (image, drawable, paint_core, + (gint) paint_core->cur_coords.x, (gint) paint_core->cur_coords.y, + mixbrush_options->sample_size_limit, + mixbrush_options->merged, + &mixbrush->last_color); + mixbrush->last_color.a *= mixbrush_options->canvas_color_density * + calc_pressure (paint_core->cur_coords.pressure, &mixbrush->pr_canvas_density); + } + else + mixbrush->last_color.a = 0.0; /* Setup the hidden color */ mixbrush->hidden_color.a = 0.0; @@ -292,27 +329,18 @@ } } - calc_pressure_params (&mixbrush->pr_main_density, - mixbrush_options->main_color_density_pressure_in1, - mixbrush_options->main_color_density_pressure_in2, - mixbrush_options->main_color_density_pressure_out1, - mixbrush_options->main_color_density_pressure_out2); - calc_pressure_params (&mixbrush->pr_main_rate, - mixbrush_options->main_color_pressure_in1, - mixbrush_options->main_color_pressure_in2, - mixbrush_options->main_color_pressure_out1, - mixbrush_options->main_color_pressure_out2); - calc_pressure_params (&mixbrush->pr_canvas_density, - mixbrush_options->canvas_color_density_pressure_in1, - mixbrush_options->canvas_color_density_pressure_in2, - mixbrush_options->canvas_color_density_pressure_out1, - mixbrush_options->canvas_color_density_pressure_out2); - calc_pressure_params (&mixbrush->pr_canvas_rate, - mixbrush_options->canvas_color_pressure_in1, - mixbrush_options->canvas_color_pressure_in2, - mixbrush_options->canvas_color_pressure_out1, - mixbrush_options->canvas_color_pressure_out2); + /* Init the mask buffer */ + if (mixbrush_options->use_alt_composite_op) + { + gint w, h; + const guchar opaque_value = OPAQUE_OPACITY; + + gimp_brush_scale_size (GIMP_BRUSH_CORE (paint_core)->brush, + paint_options->brush_scale, &w, &h); + mixbrush->mask = temp_buf_new (w, h, 1, 0, 0, &opaque_value); + } + /* Reset the rounding error */ gimp_rgba_set (&mixbrush->error, 0, 0, 0, 0); } @@ -334,6 +362,12 @@ while (mixbrush->history) gimp_mixbrush_paste_canvas (paint_core, drawable, paint_options); + + if (mixbrush->mask) + { + temp_buf_free (mixbrush->mask); + mixbrush->mask = NULL; + } } static void @@ -359,7 +393,8 @@ history->pixel_dist = paint_core->pixel_dist; /* Pick up the raw canvas color */ - get_canvas_color (image, drawable, paint_core, history, + get_canvas_color (image, drawable, paint_core, + (gint) history->coords.x, (gint) history->coords.y, mixbrush_options->sample_size_limit, mixbrush_options->merged, &history->color); @@ -438,7 +473,8 @@ &main_color, FALSE); /* Pick up the covered canvas color */ - get_canvas_color (image, drawable, paint_core, history, + get_canvas_color (image, drawable, paint_core, + (gint) paint_core->cur_coords.x, (gint) paint_core->cur_coords.y, mixbrush_options->sample_size_limit, mixbrush_options->merged, &canvas_color); @@ -456,9 +492,12 @@ composite_rgba (&canvas_color, canvas_op, &history->color, 1.0, &canvas_color, FALSE);*/ +//g_printerr ("m:%f, %f, %f %f\n",canvas_color.r,canvas_color.g,canvas_color.b,canvas_color.a); +//g_printerr ("l:%f, %f, %f %f\n",history->color.r,history->color.g,history->color.b,history->color.a); blend_rgba (&canvas_color, canvas_op, &history->color, 1.0 - canvas_op, - &canvas_color, FALSE); + &canvas_color, TRUE/*FALSE*/); +//g_printerr ("r:%f, %f, %f %f\n\n",canvas_color.r,canvas_color.g,canvas_color.b,canvas_color.a); /* Correct the rounding error came from the last process */ gimp_rgba_add (&canvas_color, &mixbrush->error); @@ -593,21 +632,22 @@ g_free (history); } -static inline void +static inline gboolean get_canvas_color (GimpImage *image, GimpDrawable *drawable, GimpPaintCore *paint_core, - CoordsHistory *history, + gint x, + gint y, guint sample_size_limit, gboolean merged, - GimpRGB *color_uchar) + GimpRGB *color) { GimpPickable *pickable; GimpItem *item = GIMP_ITEM (drawable); gint offset_x, offset_y; - offset_x = CLAMP ((gint) history->coords.x, 0, gimp_item_width (item) - 1); - offset_y = CLAMP ((gint) history->coords.y, 0, gimp_item_height (item) - 1); + offset_x = CLAMP (x, 0, gimp_item_width (item) - 1); + offset_y = CLAMP (y, 0, gimp_item_height (item) - 1); if (merged && GIMP_IS_LAYER (drawable)) { @@ -623,11 +663,11 @@ else pickable = GIMP_PICKABLE (drawable); - pick_up_avarage_color (pickable, - GIMP_BRUSH_CORE (paint_core), - offset_x, offset_y, - sample_size_limit, - color_uchar); + return pick_up_avarage_color (pickable, + GIMP_BRUSH_CORE (paint_core), + offset_x, offset_y, + sample_size_limit, + color); } static inline gboolean @@ -747,8 +787,14 @@ if (use_alt_alpha_op) { - gdouble factor = op1 / (op1 + op2); - rgb1.a = color1->a * factor + color2->a * (1.0 - factor); + op1 = pow (op1, 1.35); /* workaround against opacity inflation */ + rgb1.a = op1 + op2; + + if (rgb1.a != 0) + { + rgb1.a = op1 / rgb1.a; /* factor */ + rgb1.a = color1->a * rgb1.a + color2->a * (1.0 - rgb1.a); + } } #if 0 @@ -801,9 +847,13 @@ if (use_alt_alpha_op) { - gdouble factor = op1 / (op1 + op2); - _result.a = color1->a * factor + color2->a * (1.0 - factor); - _result.a = MAX (_result.a, color2->a); + _result.a = op1 + op2; + if (_result.a != 0) + { + gdouble factor = op1 / _result.a; + _result.a = color1->a * factor + color2->a * (1.0 - factor); + //_result.a = MAX (_result.a, color2->a); + } } #if 0 { @@ -894,15 +944,16 @@ 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; - TempBuf *opaque_mask = NULL; + //TempBuf *opaque_mask = NULL; PixelRegion srcPR, destPR, maskPR; gpointer iter; gint x, y, off_x, off_y; - const guchar opaque_value = OPAQUE_OPACITY; + //const guchar opaque_value = OPAQUE_OPACITY; - if (!brush_mask || !canvas_buf) + if (!brush_mask || !canvas_buf || opacity == 0.0) return; x = (gint) floor (core->cur_coords.x) - (brush_mask->width >> 1); @@ -948,7 +999,11 @@ gdouble op, paint_color_op, canvas_color_op; gdouble factor1, factor2; - switch (destPR.bytes) + 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; @@ -974,7 +1029,6 @@ return; } - op = opacity * (_mask_data[0] / 255.0); paint_color_op = paint_color->a * op; canvas_color_op = (1.0 - paint_color_op) * src_color.a; @@ -982,7 +1036,7 @@ factor2 = 1.0 - factor1; dest_color.r = paint_color->r * factor1 + src_color.r * factor2; - if (destPR.bytes > 2) + 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; @@ -1013,15 +1067,19 @@ } #endif - switch (destPR.bytes) + switch (srcPR.bytes) { case 1: - _dest_data[0] = _dest_data[1] = _dest_data[2] = MIN (dest_color.r * 255.0 + 0.5, 255); - _dest_data[3] = 255; + /*_dest_data[0] = _dest_data[1] = _dest_data[2] = MIN (dest_color.r * 255.0 + 0.5, 255); + _dest_data[3] = 255;*/ + _dest_data[0] = MIN (dest_color.r * 255.0 + 0.5, 255); + _dest_data[1] = 255; break; case 2: - _dest_data[0] = _dest_data[1] = _dest_data[2] = MIN (dest_color.r * 255.0 + 0.5, 255); - _dest_data[3] = MIN (dest_color.a * 255.0 + 0.5, 255); + /*_dest_data[0] = _dest_data[1] = _dest_data[2] = MIN (dest_color.r * 255.0 + 0.5, 255); + _dest_data[3] = MIN (dest_color.a * 255.0 + 0.5, 255);*/ + _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); @@ -1036,6 +1094,7 @@ _dest_data[3] = MIN (dest_color.a * 255.0 + 0.5, 255); } + label1: _dest_data += destPR.bytes; _mask_data++; } @@ -1058,13 +1117,13 @@ } #endif - opaque_mask = temp_buf_new (brush_mask->width, brush_mask->height, 1, - canvas_buf->x, canvas_buf->y, - &opaque_value); - pixel_region_init_temp_buf (&maskPR, opaque_mask, + //mixbrush->mask->x = canvas_buf->x; + //mixbrush->mask->y = canvas_buf->y; + + pixel_region_init_temp_buf (&maskPR, mixbrush->mask, off_x, off_y, - brush_mask->width, brush_mask->height); + mixbrush->mask->width, mixbrush->mask->height); gimp_paint_core_replace (core, &maskPR, drawable, 1.0, 1.0, GIMP_PAINT_INCREMENTAL); - temp_buf_free (opaque_mask); + //temp_buf_free (opaque_mask); } --- gimp-2.4.2_gpen_mixbrush/app/paint/gimpmixbrush.h.orig Sun Dec 2 05:40:20 2007 +++ gimp-2.4.2_gpen_mixbrush/app/paint/gimpmixbrush.h Thu Dec 6 01:32:25 2007 @@ -51,6 +51,7 @@ GimpDrawable *drawable; GimpPaintOptions *paint_options; + TempBuf *mask; PressureParams pr_main_density; PressureParams pr_main_rate; PressureParams pr_canvas_density;