--- gimp-painter--2.6.6.orig/app/dialogs/about-dialog.c 2009-06-25 03:46:22 +0900 +++ gimp-painter--2.6.6/app/dialogs/about-dialog.c 2009-07-15 15:52:17 +0900 @@ -609,7 +609,7 @@ gtk_widget_show (label); #endif - label = gtk_label_new (_("gimp-painter- (release 20090625)")); + label = gtk_label_new (_("gimp-painter- (release 20090715)")); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_box_reorder_child (GTK_BOX (vbox), label, 2); gtk_widget_show (label); --- gimp-painter--2.6.6.orig/app/paint/gimpmixbrush.c 2009-03-18 18:41:56 +0900 +++ gimp-painter--2.6.6/app/paint/gimpmixbrush.c 2009-07-15 15:05:55 +0900 @@ -189,6 +189,16 @@ PixelRegion *srcPR, PixelRegion *maskPR); +static void composite_dab_selection (CompositeDabParam *params, + PixelRegion *srcPR, + PixelRegion *maskPR, + PixelRegion *selPR); + +static void composite_textured_dab_selection (CompositeDabParam *params, + PixelRegion *srcPR, + PixelRegion *maskPR, + PixelRegion *selPR); + #endif @@ -1059,11 +1069,18 @@ { CompositeDabParam params; + GimpChannel *selection; TempBuf *brush_mask; TempBuf *canvas_buf; gint c_x, c_y, c_w, c_h; - PixelRegion srcPR, maskPR; - gint off_x, off_y; + PixelRegion srcPR, maskPR, selPR; + gint off_x = 0; + gint off_y = 0; + + selection = gimp_image_get_mask (gimp_item_get_image (GIMP_ITEM (drawable))); + /* don't apply the mask to itself and don't apply an empty mask */ + if (GIMP_DRAWABLE (selection) == drawable || gimp_channel_is_empty (selection)) + selection = NULL; brush_mask = gimp_brush_core_get_brush_mask (GIMP_BRUSH_CORE (core), hardness_mode, @@ -1071,11 +1088,16 @@ canvas_buf = core->canvas_buf; if (!brush_mask || - !canvas_buf || - opacity == 0.0 || - (texture && !fringe && grain <= -1.0)) + !canvas_buf || + opacity == 0.0 || + (texture && !fringe && grain <= -1.0)) return; + params.x = (gint) floor (core->cur_coords.x) - (brush_mask->width >> 1); + params.y = (gint) floor (core->cur_coords.y) - (brush_mask->height >> 1); + + gimp_item_offsets (GIMP_ITEM (drawable), ¶ms.drawable_x, ¶ms.drawable_y); + c_x = canvas_buf->x; c_y = canvas_buf->y; c_w = canvas_buf->width; @@ -1084,13 +1106,40 @@ /* set undo blocks */ gimp_paint_core_validate_undo_tiles (core, drawable, c_x, c_y, c_w, c_h); + if (selection) + { + gint x2, y2; + gint sel_x, sel_y, sel_x2, sel_y2; - /* init the pixel regions */ - params.x = (gint) floor (core->cur_coords.x) - (brush_mask->width >> 1); - params.y = (gint) floor (core->cur_coords.y) - (brush_mask->height >> 1); + gimp_item_offsets (GIMP_ITEM (selection), &sel_x, &sel_y); + + sel_x -= params.drawable_x; + sel_y -= params.drawable_y; + sel_x2 = sel_x + gimp_item_width (GIMP_ITEM (selection)); + sel_y2 = sel_y + gimp_item_height (GIMP_ITEM (selection)); + + x2 = c_x + c_w; + y2 = c_y + c_h; + + if (c_x < sel_x) + { + off_x = sel_x - c_x; + c_x = sel_x; + } + if (c_y < sel_y) + { + off_y = sel_y - c_y; + c_y = sel_y; + } + c_w = MIN (x2, sel_x2) - c_x; + c_h = MIN (y2, sel_y2) - c_y; + } - off_x = (params.x < 0) ? -params.x : 0; - off_y = (params.y < 0) ? -params.y : 0; + /* init the pixel regions */ + if (!off_x && (params.x < 0)) + off_x = -params.x; + if (!off_y && (params.y < 0)) + off_y = -params.y; pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable), c_x, c_y, c_w, c_h, @@ -1119,8 +1168,6 @@ if (texture) { - gimp_item_offsets (GIMP_ITEM (drawable), ¶ms.drawable_x, ¶ms.drawable_y); - params.grain = grain; params.fringe = fringe; params.fringe_contrast = fringe_contrast; @@ -1133,14 +1180,41 @@ params.texture_width = texture->mask->width; params.texture_height = texture->mask->height; params.texture_stride = params.texture_width * params.texture_bytes; -//g_printerr("<---"); - pixel_regions_process_parallel ((PixelProcessorFunc) composite_textured_dab, - ¶ms, 2, &srcPR, &maskPR); -//g_printerr("--->\n"); + + if (selection) + { + pixel_region_init (&selPR, + gimp_drawable_get_tiles (GIMP_DRAWABLE (selection)), + c_x + params.drawable_x, + c_y + params.drawable_y, + c_w, c_h, + FALSE); + + pixel_regions_process_parallel ((PixelProcessorFunc) composite_textured_dab_selection, + ¶ms, 3, &srcPR, &maskPR, &selPR); + } + else + pixel_regions_process_parallel ((PixelProcessorFunc) composite_textured_dab, + ¶ms, 2, &srcPR, &maskPR); } else - pixel_regions_process_parallel ((PixelProcessorFunc) composite_dab, - ¶ms, 2, &srcPR, &maskPR); + { + if (selection) + { + pixel_region_init (&selPR, + gimp_drawable_get_tiles (GIMP_DRAWABLE (selection)), + c_x + params.drawable_x, + c_y + params.drawable_y, + c_w, c_h, + FALSE); + + pixel_regions_process_parallel ((PixelProcessorFunc) composite_dab_selection, + ¶ms, 3, &srcPR, &maskPR, &selPR); + } + else + pixel_regions_process_parallel ((PixelProcessorFunc) composite_dab, + ¶ms, 2, &srcPR, &maskPR); + } #if 0 { @@ -1470,4 +1544,233 @@ } //g_printerr(">>"); } /* end of iteration */ + +/* compositing with selection */ +static void +composite_dab_selection (CompositeDabParam *params, + PixelRegion *srcPR, + PixelRegion *maskPR, + PixelRegion *selPR) +{ + gint width, height, bytes; + gint src_bytes; + gint src_stride, mask_stride, sel_stride; + guchar *src_data, *_src_data; + guchar *mask_data, *_mask_data; + guchar *sel_data, *_sel_data; + + gint i, j; + + src_data = srcPR->data; + src_bytes = srcPR->bytes; + mask_data = maskPR->data; + sel_data = selPR->data; + width = maskPR->w; + height = maskPR->h; + bytes = maskPR->bytes; + src_stride = srcPR->rowstride; + mask_stride = maskPR->rowstride; + sel_stride = selPR->rowstride; + + for (i = 0; i < height; i++) + { + _src_data = src_data; + _mask_data = mask_data; + _sel_data = sel_data; + + for (j = 0; j < width; j++) + { + gdouble op, mask_op, paint_color_op, canvas_color_op, src_op; + gdouble factor1, factor2; + gdouble component; + + if (*_mask_data && *_sel_data) + { + mask_op = *_mask_data * *_sel_data / 65025.0; + + if (params->has_alpha && params->active_components[src_bytes - 1]) + { + gfloat n; + guint32 _n; + + src_op = _src_data[src_bytes - 1] / 255.0; + + /* workaround against insufficiency of opacity */ + /*if (params->paint_color->a > src_op) + op = pow (params->opacity, 1.0 / 1.5) * mask_op;*/ + n = params->paint_color.a - src_op; + _n = (*(guint32 *) &n) >> 31; + op = (params->opacity * _n + params->adjusted_opacity * (1 - _n)) * mask_op; + + component = (params->paint_color.a * op + src_op * (1.0 - op)) * 255.0/* + error.a*/; + _src_data[src_bytes - 1] = component + .5; + /*_error.a += component - _src_data[src_bytes - 1];*/ + } + else + src_op = 1.0; + + op = params->opacity * mask_op; + paint_color_op = params->paint_color.a * op; + + if (paint_color_op > 0.0) + { + canvas_color_op = (1.0 - paint_color_op) * src_op; + + factor1 = paint_color_op / (paint_color_op + canvas_color_op); + factor2 = 1.0 - factor1; + + component = params->_paint_color.r * factor1 + _src_data[0] * factor2/* + error.r*/; + _src_data[0] = component + .5; + /*_error.r += component - _src_data[0];*/ + if (params->is_rgb) + { + component = params->_paint_color.g * factor1 + _src_data[1] * factor2/* + error.g*/; + _src_data[1] = component + .5; + /*_error.g += component - _src_data[1];*/ + + component = params->_paint_color.b * factor1 + _src_data[2] * factor2/* + error.b*/; + _src_data[2] = component + .5; + /*_error.b += component - _src_data[2];*/ + } + } + } + _src_data += src_bytes; + _mask_data++; + _sel_data++; + } + src_data += src_stride; + mask_data += mask_stride; + sel_data += sel_stride; + } +} /* end of iteration */ + +static void +composite_textured_dab_selection (CompositeDabParam *params, + PixelRegion *srcPR, + PixelRegion *maskPR, + PixelRegion *selPR) +{ + gint width, height, bytes; + gint src_bytes; + gint src_stride, mask_stride, sel_stride; + guchar *src_data, *_src_data; + guchar *mask_data, *_mask_data; + guchar *sel_data, *_sel_data; + + gint i, j; + gint texture_off_x, _texture_off_x, texture_off_y; + guchar *texture_row_data; + + /* calc origin of texture buffer */ + texture_off_x = params->drawable_x + params->x + maskPR->x + params->texture_jitter_x; + if (texture_off_x < 0) + texture_off_x = params->texture_width + (texture_off_x % params->texture_width); + + texture_off_y = params->drawable_y + params->y + maskPR->y + params->texture_jitter_y; + if (texture_off_y < 0) + texture_off_y = params->texture_height + (texture_off_y % params->texture_height); + + src_data = srcPR->data; + src_bytes = srcPR->bytes; + mask_data = maskPR->data; + sel_data = selPR->data; + width = maskPR->w; + height = maskPR->h; + bytes = maskPR->bytes; + src_stride = srcPR->rowstride; + mask_stride = maskPR->rowstride; + sel_stride = selPR->rowstride; + + for (i = 0; i < height; i++, texture_off_y++) + { + _src_data = src_data; + _mask_data = mask_data; + _sel_data = sel_data; + + texture_off_y = texture_off_y % params->texture_height; + _texture_off_x = texture_off_x; + texture_row_data = params->texture_data + texture_off_y * params->texture_stride; + + for (j = 0; j < width; j++, _texture_off_x++) + { + gdouble op, mask_op, paint_color_op, canvas_color_op, src_op; + gdouble texture_op; + gdouble factor1, factor2; + gdouble component; + + _texture_off_x = _texture_off_x % params->texture_width; + + texture_op = *(texture_row_data + _texture_off_x * params->texture_bytes) / 255.0; + texture_op = CLAMP (texture_op + params->grain, 0.0, 1.0); + + if (*_mask_data && *_sel_data) + { + mask_op = *_mask_data * *_sel_data / 65025.0; + + if (params->fringe) + texture_op = (texture_op * (1.0 - mask_op) + mask_op); + + if (params->fringe_contrast > 1.0) + mask_op = CLAMP (mask_op * texture_op * params->fringe_contrast - params->fringe_contrast_offset, 0.0, 1.0); + else + mask_op *= texture_op; + + if (mask_op) + { + if (params->has_alpha && params->active_components[src_bytes - 1]) + { + gfloat n; + guint32 _n; + + src_op = _src_data[src_bytes - 1] / 255.0; + + /* workaround against insufficiency of opacity */ + /*if (params->paint_color.a > src_op) + op = pow (params->opacity, 1.0 / 1.5) * mask_op;*/ + n = params->paint_color.a - src_op; + _n = (*(guint32 *) &n) >> 31; + op = (params->opacity * _n + params->adjusted_opacity * (1 - _n)) * mask_op; + + component = (params->paint_color.a * op + src_op * (1.0 - op)) * 255.0/* + error.a*/; + _src_data[src_bytes - 1] = component + .5; + /*_error.a += component - _src_data[src_bytes - 1];*/ + } + else + src_op = 1.0; + + op = params->opacity * mask_op; + paint_color_op = params->paint_color.a * op; + + if (paint_color_op > 0.0) + { + canvas_color_op = (1.0 - paint_color_op) * src_op; + + factor1 = paint_color_op / (paint_color_op + canvas_color_op); + factor2 = 1.0 - factor1; + + component = params->_paint_color.r * factor1 + _src_data[0] * factor2/* + error.r*/; + _src_data[0] = component + .5; + /*_error.r += component - _src_data[0];*/ + if (params->is_rgb) + { + component = params->_paint_color.g * factor1 + _src_data[1] * factor2/* + error.g*/; + _src_data[1] = component + .5; + /*_error.g += component - _src_data[1];*/ + + component = params->_paint_color.b * factor1 + _src_data[2] * factor2/* + error.b*/; + _src_data[2] = component + .5; + /*_error.b += component - _src_data[2];*/ + } + } + } + } + _src_data += src_bytes; + _mask_data++; + _sel_data++; + } + src_data += src_stride; + mask_data += mask_stride; + sel_data += sel_stride; + } +} /* end of iteration */ #endif