diff -uNr gimp-2.4.1/app/core/gimp-modules.c gimp-2.4.1-tmp/app/core/gimp-modules.c --- gimp-2.4.1/app/core/gimp-modules.c 2007-01-23 19:13:46.000000000 +0900 +++ gimp-2.4.1-tmp/app/core/gimp-modules.c 2008-03-12 23:08:27.000000000 +0900 @@ -71,6 +71,8 @@ g_return_if_fail (GIMP_IS_GIMP (gimp)); + g_print("[Trace]:Start:gimp_modules_load\n"); + if (gimp->no_interface) return; @@ -154,6 +156,7 @@ path = gimp_config_path_expand (gimp->config->module_path, TRUE, NULL); gimp_module_db_load (gimp->module_db, path); g_free (path); + g_print("[Trace]:End :gimp_modules_load\n"); } static void diff -uNr gimp-2.4.1/app/paint/Makefile.am gimp-2.4.1-tmp/app/paint/Makefile.am --- gimp-2.4.1/app/paint/Makefile.am 2007-06-27 18:50:25.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/Makefile.am 2008-03-12 23:17:57.000000000 +0900 @@ -77,7 +77,15 @@ gimpsourcecore.c \ gimpsourcecore.h \ gimpsourceoptions.c \ - gimpsourceoptions.h + gimpsourceoptions.h \ + gimpbrushmodifiercore.c \ + gimpbrushmodifiercore.h \ + gimpblendmodifier.c \ + gimpblendmodifier.h \ + gimpcustombrush.c \ + gimpcustombrush.h \ + gimpcustombrushoptions.c \ + gimpcustombrushoptions.h libapppaint_a_built_sources = paint-enums.c diff -uNr gimp-2.4.1/app/paint/Makefile.in gimp-2.4.1-tmp/app/paint/Makefile.in --- gimp-2.4.1/app/paint/Makefile.in 2007-10-31 17:09:07.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/Makefile.in 2008-03-12 23:20:45.000000000 +0900 @@ -70,7 +70,11 @@ gimppaintbrush.$(OBJEXT) gimpperspectiveclone.$(OBJEXT) \ gimpperspectivecloneoptions.$(OBJEXT) gimpsmudge.$(OBJEXT) \ gimpsmudgeoptions.$(OBJEXT) gimpsourcecore.$(OBJEXT) \ - gimpsourceoptions.$(OBJEXT) + gimpsourceoptions.$(OBJEXT) \ + gimpcustombrush.$(OBJEXT) gimpcustombrushoptions.$(OBJEXT) \ + gimpbrushmodifiercore.$(OBJEXT) gimpblendmodifier.$(OBJEXT) \ + gimpbrushmodifieroptions.$(OBJEXT) gimpblendmodifieroptions.$(OBJEXT) \ + gimpsmoothmodifier.$(OBJEXT) gimpsmoothmodifieroptions.$(OBJEXT) am_libapppaint_a_OBJECTS = $(am__objects_1) $(am__objects_2) libapppaint_a_OBJECTS = $(am_libapppaint_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) @@ -535,7 +539,23 @@ gimpsourcecore.c \ gimpsourcecore.h \ gimpsourceoptions.c \ - gimpsourceoptions.h + gimpsourceoptions.h \ + gimpbrushmodifiercore.c \ + gimpbrushmodifiercore.h \ + gimpbrushmodifieroptions.c \ + gimpbrushmodifieroptions.h \ + gimpblendmodifier.c \ + gimpblendmodifier.h \ + gimpblendmodifieroptions.c \ + gimpblendmodifieroptions.h \ + gimpsmoothmodifier.c \ + gimpsmoothmodifier.h \ + gimpsmoothmodifieroptions.c \ + gimpsmoothmodifieroptions.h \ + gimpcustombrush.c \ + gimpcustombrush.h \ + gimpcustombrushoptions.c \ + gimpcustombrushoptions.h libapppaint_a_built_sources = paint-enums.c libapppaint_a_SOURCES = $(libapppaint_a_built_sources) $(libapppaint_a_sources) @@ -625,6 +645,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpsourcecore.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpsourceoptions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/paint-enums.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpcustombrush.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpcustombrushoptions.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ diff -uNr gimp-2.4.1/app/paint/gimp-paint.c gimp-2.4.1-tmp/app/paint/gimp-paint.c --- gimp-2.4.1/app/paint/gimp-paint.c 2007-07-25 03:45:42.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimp-paint.c 2008-03-12 23:12:01.000000000 +0900 @@ -39,6 +39,7 @@ #include "gimppencil.h" #include "gimpperspectiveclone.h" #include "gimpsmudge.h" +#include "gimpcustombrush.h" /* local function prototypes */ @@ -68,12 +69,14 @@ gimp_airbrush_register, gimp_eraser_register, gimp_paintbrush_register, - gimp_pencil_register + gimp_pencil_register, + gimp_custom_brush_register }; gint i; g_return_if_fail (GIMP_IS_GIMP (gimp)); + g_print("[Trace]:gimp_paint_init\n"); gimp->paint_info_list = gimp_list_new (GIMP_TYPE_PAINT_INFO, FALSE); gimp_object_set_static_name (GIMP_OBJECT (gimp->paint_info_list), diff -uNr gimp-2.4.1/app/paint/gimpblendmodifier.c gimp-2.4.1-tmp/app/paint/gimpblendmodifier.c --- gimp-2.4.1/app/paint/gimpblendmodifier.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpblendmodifier.c 2008-03-12 23:11:37.000000000 +0900 @@ -0,0 +1,594 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include + +#include "libgimpcolor/gimpcolor.h" +#include "libgimpmath/gimpmath.h" +#include "libgimpbase/gimpbase.h" + +#include "paint-types.h" + +#include "base/temp-buf.h" + +#include "paint-funcs/paint-funcs.h" + +#include "core/gimp.h" +#include "core/gimpbrush.h" +#include "core/gimpdrawable.h" +#include "core/gimplayer.h" +#include "core/gimpgradient.h" +#include "core/gimpimage.h" +#include "core/gimppickable.h" +#include "core/gimpprojection.h" +#include "base/pixel-region.h" + +#include "gimpcustombrush.h" +#include "gimpblendmodifier.h" +#include "gimpcustombrushoptions.h" +#include "gimpblendmodifieroptions.h" + +#include "gimp-intl.h" + + +/* Debug option */ +//#define GIMP_BLENDMODIFIER_DEBUG_BLENDING + + + + +static void gimp_blend_modifier_finalize (GObject *object); + +static gboolean gimp_blend_modifier_init_motion (GimpBrushModifierCore* core, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + +gboolean +gimp_blend_modifier_register_paste_canvas (GimpBrushModifierCore *core, + GimpBrushCorePasteCanvasInfo** info, + GimpBrushCore *brush_core, + GimpPaintOptions *paint_options, + GimpDrawable *drawable, + TempBuf *area, + gdouble brush_opacity, + gdouble image_opacity, + GimpLayerModeEffects paint_mode, + GimpBrushApplicationMode brush_hardness, + GimpPaintApplicationMode mode); + +static inline gboolean +blend_modifier_get_image_color_at (GimpImage *image, + GimpDrawable *drawable, + GimpBlendModifierOptions *blendmodifier_options, + gint x, + gint y, + GimpRGB *color_at_pos); + +inline static void +blend_modifier_register_info (GimpBlendModifier *modifier, + GimpBrushCorePasteCanvasInfo** head_info, + GimpPaintCore *paint_core, + GimpPaintOptions *paint_options, + GimpDrawable *drawable, + TempBuf *area, + gdouble paint_opacity, + gdouble image_opacity, + GimpLayerModeEffects paint_mode, + GimpBrushApplicationMode brush_hardness, + GimpPaintApplicationMode mode); +static gboolean +blend_colors (GimpRGB *dest, + int num_colors, + ...); + +/* + * Utility functions + * + */ + +static gboolean +blend_colors(GimpRGB *dest, + int num_colors, + ...) +{ + va_list args; + GimpRGB *src; + gdouble opacity = dest->a; + int i; + + va_start(args, num_colors); + + if (num_colors < 1) + return FALSE; + dest->r *= dest->a; + dest->g *= dest->a; + dest->b *= dest->a; + + for (i = 0; i < num_colors; i ++) + { + src = va_arg(args, GimpRGB*); + dest->r += src->r * src->a; + dest->g += src->g * src->a; + dest->b += src->b * src->a; + opacity += src->a; + } + va_end(args); + + if (opacity > 1.0) + { + dest->r = CLAMP(dest->r, 0, 1.0); + dest->g = CLAMP(dest->g, 0, 1.0); + dest->b = CLAMP(dest->b, 0, 1.0); + opacity = 1.0; + } + else if (opacity > 0) + { + dest->r = CLAMP(dest->r / opacity, 0, 1.0); + dest->g = CLAMP(dest->g / opacity, 0, 1.0); + dest->b = CLAMP(dest->b / opacity, 0, 1.0); + } + + dest->a = opacity; + + return TRUE; +} + + +static inline gboolean +blend_modifier_get_image_color_at (GimpImage *image, + GimpDrawable *drawable, + GimpBlendModifierOptions *blend_modifier_options, + gint x, + gint y, + GimpRGB *color_at_pos) +{ + GimpPickable *pickable; + + x = CLAMP (x, 0, gimp_item_width (GIMP_ITEM (drawable)) - 1); + y = CLAMP (y, 0, gimp_item_height (GIMP_ITEM (drawable)) - 1); + + if (blend_modifier_options->merged) + { + gint item_offset_x, item_offset_y; + gimp_item_offsets (GIMP_ITEM (drawable), &item_offset_x, &item_offset_y); + x += item_offset_x; + y += item_offset_y; + + pickable = GIMP_PICKABLE (image->projection); + // g_print ("pickable=%x\n", pickable); + gimp_pickable_flush (pickable); + } + else + pickable = GIMP_PICKABLE (drawable); + + /* Pickup color from current drawable */ + if (!gimp_pickable_get_color_at (pickable, + x, y, color_at_pos)) + { + g_print ("Failed: pick up color\n"); + return FALSE; + } + return TRUE; +} + +/* + * Pickup color from Canvas or Projection, and + * merge the color with delayed and hidden color. + */ +static inline gboolean +blend_modifier_get_blended_image_color_at (GimpBlendModifier* blendmodifier, + GimpImage* image, + GimpContext* context, + GimpDrawable* drawable, + GimpBlendModifierOptions* blend_modifier_options, + // GimpRGB* delayed_color, + gint x, gint y, + GimpRGB* result) +{ + gboolean use_hidden_color = FALSE; + guchar hidden_color_uchar[MAX_CHANNELS]; + GimpRGB color_at_pos; + GimpRGB hidden_color; + + /* Pickup color from current drawable */ + if (!blend_modifier_get_image_color_at (image, drawable, + blend_modifier_options, + x, y, &color_at_pos)) + { + g_print ("Failed: pick up color\n"); + return FALSE; + } + + switch (blend_modifier_options->hidden_color) + { + case GIMP_HIDDEN_COLOR_BACKGROUND: + /* pickup hidden color from current background color */ + gimp_image_get_background (image, context, + gimp_drawable_type (drawable), + hidden_color_uchar); + hidden_color_uchar[ALPHA_PIX] = OPAQUE_OPACITY; + use_hidden_color = TRUE; + break; + + case GIMP_HIDDEN_COLOR_WHITE: + /* select white as a hidden color */ + hidden_color_uchar[0] = + hidden_color_uchar[1] = + hidden_color_uchar[2] = + hidden_color_uchar[3] = OPAQUE_OPACITY; + use_hidden_color = TRUE; + break; + + default: + break; + } + + if (use_hidden_color) + { + gdouble a; + gimp_rgba_set_uchar(&hidden_color, + hidden_color_uchar[0], + hidden_color_uchar[1], + hidden_color_uchar[2], + hidden_color_uchar[3]); + a = color_at_pos.a; + result->r = color_at_pos.r * a + (1 - a) * hidden_color.r; + result->g = color_at_pos.g * a + (1 - a) * hidden_color.g; + result->b = color_at_pos.b * a + (1 - a) * hidden_color.b; + result->a = 1.0; + } + else + { + *result = color_at_pos; + } + + return TRUE; +} + + +/* + * GimpCustomBrush class implementation + * + * + */ + + +G_DEFINE_TYPE (GimpBlendModifier, gimp_blend_modifier, GIMP_TYPE_BRUSH_MODIFIER_CORE) + +#define parent_class gimp_blend_modifier_parent_class + + +static void +gimp_blend_modifier_class_init (GimpBlendModifierClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = gimp_blend_modifier_finalize; +} + +static void +gimp_blend_modifier_init (GimpBlendModifier *blend_modifier) +{ + GimpBrushModifierCore *modifier = GIMP_BRUSH_MODIFIER_CORE(blend_modifier); + + brush_modifier_delegator_bind(&modifier->init_motion_delegator, + modifier, + gimp_blend_modifier_init_motion); + + brush_modifier_delegator_bind(&modifier->register_paste_canvas_delegator, + modifier, + gimp_blend_modifier_register_paste_canvas); +} + + +static void +gimp_blend_modifier_finalize (GObject *object) +{ + g_print("blend_modifier::finalize\n"); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + + +GimpBlendModifier* gimp_blend_modifier_new(void) +{ + GimpBlendModifier* result = (GimpBlendModifier*)g_object_new(GIMP_TYPE_BLEND_MODIFIER, NULL); + g_assert( result != NULL ); + return result; +} + + + + +static gboolean +gimp_blend_modifier_init_motion (GimpBrushModifierCore* core, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time) +{ + GimpRGB *next_color = &GIMP_BLEND_MODIFIER(core)->next_color; + GimpRGB *foreground_color = &GIMP_BLEND_MODIFIER(core)->foreground_color; + GimpCustomBrushOptions *custom_brush_options = GIMP_CUSTOM_BRUSH_OPTIONS (paint_options); + GimpBlendModifierOptions *blend_modifier_options; + GimpCustomBrush *custom_brush = GIMP_CUSTOM_BRUSH(brush_core); + + blend_modifier_options = GIMP_BLEND_MODIFIER_OPTIONS(gimp_custom_brush_options_get_options_for(custom_brush_options, + GIMP_TYPE_BLEND_MODIFIER)); + *foreground_color = custom_brush->state.color; + *next_color = *foreground_color; + + GIMP_BLEND_MODIFIER(core)->current_orig_color_rate = + blend_modifier_options->original_color_rate; + + return TRUE; +} + + + + +gboolean +gimp_blend_modifier_register_paste_canvas (GimpBrushModifierCore *modifier, + GimpBrushCorePasteCanvasInfo** info, + GimpBrushCore *brush_core, + GimpPaintOptions *paint_options, + GimpDrawable *drawable, + TempBuf *area, + gdouble brush_opacity, + gdouble image_opacity, + GimpLayerModeEffects paint_mode, + GimpBrushApplicationMode brush_hardness, + GimpPaintApplicationMode paint_appl_mode) +{ + GimpBlendModifier *blend_modifier = GIMP_BLEND_MODIFIER (modifier); + GimpPaintCore *paint_core = GIMP_PAINT_CORE (brush_core); + GimpCustomBrush *custom_brush = GIMP_CUSTOM_BRUSH(brush_core); + GimpContext *context = GIMP_CONTEXT (paint_options); + GimpImage *image; + GimpRGB *next_color = &blend_modifier->next_color; + GimpCustomBrushOptions *custom_brush_options = GIMP_CUSTOM_BRUSH_OPTIONS (paint_options); + GimpBlendModifierOptions *blend_modifier_options; + GimpRGB *foreground_color = &blend_modifier->foreground_color; + GimpRGB color_at_pos; + gdouble original_color_rate = blend_modifier->current_orig_color_rate; + gdouble canvas_color_rate; + gboolean result; + + blend_modifier_options = GIMP_BLEND_MODIFIER_OPTIONS(gimp_custom_brush_options_get_options_for(custom_brush_options, + GIMP_TYPE_BLEND_MODIFIER)); + canvas_color_rate = blend_modifier_options->canvas_color_rate; + + + image = gimp_item_get_image (GIMP_ITEM (drawable)); + + + if (brush_core->brush && brush_core->brush->pixmap) + { + /* if it's a pixmap, do pixmap stuff */ + gimp_brush_core_color_area_with_pixmap (brush_core, drawable, + area, + gimp_paint_options_get_brush_mode (paint_options)); + + paint_appl_mode = GIMP_PAINT_INCREMENTAL; + } + else + { + /* Blend brush color with underlying canvas color */ + if (blend_modifier_options->canvas_color_rate > 0.0) + { + /* Blend brush stroke color with foreground paint brush color */ + if (blend_modifier->current_orig_color_rate > 0.0) + { + + if (blend_modifier_options->original_color_pressure_rate > 0.0) + { + gdouble inv_pressure = + (blend_modifier_options->invert_original_color_pressure)? + paint_core->cur_coords.pressure : + 1 - paint_core->cur_coords.pressure; + + original_color_rate -= blend_modifier->current_orig_color_rate * + inv_pressure; + original_color_rate = CLAMP(original_color_rate, 0, 1.0); + } + } + + /* Blend brush color with underlying canvas color */ + if (blend_modifier_get_blended_image_color_at (blend_modifier, + image, context, drawable, + blend_modifier_options, + // &history->color, + (gint) paint_core->cur_coords.x, + (gint) paint_core->cur_coords.y, + &color_at_pos)) + { + if (blend_modifier_options->canvas_color_pressure_rate > 0.0) + { + gdouble inv_pressure = + (blend_modifier_options->invert_canvas_color_pressure)? + paint_core->cur_coords.pressure : + 1 - paint_core->cur_coords.pressure; + + canvas_color_rate += + blend_modifier_options->canvas_color_pressure_rate * + inv_pressure; + canvas_color_rate = CLAMP(canvas_color_rate, 0.0, 1.0); + } + foreground_color->a = original_color_rate * (1 - canvas_color_rate); + color_at_pos.a *= canvas_color_rate; + next_color->a *= (1 - original_color_rate) * (1 - canvas_color_rate); + blend_colors(next_color, 2, &color_at_pos, foreground_color); + } + } + + paint_appl_mode = GIMP_PAINT_INCREMENTAL; + } + + custom_brush->state.color = blend_modifier->next_color; + + if (next_color->a > 0) + { + blend_modifier_register_info (blend_modifier, + info, + paint_core, + paint_options, + drawable, + area, + brush_opacity, + image_opacity, + paint_mode, + brush_hardness, + paint_appl_mode); + result = TRUE; + } + else + { + result = FALSE; + } + + return result; +} + + +/* + * BrushCorePasteCanvasInfo Implementation + * + */ +static gint +blend_modifier_paste_canvas_pre_paint (GimpBrushCorePasteCanvasInfo *info, + GimpBrushCore *core, + GimpDrawable *drawable) +{ + GimpBlendModifier *blend_modifier = GIMP_BLEND_MODIFIER (info->user_data); + TempBuf *area = info->gimp_brush_area; + guchar color[MAX_CHANNELS]; + + gimp_rgba_get_uchar(&blend_modifier->next_color, + &color[0], &color[1], &color[2], &color[3]); + + color_pixels (temp_buf_data (area), color, + area->width * area->height, + area->bytes); + return 0; +} + + +static gint +blend_modifier_paste_canvas_paint(GimpBrushCorePasteCanvasInfo *info, + GimpBrushCore *core, + GimpDrawable *drawable, + PixelRegion *canvasPR, + PixelRegion *maskPR) +{ + GimpBlendModifier *blend_modifier = GIMP_BLEND_MODIFIER (info->user_data); + + TempBuf *area = info->gimp_brush_area; + gdouble paint_opacity = info->brush_opacity; + + PixelRegion canvasPR1; + PixelRegion srcPR1; + + guchar color[MAX_CHANNELS]; + gimp_rgba_get_uchar(&blend_modifier->next_color, + &color[0], &color[1], &color[2], &color[3]); + + /* srcPR will be the pixels under the current painthit from the drawable */ + pixel_region_init (&srcPR1, gimp_drawable_get_tiles (drawable), + area->x, area->y, area->width, area->height, FALSE); + + canvasPR1 = *canvasPR; + + /* + * New pixel is: + * P = brush * image_opacity * brush_opacity * paint_opacity + + * src * (image_opacity) * (1 - paint_opacity) + + * src * (1 - image_opacity) + * = image_opacity * + * ((brush * brush_opacity) * paint_opacity + (1-paint_opacity) * src) + + * (1-image_opacity) * src + * = replace( src, shade( src, brush with opacity, paint_opacity), image_opacity) + */ + shade_region(&srcPR1, &canvasPR1, color, CLAMP(paint_opacity * 255.0, 0, 255)); + + return 0; +} + +static gint +blend_modifier_paste_canvas_apply(GimpBrushCorePasteCanvasInfo *info, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + PixelRegion *srcPR, + PixelRegion *maskPR, + TileManager *undo_tiles) +{ + GimpPaintCore *paintcore = GIMP_PAINT_CORE (brush_core); + + /* apply the paint area to the image */ + gimp_drawable_replace_region (drawable, srcPR, + FALSE, NULL, + info->image_opacity, + maskPR, + paintcore->canvas_buf->x, + paintcore->canvas_buf->y); + return 0; +} + +inline static void +blend_modifier_register_info (GimpBlendModifier *modifier, + GimpBrushCorePasteCanvasInfo** head_info, + GimpPaintCore *paint_core, + GimpPaintOptions *paint_options, + GimpDrawable *drawable, + TempBuf *area, + gdouble paint_opacity, + gdouble image_opacity, + GimpLayerModeEffects paint_mode, + GimpBrushApplicationMode brush_hardness, + GimpPaintApplicationMode mode) +{ + GimpBrushCorePasteCanvasInfo *brush_info = &modifier->brush_info; + + brush_info->gimp_brush_area = area; + brush_info->brush_opacity = paint_opacity; // [error]should be paint_opacity + brush_info->image_opacity = CLAMP (image_opacity, 0, 1); + brush_info->paint_mode = paint_mode; + brush_info->apply = TRUE; + brush_info->brush_hardness = brush_hardness; + brush_info->post_paint = NULL; + + if (gimp_drawable_has_alpha(drawable)) + { + brush_info->pre_paint = NULL; + brush_info->apply_operation = blend_modifier_paste_canvas_apply; + brush_info->paint_operation = blend_modifier_paste_canvas_paint; + } + else + { + brush_info->pre_paint = blend_modifier_paste_canvas_pre_paint; + brush_info->apply_operation = NULL; + brush_info->paint_operation = NULL; + } + brush_info->user_data = modifier; // [error]should be brush_opacity + brush_info->next = NULL; + + *head_info = brush_info; +} diff -uNr gimp-2.4.1/app/paint/gimpblendmodifier.h gimp-2.4.1-tmp/app/paint/gimpblendmodifier.h --- gimp-2.4.1/app/paint/gimpblendmodifier.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpblendmodifier.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,73 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_BLEND_MODIFIER_H__ +#define __GIMP_BLEND_MODIFIER_H__ + + +#include "gimpbrushmodifiercore.h" + + +#define GIMP_TYPE_BLEND_MODIFIER (gimp_blend_modifier_get_type ()) +#define GIMP_BLEND_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BLEND_MODIFIER, GimpBlendModifier)) +#define GIMP_BLEND_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BLEND_MODIFIER, GimpBlendModifierClass)) +#define GIMP_IS_BLEND_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_BLEND_MODIFIER)) +#define GIMP_IS_BLEND_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BLEND_MODIFIER)) +#define GIMP_BLEND_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BLEND_MODIFIER, GimpBlendModifierClass)) + + +typedef struct _GimpBlendModifierCoordsHistory +{ + GimpCoords cur_coords; + GimpCoords last_coords; + gdouble pixel_dist; + GimpRGB color; +} GimpBlendModifierCoordsHistory; + +typedef struct _GimpBlendModifier GimpBlendModifier; +typedef struct _GimpBlendModifierClass GimpBlendModifierClass; + +#define GIMP_BLEND_MODIFIER_MAX_HISTORY 20 +struct _GimpBlendModifier +{ + GimpBrushModifierCore parent_instance; + + // GimpDrawable *drawable; + // GimpPaintOptions *paint_options; + gdouble current_orig_color_rate; + GimpRGB next_color; + GimpRGB foreground_color; + + /* circular history buffer */ + GimpBlendModifierCoordsHistory history[GIMP_BLEND_MODIFIER_MAX_HISTORY + 1]; + gint history_head; + gint history_tail; + GimpBrushCorePasteCanvasInfo brush_info; +}; + +struct _GimpBlendModifierClass +{ + GimpBrushModifierCoreClass parent_class; +}; + + +GType gimp_blend_modifier_get_type (void) G_GNUC_CONST; +GimpBlendModifier* gimp_blend_modifier_new(void); + + +#endif diff -uNr gimp-2.4.1/app/paint/gimpblendmodifieroptions.c gimp-2.4.1-tmp/app/paint/gimpblendmodifieroptions.c --- gimp-2.4.1/app/paint/gimpblendmodifieroptions.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpblendmodifieroptions.c 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,317 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpconfig/gimpconfig.h" +#include "paint-types.h" +#include "core/gimp.h" + +#include "gimpblendmodifier.h" +#include "gimpblendmodifieroptions.h" + + +static gboolean +gimp_blend_modifier_options_install (GimpBrushModifierOptionsClass *klass, + GimpPaintOptionsClass *options_class, + guint *base_property_id); + + + +static gboolean +gimp_blend_modifier_options_set_property (GimpBrushModifierOptions *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static gboolean +gimp_blend_modifier_options_get_property (GimpBrushModifierOptions *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + + +#define BLEND_MODIFIER_DEFAULT_CANVAS_COLOR_RATE 0.8 +#define BLEND_MODIFIER_DEFAULT_ORIGINAL_COLOR_RATE 0.5 +#define BLEND_MODIFIER_DEFAULT_MERGED FALSE +#define BLEND_MODIFIER_DEFAULT_HIDDEN_COLOR GIMP_HIDDEN_COLOR_WHITE +#define BLEND_MODIFIER_DEFAULT_REMOVE_COLOR FALSE + + +enum +{ + PROP_0, + PROP_ENABLED, + PROP_CANVAS_COLOR_RATE, + PROP_ORIGINAL_COLOR_RATE, + PROP_CANVAS_COLOR_PRESSURE_RATE, + PROP_ORIGINAL_COLOR_PRESSURE_RATE, + PROP_MERGED, + PROP_HIDDEN_COLOR, + PROP_REMOVE_COLOR, + PROP_INVERT_ORIGINAL_COLOR_PRESSURE, + PROP_INVERT_CANVAS_COLOR_PRESSURE +}; + +G_DEFINE_TYPE (GimpBlendModifierOptions, gimp_blend_modifier_options, + GIMP_TYPE_BRUSH_MODIFIER_OPTIONS) + +#define parent_class gimp_blend_modifier_options_parent_class + + +static void +gimp_blend_modifier_options_class_init (GimpBlendModifierOptionsClass *klass) +{ + GimpBrushModifierOptionsClass *modifier_class = GIMP_BRUSH_MODIFIER_OPTIONS_CLASS (klass); + + modifier_class->base_property_id = 0; + + modifier_class->install = gimp_blend_modifier_options_install; + modifier_class->set_property = gimp_blend_modifier_options_set_property; + modifier_class->get_property = gimp_blend_modifier_options_get_property; +} + +static void +gimp_blend_modifier_options_init (GimpBlendModifierOptions *options) +{ + GimpBrushModifierOptions *modifier_options = GIMP_BRUSH_MODIFIER_OPTIONS(options); + g_print("[Trace]blend_modifier_options::init\n"); + modifier_options->attached_to = GIMP_TYPE_BLEND_MODIFIER; +} + + +static gboolean +gimp_blend_modifier_options_install(GimpBrushModifierOptionsClass *klass, + GimpPaintOptionsClass *options_class, + guint *base_property_id) +{ + GObjectClass* object_class = G_OBJECT_CLASS(options_class); + guint n_properties = 0; + klass->base_property_id = *base_property_id; + + + g_print("[Trace]blend_modifier_options::install[%x]\n", *base_property_id); + + /* enabled parameter should be handled automatically, but not yet implemented */ + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_ENABLED + *base_property_id, + "blend-enabled", NULL, + TRUE, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_CANVAS_COLOR_RATE + *base_property_id, + "canvas-color-rate", NULL, + 0.0, 1.0, BLEND_MODIFIER_DEFAULT_CANVAS_COLOR_RATE, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_CANVAS_COLOR_PRESSURE_RATE + *base_property_id, + "canvas-color-pressure-rate", NULL, + 0.0, 1.0, BLEND_MODIFIER_DEFAULT_CANVAS_COLOR_RATE, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_ORIGINAL_COLOR_RATE + *base_property_id, + "original-color-rate", NULL, + 0.0, 1.0, BLEND_MODIFIER_DEFAULT_ORIGINAL_COLOR_RATE, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_ORIGINAL_COLOR_PRESSURE_RATE + *base_property_id, + "original-color-pressure-rate", NULL, + 0.0, 1.0, BLEND_MODIFIER_DEFAULT_CANVAS_COLOR_RATE, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_MERGED + *base_property_id, + "merged", NULL, + BLEND_MODIFIER_DEFAULT_MERGED, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_HIDDEN_COLOR + *base_property_id, + "hidden-color", NULL, + GIMP_TYPE_HIDDEN_COLOR, + BLEND_MODIFIER_DEFAULT_HIDDEN_COLOR, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_INVERT_ORIGINAL_COLOR_PRESSURE + *base_property_id, + "invert-original-color-pressure", NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_INVERT_CANVAS_COLOR_PRESSURE + *base_property_id, + "invert-canvas-color-pressure", NULL, + FALSE, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + return TRUE; +} + + +static gboolean +gimp_blend_modifier_options_set_property (GimpBrushModifierOptions *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpBlendModifierOptions *options = GIMP_BLEND_MODIFIER_OPTIONS (object); + + g_print("[Trace]blend_modifier_options::set_property[%x-%x]\n", + property_id, + GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(object)->base_property_id); + + switch (property_id - GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(object)->base_property_id) + { + case PROP_ENABLED: + GIMP_BRUSH_MODIFIER_OPTIONS(options)->enabled = g_value_get_boolean (value); + g_print("[Trace]->PROP_ENABLED\n"); + break; + + case PROP_CANVAS_COLOR_RATE: + options->canvas_color_rate = g_value_get_double (value); + g_print("[Trace]->PROP_CANVAS_COLOR_RATE\n"); + break; + case PROP_CANVAS_COLOR_PRESSURE_RATE: + options->canvas_color_pressure_rate = g_value_get_double (value); + g_print("[Trace]->PROP_CANVAS_COLOR_PRESSURE_RATE\n"); + break; + case PROP_ORIGINAL_COLOR_RATE: + options->original_color_rate = g_value_get_double (value); + g_print("[Trace]->PROP_ORIGINAL_COLOR_RATE\n"); + break; + case PROP_ORIGINAL_COLOR_PRESSURE_RATE: + options->original_color_pressure_rate = g_value_get_double (value); + g_print("[Trace]->PROP_ORIGINAL_COLOR_PRESSURE_RATE\n"); + break; + case PROP_MERGED: + options->merged = g_value_get_boolean (value); + g_print("[Trace]->PROP_MERGED\n"); + break; + case PROP_HIDDEN_COLOR: + options->hidden_color = g_value_get_enum (value); + g_print("[Trace]->PROP_HIDDEN_COLOR\n"); + break; + case PROP_INVERT_ORIGINAL_COLOR_PRESSURE: + options->invert_original_color_pressure = g_value_get_boolean (value); + g_print("[Trace]->PROP_INVERT_ORIGINAL_COLOR_PRESSURE\n"); + break; + case PROP_INVERT_CANVAS_COLOR_PRESSURE: + options->invert_canvas_color_pressure = g_value_get_boolean (value); + g_print("[Trace]->PROP_INVERT_CANVAS_COLOR_PRESSURE\n"); + break; + default: + return FALSE; + break; + } + return TRUE; +} + +static gboolean +gimp_blend_modifier_options_get_property (GimpBrushModifierOptions *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpBlendModifierOptions *options = GIMP_BLEND_MODIFIER_OPTIONS (object); + + g_print("[Trace]blend_modifier_options::get_property[%x-%x]\n", + property_id, + GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(object)->base_property_id); + + switch (property_id - GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(object)->base_property_id) + { + case PROP_ENABLED: + g_value_set_boolean(value, GIMP_BRUSH_MODIFIER_OPTIONS(options)->enabled); + g_print("[Trace]->PROP_ENABLED\n"); + break; + + case PROP_CANVAS_COLOR_RATE: + g_value_set_double (value, options->canvas_color_rate); + g_print("[Trace]->PROP_CANVAS_COLOR_RATE\n"); + break; + case PROP_CANVAS_COLOR_PRESSURE_RATE: + g_value_set_double (value, options->canvas_color_pressure_rate); + g_print("[Trace]->PROP_CANVAS_COLOR_PRESSURE_RATE\n"); + break; + case PROP_ORIGINAL_COLOR_RATE: + g_value_set_double (value, options->original_color_rate); + g_print("[Trace]->PROP_ORIGINAL_COLOR_RATE\n"); + break; + case PROP_ORIGINAL_COLOR_PRESSURE_RATE: + g_value_set_double (value, options->original_color_pressure_rate); + g_print("[Trace]->PROP_ORIGINAL_COLOR_PRESSURE_RATE\n"); + break; + case PROP_MERGED: + g_value_set_boolean (value, options->merged); + g_print("[Trace]->PROP_MERGED\n"); + break; + case PROP_HIDDEN_COLOR: + g_value_set_enum (value, options->hidden_color); + g_print("[Trace]->PROP_HIDDEN_COLOR\n"); + break; + case PROP_INVERT_ORIGINAL_COLOR_PRESSURE: + g_value_set_boolean (value, options->invert_original_color_pressure); + g_print("[Trace]->PROP_INVERT_ORIGINAL_COLOR_PRESSURE\n"); + break; + case PROP_INVERT_CANVAS_COLOR_PRESSURE: + g_value_set_boolean (value, options->invert_canvas_color_pressure); + g_print("[Trace]->PROP_INVERT_CANVAS_COLOR_PRESSURE\n"); + break; + default: + return FALSE; + break; + } + return TRUE; +} + + +GType +gimp_hidden_color_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_HIDDEN_COLOR_NORMAL, "GIMP_HIDDEN_COLOR_NORMAL", "normal" }, + { GIMP_HIDDEN_COLOR_WHITE, "GIMP_HIDDEN_COLOR_WHITE", "white" }, + { GIMP_HIDDEN_COLOR_BACKGROUND, "GIMP_HIDDEN_COLOR_BACKGROUND", "background color" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_HIDDEN_COLOR_NORMAL, "normal", NULL }, + { GIMP_HIDDEN_COLOR_WHITE, "white", NULL }, + { GIMP_HIDDEN_COLOR_BACKGROUND, "background color", NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (! type) + { + type = g_enum_register_static ("GimpHiddenColor", values); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} diff -uNr gimp-2.4.1/app/paint/gimpblendmodifieroptions.h gimp-2.4.1-tmp/app/paint/gimpblendmodifieroptions.h --- gimp-2.4.1/app/paint/gimpblendmodifieroptions.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpblendmodifieroptions.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,79 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_BLEND_MODIFIER_OPTIONS_H__ +#define __GIMP_BLEND_MODIFIER_OPTIONS_H__ + + +#include "gimpbrushmodifieroptions.h" + + +/* enum(s) */ + +typedef enum +{ + GIMP_HIDDEN_COLOR_NORMAL, + GIMP_HIDDEN_COLOR_WHITE, + GIMP_HIDDEN_COLOR_BACKGROUND +} GimpHiddenColor; + +GType gimp_hidden_color_get_type (void) G_GNUC_CONST; +#define GIMP_TYPE_HIDDEN_COLOR (gimp_hidden_color_get_type ()) + + +/* class */ + +#define GIMP_TYPE_BLEND_MODIFIER_OPTIONS (gimp_blend_modifier_options_get_type ()) +#define GIMP_BLEND_MODIFIER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BLEND_MODIFIER_OPTIONS, GimpBlendModifierOptions)) +#define GIMP_BLEND_MODIFIER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BLEND_MODIFIER_OPTIONS, GimpBlendModifierOptionsClass)) +#define GIMP_IS_BLEND_MODIFIER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_BLEND_MODIFIER_OPTIONS)) +#define GIMP_IS_BLEND_MODIFIER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BLEND_MODIFIER_OPTIONS)) +#define GIMP_BLEND_MODIFIER_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BLEND_MODIFIER_OPTIONS, GimpBlendModifierOptionsClass)) + + +typedef struct _GimpBlendModifierOptionsClass GimpBlendModifierOptionsClass; +typedef struct _GimpBlendModifierOptions GimpBlendModifierOptions; + + +struct _GimpBlendModifierOptions +{ + GimpBrushModifierOptions parent_instance; + + gdouble canvas_color_rate; + gdouble canvas_color_pressure_rate; + gdouble original_color_rate; + gdouble original_color_pressure_rate; + gdouble delayed_color_rate; + guint dryout; + guint delay; + gboolean merged; + gboolean tail; + GimpHiddenColor hidden_color; + gboolean remove_color; + gboolean invert_original_color_pressure; + gboolean invert_canvas_color_pressure; +}; + +struct _GimpBlendModifierOptionsClass +{ + GimpBrushModifierOptionsClass parent_class; +}; + +GType gimp_blend_modifier_options_get_type (void) G_GNUC_CONST; + +#endif /* __GIMP_BLEND_MODIFIER_OPTIONS_H__ */ diff -uNr gimp-2.4.1/app/paint/gimpbrushcore.c gimp-2.4.1-tmp/app/paint/gimpbrushcore.c --- gimp-2.4.1/app/paint/gimpbrushcore.c 2007-08-16 06:56:50.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpbrushcore.c 2008-03-12 23:08:27.000000000 +0900 @@ -41,6 +41,9 @@ #include "gimp-intl.h" +// Temporary needed! +#include "paint-funcs/paint-funcs.h" +#include "gimpairbrush.h" #define EPSILON 0.00001 @@ -810,13 +813,195 @@ GimpBrushApplicationMode brush_hardness, GimpPaintApplicationMode mode) { + PixelRegion brush_maskPR; + if (gimp_brush_core_get_brush_maskPR(core, brush_hardness, &brush_maskPR)) + { + gimp_paint_core_paste (GIMP_PAINT_CORE(core), &brush_maskPR, drawable, + brush_opacity, + image_opacity, paint_mode, + mode); + } +} + + +struct _GimpBrushCorePasteCanvasInternal +{ + GimpPaintMaskInfo info; + GimpBrushCorePasteCanvasInfo *pcinfo; + GimpBrushCore *core; + GimpDrawable *drawable; +}; +typedef struct _GimpBrushCorePasteCanvasInternal GimpBrushCorePasteCanvasInternal; + +static GimpBrushCorePasteCanvasInternal* +brush_core_create_internal_list (gint num_items, + GimpBrushCore *core, + GimpDrawable *drawable) +{ + GimpBrushCorePasteCanvasInternal *mask_info_list, *cur_mask_info; + gint i; + + cur_mask_info = + mask_info_list = + (GimpBrushCorePasteCanvasInternal*)g_malloc0(num_items * sizeof(GimpBrushCorePasteCanvasInternal)); + if (!mask_info_list) + return NULL; + + for (i = 0; i < num_items; i ++) + { + if (i == num_items - 1) + cur_mask_info->info.next = NULL; + else + cur_mask_info->info.next = &(cur_mask_info + 1)->info; + + cur_mask_info->info.delegator_data = cur_mask_info; + cur_mask_info->core = core; + cur_mask_info->drawable = drawable; + cur_mask_info ++; + } + + return mask_info_list; +} + + + +static gint +gimp_brush_core_process_paste_canvas_pre_paint (GimpPaintMaskInfo *info, + GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintApplicationMode mode) +{ + GimpBrushCorePasteCanvasInternal *internal = (GimpBrushCorePasteCanvasInternal*)info->delegator_data; + internal->pcinfo->pre_paint(internal->pcinfo, GIMP_BRUSH_CORE(core), drawable); + + return 0; +} + + + +static gint +gimp_brush_core_process_paste_canvas_paint (GimpPaintMaskInfo *info, + GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintApplicationMode mode, + PixelRegion *srcPR) +{ + GimpBrushCorePasteCanvasInternal *internal = (GimpBrushCorePasteCanvasInternal*)info->delegator_data; + if (!gimp_brush_core_get_brush_maskPR(GIMP_BRUSH_CORE(core), + internal->pcinfo->brush_hardness, + info->paint_maskPR)) + return -1; + { + PixelRegion paint_maskPR_copy = *info->paint_maskPR; + + if (internal->pcinfo->paint_operation) + return internal->pcinfo->paint_operation(internal->pcinfo, GIMP_BRUSH_CORE(core), + drawable, srcPR, &paint_maskPR_copy); + else if (mode == GIMP_PAINT_CONSTANT) + /* combine the mask to the canvas tiles */ + combine_mask_and_region (srcPR, &paint_maskPR_copy, + info->paint_opacity * 255.999, GIMP_IS_AIRBRUSH (core)); + else + /* apply the mask */ + apply_mask_to_region (srcPR, &paint_maskPR_copy, info->paint_opacity * 255.999); + } + return 0; +} + + + +static gint +gimp_brush_core_process_paste_canvas_post_paint (GimpPaintMaskInfo *info, + GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintApplicationMode mode) +{ + GimpBrushCorePasteCanvasInternal *internal = (GimpBrushCorePasteCanvasInternal*)info->delegator_data; + /* This function is called only if pcinfo->post_paint != NULL */ + return internal->pcinfo->post_paint(internal->pcinfo, GIMP_BRUSH_CORE(core), drawable); + + return 0; +} + + + +static gint +gimp_brush_core_process_paste_canvas_apply (GimpPaintMaskInfo *info, + GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintApplicationMode mode, + PixelRegion *srcPR, + TileManager *undo_tiles) +{ + GimpBrushCorePasteCanvasInternal *internal = (GimpBrushCorePasteCanvasInternal*)info->delegator_data; + PixelRegion paint_maskPR_copy = *info->paint_maskPR; + /* This function is called only if pcinfo->apply_operation != NULL */ + return internal->pcinfo->apply_operation(internal->pcinfo, GIMP_BRUSH_CORE(core), + drawable, srcPR, &paint_maskPR_copy, undo_tiles); +} + + +void +gimp_brush_core_process_paste_canvas (GimpBrushCore *core, + GimpDrawable *drawable, + GimpBrushCorePasteCanvasInfo *info, + GimpPaintApplicationMode mode) +{ + PixelRegion brush_maskPR; + GimpBrushCorePasteCanvasInternal *mask_info_list, *cur_mask_info; + gint info_num = 0; + GimpBrushCorePasteCanvasInfo *cur_info = info; + + /* Create GimpPaintMask Info list */ + while (cur_info) + { + cur_info = cur_info->next; + info_num ++; + } + + cur_mask_info = + mask_info_list = + brush_core_create_internal_list (info_num, core, drawable); + + /* Setup info parameters */ + while (info) + { + cur_mask_info->info.paint_maskPR = &brush_maskPR; + cur_mask_info->info.paint_opacity = info->brush_opacity; + cur_mask_info->info.image_opacity = info->image_opacity; + cur_mask_info->info.apply = info->apply; + cur_mask_info->info.paint_mode = info->paint_mode; + cur_mask_info->pcinfo = info; + cur_mask_info->info.paint_operation = gimp_brush_core_process_paste_canvas_paint; + if (info->pre_paint) + cur_mask_info->info.pre_paint = gimp_brush_core_process_paste_canvas_pre_paint; + if (info->post_paint) + cur_mask_info->info.post_paint = gimp_brush_core_process_paste_canvas_post_paint; + if (info->apply_operation) + cur_mask_info->info.apply_operation = gimp_brush_core_process_paste_canvas_apply; + + cur_mask_info ++; + info = info->next; + } + + /* Execute paste processing */ + gimp_paint_core_paste_mask_list (GIMP_PAINT_CORE(core), drawable, + &mask_info_list->info, + mode); + g_free (mask_info_list); +} + +gboolean +gimp_brush_core_get_brush_maskPR (GimpBrushCore *core, + GimpBrushApplicationMode brush_hardness, + PixelRegion *brush_maskPR) +{ TempBuf *brush_mask = gimp_brush_core_get_brush_mask (core, brush_hardness); if (brush_mask) { GimpPaintCore *paint_core = GIMP_PAINT_CORE (core); - PixelRegion brush_maskPR; gint x; gint y; gint off_x; @@ -828,16 +1013,14 @@ off_x = (x < 0) ? -x : 0; off_y = (y < 0) ? -y : 0; - pixel_region_init_temp_buf (&brush_maskPR, brush_mask, + pixel_region_init_temp_buf (brush_maskPR, brush_mask, off_x, off_y, paint_core->canvas_buf->width, paint_core->canvas_buf->height); - - gimp_paint_core_paste (paint_core, &brush_maskPR, drawable, - brush_opacity, - image_opacity, paint_mode, - mode); + return TRUE; } + else + return FALSE; } /* Similar to gimp_brush_core_paste_canvas, but replaces the alpha channel diff -uNr gimp-2.4.1/app/paint/gimpbrushcore.h gimp-2.4.1-tmp/app/paint/gimpbrushcore.h --- gimp-2.4.1/app/paint/gimpbrushcore.h 2007-07-25 03:45:42.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpbrushcore.h 2008-03-12 23:08:27.000000000 +0900 @@ -98,6 +98,46 @@ GimpBrush *brush); }; +typedef struct _GimpBrushCorePasteCanvasInfo GimpBrushCorePasteCanvasInfo; +typedef gint (*GimpBrushCorePasteCanvasInfoEventCallback) + (GimpBrushCorePasteCanvasInfo *info, + GimpBrushCore *core, + GimpDrawable *drawable); + +typedef gint (*GimpBrushCorePasteCanvasInfoPaintDelegator) + (GimpBrushCorePasteCanvasInfo *info, + GimpBrushCore *core, + GimpDrawable *drawable, + PixelRegion *srcPR, + PixelRegion *brush_maskPR); + +typedef gint (*GimpBrushCorePasteCanvasInfoApplicationDelegator) + (GimpBrushCorePasteCanvasInfo *info, + GimpBrushCore *core, + GimpDrawable *drawable, + PixelRegion *srcPR, + PixelRegion *maskPR, + TileManager *undo_tiles); + + +struct _GimpBrushCorePasteCanvasInfo +{ + TempBuf *gimp_brush_area; + gdouble brush_opacity; + gdouble image_opacity; + GimpLayerModeEffects paint_mode; + GimpBrushApplicationMode brush_hardness; + GimpPaintApplicationMode mode; + GimpBrushCorePasteCanvasInfoPaintDelegator paint_operation; + GimpBrushCorePasteCanvasInfoEventCallback pre_paint; + GimpBrushCorePasteCanvasInfoEventCallback post_paint; + GimpBrushCorePasteCanvasInfoApplicationDelegator apply_operation; + gboolean apply; + void *user_data; + GimpBrushCorePasteCanvasInfo *next; +}; + + GType gimp_brush_core_get_type (void) G_GNUC_CONST; @@ -113,6 +153,11 @@ GimpLayerModeEffects paint_mode, GimpBrushApplicationMode brush_hardness, GimpPaintApplicationMode mode); +void gimp_brush_core_process_paste_canvas + (GimpBrushCore *core, + GimpDrawable *drawable, + GimpBrushCorePasteCanvasInfo *info, + GimpPaintApplicationMode mode); void gimp_brush_core_replace_canvas (GimpBrushCore *core, GimpDrawable *drawable, gdouble brush_opacity, @@ -126,5 +171,9 @@ TempBuf *area, GimpBrushApplicationMode mode); +gboolean +gimp_brush_core_get_brush_maskPR (GimpBrushCore *core, + GimpBrushApplicationMode brush_hardness, + PixelRegion *brush_maskPR); #endif /* __GIMP_BRUSH_CORE_H__ */ diff -uNr gimp-2.4.1/app/paint/gimpbrushmodifiercore.c gimp-2.4.1-tmp/app/paint/gimpbrushmodifiercore.c --- gimp-2.4.1/app/paint/gimpbrushmodifiercore.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpbrushmodifiercore.c 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,128 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include + +#include "libgimpmath/gimpmath.h" + +#include "paint-types.h" + +#include "base/boundary.h" +#include "base/pixel-region.h" +#include "base/temp-buf.h" + +#include "core/gimpbrush.h" +#include "core/gimpdrawable.h" + +#include "gimpbrushcore.h" + +#include "gimpbrushmodifiercore.h" + +/* local function prototypes */ + +static void gimp_brush_modifier_core_finalize (GObject *object); + + +/* BrushModifierDelegator stuff */ + +void +brush_modifier_delegator_init (BrushModifierDelegator *delegator) +{ + g_assert(delegator != NULL); + delegator->callback = NULL; + delegator->modifier = NULL; + delegator->next = NULL; +} + +void +brush_modifier_delegator_bind (BrushModifierDelegator *delegator, + GimpBrushModifierCore *modifier, + gpointer callback) +{ + g_assert(delegator != NULL); + delegator->callback = callback; + delegator->modifier = modifier; +} + + +BrushModifierDelegator* +brush_modifier_delegator_append (BrushModifierDelegator *delegators, + BrushModifierDelegator *new_delegator) +{ + if (!delegators) + { + if ( !new_delegator || + !new_delegator->callback || + !new_delegator->modifier ) + return NULL; + + new_delegator->next = NULL; + return new_delegator; + } + else + { + if ( new_delegator->callback != NULL && + new_delegator->modifier != NULL) + { + BrushModifierDelegator *pointer = delegators; + while (pointer->next != NULL) + pointer = pointer->next; + + pointer->next = new_delegator; + new_delegator->next = NULL; + } + } + return delegators; +} + + + +/* BrushModifierCore stuff */ + +G_DEFINE_TYPE (GimpBrushModifierCore, gimp_brush_modifier_core, GIMP_TYPE_OBJECT) + +#define parent_class gimp_brush_modifier_core_parent_class + + +static void +gimp_brush_modifier_core_class_init (GimpBrushModifierCoreClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gimp_brush_modifier_core_finalize; +} + +static void +gimp_brush_modifier_core_init (GimpBrushModifierCore *modifier) +{ + brush_modifier_delegator_init(&modifier->init_motion_delegator); + brush_modifier_delegator_init(&modifier->motion_delegator); + brush_modifier_delegator_init(&modifier->finish_motion_delegator); + brush_modifier_delegator_init(&modifier->register_paste_canvas_delegator); + brush_modifier_delegator_init(&modifier->scale_mask_size_delegator); +} + +static void +gimp_brush_modifier_core_finalize (GObject *object) +{ + G_OBJECT_CLASS (parent_class)->finalize (object); +} diff -uNr gimp-2.4.1/app/paint/gimpbrushmodifiercore.h gimp-2.4.1-tmp/app/paint/gimpbrushmodifiercore.h --- gimp-2.4.1/app/paint/gimpbrushmodifiercore.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpbrushmodifiercore.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,176 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_BRUSHMODIFIER_CORE_H__ +#define __GIMP_BRUSHMODIFIER_CORE_H__ + + +#include "gimpbrushcore.h" + + +#define GIMP_TYPE_BRUSH_MODIFIER_CORE (gimp_brush_modifier_core_get_type ()) +#define GIMP_BRUSH_MODIFIER_CORE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH_MODIFIER_CORE, GimpBrushModifierCore)) +#define GIMP_BRUSH_MODIFIER_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_MODIFIER_CORE, GimpBrushModifierCoreClass)) +#define GIMP_IS_BRUSH_MODIFIER_CORE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_BRUSH_MODIFIER_CORE)) +#define GIMP_IS_BRUSH_MODIFIER_CORE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_MODIFIER_CORE)) +#define GIMP_BRUSH_MODIFIER_CORE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BRUSH_MODIFIER_CORE, GimpBrushModifierCoreClass)) + + +typedef struct _GimpBrushModifierCore GimpBrushModifierCore; +typedef struct _GimpBrushModifierCoreClass GimpBrushModifierCoreClass; + + +typedef gboolean +(* BrushModifierInitMotion) (GimpBrushModifierCore *modifier, + GimpBrushCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + +typedef gboolean +(* BrushModifierMotion) (GimpBrushModifierCore *modifier, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + +typedef gboolean +(* BrushModifierFinishMotion) (GimpBrushModifierCore *modifier, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + +typedef gboolean +(* BrushModifierRegisterPasteCanvas)(GimpBrushModifierCore *modifier, + GimpBrushCorePasteCanvasInfo** info, + GimpBrushCore *brush_core, + GimpPaintOptions *paint_options, + GimpDrawable *drawable, + TempBuf *area, + gdouble brush_opacity, + gdouble image_opacity, + GimpLayerModeEffects paint_mode, + GimpBrushApplicationMode brush_hardness, + GimpPaintApplicationMode mode); + +typedef gboolean +(* BrushModifierScaleMaskSize) (GimpBrushModifierCore *modifier, + GimpBrushCore *brush_core, + GimpPaintOptions *paint_options, + gdouble pressure); + + + +typedef struct _BrushModifierDelegator BrushModifierDelegator; +struct _BrushModifierDelegator { + union { + BrushModifierInitMotion init_motion; + BrushModifierMotion motion; + BrushModifierFinishMotion finish_motion; + BrushModifierRegisterPasteCanvas register_paste_canvas; + gpointer callback; + }; + GimpBrushModifierCore *modifier; + BrushModifierDelegator *next; +}; + +void +brush_modifier_delegator_init (BrushModifierDelegator *delegator); + +void +brush_modifier_delegator_bind (BrushModifierDelegator *delegator, + GimpBrushModifierCore *modifier, + gpointer callback); +BrushModifierDelegator* +brush_modifier_delegator_append (BrushModifierDelegator *delegators, + BrushModifierDelegator *new_delegator); + + + +struct _GimpBrushModifierCore +{ + GimpObject parent_instance; + + BrushModifierDelegator init_motion_delegator; + BrushModifierDelegator motion_delegator; + BrushModifierDelegator finish_motion_delegator; + BrushModifierDelegator register_paste_canvas_delegator; + BrushModifierDelegator scale_mask_size_delegator; +}; + + +typedef struct _GimpCustomBrushState +{ + GimpRGB color; +} GimpCustomBrushState; + + +struct _GimpBrushModifierCoreClass +{ + GimpObjectClass parent_class; + + /* virtual functions */ + + /* brushmodifier operations */ +#if 0 + gboolean (* init_motion) (GimpBrushModifierCore *modifier, + GimpBrushCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + + gboolean (* motion) (GimpBrushModifierCore *modifier, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + + gboolean (* finish_motion) (GimpBrushModifierCore *modifier, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + + gboolean (*register_paste_canvas)(GimpBrushModifierCore *modifier, + GimpBrushCorePasteCanvasInfo** info, + GimpBrushCore *brush_core, + GimpPaintOptions *paint_options, + GimpDrawable *drawable, + TempBuf *area, + gdouble brush_opacity, + gdouble image_opacity, + GimpLayerModeEffects paint_mode, + GimpBrushApplicationMode brush_hardness, + GimpPaintApplicationMode mode); + + gboolean (* scale_mask_size)(GimpBrushModifierCore *modifier, + GimpBrushCore *brush_core, + GimpPaintOptions *paint_options, + gdouble pressure); +#endif + /* modifier properties */ + gboolean (* get_priority) (GimpBrushModifierCore *modifier, + GimpPaintCore *core, + GimpDrawable *drawable); +}; + + +GType gimp_brush_modifier_core_get_type (void) G_GNUC_CONST; + +#endif diff -uNr gimp-2.4.1/app/paint/gimpbrushmodifieroptions.c gimp-2.4.1-tmp/app/paint/gimpbrushmodifieroptions.c --- gimp-2.4.1/app/paint/gimpbrushmodifieroptions.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpbrushmodifieroptions.c 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,188 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpbase/gimpbase.h" +#include "libgimpmath/gimpmath.h" +#include "libgimpconfig/gimpconfig.h" +#include "paint-types.h" +#include "core/gimp.h" + +#include "gimpbrushmodifiercore.h" +#include "gimpbrushmodifieroptions.h" + + +/* static function declarations */ + +static void gimp_brush_modifier_options_finalize (GObject *object); + +static gboolean +gimp_brush_modifier_options_real_install(GimpBrushModifierOptionsClass *klass, + GimpPaintOptionsClass *options_class, + guint *base_property_id); + +static gboolean +gimp_brush_modifier_options_real_set_property (GimpBrushModifierOptions *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); + +static gboolean +gimp_brush_modifier_options_real_get_property (GimpBrushModifierOptions *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static gboolean +gimp_brush_modifier_options_real_notify (GimpBrushModifierOptions *object, + GParamSpec *pspec); + + +/* + * BrushModifier class definitions + * + * + */ + +G_DEFINE_TYPE (GimpBrushModifierOptions, gimp_brush_modifier_options, GIMP_TYPE_OBJECT) + +#define parent_class gimp_brush_modifier_options_parent_class + + +static void +gimp_brush_modifier_options_class_init (GimpBrushModifierOptionsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gimp_brush_modifier_options_finalize; + klass->install = gimp_brush_modifier_options_real_install; + klass->set_property = gimp_brush_modifier_options_real_set_property; + klass->get_property = gimp_brush_modifier_options_real_get_property; + klass->notify = gimp_brush_modifier_options_real_notify; + + klass->base_property_id = 0; + klass->installed = FALSE; +} + + +static void +gimp_brush_modifier_options_init (GimpBrushModifierOptions *options) +{ + options->enabled = TRUE; + options->attached_to = GIMP_TYPE_BRUSH_MODIFIER_CORE; +} + + +static void +gimp_brush_modifier_options_finalize (GObject *object) +{ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + +/* default method implementations */ + +static +gboolean gimp_brush_modifier_options_real_install(GimpBrushModifierOptionsClass *klass, + GimpPaintOptionsClass *options_class, + guint *base_property_id) +{ + klass->base_property_id = *base_property_id; + return TRUE; +} + + +static gboolean +gimp_brush_modifier_options_real_set_property (GimpBrushModifierOptions *options, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + return FALSE; +} + +static gboolean +gimp_brush_modifier_options_real_get_property (GimpBrushModifierOptions *options, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + return FALSE; +} + +static gboolean +gimp_brush_modifier_options_real_notify (GimpBrushModifierOptions *options, + GParamSpec *pspec) +{ + return FALSE; +} + + + +/* method definitions */ + +gboolean +gimp_brush_modifier_options_set_property (GimpBrushModifierOptions *options, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + return GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(options)->set_property(options, property_id, value, pspec); +} + +gboolean +gimp_brush_modifier_options_get_property (GimpBrushModifierOptions *options, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + return GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(options)->get_property(options, property_id, value, pspec); +} + + +gboolean +gimp_brush_modifier_options_notify (GimpBrushModifierOptions *options, + GParamSpec *pspec) +{ + return GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(options)->notify(options, pspec); +} + + +/* memory allocator */ + +GimpBrushModifierOptions * +gimp_brush_modifier_options_new () +{ + /* + GimpBrushModifierOptions *options; + + g_return_val_if_fail (GIMP_IS_BRUSH_MODIFIER_INFO (brush_modifier_info), NULL); + + options = g_object_new (brush_modifier_info->brush_modifier_options_type, + "gimp", brush_modifier_info->gimp, + "name", GIMP_OBJECT (brush_modifier_info)->name, + "brush_modifier-info", brush_modifier_info, + NULL); + + return options; + */ + return NULL; +} diff -uNr gimp-2.4.1/app/paint/gimpbrushmodifieroptions.h gimp-2.4.1-tmp/app/paint/gimpbrushmodifieroptions.h --- gimp-2.4.1/app/paint/gimpbrushmodifieroptions.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpbrushmodifieroptions.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,90 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_BRUSH_MODIFIER_OPTIONS_H__ +#define __GIMP_BRUSH_MODIFIER_OPTIONS_H__ + + +#include "gimppaintoptions.h" + +#define GIMP_TYPE_BRUSH_MODIFIER_OPTIONS (gimp_brush_modifier_options_get_type ()) +#define GIMP_BRUSH_MODIFIER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH_MODIFIER_OPTIONS, GimpBrushModifierOptions)) +#define GIMP_BRUSH_MODIFIER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_MODIFIER_OPTIONS, GimpBrushModifierOptionsClass)) +#define GIMP_IS_BRUSH_MODIFIER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_BRUSH_MODIFIER_OPTIONS)) +#define GIMP_IS_BRUSH_MODIFIER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_MODIFIER_OPTIONS)) +#define GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BRUSH_MODIFIER_OPTIONS, GimpBrushModifierOptionsClass)) + + +typedef struct _GimpBrushModifierOptionsClass GimpBrushModifierOptionsClass; +typedef struct _GimpBrushModifierOptions GimpBrushModifierOptions; + + +struct _GimpBrushModifierOptions +{ + GimpObject parent_instance; + + GType attached_to; + gboolean enabled; +}; + +struct _GimpBrushModifierOptionsClass +{ + GimpObjectClass parent_class; + + guint base_property_id; + gboolean installed; + + /* static function */ + gboolean (*install) (GimpBrushModifierOptionsClass *class, + GimpPaintOptionsClass *options_class, + guint *base_property_id); + + /* instance functions */ + gboolean (*set_property)(GimpBrushModifierOptions *options, + guint property_id, + const GValue *value, + GParamSpec *pspec); + + gboolean (*get_property)(GimpBrushModifierOptions *options, + guint property_id, + GValue *value, + GParamSpec *pspec); + + gboolean (*notify) (GimpBrushModifierOptions *options, + GParamSpec *pspec); +}; + +gboolean +gimp_brush_modifier_options_set_property(GimpBrushModifierOptions *options, + guint property_id, + const GValue *value, + GParamSpec *pspec); + +gboolean +gimp_brush_modifier_options_get_property(GimpBrushModifierOptions *options, + guint property_id, + GValue *value, + GParamSpec *pspec); + +gboolean +gimp_brush_modifier_options_notify (GimpBrushModifierOptions *options, + GParamSpec *pspec); + +GType gimp_brush_modifier_options_get_type (void) G_GNUC_CONST; + +#endif /* __GIMP_BRUSH_MODIFIER_OPTIONS_H__ */ diff -uNr gimp-2.4.1/app/paint/gimpcustombrush.c gimp-2.4.1-tmp/app/paint/gimpcustombrush.c --- gimp-2.4.1/app/paint/gimpcustombrush.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpcustombrush.c 2008-03-12 23:10:46.000000000 +0900 @@ -0,0 +1,458 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include + +#include "libgimpcolor/gimpcolor.h" +#include "libgimpmath/gimpmath.h" +#include "libgimpbase/gimpbase.h" + +#include "paint-types.h" + +#include "base/temp-buf.h" + +#include "paint-funcs/paint-funcs.h" + +#include "core/gimp.h" +#include "core/gimpbrush.h" +#include "core/gimpdrawable.h" +#include "core/gimplayer.h" +#include "core/gimpgradient.h" +#include "core/gimpimage.h" +#include "core/gimppickable.h" +#include "core/gimpprojection.h" +#include "base/pixel-region.h" + +#include "gimpcustombrush.h" +#include "gimpcustombrushoptions.h" + +#include "gimp-intl.h" + + +/* Debug option */ +//#define GIMP_CUSTOM_BRUSH_DEBUG_MIXING + + + + +static void gimp_custom_brush_load (GimpCustomBrush *object); +static void gimp_custom_brush_unload (GimpCustomBrush *object); + +static void gimp_custom_brush_finalize (GObject *object); +static void gimp_custom_brush_paint (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + GimpPaintState paint_state, + guint32 time); + +inline +static void gimp_custom_brush_start (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + +inline +static void gimp_custom_brush_motion (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + gdouble opacity, + guint32 time); + +inline +static void gimp_custom_brush_finish (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); +static gint +custom_brush_default_pre_paint (GimpBrushCorePasteCanvasInfo *info, + GimpBrushCore *brush_core, + GimpDrawable *drawable); + + + +/* class definition */ + +G_DEFINE_TYPE (GimpCustomBrush, gimp_custom_brush, GIMP_TYPE_PAINTBRUSH) + +#define parent_class gimp_custom_brush_parent_class + + +void +gimp_custom_brush_register (Gimp *gimp, + GimpPaintRegisterCallback callback) +{ + (* callback) (gimp, + GIMP_TYPE_CUSTOM_BRUSH, + GIMP_TYPE_CUSTOM_BRUSH_OPTIONS, + "gimp-custom-brush", + _("CustomBrush"), + "gimp-tool-custom-brush"); +} + +static void +gimp_custom_brush_class_init (GimpCustomBrushClass *klass) +{ + GimpPaintCoreClass *paint_core_class = GIMP_PAINT_CORE_CLASS (klass); + GimpBrushCoreClass *brush_core_class = GIMP_BRUSH_CORE_CLASS (klass); + + paint_core_class->paint = gimp_custom_brush_paint; + G_OBJECT_CLASS (klass)->finalize = gimp_custom_brush_finalize; + + brush_core_class->handles_changing_brush = TRUE; +} + + +static void +gimp_custom_brush_init (GimpCustomBrush *custom_brush) +{ + custom_brush->modifiers = NULL; + gimp_custom_brush_load(custom_brush); +} + + +static void +gimp_custom_brush_finalize (GObject *object) +{ + gimp_custom_brush_unload(GIMP_CUSTOM_BRUSH(object)); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +/* load modifiers (should be dynamically loaded) */ +#include "gimpblendmodifier.h" +#include "gimpsmoothmodifier.h" +static void +gimp_custom_brush_load (GimpCustomBrush *custom_brush) +{ + GimpBrushModifierCore* modifier; + + modifier = GIMP_BRUSH_MODIFIER_CORE(gimp_blend_modifier_new()); + custom_brush->modifiers = g_list_append(custom_brush->modifiers, (gpointer)modifier); + + modifier = GIMP_BRUSH_MODIFIER_CORE(gimp_smooth_modifier_new()); + custom_brush->modifiers = g_list_append(custom_brush->modifiers, (gpointer)modifier); +} + + + + +static void +gimp_custom_brush_delete_link (gpointer data, gpointer user_data) +{ + g_object_unref(G_OBJECT(data)); +} + + +static void +gimp_custom_brush_unload (GimpCustomBrush *custom_brush) +{ + g_list_foreach(custom_brush->modifiers, + gimp_custom_brush_delete_link, + NULL); + g_list_free(custom_brush->modifiers); +} + + + +static void +gimp_custom_brush_paint (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + GimpPaintState paint_state, + guint32 time) +{ + switch (paint_state) + { + case GIMP_PAINT_STATE_INIT: + gimp_custom_brush_start (paint_core, drawable, paint_options, time); + break; + + case GIMP_PAINT_STATE_MOTION: + gimp_custom_brush_motion (paint_core, drawable, paint_options, GIMP_OPACITY_OPAQUE, time); + break; + + case GIMP_PAINT_STATE_FINISH: + gimp_custom_brush_finish (paint_core, drawable, paint_options, time); + break; + + default: + break; + } +} + + +void +gimp_custom_brush_start (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time) +{ + GimpContext *context = GIMP_CONTEXT (paint_options); + GimpImage *image; + GimpCustomBrush *custom_brush = GIMP_CUSTOM_BRUSH(paint_core); + GimpBrushCore *brush_core = GIMP_BRUSH_CORE(paint_core); + GList *modifier; + GList *first; + GimpCustomBrushOptions *options; + BrushModifierDelegator *delegator; + guchar col[MAX_CHANNELS]; + TempBuf *area; + + first = g_list_first(custom_brush->modifiers); + options = GIMP_CUSTOM_BRUSH_OPTIONS(paint_options); + + + custom_brush->init_motion_delegator = NULL; + custom_brush->motion_delegator = NULL; + custom_brush->finish_motion_delegator = NULL; + custom_brush->register_paste_canvas_delegator = NULL; + + + /* construct delegator list */ + + for (modifier = first; modifier != NULL; modifier = g_list_next(modifier)) { + GimpBrushModifierCore *modifier_core; + GimpBrushModifierOptions *modifier_options; + GType type; + + modifier_core = GIMP_BRUSH_MODIFIER_CORE(modifier->data); + type = G_OBJECT_TYPE(modifier_core); + modifier_options = gimp_custom_brush_options_get_options_for(options, type); + + if (modifier_options && modifier_options->enabled) + { + custom_brush->init_motion_delegator = + brush_modifier_delegator_append(custom_brush->init_motion_delegator, + &modifier_core->init_motion_delegator); + + custom_brush->motion_delegator = + brush_modifier_delegator_append(custom_brush->motion_delegator, + &modifier_core->motion_delegator); + + custom_brush->finish_motion_delegator = + brush_modifier_delegator_append(custom_brush->finish_motion_delegator, + &modifier_core->finish_motion_delegator); + + custom_brush->register_paste_canvas_delegator = + brush_modifier_delegator_append(custom_brush->register_paste_canvas_delegator, + &modifier_core->register_paste_canvas_delegator); + } + } + + /* initialize state data */ + area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options); + if (! area) + return; + image = gimp_item_get_image (GIMP_ITEM (drawable)); + gimp_image_get_foreground (image, context, gimp_drawable_type (drawable), + col); + col[area->bytes - 1] = OPAQUE_OPACITY; + gimp_rgba_set_uchar(&custom_brush->state.color, col[0], col[1], col[2], col[3]); + + + /* invoke init_motion event chain */ + + for (delegator = custom_brush->init_motion_delegator; + delegator; + delegator = delegator->next) { + BrushModifierInitMotion callback; + callback = (BrushModifierInitMotion)delegator->callback; + (*callback)(delegator->modifier, + brush_core, + drawable, + paint_options, + time); + } +} + + + + +void +gimp_custom_brush_motion (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + gdouble opacity, + guint32 time) +{ + GimpCustomBrush *custom_brush = GIMP_CUSTOM_BRUSH(paint_core); + GimpContext *context = GIMP_CONTEXT (paint_options); + GimpBrushCore *brush_core = GIMP_BRUSH_CORE (paint_core); + GimpPressureOptions *pressure_options = paint_options->pressure_options; + GimpImage *image; + TempBuf *area; + GimpPaintApplicationMode paint_appl_mode; + BrushModifierDelegator* delegator; + gboolean do_paste = TRUE; + GimpBrushCorePasteCanvasInfo *head_info = NULL; + + + /* invoke motion event chain */ + for (delegator = custom_brush->motion_delegator; + delegator; + delegator = delegator->next) { + BrushModifierMotion callback; + callback = (BrushModifierMotion)delegator->callback; + (*callback)(delegator->modifier, + brush_core, + drawable, + paint_options, + time); + } + + image = gimp_item_get_image (GIMP_ITEM (drawable)); + paint_appl_mode = paint_options->application_mode; + + area = gimp_paint_core_get_paint_area (paint_core, drawable, paint_options); + if (! area) + return; + + opacity *= gimp_paint_options_get_fade (paint_options, image, + paint_core->pixel_dist); + if (opacity == 0.0) + return; + + + if (pressure_options->opacity) + opacity *= PRESSURE_SCALE * paint_core->cur_coords.pressure; + + + /* execute PASTE_CANVAS event chain: construct GimpBrushCorePasteCanvasInfo chain. */ + { + GimpLayerModeEffects effect = gimp_context_get_paint_mode(context); + GimpBrushApplicationMode brush_hardness = gimp_paint_options_get_brush_mode(paint_options); + gdouble image_opacity = gimp_context_get_opacity(context); + + for (delegator = custom_brush->register_paste_canvas_delegator; + delegator; + delegator = delegator->next) { + BrushModifierRegisterPasteCanvas callback; + callback = (BrushModifierRegisterPasteCanvas)delegator->callback; + do_paste = (*callback)(delegator->modifier, + &head_info, + brush_core, + paint_options, + drawable, + area, + CLAMP (opacity, 0, 1.0), + CLAMP (image_opacity, 0, 1.0), + effect, + brush_hardness, + paint_appl_mode) && do_paste; + } + + /* finally, let the brush core paste the prepared area on the canvas */ + if (do_paste) + { + GimpBrushCorePasteCanvasInfo brush_info; + if (!head_info) + { + /* if no modifier makes PasteCanvasInfo, then prepare default info structure. */ + brush_info.gimp_brush_area = area; + brush_info.brush_opacity = CLAMP (opacity, 0, 1.0); + brush_info.image_opacity = CLAMP (image_opacity, 0, 1.0); + brush_info.paint_mode = effect; + brush_info.apply = TRUE; + brush_info.brush_hardness = brush_hardness; + brush_info.post_paint = NULL; + brush_info.mode = paint_appl_mode; + + brush_info.pre_paint = custom_brush_default_pre_paint; + brush_info.apply_operation = NULL; + brush_info.paint_operation = NULL; + + brush_info.user_data = NULL; + brush_info.next = NULL; + head_info = &brush_info; + } + gimp_brush_core_process_paste_canvas (GIMP_BRUSH_CORE(paint_core), drawable, + head_info, + paint_appl_mode); + } + } +} + + +void +gimp_custom_brush_finish (GimpPaintCore *paint_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time) +{ + + GimpCustomBrush *custom_brush = GIMP_CUSTOM_BRUSH(paint_core); + GimpBrushCore *brush_core = GIMP_BRUSH_CORE(paint_core); + + /* invoke finish_motion event chain */ + BrushModifierDelegator* delegator; + + for (delegator = custom_brush->finish_motion_delegator; + delegator; + delegator = delegator->next) { + BrushModifierFinishMotion callback; + callback = (BrushModifierFinishMotion)delegator->callback; + (*callback)(delegator->modifier, + brush_core, + drawable, + paint_options, + time); + } +} + + +/* + * BrushCorePasteCanvasInfo Implementation + * + */ +static gint +custom_brush_default_pre_paint (GimpBrushCorePasteCanvasInfo *info, + GimpBrushCore *brush_core, + GimpDrawable *drawable) +{ + GimpCustomBrush *custom_brush = GIMP_CUSTOM_BRUSH(brush_core); + // GimpRGB gradient_color; + TempBuf *area = info->gimp_brush_area; + guchar col[MAX_CHANNELS]; + GimpPaintApplicationMode paint_appl_mode = info->mode; + + /* otherwise check if the brush has a pixmap and use that to color the area */ + if (brush_core->brush && brush_core->brush->pixmap) + { + gimp_brush_core_color_area_with_pixmap (brush_core, drawable, + area, + info->brush_hardness); + + paint_appl_mode = GIMP_PAINT_INCREMENTAL; + } + /* otherwise fill the area with the foreground color */ + else + { + gimp_rgba_get_uchar(&custom_brush->state.color, + &col[0], &col[1], &col[2], &col[3]); + + col[area->bytes - 1] = OPAQUE_OPACITY; + + color_pixels (temp_buf_data (area), col, + area->width * area->height, + area->bytes); + } + return 0; +} diff -uNr gimp-2.4.1/app/paint/gimpcustombrush.h gimp-2.4.1-tmp/app/paint/gimpcustombrush.h --- gimp-2.4.1/app/paint/gimpcustombrush.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpcustombrush.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,62 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_CUSTOM_BRUSH_H__ +#define __GIMP_CUSTOM_BRUSH_H__ + + +#include "gimppaintbrush.h" +#include "gimpbrushmodifiercore.h" + + +#define GIMP_TYPE_CUSTOM_BRUSH (gimp_custom_brush_get_type ()) +#define GIMP_CUSTOM_BRUSH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CUSTOM_BRUSH, GimpCustomBrush)) +#define GIMP_CUSTOM_BRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CUSTOM_BRUSH, GimpCustomBrushClass)) +#define GIMP_IS_CUSTOM_BRUSH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CUSTOM_BRUSH)) +#define GIMP_IS_CUSTOM_BRUSH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CUSTOM_BRUSH)) +#define GIMP_CUSTOM_BRUSH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CUSTOM_BRUSH, GimpCustomBrushClass)) + +struct _GimpCustomBrush +{ + GimpPaintbrush parent_instance; + + GimpDrawable *drawable; + GimpPaintOptions *paint_options; + GimpCustomBrushState state; + + GList *modifiers; + BrushModifierDelegator *init_motion_delegator; + BrushModifierDelegator *motion_delegator; + BrushModifierDelegator *finish_motion_delegator; + BrushModifierDelegator *register_paste_canvas_delegator; + +}; + +typedef struct _GimpCustomBrushClass +{ + GimpPaintbrushClass parent_class; +} GimpCustomBrushClass; + + +void gimp_custom_brush_register (Gimp *gimp, + GimpPaintRegisterCallback callback); + +GType gimp_custom_brush_get_type (void) G_GNUC_CONST; + + +#endif /* __GIMP_CUSTOM_BRUSH_H__ */ diff -uNr gimp-2.4.1/app/paint/gimpcustombrushoptions.c gimp-2.4.1-tmp/app/paint/gimpcustombrushoptions.c --- gimp-2.4.1/app/paint/gimpcustombrushoptions.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpcustombrushoptions.c 2008-03-12 23:11:16.000000000 +0900 @@ -0,0 +1,247 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpconfig/gimpconfig.h" + +#include "paint-types.h" + +#include "gimpcustombrushoptions.h" + +static void +gimp_custom_brush_options_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void +gimp_custom_brush_options_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +/* + * class definition + * + * + */ +G_DEFINE_TYPE (GimpCustomBrushOptions, gimp_custom_brush_options, + GIMP_TYPE_PAINT_OPTIONS) + +#define parent_class gimp_custom_brush_options_parent_class + + + +static void +gimp_custom_brush_options_register (GimpCustomBrushOptions *options, + GimpBrushModifierOptions* modifier); + +static void +gimp_custom_brush_options_load (GimpCustomBrushOptions *options); + + + + +void +gimp_custom_brush_options_register(GimpCustomBrushOptions *options, + GimpBrushModifierOptions *modifier) +{ + GimpBrushModifierOptionsClass *modifier_class; + GimpPaintOptionsClass *options_class; + guint n_properties; + + + modifier_class = GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(modifier); + options_class = GIMP_PAINT_OPTIONS_GET_CLASS(options); + + if (!modifier_class->installed) + { + g_object_class_list_properties(G_OBJECT_CLASS(options_class), &n_properties); + modifier_class->install(modifier_class, options_class, &n_properties); + modifier_class->installed = TRUE; + } +} + + +static void +gimp_custom_brush_options_class_init (GimpCustomBrushOptionsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gimp_custom_brush_options_set_property; + object_class->get_property = gimp_custom_brush_options_get_property; +} + + +static void +custom_brush_delete_hash (gpointer key, gpointer value, gpointer user_data) +{ + GObject *object = G_OBJECT(value); + g_object_unref(object); +} + + +static void +gimp_custom_brush_options_init (GimpCustomBrushOptions *options) +{ + options->modifier_options = g_hash_table_new(g_direct_hash, g_int_equal); + + g_print("[Trace]custom_brush_options::init\n"); + + gimp_custom_brush_options_load(options); +} + + +static void +gimp_custom_brush_options_finalize (GObject *object) +{ + GimpCustomBrushOptions *options = GIMP_CUSTOM_BRUSH_OPTIONS(object); + g_hash_table_foreach(options->modifier_options, custom_brush_delete_hash, NULL); + g_hash_table_destroy(options->modifier_options); +} + + + +/* load modifier options (should be dynamically loaded) */ +#include "gimpblendmodifieroptions.h" +#include "gimpsmoothmodifieroptions.h" +void +gimp_custom_brush_options_load(GimpCustomBrushOptions *options) +{ + GimpBrushModifierOptions* modifier; + + modifier = GIMP_BRUSH_MODIFIER_OPTIONS(g_object_new (GIMP_TYPE_BLEND_MODIFIER_OPTIONS, NULL)); + g_hash_table_insert(options->modifier_options, (gpointer)modifier->attached_to, modifier); + // g_print("add type=%x, ptr=%x\n", (gpointer)modifier->attached_to, modifier); + gimp_custom_brush_options_register(options, modifier); + + // g_print("hash_size=%d\n", g_hash_table_size(options->modifier_options)); + + modifier = GIMP_BRUSH_MODIFIER_OPTIONS(g_object_new (GIMP_TYPE_SMOOTH_MODIFIER_OPTIONS, NULL)); + g_hash_table_insert(options->modifier_options, (gpointer)modifier->attached_to, modifier); + // g_print("add type=%x, ptr=%x\n", (gpointer)modifier->attached_to, modifier); + + // g_print("hash_size=%d\n", g_hash_table_size(options->modifier_options)); + gimp_custom_brush_options_register(options, modifier); +} + + +static void +gimp_custom_brush_options_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpCustomBrushOptions *options = GIMP_CUSTOM_BRUSH_OPTIONS(object); +#if 0 + // GHashTableIter is introduced since 2.16 ... + GHashTableIter iter; + gpointer key, value; + g_hash_table_iter_init (&iter, options->modifier_options); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + GimpBrushModifierOptions *modifier_option = GIMP_BRUSH_MODIFIER_OPTIONS(value); + if (gimp_brush_modifier_options_set_property(modifier_option, prperty_id, value, pspec)) + { + return; + } + } +#else + struct SetPropertyCallback { + GObject *object; + guint property_id; + const GValue *value; + GParamSpec *pspec; + gboolean result; + }; + struct SetPropertyCallback args = { object, property_id, value, pspec, FALSE }; + void custom_brush_set_property_callback(gpointer key, gpointer value, gpointer user_data) { + GimpBrushModifierOptions *modifier_option = GIMP_BRUSH_MODIFIER_OPTIONS(value); + struct SetPropertyCallback* callback_data = (struct SetPropertyCallback*)user_data; + callback_data->result = + callback_data->result || + gimp_brush_modifier_options_set_property(modifier_option, + callback_data->property_id, + callback_data->value, + callback_data->pspec); + } + g_hash_table_foreach(options->modifier_options, custom_brush_set_property_callback, &args); + if (args.result) + return; +#endif + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +gimp_custom_brush_options_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpCustomBrushOptions *options = GIMP_CUSTOM_BRUSH_OPTIONS(object); +#if 0 + // GHashTableIter is introduced since 2.16 ... + GHashTableIter iter; + gpointer key, value; + g_hash_table_iter_init (&iter, options->modifier_options); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + GimpBrushModifierOptions *modifier_option = GIMP_BRUSH_MODIFIER_OPTIONS(value); + if (gimp_brush_modifier_options_get_property(modifier_option, prperty_id, value, pspec)) + { + return; + } + } +#else + + struct GetPropertyCallback { + GObject *object; + guint property_id; + GValue *value; + GParamSpec *pspec; + gboolean result; + }; + struct GetPropertyCallback args = { object, property_id, value, pspec, FALSE }; + void custom_brush_get_property_callback(gpointer key, gpointer value, gpointer user_data) { + GimpBrushModifierOptions *modifier_option = GIMP_BRUSH_MODIFIER_OPTIONS(value); + struct GetPropertyCallback* callback_data = (struct GetPropertyCallback*)user_data; + callback_data->result = + callback_data->result || + gimp_brush_modifier_options_get_property(modifier_option, + callback_data->property_id, + callback_data->value, + callback_data->pspec); + } + g_hash_table_foreach(options->modifier_options, custom_brush_get_property_callback, &args); + if (args.result) + return; + +#endif + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + + +GimpBrushModifierOptions* +gimp_custom_brush_options_get_options_for (GimpCustomBrushOptions *options, + GType type) +{ + return GIMP_BRUSH_MODIFIER_OPTIONS(g_hash_table_lookup(options->modifier_options, (gpointer)type)); +} + diff -uNr gimp-2.4.1/app/paint/gimpcustombrushoptions.h gimp-2.4.1-tmp/app/paint/gimpcustombrushoptions.h --- gimp-2.4.1/app/paint/gimpcustombrushoptions.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpcustombrushoptions.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,59 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_CUSTOM_BRUSH_OPTIONS_H__ +#define __GIMP_CUSTOM_BRUSH_OPTIONS_H__ + + +#include "gimppaintoptions.h" +#include "gimpbrushmodifieroptions.h" + + + +#define GIMP_TYPE_CUSTOM_BRUSH_OPTIONS (gimp_custom_brush_options_get_type ()) +#define GIMP_CUSTOM_BRUSH_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CUSTOM_BRUSH_OPTIONS, GimpCustomBrushOptions)) +#define GIMP_CUSTOM_BRUSH_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CUSTOM_BRUSH_OPTIONS, GimpCustomBrushOptionsClass)) +#define GIMP_IS_CUSTOM_BRUSH_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CUSTOM_BRUSH_OPTIONS)) +#define GIMP_IS_CUSTOM_BRUSH_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CUSTOM_BRUSH_OPTIONS)) +#define GIMP_CUSTOM_BRUSH_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CUSTOM_BRUSH_OPTIONS, GimpCustomBrushOptionsClass)) + + +typedef struct _GimpCustomBrushOptionsClass GimpCustomBrushOptionsClass; + +struct _GimpCustomBrushOptions +{ + GimpPaintOptions parent_instance; + GHashTable *modifier_options; +}; + +struct _GimpCustomBrushOptionsClass +{ + GimpPaintOptionsClass parent_class; +}; + + +GimpBrushModifierOptions* +gimp_custom_brush_options_get_options_for (GimpCustomBrushOptions *options, + GType type); + + +GType gimp_custom_brush_options_get_type (void) G_GNUC_CONST; + + +#endif /* __GIMP_CUSTOM_BRUSH_OPTIONS_H__ */ diff -uNr gimp-2.4.1/app/paint/gimppaintcore.c gimp-2.4.1-tmp/app/paint/gimppaintcore.c --- gimp-2.4.1/app/paint/gimppaintcore.c 2007-09-22 04:40:01.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimppaintcore.c 2008-03-12 23:08:27.000000000 +0900 @@ -873,6 +873,167 @@ core->canvas_buf->height); } + +/* + * Apply two or more paint mask to the canvas + */ +void +gimp_paint_core_paste_mask_list (GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintMaskInfo *info, + GimpPaintApplicationMode mode) +{ + GimpImage *image; + TileManager *alt = NULL; + gint off_x; + gint off_y; + gboolean canvas_valid = FALSE; + + image = gimp_item_get_image (GIMP_ITEM (drawable)); + + gimp_item_offsets (GIMP_ITEM (drawable), &off_x, &off_y); + + /* set undo blocks */ + gimp_paint_core_validate_undo_tiles (core, drawable, + core->canvas_buf->x, + core->canvas_buf->y, + core->canvas_buf->width, + core->canvas_buf->height); + + if (core->use_saved_proj) + { + GimpPickable *pickable = GIMP_PICKABLE (image->projection); + + gimp_paint_core_validate_saved_proj_tiles (core, pickable, + core->canvas_buf->x + off_x, + core->canvas_buf->y + off_y, + core->canvas_buf->width, + core->canvas_buf->height); + } + + while (info) + { + alt = NULL; + + /* If the mode is CONSTANT: + * combine the canvas buf, the paint mask to the canvas tiles + */ + if (mode == GIMP_PAINT_CONSTANT) + { + /* Some tools (ink) paint the mask to paint_core->canvas_tiles + * directly. Don't need to copy it in this case. + */ + if (info->paint_maskPR->tiles != core->canvas_tiles) + { + // if (!canvas_valid) + { + /* initialize any invalid canvas tiles */ + gimp_paint_core_validate_canvas_tiles (core, + core->canvas_buf->x, + core->canvas_buf->y, + core->canvas_buf->width, + core->canvas_buf->height); + canvas_valid = TRUE; + } + + if (info->pre_paint) + info->pre_paint (info, core, drawable, mode); + + if (info->paint_operation) + { + PixelRegion srcPR; + + /* combine the paint mask and the canvas tiles */ + pixel_region_init (&srcPR, core->canvas_tiles, + core->canvas_buf->x, + core->canvas_buf->y, + core->canvas_buf->width, + core->canvas_buf->height, + TRUE); + + info->paint_operation (info, core, drawable, mode, &srcPR); + } + else + { + paint_mask_to_canvas_tiles (core, info->paint_maskPR, info->paint_opacity); + } + + if (info->post_paint) + info->post_paint (info, core, drawable, mode); + } + + canvas_tiles_to_canvas_buf (core); + alt = core->undo_tiles; + } + /* Otherwise: + * combine the canvas buf and the paint mask to the canvas buf + */ + else + { + if (info->pre_paint) + info->pre_paint (info, core, drawable, mode); + + + /* combine the canvas buf and the paint mask to the canvas buf */ + if (info->paint_operation) + { + PixelRegion srcPR; + pixel_region_init_temp_buf (&srcPR, core->canvas_buf, + 0, 0, + core->canvas_buf->width, + core->canvas_buf->height); + info->paint_operation (info, core, drawable, mode, &srcPR); + } + else + { + paint_mask_to_canvas_buf (core, info->paint_maskPR, info->paint_opacity); + } + + + if (info->post_paint) + info->post_paint (info, core, drawable, mode); + } + + /* intialize canvas buf source pixel regions */ + if (info->apply) { + PixelRegion srcPR; + pixel_region_init_temp_buf (&srcPR, core->canvas_buf, + 0, 0, + core->canvas_buf->width, + core->canvas_buf->height); + + /* apply the paint area to the image */ + if (info->apply_operation) + info->apply_operation(info, core, drawable, mode, &srcPR, alt); + else { + gimp_drawable_apply_region (drawable, &srcPR, + FALSE, NULL, + info->image_opacity, info->paint_mode, + alt, /* specify an alternative src1 */ + core->canvas_buf->x, + core->canvas_buf->y); + } + } + + info = info->next; + } + /* 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); + + /* Update the image -- It is important to call gimp_image_update() + * instead of gimp_drawable_update() because we don't want the + * drawable preview to be constantly invalidated + */ + gimp_image_update (image, + core->canvas_buf->x + off_x, + core->canvas_buf->y + off_y, + core->canvas_buf->width, + core->canvas_buf->height); +} + /* This works similarly to gimp_paint_core_paste. However, instead of * combining the canvas to the paint core drawable using one of the * combination modes, it uses a "replace" mode (i.e. transparent diff -uNr gimp-2.4.1/app/paint/gimppaintcore.h gimp-2.4.1-tmp/app/paint/gimppaintcore.h --- gimp-2.4.1/app/paint/gimppaintcore.h 2007-04-25 00:12:31.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimppaintcore.h 2008-03-12 23:08:27.000000000 +0900 @@ -34,6 +34,41 @@ typedef struct _GimpPaintCoreClass GimpPaintCoreClass; +typedef struct _GimpPaintMaskInfo GimpPaintMaskInfo; +typedef gint (*GimpPaintMaskPaintDelegator) (GimpPaintMaskInfo *info, + GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintApplicationMode mode, + PixelRegion *srcPR); + +typedef gint (*GimpPaintMaskApplicationDelegator) (GimpPaintMaskInfo *info, + GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintApplicationMode mode, + PixelRegion *srcPR, + TileManager* *undo_tiles); + +typedef gint (*GimpPaintMaskEventCallback) (GimpPaintMaskInfo *info, + GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintApplicationMode mode); + +struct _GimpPaintMaskInfo +{ + PixelRegion *paint_maskPR; + gdouble paint_opacity; + gdouble image_opacity; + gboolean apply; + GimpLayerModeEffects paint_mode; + + GimpPaintMaskEventCallback pre_paint; + GimpPaintMaskEventCallback post_paint; + GimpPaintMaskPaintDelegator paint_operation; + GimpPaintMaskApplicationDelegator apply_operation; + void *delegator_data; + GimpPaintMaskInfo *next; +}; + struct _GimpPaintCore { GimpObject parent_instance; @@ -159,6 +194,10 @@ gdouble image_opacity, GimpLayerModeEffects paint_mode, GimpPaintApplicationMode mode); +void gimp_paint_core_paste_mask_list (GimpPaintCore *core, + GimpDrawable *drawable, + GimpPaintMaskInfo *info, + GimpPaintApplicationMode mode); void gimp_paint_core_replace (GimpPaintCore *core, PixelRegion *paint_maskPR, GimpDrawable *drawable, diff -uNr gimp-2.4.1/app/paint/gimpsmoothmodifier.c gimp-2.4.1-tmp/app/paint/gimpsmoothmodifier.c --- gimp-2.4.1/app/paint/gimpsmoothmodifier.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpsmoothmodifier.c 2008-03-12 23:24:54.000000000 +0900 @@ -0,0 +1,432 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include + +#include "libgimpcolor/gimpcolor.h" +#include "libgimpmath/gimpmath.h" +#include "libgimpbase/gimpbase.h" + +#include "paint-types.h" + +#include "base/temp-buf.h" + +#include "paint-funcs/paint-funcs.h" + +#include "core/gimp.h" +#include "core/gimpbrush.h" +#include "core/gimpdrawable.h" +#include "core/gimplayer.h" +#include "core/gimpgradient.h" +#include "core/gimpimage.h" +#include "core/gimppickable.h" +#include "core/gimpprojection.h" +#include "base/pixel-region.h" + +#include "gimpsmoothmodifier.h" +#include "gimpcustombrushoptions.h" +#include "gimpsmoothmodifieroptions.h" + +#include "gimp-intl.h" + + + +static void gimp_smooth_modifier_finalize (GObject *object); + +static gboolean gimp_smooth_modifier_init_motion (GimpBrushModifierCore* core, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); + +static gboolean gimp_smooth_modifier_motion (GimpBrushModifierCore* core, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time); +static gdouble PI; + +#define HIST_IGNORE_THRESHOULD 0.0001 + +/* + * Utility functions + * + */ + + +/* Time and Dist smoothing functions (taken from GimpInk) */ + +static void +time_smoother_init (GimpSmoothModifier *modifier, + guint32 initval) +{ + gint i; + + modifier->ts_index = 0; + + for (i = 0; i < GIMP_SMOOTH_MODIFIER_TIME_SMOOTHER_BUFFER; i++) + modifier->ts_buffer[i] = initval; +} + +static guint32 +time_smoother_result (GimpSmoothModifier *modifier) +{ + gint i; + guint64 result = 0; + + for (i = 0; i < GIMP_SMOOTH_MODIFIER_TIME_SMOOTHER_BUFFER; i++) + result += modifier->ts_buffer[i]; + + return (result / (guint64) GIMP_SMOOTH_MODIFIER_TIME_SMOOTHER_BUFFER); +} + +static void +time_smoother_add (GimpSmoothModifier *modifier, + guint32 value) +{ + guint64 long_value = (guint64) value; + + /* handle wrap-around of time values */ + if (long_value < modifier->ts_buffer[modifier->ts_index]) + long_value += (guint64) + G_MAXUINT32; + + modifier->ts_buffer[modifier->ts_index++] = long_value; + + modifier->ts_buffer[modifier->ts_index++] = value; + + if (modifier->ts_index == GIMP_SMOOTH_MODIFIER_TIME_SMOOTHER_BUFFER) + modifier->ts_index = 0; +} + + +static void +dist_smoother_init (GimpSmoothModifier *modifier, + gdouble initval) +{ + gint i; + + modifier->dt_index = 0; + + for (i = 0; i < GIMP_SMOOTH_MODIFIER_DIST_SMOOTHER_BUFFER; i++) + modifier->dt_buffer[i] = initval; +} + +static gdouble +dist_smoother_result (GimpSmoothModifier *modifier) +{ + gint i; + gdouble result = 0.0; + + for (i = 0; i < GIMP_SMOOTH_MODIFIER_DIST_SMOOTHER_BUFFER; i++) + result += modifier->dt_buffer[i]; + + return (result / (gdouble) GIMP_SMOOTH_MODIFIER_DIST_SMOOTHER_BUFFER); +} + +static void +dist_smoother_add (GimpSmoothModifier *modifier, + gdouble value) +{ + modifier->dt_buffer[modifier->dt_index++] = value; + + if (modifier->dt_index == GIMP_SMOOTH_MODIFIER_DIST_SMOOTHER_BUFFER) + modifier->dt_index = 0; +} + +/* Coords history */ +/* + * [Memo] + * paint_history_* functions should be moved into GimpPaintCore in the future + * because G-pen patch can share the code. + */ +static inline void +history_init (GimpSmoothModifier *modifier) +{ + modifier->hist_index = 0; + modifier->hist_count = 0; +} + + +static inline gint +history_get_length (GimpSmoothModifier *modifier) +{ + return modifier->hist_count; +} + + +static inline void +history_add (GimpSmoothModifier *modifier, + GimpCoords *coords, + gdouble pixel_dist) +{ + gdouble dist = 0; + + if (coords) { + if (modifier->hist_count > 0) { + gint prev_index = (modifier->hist_index + GIMP_SMOOTH_MODIFIER_MAX_HISTORY - 1) % GIMP_SMOOTH_MODIFIER_MAX_HISTORY; + gdouble dist_x = coords->x - modifier->history[prev_index].cur_coords.x; + gdouble dist_y = coords->y - modifier->history[prev_index].cur_coords.y; + + dist = sqrt(dist_x * dist_x + dist_y * dist_y); + + if (dist < HIST_IGNORE_THRESHOULD) + return; + } + modifier->history[modifier->hist_index].cur_coords = *coords; + modifier->history[modifier->hist_index].pixel_dist = pixel_dist; + modifier->hist_index ++; + + if (modifier->hist_count < GIMP_SMOOTH_MODIFIER_MAX_HISTORY) + modifier->hist_count ++; + + if (modifier->hist_index == GIMP_SMOOTH_MODIFIER_MAX_HISTORY) + modifier->hist_index = 0; + } +} + + +static GimpCoords +history_result(GimpSmoothModifier *modifier, + guint history_size, + gdouble rate) +{ + gint i; + GimpCoords result; + gdouble scale_sum = 0.0; + result.x = result.y = 0.0; + if (modifier->hist_count > 0) { + gint max_hist_count = MIN(modifier->hist_count , history_size); + gint cur_index = (modifier->hist_index + GIMP_SMOOTH_MODIFIER_MAX_HISTORY - 1) % GIMP_SMOOTH_MODIFIER_MAX_HISTORY; + + gdouble gaussian_weight = 0.0; + gdouble gaussian_weight2; + gdouble dist_sum = 0.0; + + gdouble base_rate = 0.0; + + gaussian_weight2 = rate * rate; + + if (gaussian_weight2 != 0.0) + gaussian_weight = 1 / (sqrt(2 * PI) * rate); + + for (i = 0; i < max_hist_count; i ++, cur_index --) + { + gdouble rate = 0; + if (cur_index == -1) + cur_index = GIMP_SMOOTH_MODIFIER_MAX_HISTORY - 1; + + if (gaussian_weight2 != 0) + { + /* We use gaussian function with velocity as a window function */ + dist_sum += modifier->history[cur_index].pixel_dist; + rate = gaussian_weight * exp(-dist_sum*dist_sum / (2*gaussian_weight2)); + /* If i == 0 && rate == 0.0, resulting value becomes zero. + * To avoid this, we treat this as a special case. + */ + if (i == 0 && rate == 0.0) + rate = 1.0; +#if 0 + //Debug + if (base_rate == 0.0) + base_rate = rate; + g_print("%d:(x %3.5f)", i, base_rate > 0 ? rate / base_rate : 0); +#endif + } + else + { + rate = (i == 0) ? 1.0: 0.0; + } + scale_sum += rate; + result.x += rate * modifier->history[cur_index].cur_coords.x; + result.y += rate * modifier->history[cur_index].cur_coords.y; + } +#if 0 + g_print("\n"); +#endif + + if (scale_sum != 0.0) + { + result.x /= scale_sum; + result.y /= scale_sum; + } + } + return result; +} + + + + +/* + * GimpCustombrush class implementation + * + * + */ + + +G_DEFINE_TYPE (GimpSmoothModifier, gimp_smooth_modifier, GIMP_TYPE_BRUSH_MODIFIER_CORE) + +#define parent_class gimp_smooth_modifier_parent_class + + +static void +gimp_smooth_modifier_class_init (GimpSmoothModifierClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = gimp_smooth_modifier_finalize; + + PI = 4 * atan(1); +} + +static void +gimp_smooth_modifier_init (GimpSmoothModifier *smooth_modifier) +{ + GimpBrushModifierCore* modifier; + modifier = GIMP_BRUSH_MODIFIER_CORE(smooth_modifier); + + g_print("smooth_modifier::init\n"); + brush_modifier_delegator_bind(&modifier->init_motion_delegator, modifier, gimp_smooth_modifier_init_motion); + brush_modifier_delegator_bind(&modifier->motion_delegator, modifier, gimp_smooth_modifier_motion); +} + + +static void +gimp_smooth_modifier_finalize (GObject *object) +{ + g_print("smooth_modifier::finalize\n"); + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + + +GimpSmoothModifier* gimp_smooth_modifier_new(void) +{ + GimpSmoothModifier* result = (GimpSmoothModifier*)g_object_new(GIMP_TYPE_SMOOTH_MODIFIER, NULL); + g_assert( result != NULL ); + return result; +} + + + + +static gboolean +gimp_smooth_modifier_init_motion (GimpBrushModifierCore* modifier, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time) +{ + GimpSmoothModifier *smooth_modifier = GIMP_SMOOTH_MODIFIER (modifier); + GimpPaintCore *paint_core = GIMP_PAINT_CORE (brush_core); + history_init (smooth_modifier); + time_smoother_init (smooth_modifier, 0); + + history_add (smooth_modifier, &paint_core->cur_coords, 0); + time_smoother_add(smooth_modifier, time); + dist_smoother_init (smooth_modifier, 0.0); + smooth_modifier->last_time = time; + + return TRUE; +} + + +static gboolean +gimp_smooth_modifier_motion (GimpBrushModifierCore* modifier, + GimpBrushCore *brush_core, + GimpDrawable *drawable, + GimpPaintOptions *paint_options, + guint32 time) +{ + GimpSmoothModifier *smooth_modifier = GIMP_SMOOTH_MODIFIER(modifier); + GimpCustomBrushOptions *custom_brush_options = GIMP_CUSTOM_BRUSH_OPTIONS(paint_options); + GimpPaintCore *paint_core = GIMP_PAINT_CORE(brush_core); + GimpSmoothModifierOptions *options; + + gdouble dist; + // gdouble velocity; + guint32 lasttime = smooth_modifier->last_time; + guint32 thistime; + GimpCoords average_hist; + // GimpCoords average_velocity; + + options = GIMP_SMOOTH_MODIFIER_OPTIONS(gimp_custom_brush_options_get_options_for(custom_brush_options, G_OBJECT_TYPE(modifier))); + + time_smoother_add (smooth_modifier, time); + thistime = smooth_modifier->last_time = time_smoother_result (smooth_modifier); + + /* The time resolution on X-based GDK motion events is bloody + * awful, hence the use of the smoothing function. Sadly this + * also means that there is always the chance of having an + * indeterminite velocity since this event and the previous + * several may still appear to issue at the same + * instant. -ADM + */ + if (thistime == lasttime) + thistime = lasttime + 1; + + dist = sqrt ((paint_core->last_coords.x - paint_core->cur_coords.x) * + (paint_core->last_coords.x - paint_core->cur_coords.x) + + (paint_core->last_coords.y - paint_core->cur_coords.y) * + (paint_core->last_coords.y - paint_core->cur_coords.y)); + + if (smooth_modifier->init_velocity) + { + dist_smoother_init (smooth_modifier, dist); + smooth_modifier->init_velocity = FALSE; + } + else + { + dist_smoother_add (smooth_modifier, dist); + dist = dist_smoother_result (smooth_modifier); + } + + // velocity = 10.0 * sqrt ((dist) / (gdouble) (thistime - lasttime)); + + if (options->smoothing_hist_size > 1) + { + history_add(smooth_modifier, &paint_core->cur_coords, + options->distance_scale > 0 ? dist / options->distance_scale : 0.0); + average_hist = history_result(smooth_modifier, options->smoothing_hist_size, options->smoothing_rate); + paint_core->cur_coords.x = average_hist.x; + paint_core->cur_coords.y = average_hist.y; + } +#if 0 + { + gint a; + gdouble weight = 0; + gdouble dist = 0; + for (a = smooth_modifier->hist_count - 1; a >= 0; a --) { + gint index = smooth_modifier->hist_index + a; + while (index >= 20) + index -= 20; + GimpCoords* coords = &smooth_modifier->history[index].cur_coords; + dist += smooth_modifier->history[index].pixel_dist; + if (weight == 0) + weight = dist; + // g_print(" %d: %f, %f, %f(x %3.5f)\n", a, coords->x, coords->y, dist, weight > 0 ? dist / weight : 0); + g_print("%d:(x %3.5f)", a, weight > 0 ? dist / weight : 0); + } + g_print("\n"); + } + + g_print(" -> %f, %f\n", paint_core->cur_coords.x, paint_core->cur_coords.y); +#endif + return TRUE; +} diff -uNr gimp-2.4.1/app/paint/gimpsmoothmodifier.h gimp-2.4.1-tmp/app/paint/gimpsmoothmodifier.h --- gimp-2.4.1/app/paint/gimpsmoothmodifier.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpsmoothmodifier.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,78 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_SMOOTH_MODIFIER_H__ +#define __GIMP_SMOOTH_MODIFIER_H__ + + +#include "gimpbrushmodifiercore.h" + + +#define GIMP_TYPE_SMOOTH_MODIFIER (gimp_smooth_modifier_get_type ()) +#define GIMP_SMOOTH_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SMOOTH_MODIFIER, GimpSmoothModifier)) +#define GIMP_SMOOTH_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SMOOTH_MODIFIER, GimpSmoothModifierClass)) +#define GIMP_IS_SMOOTH_MODIFIER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SMOOTH_MODIFIER)) +#define GIMP_IS_SMOOTH_MODIFIER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SMOOTH_MODIFIER)) +#define GIMP_SMOOTH_MODIFIER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SMOOTH_MODIFIER, GimpSmoothModifierClass)) + + +typedef struct _GimpSmoothModifierCoordsHistory +{ + GimpCoords cur_coords; + gdouble pixel_dist; +} GimpSmoothModifierCoordsHistory; + +typedef struct _GimpSmoothModifier GimpSmoothModifier; +typedef struct _GimpSmoothModifierClass GimpSmoothModifierClass; + + +#define GIMP_SMOOTH_MODIFIER_DIST_SMOOTHER_BUFFER 10 +#define GIMP_SMOOTH_MODIFIER_TIME_SMOOTHER_BUFFER 10 + +#define GIMP_SMOOTH_MODIFIER_MAX_HISTORY 20 +struct _GimpSmoothModifier +{ + GimpBrushModifierCore parent_instance; + + guint32 last_time; + gdouble init_velocity; + + guint32 ts_buffer[GIMP_SMOOTH_MODIFIER_TIME_SMOOTHER_BUFFER]; + gint ts_index; + + /* circular distance history buffer */ + gdouble dt_buffer[GIMP_SMOOTH_MODIFIER_DIST_SMOOTHER_BUFFER]; + gint dt_index; + + /* circular history buffer */ + GimpSmoothModifierCoordsHistory history[GIMP_SMOOTH_MODIFIER_MAX_HISTORY + 1]; + gint hist_count; + gint hist_index; +}; + +struct _GimpSmoothModifierClass +{ + GimpBrushModifierCoreClass parent_class; +}; + + +GType gimp_smooth_modifier_get_type (void) G_GNUC_CONST; +GimpSmoothModifier* gimp_smooth_modifier_new(void); + + +#endif diff -uNr gimp-2.4.1/app/paint/gimpsmoothmodifieroptions.c gimp-2.4.1-tmp/app/paint/gimpsmoothmodifieroptions.c --- gimp-2.4.1/app/paint/gimpsmoothmodifieroptions.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpsmoothmodifieroptions.c 2008-03-12 23:24:21.000000000 +0900 @@ -0,0 +1,199 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpconfig/gimpconfig.h" +#include "paint-types.h" +#include "core/gimp.h" + +#include "gimpsmoothmodifier.h" +#include "gimpsmoothmodifieroptions.h" + + +static gboolean +gimp_smooth_modifier_options_install (GimpBrushModifierOptionsClass *klass, + GimpPaintOptionsClass *options_class, + guint *base_property_id); + + + +static gboolean +gimp_smooth_modifier_options_set_property (GimpBrushModifierOptions *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static gboolean +gimp_smooth_modifier_options_get_property (GimpBrushModifierOptions *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + + +enum +{ + PROP_0, + PROP_ENABLED, + PROP_COMPENSATION_HIST_SIZE, + PROP_DISTANCE_SCALE, + PROP_COMPENSATION_RATE +}; + +G_DEFINE_TYPE (GimpSmoothModifierOptions, gimp_smooth_modifier_options, + GIMP_TYPE_BRUSH_MODIFIER_OPTIONS) + +#define parent_class gimp_smooth_modifier_options_parent_class + + +static void +gimp_smooth_modifier_options_class_init (GimpSmoothModifierOptionsClass *klass) +{ + GimpBrushModifierOptionsClass *modifier_class = GIMP_BRUSH_MODIFIER_OPTIONS_CLASS (klass); + + modifier_class->base_property_id = 0; + + modifier_class->install = gimp_smooth_modifier_options_install; + modifier_class->set_property = gimp_smooth_modifier_options_set_property; + modifier_class->get_property = gimp_smooth_modifier_options_get_property; +} + +static void +gimp_smooth_modifier_options_init (GimpSmoothModifierOptions *options) +{ + GimpBrushModifierOptions *modifier_options = GIMP_BRUSH_MODIFIER_OPTIONS(options); + g_print("[Trace]smooth_modifier_options::init\n"); + modifier_options->attached_to = GIMP_TYPE_SMOOTH_MODIFIER; +} + + +static gboolean +gimp_smooth_modifier_options_install(GimpBrushModifierOptionsClass *klass, + GimpPaintOptionsClass *options_class, + guint *base_property_id) +{ + GObjectClass* object_class = G_OBJECT_CLASS(options_class); + guint n_properties = 0; + klass->base_property_id = *base_property_id; + + + g_print("[Trace]smooth_modifier_options::install[%x]\n", *base_property_id); + + /* enabled parameter should be handled automatically, but not yet implemented */ + GIMP_CONFIG_INSTALL_PROP_BOOLEAN (object_class, PROP_ENABLED + *base_property_id, + "smooth-enabled", NULL, + TRUE, + GIMP_PARAM_STATIC_STRINGS); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_INT (object_class, PROP_COMPENSATION_HIST_SIZE + *base_property_id, + "smoothing-history-size", NULL, + 1, 20, 20, 0); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_DISTANCE_SCALE + *base_property_id, + "distance-scale", NULL, + 0.0, 200, 25, + 0); + n_properties ++; + + GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_COMPENSATION_RATE + *base_property_id, + "smoothing-rate", NULL, + 0.0, 10, 1, + 0); + n_properties ++; + + return TRUE; +} + + +static gboolean +gimp_smooth_modifier_options_set_property (GimpBrushModifierOptions *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GimpSmoothModifierOptions *options = GIMP_SMOOTH_MODIFIER_OPTIONS (object); + + g_print("[Trace]smooth_modifier_options::set_property[%x-%x]\n", + property_id, + GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(object)->base_property_id); + + switch (property_id - GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(object)->base_property_id) + { + case PROP_ENABLED: + GIMP_BRUSH_MODIFIER_OPTIONS(options)->enabled = g_value_get_boolean (value); + g_print("[Trace]->PROP_ENABLED\n"); + break; + + case PROP_COMPENSATION_HIST_SIZE: + options->smoothing_hist_size = g_value_get_int (value); + break; + + case PROP_DISTANCE_SCALE: + options->distance_scale = g_value_get_double (value); + break; + + case PROP_COMPENSATION_RATE: + options->smoothing_rate = g_value_get_double (value); + break; + default: + return FALSE; + break; + } + return TRUE; +} + +static gboolean +gimp_smooth_modifier_options_get_property (GimpBrushModifierOptions *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GimpSmoothModifierOptions *options = GIMP_SMOOTH_MODIFIER_OPTIONS (object); + + g_print("[Trace]smooth_modifier_options::get_property[%x-%x]\n", + property_id, + GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(object)->base_property_id); + + switch (property_id - GIMP_BRUSH_MODIFIER_OPTIONS_GET_CLASS(object)->base_property_id) + { + case PROP_ENABLED: + g_value_set_boolean(value, GIMP_BRUSH_MODIFIER_OPTIONS(options)->enabled); + g_print("[Trace]->PROP_ENABLED\n"); + break; + + case PROP_COMPENSATION_HIST_SIZE: + g_value_set_int (value, options->smoothing_hist_size); + break; + + case PROP_DISTANCE_SCALE: + g_value_set_double (value, options->distance_scale); + break; + + case PROP_COMPENSATION_RATE: + g_value_set_double (value, options->smoothing_rate); + break; + + default: + return FALSE; + break; + } + return TRUE; +} diff -uNr gimp-2.4.1/app/paint/gimpsmoothmodifieroptions.h gimp-2.4.1-tmp/app/paint/gimpsmoothmodifieroptions.h --- gimp-2.4.1/app/paint/gimpsmoothmodifieroptions.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/gimpsmoothmodifieroptions.h 2008-03-12 23:23:36.000000000 +0900 @@ -0,0 +1,56 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_SMOOTH_MODIFIER_OPTIONS_H__ +#define __GIMP_SMOOTH_MODIFIER_OPTIONS_H__ + + +#include "gimpbrushmodifieroptions.h" + + +/* class */ + +#define GIMP_TYPE_SMOOTH_MODIFIER_OPTIONS (gimp_smooth_modifier_options_get_type ()) +#define GIMP_SMOOTH_MODIFIER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SMOOTH_MODIFIER_OPTIONS, GimpSmoothModifierOptions)) +#define GIMP_SMOOTH_MODIFIER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SMOOTH_MODIFIER_OPTIONS, GimpSmoothModifierOptionsClass)) +#define GIMP_IS_SMOOTH_MODIFIER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SMOOTH_MODIFIER_OPTIONS)) +#define GIMP_IS_SMOOTH_MODIFIER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SMOOTH_MODIFIER_OPTIONS)) +#define GIMP_SMOOTH_MODIFIER_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SMOOTH_MODIFIER_OPTIONS, GimpSmoothModifierOptionsClass)) + + +typedef struct _GimpSmoothModifierOptionsClass GimpSmoothModifierOptionsClass; +typedef struct _GimpSmoothModifierOptions GimpSmoothModifierOptions; + + +struct _GimpSmoothModifierOptions +{ + GimpBrushModifierOptions parent_instance; + + guint smoothing_hist_size; + gdouble distance_scale; + gdouble smoothing_rate; +}; + +struct _GimpSmoothModifierOptionsClass +{ + GimpBrushModifierOptionsClass parent_class; +}; + +GType gimp_smooth_modifier_options_get_type (void) G_GNUC_CONST; + +#endif /* __GIMP_SMOOTH_MODIFIER_OPTIONS_H__ */ diff -uNr gimp-2.4.1/app/paint/paint-types.h gimp-2.4.1-tmp/app/paint/paint-types.h --- gimp-2.4.1/app/paint/paint-types.h 2007-03-08 18:53:41.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint/paint-types.h 2008-03-12 23:19:39.000000000 +0900 @@ -41,6 +41,7 @@ typedef struct _GimpPencil GimpPencil; typedef struct _GimpPerspectiveClone GimpPerspectiveClone; typedef struct _GimpSmudge GimpSmudge; +typedef struct _GimpCustomBrush GimpCustomBrush; /* paint options */ @@ -57,6 +58,7 @@ typedef struct _GimpPencilOptions GimpPencilOptions; typedef struct _GimpPerspectiveCloneOptions GimpPerspectiveCloneOptions; typedef struct _GimpSmudgeOptions GimpSmudgeOptions; +typedef struct _GimpCustomBrushOptions GimpCustomBrushOptions; /* paint undos */ diff -uNr gimp-2.4.1/app/paint-funcs/paint-funcs-generic.h gimp-2.4.1-tmp/app/paint-funcs/paint-funcs-generic.h --- gimp-2.4.1/app/paint-funcs/paint-funcs-generic.h 2007-01-23 19:13:51.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint-funcs/paint-funcs-generic.h 2008-03-12 23:08:27.000000000 +0900 @@ -348,10 +348,64 @@ const guchar *col, guchar blend, guint w, - guint bytes, - gboolean has_alpha) -{ + guint bytes) + // guint bytes, + // gboolean has_alpha) +{ + if (HAS_ALPHA (bytes)) + { + const guint blend1 = 255 - blend; + const guint blend2 = blend + 1; + const guint c = bytes - 1; + const gint a2 = blend2 * col[c]; + gint cola[MAX_CHANNELS]; + guint b; + + for (b = 0; b < c; b++) + cola[b] = col[b] * a2; + + while (w--) + { + const gint a1 = blend1 * src[c]; + const gint a = a1 + a2; + + if (!a) + { + for (b = 0; b < bytes; b++) + dest[b] = 0; + } + else + { + for (b = 0; b < c; b++) + dest[b] = + src[b] + (src[b] * a1 + cola[b] - a * src[b]) / a; + + dest[c] = a >> 8; + } + + src += bytes; + dest += bytes; + } + } + else + { + const guchar blend1 = 255 - blend; + + while (w--) + { + guint b; + + for (b = 0; b < bytes; b++) + dest[b] = + src[b] + (src[b] * blend1 + col[b] * blend - src[b] * 255) / 255; + + src += bytes; + dest += bytes; + } + } +#if 0 const guchar blend2 = (255 - blend); + const guint has_alpha = HAS_ALPHA(bytes); const guint alpha = (has_alpha) ? bytes - 1 : bytes; while (w--) @@ -367,6 +421,7 @@ src += bytes; dest += bytes; } +#endif } diff -uNr gimp-2.4.1/app/paint-funcs/paint-funcs.c gimp-2.4.1-tmp/app/paint-funcs/paint-funcs.c --- gimp-2.4.1/app/paint-funcs/paint-funcs.c 2007-10-23 04:16:17.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint-funcs/paint-funcs.c 2008-03-12 23:08:27.000000000 +0900 @@ -1975,20 +1975,28 @@ guchar *color, guchar blend) { - const guchar *s = src->data; - guchar *d = dest->data; - gint h = src->h; + gpointer pr; - while (h --) + for (pr = pixel_regions_register (2, src, dest); + pr != NULL; + pr = pixel_regions_process (pr)) { - blend_pixels (s, d, color, blend, src->w, src->bytes); + const guchar *s = src->data; + guchar *d = dest->data; + gint h = src->h; - s += src->rowstride; - d += dest->rowstride; + while (h --) + { + shade_pixels (s, d, color, blend, src->w, src->bytes); + + s += src->rowstride; + d += dest->rowstride; + } } } + void copy_region (PixelRegion *src, PixelRegion *dest) diff -uNr gimp-2.4.1/app/paint-funcs/paint-funcs.h gimp-2.4.1-tmp/app/paint-funcs/paint-funcs.h --- gimp-2.4.1/app/paint-funcs/paint-funcs.h 2007-10-23 04:16:17.000000000 +0900 +++ gimp-2.4.1-tmp/app/paint-funcs/paint-funcs.h 2008-03-12 23:08:27.000000000 +0900 @@ -58,8 +58,9 @@ const guchar *color, guchar rblend, guint w, - guint bytes, - gboolean has_alpha); + guint bytes); + // guint bytes, + // gboolean has_alpha); void extract_alpha_pixels (const guchar *src, const guchar *mask, diff -uNr gimp-2.4.1/app/tools/Makefile.am gimp-2.4.1-tmp/app/tools/Makefile.am --- gimp-2.4.1/app/tools/Makefile.am 2007-06-27 18:50:25.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/Makefile.am 2008-03-12 23:15:28.000000000 +0900 @@ -167,7 +167,9 @@ gimpvectoroptions.c \ gimpvectoroptions.h \ gimpvectortool.c \ - gimpvectortool.h + gimpvectortool.h \ + gimpcustombrushtool.c \ + gimpcustombrushtool.h libapptools_a_built_sources = tools-enums.c diff -uNr gimp-2.4.1/app/tools/Makefile.in gimp-2.4.1-tmp/app/tools/Makefile.in --- gimp-2.4.1/app/tools/Makefile.in 2007-10-31 17:09:08.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/Makefile.in 2008-03-12 23:20:21.000000000 +0900 @@ -100,7 +100,11 @@ gimptoolcontrol.$(OBJEXT) gimptooloptions-gui.$(OBJEXT) \ gimptransformoptions.$(OBJEXT) gimptransformtool.$(OBJEXT) \ gimptransformtoolundo.$(OBJEXT) gimpvectoroptions.$(OBJEXT) \ - gimpvectortool.$(OBJEXT) + gimpvectortool.$(OBJEXT) \ + gimpbrushmodifiertool.$(OBJEXT) \ + gimpblendmodifiertool.$(OBJEXT) \ + gimpsmoothmodifiertool.$(OBJEXT) \ + gimpcustombrushtool.$(OBJEXT) am_libapptools_a_OBJECTS = $(am__objects_1) $(am__objects_2) libapptools_a_OBJECTS = $(am_libapptools_a_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) @@ -655,7 +659,15 @@ gimpvectoroptions.c \ gimpvectoroptions.h \ gimpvectortool.c \ - gimpvectortool.h + gimpvectortool.h \ + gimpbrushmodifiertool.c \ + gimpbrushmodifiertool.h \ + gimpblendmodifiertool.c \ + gimpblendmodifiertool.h \ + gimpsmoothmodifiertool.c \ + gimpsmoothmodifiertool.h \ + gimpcustombrushtool.c \ + gimpcustombrushtool.h libapptools_a_built_sources = tools-enums.c libapptools_a_SOURCES = $(libapptools_a_built_sources) $(libapptools_a_sources) @@ -807,6 +819,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tool_manager.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools-enums.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tools-utils.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gimpcustombrushtool.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ diff -uNr gimp-2.4.1/app/tools/gimp-tools.c gimp-2.4.1-tmp/app/tools/gimp-tools.c --- gimp-2.4.1/app/tools/gimp-tools.c 2007-07-25 03:45:41.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimp-tools.c 2008-03-12 23:21:40.000000000 +0900 @@ -77,6 +77,7 @@ #include "gimpsmudgetool.h" #include "gimptexttool.h" #include "gimpvectortool.h" +#include "gimpcustombrushtool.h" #include "gimp-intl.h" @@ -138,6 +139,7 @@ gimp_blend_tool_register, gimp_bucket_fill_tool_register, gimp_text_tool_register, + gimp_custom_brush_tool_register, /* transform tools */ @@ -177,6 +179,8 @@ g_return_if_fail (GIMP_IS_GIMP (gimp)); + g_print("[Trace]:gimp_tool_init\n"); + tool_manager_init (gimp); gimp_container_freeze (gimp->tool_info_list); @@ -426,7 +430,7 @@ GimpToolInfo *tool_info; const gchar *paint_core_name; gboolean visible; - + g_return_if_fail (GIMP_IS_GIMP (gimp)); g_return_if_fail (g_type_is_a (tool_type, GIMP_TYPE_TOOL)); g_return_if_fail (tool_options_type == G_TYPE_NONE || @@ -479,6 +483,10 @@ { paint_core_name = "gimp-ink"; } + else if (tool_type == GIMP_TYPE_CUSTOM_BRUSH_TOOL) + { + paint_core_name = "gimp-custom-brush"; + } else { paint_core_name = "gimp-paintbrush"; diff -uNr gimp-2.4.1/app/tools/gimpblendmodifiertool.c gimp-2.4.1-tmp/app/tools/gimpblendmodifiertool.c --- gimp-2.4.1/app/tools/gimpblendmodifiertool.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimpblendmodifiertool.c 2008-03-12 23:13:56.000000000 +0900 @@ -0,0 +1,158 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "tools-types.h" + +#include "paint/gimpcustombrushoptions.h" + +#include "widgets/gimphelp-ids.h" + +#include "gimpblendmodifiertool.h" +#include "gimppaintoptions-gui.h" +#include "gimptoolcontrol.h" + +#include "gimp-intl.h" + + +static void +gimp_blend_modifier_options_gui (GimpBrushModifierTool *tool, + GObject *config, + GtkContainer *container); + + +G_DEFINE_TYPE (GimpBlendModifierTool, gimp_blend_modifier_tool, GIMP_TYPE_BRUSH_MODIFIER_TOOL) + + +static void +gimp_blend_modifier_tool_class_init (GimpBlendModifierToolClass *klass) +{ + GimpBrushModifierToolClass *tool_class = GIMP_BRUSH_MODIFIER_TOOL_CLASS (klass); + tool_class->gui = gimp_blend_modifier_options_gui; +} + +static void +gimp_blend_modifier_tool_init (GimpBlendModifierTool *blend_modifier) +{ + GimpBrushModifierTool *tool = GIMP_BRUSH_MODIFIER_TOOL (blend_modifier); + tool->name = "Blend"; + tool->enabled_options_name = "blend-enabled"; + g_print("[Trace]blend_modifier_tool::init\n"); +} + + +/* tool options stuff */ + +void +gimp_blend_modifier_options_gui (GimpBrushModifierTool *tool, + GObject *config, + GtkContainer *container) +{ + GtkWidget *vbox = GTK_WIDGET(container); + GtkWidget *table; + GtkWidget *blend_modifier_box; + GtkWidget *blend_modifier_vbox; + GtkWidget *blend_modifier_button; + GtkWidget *blend_modifier_frame; + + g_print("[Trace]:blend_modifier_tool::gui\n"); + + table = gtk_table_new (2, 3, FALSE); + gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2); + gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); + gtk_widget_show (table); + + /* Canvas Color Picking Configurations */ + blend_modifier_box = gtk_frame_new (_("Canvas Color")); + gtk_box_pack_start (GTK_BOX (vbox), blend_modifier_box, FALSE, TRUE, 0); + gtk_widget_show(blend_modifier_box); + blend_modifier_vbox = gtk_vbox_new (FALSE, 2); + gtk_container_add (GTK_CONTAINER (blend_modifier_box), blend_modifier_vbox); + gtk_widget_show (blend_modifier_vbox); + + table = gtk_table_new (3, 5, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_box_pack_start (GTK_BOX (blend_modifier_vbox), table, TRUE, TRUE, 0); + gtk_widget_show (table); + + gimp_prop_scale_entry_new (config, "canvas-color-rate", + GTK_TABLE (table), 0, 0, + _("Rate:"), + 0.01, 0.1, 2, + FALSE, 0.0, 1.0); + + gimp_prop_scale_entry_new (config, "canvas-color-pressure-rate", + GTK_TABLE (table), 0, 1, + _("Pressure:"), + 0.01, 0.1, 2, + FALSE, 0.0, 1.0); + + blend_modifier_button = gimp_prop_check_button_new (config, "invert-canvas-color-pressure", _("Invert Pressure")); + gtk_box_pack_start (GTK_BOX (blend_modifier_vbox), blend_modifier_button, FALSE, TRUE, 0); + gtk_widget_show (blend_modifier_button); + + /* Original Color Picking Configurations */ + blend_modifier_box = gtk_frame_new (_("Original Color")); + gtk_box_pack_start (GTK_BOX (vbox), blend_modifier_box, FALSE, TRUE, 0); + gtk_widget_show(blend_modifier_box); + blend_modifier_vbox = gtk_vbox_new (FALSE, 2); + gtk_container_add (GTK_CONTAINER (blend_modifier_box), blend_modifier_vbox); + gtk_widget_show (blend_modifier_vbox); + + table = gtk_table_new (3, 4, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_box_pack_start (GTK_BOX (blend_modifier_vbox), table, TRUE, TRUE, 0); + gtk_widget_show (table); + + gimp_prop_scale_entry_new (config, "original-color-rate", + GTK_TABLE (table), 0, 0, + _("Rate:"), + 0.01, 0.1, 2, + FALSE, 0.0, 1.0); + + gimp_prop_scale_entry_new (config, "original-color-pressure-rate", + GTK_TABLE (table), 0, 1, + _("Pressure:"), + 0.01, 0.1, 2, + FALSE, 0.0, 1.0); + + blend_modifier_button = gimp_prop_check_button_new (config, "invert-original-color-pressure", _("Invert Pressure")); + gtk_box_pack_start (GTK_BOX (blend_modifier_vbox), blend_modifier_button, FALSE, TRUE, 0); + gtk_widget_show (blend_modifier_button); + + table = gtk_table_new (3, 1, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, TRUE, 0); + gtk_widget_show (table); + + /*blend_modifier_button = gimp_prop_check_button_new (config, "merged", _("Pick up underlying color"));*/ + blend_modifier_button = gimp_prop_check_button_new (config, "merged", _("Pick up merged color")); + gtk_box_pack_start (GTK_BOX (vbox), blend_modifier_button, FALSE, TRUE, 0); + gtk_widget_show (blend_modifier_button); + + blend_modifier_frame = gimp_prop_enum_radio_frame_new (config, "hidden-color", + _("Assume that the hidden color is:"), + 0, 0); + gtk_box_pack_start (GTK_BOX (vbox), blend_modifier_frame, FALSE, TRUE, 0); + gtk_widget_show (blend_modifier_frame); +} diff -uNr gimp-2.4.1/app/tools/gimpblendmodifiertool.h gimp-2.4.1-tmp/app/tools/gimpblendmodifiertool.h --- gimp-2.4.1/app/tools/gimpblendmodifiertool.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimpblendmodifiertool.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,50 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_BLEND_MODIFIER_TOOL_H__ +#define __GIMP_BLEND_MODIFIER_TOOL_H__ + + +#include "gimpbrushmodifiertool.h" + + +#define GIMP_TYPE_BLEND_MODIFIER_TOOL (gimp_blend_modifier_tool_get_type ()) +#define GIMP_BLEND_MODIFIER_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BLEND_MODIFIER_TOOL, GimpBlendModifierTool)) +#define GIMP_BLEND_MODIFIER_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BLEND_MODIFIER_TOOL, GimpBlendModifierToolClass)) +#define GIMP_IS_BLEND_MODIFIER_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_BLEND_MODIFIER_TOOL)) +#define GIMP_IS_BLEND_MODIFIER_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BLEND_MODIFIER_TOOL)) +#define GIMP_BLEND_MODIFIER_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BLEND_MODIFIER_TOOL, GimpBlendModifierToolClass)) + + +typedef struct _GimpBlendModifierTool GimpBlendModifierTool; +typedef struct _GimpBlendModifierToolClass GimpBlendModifierToolClass; + +struct _GimpBlendModifierTool +{ + GimpBrushModifierTool parent_instance; +}; + +struct _GimpBlendModifierToolClass +{ + GimpBrushModifierToolClass parent_class; +}; + +GType gimp_blend_modifier_tool_get_type (void) G_GNUC_CONST; + + +#endif /* __GIMP_BLEND_MODIFIER_TOOL_H__ */ diff -uNr gimp-2.4.1/app/tools/gimpbrushmodifiertool.c gimp-2.4.1-tmp/app/tools/gimpbrushmodifiertool.c --- gimp-2.4.1/app/tools/gimpbrushmodifiertool.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimpbrushmodifiertool.c 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,63 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "tools-types.h" + +#include "paint/gimpbrushmodifieroptions.h" + +#include "widgets/gimphelp-ids.h" + +#include "gimp-intl.h" + +#include "gimpbrushmodifiertool.h" + +static void +gimp_brush_modifier_tool_gui (GimpBrushModifierTool *tool, + GObject *config, + GtkContainer *container); + + +G_DEFINE_TYPE (GimpBrushModifierTool, gimp_brush_modifier_tool, GIMP_TYPE_OBJECT) + +static void +gimp_brush_modifier_tool_class_init (GimpBrushModifierToolClass *klass) +{ + klass->gui = gimp_brush_modifier_tool_gui; +} + +static void +gimp_brush_modifier_tool_init (GimpBrushModifierTool *brush_modifier) +{ + brush_modifier->name = "BrushModifier"; +} + + +/* tool options stuff */ + +static void +gimp_brush_modifier_tool_gui (GimpBrushModifierTool *tool, + GObject *config, + GtkContainer *container) +{ +} diff -uNr gimp-2.4.1/app/tools/gimpbrushmodifiertool.h gimp-2.4.1-tmp/app/tools/gimpbrushmodifiertool.h --- gimp-2.4.1/app/tools/gimpbrushmodifiertool.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimpbrushmodifiertool.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,53 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_BRUSH_MODIFIER_TOOL_H__ +#define __GIMP_BRUSH_MODIFIER_TOOL_H__ + + +#define GIMP_TYPE_BRUSH_MODIFIER_TOOL (gimp_brush_modifier_tool_get_type ()) +#define GIMP_BRUSH_MODIFIER_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_BRUSH_MODIFIER_TOOL, GimpBrushModifierTool)) +#define GIMP_BRUSH_MODIFIER_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_BRUSH_MODIFIER_TOOL, GimpBrushModifierToolClass)) +#define GIMP_IS_BRUSH_MODIFIER_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_BRUSH_MODIFIER_TOOL)) +#define GIMP_IS_BRUSH_MODIFIER_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_BRUSH_MODIFIER_TOOL)) +#define GIMP_BRUSH_MODIFIER_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_BRUSH_MODIFIER_TOOL, GimpBrushModifierToolClass)) + + +typedef struct _GimpBrushModifierTool GimpBrushModifierTool; +typedef struct _GimpBrushModifierToolClass GimpBrushModifierToolClass; + +struct _GimpBrushModifierTool +{ + GimpObject parent_instance; + char *name; + char *enabled_options_name; +}; + +struct _GimpBrushModifierToolClass +{ + GimpObjectClass parent_class; + + void (*gui) (GimpBrushModifierTool *tool, + GObject *config, + GtkContainer *container); +}; + +GType gimp_brush_modifier_tool_get_type (void) G_GNUC_CONST; + + +#endif /* __GIMP_BRUSH_MODIFIER_TOOL_H__ */ diff -uNr gimp-2.4.1/app/tools/gimpcustombrushtool.c gimp-2.4.1-tmp/app/tools/gimpcustombrushtool.c --- gimp-2.4.1/app/tools/gimpcustombrushtool.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimpcustombrushtool.c 2008-03-12 23:13:02.000000000 +0900 @@ -0,0 +1,188 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "tools-types.h" + +#include "paint/gimpcustombrushoptions.h" + +#include "widgets/gimphelp-ids.h" + +#include "gimpcustombrushtool.h" +#include "gimppaintoptions-gui.h" +#include "gimptoolcontrol.h" + +#include "gimp-intl.h" + + +static GtkWidget * gimp_custom_brush_options_gui (GimpToolOptions *tool_options); + +static gboolean modifier_tools_initialized = FALSE; +static GList *modifier_tools = NULL; +static void gimp_custom_brush_tool_load (void); +static void gimp_custom_brush_tool_unload (void); + +G_DEFINE_TYPE (GimpCustomBrushTool, gimp_custom_brush_tool, GIMP_TYPE_PAINTBRUSH_TOOL) + + +void +gimp_custom_brush_tool_register (GimpToolRegisterCallback callback, + gpointer data) +{ + g_print("[Trace]:custom_brush_tool::register\n"); + (* callback) (GIMP_TYPE_CUSTOM_BRUSH_TOOL, + GIMP_TYPE_CUSTOM_BRUSH_OPTIONS, + gimp_custom_brush_options_gui, + GIMP_PAINT_OPTIONS_CONTEXT_MASK | + GIMP_CONTEXT_GRADIENT_MASK, + "gimp-custom-brush-tool", + _("CustomBrush"), + _("CustomBrush Tool: Paint brush with extension features."), + N_("_CustomBrush"), "W", + NULL, GIMP_HELP_TOOL_PAINTBRUSH, + GIMP_STOCK_TOOL_PAINTBRUSH, + data); +} + + +static void +gimp_custom_brush_tool_class_init (GimpCustomBrushToolClass *klass) +{ + gimp_custom_brush_tool_load(); + g_print("[Trace]:custom_brush_tool_class::init\n"); +} + +#include "gimpblendmodifiertool.h" +#include "gimpsmoothmodifiertool.h" +static void +gimp_custom_brush_tool_load () +{ + if (!modifier_tools_initialized) + { + GObject* tool; + tool = g_object_new(GIMP_TYPE_BLEND_MODIFIER_TOOL, NULL); + modifier_tools = g_list_append(modifier_tools, (gpointer)tool); + + tool = g_object_new(GIMP_TYPE_SMOOTH_MODIFIER_TOOL, NULL); + modifier_tools = g_list_append(modifier_tools, (gpointer)tool); + + modifier_tools_initialized = TRUE; + } +} + +static void +gimp_custom_brush_tool_init (GimpCustomBrushTool *custom_tool) +{ + GimpTool *tool = GIMP_TOOL (custom_tool); + + gimp_tool_control_set_tool_cursor (tool->control, GIMP_TOOL_CURSOR_PAINTBRUSH); + + gimp_paint_tool_enable_color_picker (GIMP_PAINT_TOOL (custom_tool), + GIMP_COLOR_PICK_MODE_FOREGROUND); + + g_print("[Trace]:custom_brush_tool::init\n"); +} + + +static void +gimp_custom_brush_tool_unlink (gpointer data, gpointer user_data) +{ + g_object_unref(G_OBJECT(data)); +} + + +static void +gimp_custom_brush_tool_unload () +{ + g_list_foreach(modifier_tools, + gimp_custom_brush_tool_unlink, + NULL); + g_list_free(modifier_tools); +} + + +/* tool options stuff */ +static void +modifier_enabled_toggled (GtkToggleButton *togglebutton, + gpointer user_data) +{ + GtkWidget* widget = GTK_WIDGET(user_data); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton))) + { + gtk_widget_show(widget); + } + else + { + gtk_widget_hide(widget); + } +} + +static GtkWidget * +gimp_custom_brush_options_gui (GimpToolOptions *tool_options) +{ + GObject *config = G_OBJECT (tool_options); + GtkWidget *vbox = gimp_paint_options_gui (tool_options); + GList *list; + + g_print("[Trace]:custom_brush_tool::gui\n"); + gimp_custom_brush_tool_load (); + + /* call GUI handlers of all modifiers */ + for (list = g_list_first(modifier_tools); + list != NULL; + list = g_list_next(list)) + { + GimpBrushModifierTool* tool = GIMP_BRUSH_MODIFIER_TOOL(list->data); + GtkWidget *custom_brush_box; + GtkWidget *custom_brush_vbox; + GtkWidget *enabled_check; + gboolean enabled; + + g_object_get(config, tool->enabled_options_name, &enabled, NULL); + + enabled_check = gimp_prop_check_button_new (config, tool->enabled_options_name, _(tool->name)); + gtk_box_pack_start (GTK_BOX (vbox), enabled_check, FALSE, TRUE, 0); + gtk_widget_show (enabled_check); + + custom_brush_box = gtk_frame_new (NULL); + gtk_box_pack_start (GTK_BOX (vbox), custom_brush_box, FALSE, TRUE, 0); + gtk_widget_show(custom_brush_box); + + + custom_brush_vbox = gtk_vbox_new (FALSE, 2); + gtk_container_add (GTK_CONTAINER (custom_brush_box), custom_brush_vbox); + g_print("here\n"); + if (enabled) + gtk_widget_show (custom_brush_vbox); + else + gtk_widget_hide (custom_brush_vbox); + + GIMP_BRUSH_MODIFIER_TOOL_GET_CLASS(tool)->gui(tool, config, GTK_CONTAINER(custom_brush_vbox)); + + g_signal_connect (GTK_OBJECT(enabled_check), "toggled", + GTK_SIGNAL_FUNC(modifier_enabled_toggled), (gpointer)custom_brush_vbox); + } + + return vbox; +} diff -uNr gimp-2.4.1/app/tools/gimpcustombrushtool.h gimp-2.4.1-tmp/app/tools/gimpcustombrushtool.h --- gimp-2.4.1/app/tools/gimpcustombrushtool.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimpcustombrushtool.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,54 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_CUSTOM_BRUSH_TOOL_H__ +#define __GIMP_CUSTOM_BRUSH_TOOL_H__ + + +#include "gimppaintbrushtool.h" + + +#define GIMP_TYPE_CUSTOM_BRUSH_TOOL (gimp_custom_brush_tool_get_type ()) +#define GIMP_CUSTOM_BRUSH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CUSTOM_BRUSH_TOOL, GimpCustomBrushTool)) +#define GIMP_CUSTOM_BRUSH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CUSTOM_BRUSH_TOOL, GimpCustomBrushToolClass)) +#define GIMP_IS_CUSTOM_BRUSH_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_CUSTOM_BRUSH_TOOL)) +#define GIMP_IS_CUSTOM_BRUSH_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_CUSTOM_BRUSH_TOOL)) +#define GIMP_CUSTOM_BRUSH_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_CUSTOM_BRUSH_TOOL, GimpCustomBrushToolClass)) + + +typedef struct _GimpCustomBrushTool GimpCustomBrushTool; +typedef struct _GimpCustomBrushToolClass GimpCustomBrushToolClass; + +struct _GimpCustomBrushTool +{ + GimpPaintbrushTool parent_instance; +}; + +struct _GimpCustomBrushToolClass +{ + GimpPaintbrushToolClass parent_class; +}; + + +void gimp_custom_brush_tool_register (GimpToolRegisterCallback callback, + gpointer data); + +GType gimp_custom_brush_tool_get_type (void) G_GNUC_CONST; + + +#endif /* __GIMP_CUSTOM_BRUSH_TOOL_H__ */ diff -uNr gimp-2.4.1/app/tools/gimppaintoptions-gui.c gimp-2.4.1-tmp/app/tools/gimppaintoptions-gui.c --- gimp-2.4.1/app/tools/gimppaintoptions-gui.c 2007-10-23 04:16:17.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimppaintoptions-gui.c 2008-03-12 23:14:21.000000000 +0900 @@ -46,6 +46,7 @@ #include "gimppenciltool.h" #include "gimpperspectiveclonetool.h" #include "gimpsmudgetool.h" +#include "gimpcustombrushtool.h" #include "gimptooloptions-gui.h" #include "gimp-intl.h" @@ -175,6 +176,7 @@ /* the "incremental" toggle */ if (tool_type == GIMP_TYPE_PENCIL_TOOL || tool_type == GIMP_TYPE_PAINTBRUSH_TOOL || + tool_type == GIMP_TYPE_CUSTOM_BRUSH_TOOL || tool_type == GIMP_TYPE_ERASER_TOOL) { incremental_toggle = @@ -293,6 +295,7 @@ tool_type == GIMP_TYPE_DODGE_BURN_TOOL || tool_type == GIMP_TYPE_ERASER_TOOL || tool_type == GIMP_TYPE_PAINTBRUSH_TOOL || + tool_type == GIMP_TYPE_CUSTOM_BRUSH_TOOL || tool_type == GIMP_TYPE_PENCIL_TOOL) { button = gimp_prop_check_button_new (config, "pressure-size", diff -uNr gimp-2.4.1/app/tools/gimpsmoothmodifiertool.c gimp-2.4.1-tmp/app/tools/gimpsmoothmodifiertool.c --- gimp-2.4.1/app/tools/gimpsmoothmodifiertool.c 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimpsmoothmodifiertool.c 2008-03-12 23:23:04.000000000 +0900 @@ -0,0 +1,107 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "libgimpwidgets/gimpwidgets.h" + +#include "tools-types.h" + +#include "paint/gimpcustombrushoptions.h" + +#include "widgets/gimphelp-ids.h" + +#include "gimpsmoothmodifiertool.h" +#include "gimppaintoptions-gui.h" +#include "gimptoolcontrol.h" + +#include "gimp-intl.h" + + +static void +gimp_smooth_modifier_options_gui (GimpBrushModifierTool *tool, + GObject *config, + GtkContainer *container); + + +G_DEFINE_TYPE (GimpSmoothModifierTool, gimp_smooth_modifier_tool, GIMP_TYPE_BRUSH_MODIFIER_TOOL) + + +static void +gimp_smooth_modifier_tool_class_init (GimpSmoothModifierToolClass *klass) +{ + GimpBrushModifierToolClass *tool_class = GIMP_BRUSH_MODIFIER_TOOL_CLASS (klass); + tool_class->gui = gimp_smooth_modifier_options_gui; +} + +static void +gimp_smooth_modifier_tool_init (GimpSmoothModifierTool *smooth_modifier) +{ + GimpBrushModifierTool *tool = GIMP_BRUSH_MODIFIER_TOOL (smooth_modifier); + tool->name = "Smooth"; + tool->enabled_options_name = "smooth-enabled"; + g_print("[Trace]smooth_modifier_tool::init\n"); +} + + +/* tool options stuff */ + +void +gimp_smooth_modifier_options_gui (GimpBrushModifierTool *tool, + GObject *config, + GtkContainer *container) +{ + GtkWidget *vbox = GTK_WIDGET(container); + GtkWidget *table; + GtkWidget *smooth_modifier_box; + GtkWidget *smooth_modifier_vbox; + + GtkWidget *adj; + + g_print("[Trace]:smooth_modifier_tool::gui\n"); + + /* smoothing options */ + table = gtk_table_new (3, 3, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_box_pack_start (GTK_BOX (container), table, TRUE, TRUE, 0); + gtk_widget_show (table); + + /* smoothing history size slider */ + gimp_prop_scale_entry_new (config, "smoothing-history-size", + GTK_TABLE (table), 0, 0, + _("Quality:"), + 1, 1, 0, + FALSE, 1.0, 20); + + /* smoothing scaling rate slider */ + adj = gimp_prop_scale_entry_new (config, "distance-scale", + GTK_TABLE (table), 0, 1, + _("Distance Scale:"), + 1, 10, 1, + FALSE, 0, 100); + + /* smoothing rate slider */ + adj = gimp_prop_scale_entry_new (config, "smoothing-rate", + GTK_TABLE (table), 0, 2, + _("Rate:"), + 1, 1, 2, + FALSE, 0, 100); + gimp_scale_entry_set_logarithmic (adj, TRUE); +} diff -uNr gimp-2.4.1/app/tools/gimpsmoothmodifiertool.h gimp-2.4.1-tmp/app/tools/gimpsmoothmodifiertool.h --- gimp-2.4.1/app/tools/gimpsmoothmodifiertool.h 1970-01-01 09:00:00.000000000 +0900 +++ gimp-2.4.1-tmp/app/tools/gimpsmoothmodifiertool.h 2008-03-12 23:08:27.000000000 +0900 @@ -0,0 +1,50 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GIMP_SMOOTH_MODIFIER_TOOL_H__ +#define __GIMP_SMOOTH_MODIFIER_TOOL_H__ + + +#include "gimpbrushmodifiertool.h" + + +#define GIMP_TYPE_SMOOTH_MODIFIER_TOOL (gimp_smooth_modifier_tool_get_type ()) +#define GIMP_SMOOTH_MODIFIER_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_SMOOTH_MODIFIER_TOOL, GimpSmoothModifierTool)) +#define GIMP_SMOOTH_MODIFIER_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_SMOOTH_MODIFIER_TOOL, GimpSmoothModifierToolClass)) +#define GIMP_IS_SMOOTH_MODIFIER_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_SMOOTH_MODIFIER_TOOL)) +#define GIMP_IS_SMOOTH_MODIFIER_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_SMOOTH_MODIFIER_TOOL)) +#define GIMP_SMOOTH_MODIFIER_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_SMOOTH_MODIFIER_TOOL, GimpSmoothModifierToolClass)) + + +typedef struct _GimpSmoothModifierTool GimpSmoothModifierTool; +typedef struct _GimpSmoothModifierToolClass GimpSmoothModifierToolClass; + +struct _GimpSmoothModifierTool +{ + GimpBrushModifierTool parent_instance; +}; + +struct _GimpSmoothModifierToolClass +{ + GimpBrushModifierToolClass parent_class; +}; + +GType gimp_smooth_modifier_tool_get_type (void) G_GNUC_CONST; + + +#endif /* __GIMP_SMOOTH_MODIFIER_TOOL_H__ */