Modified Files: ChangeLog app/Makefile.am app/airbrush.c app/app_procs.c

Modified Files:
 	ChangeLog app/Makefile.am app/airbrush.c app/app_procs.c
 	app/brush_select.c app/brush_select.h app/clone.c
 	app/colormaps.c app/commands.c app/convolve.c app/devices.c
 	app/eraser.c app/gimage_mask.c app/gimpobject.h app/ink.c
 	app/internal_procs.c app/paint_core.c app/paint_core.h
 	app/paintbrush.c app/pencil.c app/preferences_dialog.c
      Minor modifications to support new brush functionality

 Added Files:
 	app/brush_edit.c app/brush_edit.h app/gimpbrush.c
 	app/gimpbrush.h app/gimpbrushgenerated.c
 	app/gimpbrushgenerated.h app/gimpbrushlist.c
 	app/gimpbrushlist.h
      new files to support vector generated brushes and
      reorganization/objectification of the brush class

 Removed Files:
 	app/brushes.c app/brushes.h
    Obsoleted by gimpbrush.? and gimpbrushlist.?

 ----------------------------------------------------------------------
This commit is contained in:
jaycox 1998-07-09 05:31:06 +00:00
parent 354d726481
commit b7d8e6ea91
77 changed files with 3649 additions and 646 deletions

View File

@ -1,3 +1,27 @@
Wed Jul 8 21:34:31 PDT 1998 Jay Cox <jaycox@earthlink.net>
* app/brushes.c app/brushes.h: removed files
* app/gimpbrush.c app/gimpbrush.h
* app/gimpbrushlist.c app/gimpbrushlist.h
the New files replace the functionality of brushes.[ch]
and objectify the brushes. The basic structure is in
but signals are not used as much as they should be.
* app/gimpbrushgenerated.c app/gimpbrushgenerated.h
New type of brush that is can be modified on the fly
* brush_edit.c brush_edit.h
new files that implement a gui for the GimpBrushGenerated class.
very basic.
* brush_select.c devices.c ink.c gimpobject.h paint_core.c
brush_select.h brush_edit.h preferences_dialog.c pencil.c
paintbrush.c internal_procs.c gimage_mask.c eraser.c convolve.c
commands.c colormaps.c airbrush.c clone.c app_procs.c
paint_core.h
Minor changes to support above new functionality.
Wed Jul 8 22:36:12 CDT 1998 Larry Ewing <lewing@gimp.org>
* app/color_area.c (color_area_edit): raise the color select when
@ -66,6 +90,7 @@ Wed Jul 8 01:35:22 EEST 1998 Lauri Alanko <nether@gimp.org>
* app/app_procs.c (app_exit_finish): Unregister pdb procs _before_
destroying pdb.
>>>>>>> 1.475
Mon Jul 6 20:38:36 1998 Scott Goehring <scott@poverty.bloomington.in.us>
* app/gimage_mask.c (gimage_mask_boundary): fixed crash when you

View File

@ -32,11 +32,11 @@ gimp_SOURCES = \
boundary.h \
brightness_contrast.c \
brightness_contrast.h \
brush_edit.c \
brush_edit.h \
brush_header.h \
brush_select.c \
brush_select.h \
brushes.c \
brushes.h \
bucket_fill.c \
bucket_fill.h \
buildmenu.c \
@ -142,6 +142,12 @@ gimp_SOURCES = \
gimage_mask.h \
gimage_mask_cmds.c \
gimage_mask_cmds.h \
gimpbrush.c \
gimpbrush.h \
gimpbrushgenerated.c \
gimpbrushgenerated.h \
gimpbrushlist.c \
gimpbrushlist.h \
gimprc.c \
gimprc.h \
global_edit.c \

View File

@ -23,7 +23,7 @@
#include "actionarea.h"
#include "app_procs.h"
#include "brightness_contrast.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "by_color_select.h"
#include "channels_dialog.h"
#include "colormaps.h"

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -143,7 +143,7 @@ airbrush_paint_func (PaintCore *paint_core,
GimpDrawable *drawable,
int state)
{
GBrushP brush;
GimpBrushP brush;
if (!drawable)
return NULL;
@ -267,8 +267,8 @@ airbrush_motion (PaintCore *paint_core,
/* paste the newly painted area to the image */
paint_core_paste_canvas (paint_core, drawable,
opacity,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (),
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (),
SOFT, CONSTANT);
}

View File

@ -27,7 +27,7 @@
#include "appenv.h"
#include "app_procs.h"
#include "batch.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "color_transfer.h"
#include "curves.h"
#include "devices.h"

205
app/brush_edit.c Normal file
View File

@ -0,0 +1,205 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* brush_edit module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 "appenv.h"
#include "gimpbrushgenerated.h"
#include "brush_edit.h"
static void
update_brush_callback (GtkAdjustment *adjustment,
BrushEditGeneratedWindow *begw)
{
if (begw->brush &&
((begw->radius_data->value
!= gimp_brush_generated_get_radius(begw->brush))
|| (begw->hardness_data->value
!= gimp_brush_generated_get_hardness(begw->brush))
|| (begw->aspect_ratio_data->value
!= gimp_brush_generated_get_aspect_ratio(begw->brush))
|| (begw->angle_data->value
!=gimp_brush_generated_get_angle(begw->brush))))
{
gimp_brush_generated_set_radius (begw->brush,
begw->radius_data->value);
gimp_brush_generated_set_hardness (begw->brush,
begw->hardness_data->value);
gimp_brush_generated_set_aspect_ratio (begw->brush,
begw->aspect_ratio_data->value);
gimp_brush_generated_set_angle (begw->brush,
begw->angle_data->value);
gimp_brush_generated_generate(begw->brush);
}
}
static int
brush_edit_delete_callback (GtkWidget *w,
BrushEditGeneratedWindow *begw)
{
if (GTK_WIDGET_VISIBLE (w))
gtk_widget_hide (w);
return TRUE;
}
void
brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
GimpBrush *gbrush)
{
GimpBrushGenerated *brush = 0;
if (!GIMP_IS_BRUSH_GENERATED(gbrush))
return;
brush = GIMP_BRUSH_GENERATED(gbrush);
if (begw)
{
begw->brush = NULL;
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->radius_data),
gimp_brush_generated_get_radius (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->hardness_data),
gimp_brush_generated_get_hardness (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->angle_data),
gimp_brush_generated_get_angle (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->aspect_ratio_data),
gimp_brush_generated_get_aspect_ratio(brush));
begw->brush = brush;
}
}
BrushEditGeneratedWindow *
brush_edit_generated_new ()
{
BrushEditGeneratedWindow *begw ;
GtkWidget *vbox;
GtkWidget *sbar;
GtkWidget *label;
GtkWidget *slider;
GtkWidget *table;
GtkWidget *button1, *button2;
begw = g_malloc (sizeof (BrushEditGeneratedWindow));
begw->redraw = TRUE;
begw->shell = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (begw->shell), "generatedbrusheditor",
"Gimp");
gtk_window_set_title (GTK_WINDOW (begw->shell), "Brush Editor");
gtk_window_set_policy(GTK_WINDOW(begw->shell), FALSE, TRUE, FALSE);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_border_width (GTK_CONTAINER (vbox), 2);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (begw->shell)->vbox), vbox,
TRUE, TRUE, 0);
/* handle the wm close signal */
gtk_signal_connect (GTK_OBJECT (begw->shell), "delete_event",
GTK_SIGNAL_FUNC (brush_edit_delete_callback),
begw);
/* Populate the window with some widgets */
/* brush's preview widget w/frame */
begw->frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (begw->frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (vbox), begw->frame, TRUE, TRUE, 0);
begw->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (begw->preview), 100, 100);
gtk_container_add (GTK_CONTAINER (begw->frame), begw->preview);
gtk_widget_show(begw->preview);
gtk_widget_show(begw->frame);
/* table for sliders/labels */
table = gtk_table_new(2, 4, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* brush radius scale */
label = gtk_label_new ("Radius:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 0, 1, 0, 0, 0, 0);
begw->radius_data = GTK_ADJUSTMENT (gtk_adjustment_new (10.0, 0.0, 100.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->radius_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 0, 1);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->radius_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush hardness scale */
label = gtk_label_new ("Hardness:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 1, 2, 0, 0, 0, 0);
begw->hardness_data = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.01, 0.0));
slider = gtk_hscale_new (begw->hardness_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 1, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->hardness_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush aspect ratio scale */
label = gtk_label_new ("Aspect Ratio:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 2, 3, 0, 0, 0, 0);
begw->aspect_ratio_data = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 20.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->aspect_ratio_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 2, 3);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->aspect_ratio_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush angle scale */
label = gtk_label_new ("Angle:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 3, 4, 0, 0, 0, 0);
begw->angle_data = GTK_ADJUSTMENT (gtk_adjustment_new (00.0, 0.0, 180.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->angle_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 3, 4);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->angle_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
gtk_table_set_row_spacings(GTK_TABLE (table), 3);
gtk_table_set_col_spacing(GTK_TABLE (table), 0, 3);
gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (begw->shell);
return begw;
}

49
app/brush_edit.h Normal file
View File

@ -0,0 +1,49 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* brush_edit module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 __BRUSH_EDIT_H__
#define __BRUSH_EDIT_H__
#include "gimpbrushgenerated.h"
typedef struct _BrushEditGeneratedWindow
{
GtkWidget *shell;
GtkWidget *frame;
GtkWidget *preview;
GtkWidget *options_box;
GtkAdjustment *radius_data;
GtkAdjustment *hardness_data;
GtkAdjustment *angle_data;
GtkAdjustment *aspect_ratio_data;
int width, height;
int cell_width, cell_height;
int redraw;
/* Brush preview */
GtkWidget *brush_preview;
GimpBrushGenerated *brush;
} BrushEditGeneratedWindow;
void brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
GimpBrush *brush);
BrushEditGeneratedWindow *brush_edit_generated_new ();
#endif /* __BRUSH_EDIT_H__ */

View File

@ -20,7 +20,12 @@
#include <string.h>
#include "appenv.h"
#include "actionarea.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "gimpset.h"
#include "gimpsetP.h" /* FIXME: get rid of this include */
#include "gimpbrushgenerated.h"
#include "brush_edit.h"
#include "brush_select.h"
#include "brush_select.h"
#include "buildmenu.h"
#include "colormaps.h"
@ -48,14 +53,18 @@
GDK_ENTER_NOTIFY_MASK
/* local function prototypes */
static void brush_popup_open (BrushSelectP, int, int, GBrushP);
static void brush_popup_open (BrushSelectP, int, int, GimpBrushP);
static void brush_popup_close (BrushSelectP);
static void display_brush (BrushSelectP, GBrushP, int, int);
static void display_brush (BrushSelectP, GimpBrushP, int, int);
static void display_brushes (BrushSelectP);
static void display_setup (BrushSelectP);
static void preview_calc_scrollbar (BrushSelectP);
static void brush_select_show_selected (BrushSelectP, int, int);
static void update_active_brush_field (BrushSelectP);
static gint edit_brush_callback (GtkWidget *w, GdkEvent *e,
gpointer data);
static gint new_brush_callback (GtkWidget *w, GdkEvent *e,
gpointer data);
static void brush_select_close_callback (GtkWidget *, gpointer);
static void brush_select_refresh_callback(GtkWidget *, gpointer);
static void paint_mode_menu_callback (GtkWidget *, gpointer);
@ -99,6 +108,7 @@ static ActionAreaItem action_items[] =
static double old_opacity;
static int old_spacing;
static int old_paint_mode;
static BrushEditGeneratedWindow *brush_edit_generated_dialog;
int NUM_BRUSH_COLUMNS=5;
int NUM_BRUSH_ROWS=5;
@ -131,7 +141,8 @@ brush_select_new ()
GtkWidget *util_box;
GtkWidget *option_menu;
GtkWidget *slider;
GBrushP active;
GimpBrushP active;
GtkWidget *button1, *button2;
bsp = g_malloc (sizeof (_BrushSelect));
bsp->redraw = TRUE;
@ -209,7 +220,7 @@ brush_select_new ()
gtk_widget_show (util_box);
/* Create the paint mode option menu */
old_paint_mode = get_brush_paint_mode ();
old_paint_mode = gimp_brush_get_paint_mode ();
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 0);
@ -225,7 +236,7 @@ brush_select_new ()
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
/* Create the opacity scale widget */
old_opacity = get_brush_opacity ();
old_opacity = gimp_brush_get_opacity ();
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 0);
@ -244,7 +255,7 @@ brush_select_new ()
gtk_widget_show (util_box);
/* Create the brush spacing scale widget */
old_spacing = get_brush_spacing ();
old_spacing = gimp_brush_get_spacing ();
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 0);
@ -262,6 +273,25 @@ brush_select_new ()
gtk_widget_show (slider);
gtk_widget_show (util_box);
/* Create the edit/new buttons */
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 0);
button1 = gtk_button_new_with_label ("Edit Brush");
gtk_signal_connect (GTK_OBJECT (button1), "clicked",
(GtkSignalFunc) edit_brush_callback,
NULL);
gtk_box_pack_start (GTK_BOX (util_box), button1, TRUE, TRUE, 5);
button2 = gtk_button_new_with_label ("New Brush");
gtk_signal_connect (GTK_OBJECT (button2), "clicked",
(GtkSignalFunc) new_brush_callback,
NULL);
gtk_box_pack_start (GTK_BOX (util_box), button2, TRUE, TRUE, 5);
gtk_widget_show (button1);
gtk_widget_show (button2);
gtk_widget_show (util_box);
/* The action area */
action_items[0].user_data = bsp;
action_items[1].user_data = bsp;
@ -322,6 +352,24 @@ brush_select_free (BrushSelectP bsp)
}
}
void
brush_select_brush_changed(BrushSelectP bsp, GimpBrushP brush)
{
/* TODO: be smarter here and only update the part of the preview
* that has changed */
if (bsp)
{
display_brushes(bsp);
gtk_widget_draw (bsp->preview, NULL);
}
}
void
brush_select_brush_dirty_callback(GimpBrushP brush, BrushSelectP bsp)
{
brush_select_brush_changed(bsp, brush);
}
/*
* Local functions
@ -330,7 +378,7 @@ static void
brush_popup_open (BrushSelectP bsp,
int x,
int y,
GBrushP brush)
GimpBrushP brush)
{
gint x_org, y_org;
gint scr_w, scr_h;
@ -399,9 +447,10 @@ brush_popup_close (BrushSelectP bsp)
if (bsp->brush_popup != NULL)
gtk_widget_hide (bsp->brush_popup);
}
static void
display_brush (BrushSelectP bsp,
GBrushP brush,
GimpBrushP brush,
int col,
int row)
{
@ -477,9 +526,10 @@ display_setup (BrushSelectP bsp)
static void
display_brushes (BrushSelectP bsp)
{
GSList * list = brush_list; /* the global brush list */
/* FIXME: use gimp_set_foreach?? */
GSList * list = GIMP_SET(brush_list)->list; /* the global brush list */
int row, col;
GBrushP brush;
GimpBrushP brush;
/* If there are no brushes, insensitize widgets */
if (brush_list == NULL)
@ -497,7 +547,7 @@ display_brushes (BrushSelectP bsp)
row = col = 0;
while (list)
{
brush = (GBrushP) list->data;
brush = (GimpBrushP) list->data;
/* Display the brush */
display_brush (bsp, brush, col, row);
@ -610,7 +660,8 @@ preview_calc_scrollbar (BrushSelectP bsp)
/* int rowy; */
offs = bsp->scroll_offset;
num_rows = (num_brushes + NUM_BRUSH_COLUMNS - 1) / NUM_BRUSH_COLUMNS;
num_rows = (brush_list->num_brushes + NUM_BRUSH_COLUMNS - 1)
/ NUM_BRUSH_COLUMNS;
max = num_rows * bsp->cell_width;
if (!num_rows) num_rows = 1;
page_size = bsp->preview->allocation.height;
@ -640,7 +691,7 @@ brush_select_resize (GtkWidget *widget,
BrushSelectP bsp)
{
NUM_BRUSH_COLUMNS = (gint)((widget->allocation.width - 4) / STD_CELL_WIDTH);
NUM_BRUSH_ROWS = (num_brushes + NUM_BRUSH_COLUMNS - 1) / NUM_BRUSH_COLUMNS;
NUM_BRUSH_ROWS = (brush_list->num_brushes + NUM_BRUSH_COLUMNS - 1) / NUM_BRUSH_COLUMNS;
bsp->width = widget->allocation.width - 4;
bsp->height = widget->allocation.height - 4;
@ -663,7 +714,7 @@ brush_select_resize (GtkWidget *widget,
static void
update_active_brush_field (BrushSelectP bsp)
{
GBrushP brush;
GimpBrushP brush;
char buf[32];
brush = get_active_brush ();
@ -679,7 +730,7 @@ update_active_brush_field (BrushSelectP bsp)
gtk_label_set (GTK_LABEL (bsp->brush_size), buf);
/* Set brush spacing */
bsp->spacing_data->value = get_brush_spacing ();
bsp->spacing_data->value = gimp_brush_get_spacing ();
gtk_signal_emit_by_name (GTK_OBJECT (bsp->spacing_data), "value_changed");
}
@ -690,7 +741,7 @@ brush_select_events (GtkWidget *widget,
BrushSelectP bsp)
{
GdkEventButton *bevent;
GBrushP brush;
GimpBrushP brush;
int row, col, index;
switch (event->type)
@ -718,6 +769,9 @@ brush_select_events (GtkWidget *widget,
/* Make this brush the active brush */
select_brush (brush);
if (brush_edit_generated_dialog)
brush_edit_generated_set_brush(brush_edit_generated_dialog,
get_active_brush());
/* Show the brush popup window if the brush is too large */
if (brush->mask->width > bsp->cell_width ||
@ -750,6 +804,39 @@ brush_select_events (GtkWidget *widget,
return FALSE;
}
static gint
edit_brush_callback (GtkWidget *w, GdkEvent *e, gpointer data)
{
if (GIMP_IS_BRUSH_GENERATED(get_active_brush()))
{
if (!brush_edit_generated_dialog)
{
/* Create the dialog... */
brush_edit_generated_dialog = brush_edit_generated_new();
brush_edit_generated_set_brush(brush_edit_generated_dialog,
get_active_brush());
}
else
{
/* Popup the dialog */
if (!GTK_WIDGET_VISIBLE (brush_edit_generated_dialog->shell))
gtk_widget_show (brush_edit_generated_dialog->shell);
else
gdk_window_raise(brush_edit_generated_dialog->shell->window);
}
}
else
g_message("We are all out of brush editors today, please try again tomorrow\n");
return TRUE;
}
static gint
new_brush_callback (GtkWidget *w, GdkEvent *e, gpointer data)
{
brush_changed_notify(GIMP_BRUSH(gimp_brush_generated_new(10, .5, 0.0, 1.0)));
return TRUE;
}
static gint
brush_select_delete_callback (GtkWidget *w, GdkEvent *e, gpointer data)
{
@ -766,9 +853,9 @@ brush_select_close_callback (GtkWidget *w,
bsp = (BrushSelectP) client_data;
old_paint_mode = get_brush_paint_mode ();
old_opacity = get_brush_opacity ();
old_spacing = get_brush_spacing ();
old_paint_mode = gimp_brush_get_paint_mode ();
old_opacity = gimp_brush_get_opacity ();
old_spacing = gimp_brush_get_spacing ();
if (GTK_WIDGET_VISIBLE (bsp->shell))
gtk_widget_hide (bsp->shell);
@ -780,7 +867,7 @@ brush_select_refresh_callback (GtkWidget *w,
gpointer client_data)
{
BrushSelectP bsp;
GBrushP active;
GimpBrushP active;
bsp = (BrushSelectP) client_data;
@ -811,7 +898,7 @@ preview_scroll_update (GtkAdjustment *adjustment,
gpointer data)
{
BrushSelectP bsp;
GBrushP active;
GimpBrushP active;
int row, col;
bsp = data;
@ -838,7 +925,7 @@ static void
paint_mode_menu_callback (GtkWidget *w,
gpointer client_data)
{
set_brush_paint_mode ((long) client_data);
gimp_brush_set_paint_mode ((long) client_data);
}
@ -846,7 +933,7 @@ static void
opacity_scale_update (GtkAdjustment *adjustment,
gpointer data)
{
set_brush_opacity (adjustment->value / 100.0);
gimp_brush_set_opacity (adjustment->value / 100.0);
}
@ -854,5 +941,5 @@ static void
spacing_scale_update (GtkAdjustment *adjustment,
gpointer data)
{
set_brush_spacing ((int) adjustment->value);
gimp_brush_set_spacing ((int) adjustment->value);
}

View File

@ -19,6 +19,7 @@
#define __BRUSH_SELECT_H__
#include "buildmenu.h"
#include "gimpbrush.h"
typedef struct _BrushSelect _BrushSelect, *BrushSelectP;
@ -44,6 +45,8 @@ struct _BrushSelect {
BrushSelectP brush_select_new (void);
void brush_select_select (BrushSelectP, int);
void brush_select_free (BrushSelectP);
void brush_select_brush_changed(BrushSelectP bsp,
GimpBrushP brush);
/* An interface to other dialogs which need to create a paint mode menu */
GtkWidget * create_paint_mode_menu (MenuItemCallback);

View File

@ -1,71 +0,0 @@
/* The GIMP -- an 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 __BRUSHES_H__
#define __BRUSHES_H__
#include <glib.h>
#include "procedural_db.h"
#include "temp_buf.h"
typedef struct _GBrush GBrush, * GBrushP;
struct _GBrush
{
char * filename; /* actual filename--brush's location on disk */
char * name; /* brush's name--for brush selection dialog */
int spacing; /* brush's spacing */
int index; /* brush's index... */
TempBuf * mask; /* the actual mask... */
};
/* global variables */
extern GSList * brush_list;
extern int num_brushes;
/* function declarations */
void brushes_init (int no_data);
void brushes_free (void);
void brush_select_dialog_free (void);
void select_brush (GBrushP);
GBrushP get_brush_by_index (int);
GBrushP get_active_brush (void);
void create_brush_dialog (void);
/* access functions */
double get_brush_opacity (void);
int get_brush_spacing (void);
int get_brush_paint_mode (void);
void set_brush_opacity (double);
void set_brush_spacing (int);
void set_brush_paint_mode (int);
/* Brush procedures */
extern ProcRecord brushes_get_brush_proc;
extern ProcRecord brushes_set_brush_proc;
extern ProcRecord brushes_get_opacity_proc;
extern ProcRecord brushes_set_opacity_proc;
extern ProcRecord brushes_get_spacing_proc;
extern ProcRecord brushes_set_spacing_proc;
extern ProcRecord brushes_get_paint_mode_proc;
extern ProcRecord brushes_set_paint_mode_proc;
extern ProcRecord brushes_list_proc;
extern ProcRecord brushes_refresh_brush_proc;
#endif /* __BRUSHES_H__ */

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -447,8 +447,8 @@ clone_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), SOFT, CONSTANT);
}
static void

View File

@ -19,7 +19,7 @@
#include <math.h>
#include "appenv.h"
#include "app_procs.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "colormaps.h"
#include "errors.h"
#include "general.h"

View File

@ -23,7 +23,7 @@
#include "actionarea.h"
#include "app_procs.h"
#include "brightness_contrast.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "by_color_select.h"
#include "channels_dialog.h"
#include "colormaps.h"

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <stdio.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "convolve.h"
@ -329,7 +329,7 @@ convolve_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_replace_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
(int) (gimp_brush_get_opacity () * 255),
SOFT, INCREMENTAL);
}

228
app/core/gimpbrush-load.c Normal file
View File

@ -0,0 +1,228 @@
/* The GIMP -- an 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "gimpbrush.h"
#include "gimpbrushlist.h"
#include "gimpsignal.h"
#include "gimprc.h"
#include "brush_header.h"
enum{
DIRTY,
RENAME,
LAST_SIGNAL
};
static guint gimp_brush_signals[LAST_SIGNAL];
static GimpObjectClass* parent_class;
static void
gimp_brush_destroy(GtkObject *object)
{
GimpBrush* brush=GIMP_BRUSH(object);
if (brush->filename)
g_free(brush->filename);
if (brush->name)
g_free(brush->name);
if (brush->mask)
temp_buf_free(brush->mask);
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
static void
gimp_brush_class_init (GimpBrushClass *klass)
{
GtkObjectClass *object_class;
GtkType type;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (gimp_object_get_type ());
type=object_class->type;
object_class->destroy = gimp_brush_destroy;
gimp_brush_signals[DIRTY] =
gimp_signal_new ("dirty", 0, type, 0, gimp_sigtype_void);
gimp_brush_signals[RENAME] =
gimp_signal_new ("rename", 0, type, 0, gimp_sigtype_void);
gtk_object_class_add_signals (object_class, gimp_brush_signals, LAST_SIGNAL);
}
void
gimp_brush_init(GimpBrush *brush)
{
brush->filename = NULL;
brush->name = NULL;
brush->spacing = 20;
brush->index = 0;
brush->mask = NULL;
}
GtkType gimp_brush_get_type(void)
{
static GtkType type;
if(!type){
GtkTypeInfo info={
"GimpBrush",
sizeof(GimpBrush),
sizeof(GimpBrushClass),
(GtkClassInitFunc)gimp_brush_class_init,
(GtkObjectInitFunc)gimp_brush_init,
NULL,
NULL };
type=gtk_type_unique(gimp_object_get_type(), &info);
}
return type;
}
GimpBrush *
gimp_brush_new (char *filename)
{
GimpBrush *brush=GIMP_BRUSH(gtk_type_new(gimp_brush_get_type ()));
gimp_brush_load(brush, filename);
return brush;
}
TempBuf *
gimp_brush_get_mask (GimpBrush *brush)
{
g_return_val_if_fail(GIMP_IS_BRUSH(brush), NULL);
return brush->mask;
}
void
gimp_brush_load(GimpBrush *brush, char *filename)
{
FILE * fp;
int bn_size;
unsigned char buf [sz_BrushHeader];
BrushHeader header;
unsigned int * hp;
int i;
brush->filename = g_strdup (filename);
/* Open the requested file */
if (! (fp = fopen (filename, "r")))
{
gimp_object_destroy (brush);
return;
}
/* Read in the header size */
if ((fread (buf, 1, sz_BrushHeader, fp)) < sz_BrushHeader)
{
fclose (fp);
gimp_object_destroy (brush);
return;
}
/* rearrange the bytes in each unsigned int */
hp = (unsigned int *) &header;
for (i = 0; i < (sz_BrushHeader / 4); i++)
hp [i] = (buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]);
/* Check for correct file format */
if (header.magic_number != GBRUSH_MAGIC)
{
/* One thing that can save this error is if the brush is version 1 */
if (header.version != 1)
{
fclose (fp);
gimp_object_destroy (brush);
return;
}
}
if (header.version == 1)
{
/* If this is a version 1 brush, set the fp back 8 bytes */
fseek (fp, -8, SEEK_CUR);
header.header_size += 8;
/* spacing is not defined in version 1 */
header.spacing = 25;
}
/* Read in the brush name */
if ((bn_size = (header.header_size - sz_BrushHeader)))
{
brush->name = (char *) g_malloc (sizeof (char) * bn_size);
if ((fread (brush->name, 1, bn_size, fp)) < bn_size)
{
g_message ("Error in GIMP brush file...aborting.");
fclose (fp);
gimp_object_destroy (brush);
return;
}
}
else
brush->name = g_strdup ("Unnamed");
switch(header.version)
{
case 1:
case 2:
/* Get a new brush mask */
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
0, 0, NULL);
brush->spacing = header.spacing;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask), 1, header.width * header.height,
fp)) < header.width * header.height)
g_message ("GIMP brush file appears to be truncated.");
break;
case 3:
fprintf(stderr, "loading generated brush\n");
fprintf(stderr, "currently unimplemeted expect a crash to occur any second\n");
fprintf(stderr, "finished loading generated brush\n");
break;
default:
g_message ("Unknown brush format version #%d in \"%s\"\n",
header.version, filename);
fclose (fp);
gimp_object_destroy (brush);
return;
}
/* Clean up */
fclose (fp);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (brush->mask);
/* TODO: get rid of this call */
gimp_brush_list_add(brush_list, brush);
/* Check if the current brush is the default one */
/* lets see if it works with out this for now */
/* if (strcmp(default_brush, prune_filename(filename)) == 0) {
active_brush = brush;
have_default_brush = 1;
}*/ /* if */
}

228
app/core/gimpbrush.c Normal file
View File

@ -0,0 +1,228 @@
/* The GIMP -- an 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "gimpbrush.h"
#include "gimpbrushlist.h"
#include "gimpsignal.h"
#include "gimprc.h"
#include "brush_header.h"
enum{
DIRTY,
RENAME,
LAST_SIGNAL
};
static guint gimp_brush_signals[LAST_SIGNAL];
static GimpObjectClass* parent_class;
static void
gimp_brush_destroy(GtkObject *object)
{
GimpBrush* brush=GIMP_BRUSH(object);
if (brush->filename)
g_free(brush->filename);
if (brush->name)
g_free(brush->name);
if (brush->mask)
temp_buf_free(brush->mask);
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
static void
gimp_brush_class_init (GimpBrushClass *klass)
{
GtkObjectClass *object_class;
GtkType type;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (gimp_object_get_type ());
type=object_class->type;
object_class->destroy = gimp_brush_destroy;
gimp_brush_signals[DIRTY] =
gimp_signal_new ("dirty", 0, type, 0, gimp_sigtype_void);
gimp_brush_signals[RENAME] =
gimp_signal_new ("rename", 0, type, 0, gimp_sigtype_void);
gtk_object_class_add_signals (object_class, gimp_brush_signals, LAST_SIGNAL);
}
void
gimp_brush_init(GimpBrush *brush)
{
brush->filename = NULL;
brush->name = NULL;
brush->spacing = 20;
brush->index = 0;
brush->mask = NULL;
}
GtkType gimp_brush_get_type(void)
{
static GtkType type;
if(!type){
GtkTypeInfo info={
"GimpBrush",
sizeof(GimpBrush),
sizeof(GimpBrushClass),
(GtkClassInitFunc)gimp_brush_class_init,
(GtkObjectInitFunc)gimp_brush_init,
NULL,
NULL };
type=gtk_type_unique(gimp_object_get_type(), &info);
}
return type;
}
GimpBrush *
gimp_brush_new (char *filename)
{
GimpBrush *brush=GIMP_BRUSH(gtk_type_new(gimp_brush_get_type ()));
gimp_brush_load(brush, filename);
return brush;
}
TempBuf *
gimp_brush_get_mask (GimpBrush *brush)
{
g_return_val_if_fail(GIMP_IS_BRUSH(brush), NULL);
return brush->mask;
}
void
gimp_brush_load(GimpBrush *brush, char *filename)
{
FILE * fp;
int bn_size;
unsigned char buf [sz_BrushHeader];
BrushHeader header;
unsigned int * hp;
int i;
brush->filename = g_strdup (filename);
/* Open the requested file */
if (! (fp = fopen (filename, "r")))
{
gimp_object_destroy (brush);
return;
}
/* Read in the header size */
if ((fread (buf, 1, sz_BrushHeader, fp)) < sz_BrushHeader)
{
fclose (fp);
gimp_object_destroy (brush);
return;
}
/* rearrange the bytes in each unsigned int */
hp = (unsigned int *) &header;
for (i = 0; i < (sz_BrushHeader / 4); i++)
hp [i] = (buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]);
/* Check for correct file format */
if (header.magic_number != GBRUSH_MAGIC)
{
/* One thing that can save this error is if the brush is version 1 */
if (header.version != 1)
{
fclose (fp);
gimp_object_destroy (brush);
return;
}
}
if (header.version == 1)
{
/* If this is a version 1 brush, set the fp back 8 bytes */
fseek (fp, -8, SEEK_CUR);
header.header_size += 8;
/* spacing is not defined in version 1 */
header.spacing = 25;
}
/* Read in the brush name */
if ((bn_size = (header.header_size - sz_BrushHeader)))
{
brush->name = (char *) g_malloc (sizeof (char) * bn_size);
if ((fread (brush->name, 1, bn_size, fp)) < bn_size)
{
g_message ("Error in GIMP brush file...aborting.");
fclose (fp);
gimp_object_destroy (brush);
return;
}
}
else
brush->name = g_strdup ("Unnamed");
switch(header.version)
{
case 1:
case 2:
/* Get a new brush mask */
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
0, 0, NULL);
brush->spacing = header.spacing;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask), 1, header.width * header.height,
fp)) < header.width * header.height)
g_message ("GIMP brush file appears to be truncated.");
break;
case 3:
fprintf(stderr, "loading generated brush\n");
fprintf(stderr, "currently unimplemeted expect a crash to occur any second\n");
fprintf(stderr, "finished loading generated brush\n");
break;
default:
g_message ("Unknown brush format version #%d in \"%s\"\n",
header.version, filename);
fclose (fp);
gimp_object_destroy (brush);
return;
}
/* Clean up */
fclose (fp);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (brush->mask);
/* TODO: get rid of this call */
gimp_brush_list_add(brush_list, brush);
/* Check if the current brush is the default one */
/* lets see if it works with out this for now */
/* if (strcmp(default_brush, prune_filename(filename)) == 0) {
active_brush = brush;
have_default_brush = 1;
}*/ /* if */
}

55
app/core/gimpbrush.h Normal file
View File

@ -0,0 +1,55 @@
/* The GIMP -- an 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 __GIMPBRUSH_H__
#define __GIMPBRUSH_H__
#include "gimpobjectP.h"
#include "temp_buf.h"
typedef struct _GimpBrush GimpBrush, * GimpBrushP;
struct _GimpBrush
{
GimpObject gobject;
char * filename; /* actual filename--brush's location on disk */
char * name; /* brush's name--for brush selection dialog */
int spacing; /* brush's spacing */
int index; /* brush's index... */
TempBuf * mask; /* the actual mask... */
};
struct _GimpBrushClass
{
GimpObjectClass parent_class;
};
typedef struct _GimpBrushClass GimpBrushClass;
#define BRUSH_CLASS(klass) \
GTK_CHECK_CLASS_CAST (klass, gimp_brush_get_type(), GimpBrushClass)
#define GIMP_TYPE_BRUSH (gimp_brush_get_type ())
#define GIMP_BRUSH(obj) (GIMP_CHECK_CAST ((obj), GIMP_TYPE_BRUSH, GimpBrush))
#define GIMP_IS_BRUSH(obj) (GIMP_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH))
GimpBrush * gimp_brush_new (char *filename);
void gimp_brush_load (GimpBrush *brush, char *filename);
GtkType gimp_brush_get_type (void);
TempBuf * gimp_brush_get_mask (GimpBrush *brush);
#endif /* __GIMPBRUSH_H__ */

View File

@ -0,0 +1,285 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimp_brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 "appenv.h"
#include "gimpbrushgenerated.h"
#include "gimpbrushlist.h"
#include "paint_core.h"
#include <math.h>
#define OVERSAMPLING 5
static GimpObjectClass* parent_class;
static void
gimp_brush_generated_destroy(GimpBrushGenerated *object)
{
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
static void
gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
{
GtkObjectClass *object_class;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (GIMP_TYPE_BRUSH);
object_class->destroy = gimp_brush_generated_destroy;
}
void
gimp_brush_generated_init(GimpBrushGenerated *brush)
{
brush->radius = 5.0;
brush->hardness = 0.0;
brush->angle = 0.0;
brush->aspect_ratio = 1.0;
}
guint gimp_brush_generated_get_type(void)
{
static GtkType type;
if(!type){
GtkTypeInfo info={
"GimpBrushGenerated",
sizeof(GimpBrushGenerated),
sizeof(GimpBrushGeneratedClass),
(GtkClassInitFunc)gimp_brush_generated_class_init,
(GtkObjectInitFunc)gimp_brush_generated_init,
NULL,
NULL };
type=gtk_type_unique(GIMP_TYPE_BRUSH, &info);
}
return type;
}
GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
float angle, float aspect_ratio)
{
GimpBrushGenerated *brush;
/* set up normal brush data */
brush = GIMP_BRUSH_GENERATED(gimp_type_new(gimp_brush_generated_get_type ()));
GIMP_BRUSH(brush)->name = g_strdup ("AAAGenerated");
GIMP_BRUSH(brush)->spacing = 20;
/* set up gimp_brush_generated data */
brush->radius = radius;
brush->hardness = hardness;
brush->angle = angle;
brush->aspect_ratio = aspect_ratio;
/* render brush mask */
gimp_brush_generated_generate(brush);
/* add brush to brush list */
/* FIXME: Get rid of this */
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
select_brush(GIMP_BRUSH(brush));
return brush;
}
void
gimp_brush_generated_generate(GimpBrushGenerated *brush)
{
register GimpBrush *gbrush = NULL;
register int x, y;
register guchar *centerp;
register double d;
register double exponent;
register guchar a;
register int length;
register char *lookup;
double buffer[OVERSAMPLING];
register double sum, c, s, tx, ty;
int width, height;
if (!GIMP_IS_BRUSH_GENERATED(brush))
{
g_message("call to gimp_brush_generated_generate on non generated brush");
return;
}
gbrush = GIMP_BRUSH(brush);
if (gbrush->mask)
{
temp_buf_free(gbrush->mask);
}
#define D_TO_R M_PI/180
/* compute the range of the brush, should do a better job than this */
s = sin(brush->angle*M_PI/180);
c = cos(brush->angle*M_PI/180);
tx = MAXIMUM(fabs(c*ceil(brush->radius) - s*ceil(brush->radius)
/brush->aspect_ratio),
fabs(c*ceil(brush->radius) + s*ceil(brush->radius)
/brush->aspect_ratio));
ty = MAXIMUM(fabs(s*ceil(brush->radius) + c*ceil(brush->radius)
/brush->aspect_ratio),
fabs(s*ceil(brush->radius) - c*ceil(brush->radius)
/brush->aspect_ratio));
if (brush->radius > tx)
width = ceil(tx);
else
width = ceil(brush->radius+1);
if (brush->radius > ty)
height = ceil(ty);
else
height = ceil(brush->radius);
gbrush->mask = temp_buf_new(width*2 + 1,
height*2 + 1,
1, width, height, 0);
centerp = &gbrush->mask->data[height*gbrush->mask->width + width];
if ((1.0 - brush->hardness) < 0.000001)
exponent = 1000000;
else
exponent = 1/(1.0 - brush->hardness);
/* set up lookup table */
length = ceil(sqrt(2*ceil(brush->radius+1)*ceil(brush->radius+1))+1) * OVERSAMPLING;
lookup = g_malloc(length);
sum = 0.0;
for (x = 0; x < OVERSAMPLING; x++)
{
d = fabs((x+.5)/OVERSAMPLING - .5);
if (d > brush->radius)
buffer[x] = 0.0;
else
buffer[x] = (1.0 - pow(d/brush->radius, exponent));
sum += buffer[x];
}
for (x = 0; d < brush->radius || sum > .00001; d += 1.0/OVERSAMPLING)
{
sum -= buffer[x%OVERSAMPLING];
if (d > brush->radius)
buffer[x%OVERSAMPLING] = 0.0;
else
buffer[x%OVERSAMPLING] = (1.0 - pow(d/brush->radius, exponent));
sum += buffer[x%OVERSAMPLING];
lookup[x++] = rint(sum*(255.0/OVERSAMPLING));
}
while (x < length)
{
lookup[x++] = 0;
}
/* compute one half and mirror it */
for (y = 0; y <= height; y++)
{
for (x = -width; x <= width; x++)
{
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
d = sqrt(tx*tx + ty*ty);
if (d < brush->radius+1)
a = lookup[(int)rint(d*OVERSAMPLING)];
else
a = 0;
centerp[ y*gbrush->mask->width + x] = a;
centerp[-1*y*gbrush->mask->width - x] = a;
/* centerp[-1*y*brush->mask->width + x] = a;
centerp[-1*y*brush->mask->width - x] = a;
centerp[ x*brush->mask->width + y] = a;
centerp[ x*brush->mask->width - y] = a;
centerp[-1*x*brush->mask->width + y] = a;
centerp[-1*x*brush->mask->width - y] = a;*/
}
}
g_free (lookup);
/* gtk_signal_emit_by_name(brush, "dirty"); */
brush_changed_notify(GIMP_BRUSH(brush));
}
float
gimp_brush_generated_set_radius (GimpBrushGenerated* brush, float radius)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (radius < 0.0)
radius = 0.0;
else if(radius > 32767.0)
radius = 32767.0;
brush->radius = radius;
return brush->radius;
}
float
gimp_brush_generated_set_hardness (GimpBrushGenerated* brush, float hardness)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (hardness < 0.0)
hardness = 0.0;
else if(hardness > 1.0)
hardness = 1.0;
brush->hardness = hardness;
return brush->hardness;
}
float
gimp_brush_generated_set_angle (GimpBrushGenerated* brush, float angle)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (angle < 0.0)
angle = -1.0 * fmod(angle, 180.0);
else if(angle > 180.0)
angle = fmod(angle, 180.0);
brush->angle = angle;
return brush->angle;
}
float
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated* brush, float ratio)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (ratio < 1.0)
ratio = 1.0;
else if(ratio > 1000)
ratio = 1000;
brush->aspect_ratio = ratio;
return brush->aspect_ratio;
}
float
gimp_brush_generated_get_radius (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->radius;
}
float
gimp_brush_generated_get_hardness (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->hardness;
}
float
gimp_brush_generated_get_angle (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->angle;
}
float
gimp_brush_generated_get_aspect_ratio (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->aspect_ratio;
}

View File

@ -0,0 +1,285 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimp_brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 "appenv.h"
#include "gimpbrushgenerated.h"
#include "gimpbrushlist.h"
#include "paint_core.h"
#include <math.h>
#define OVERSAMPLING 5
static GimpObjectClass* parent_class;
static void
gimp_brush_generated_destroy(GimpBrushGenerated *object)
{
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
static void
gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
{
GtkObjectClass *object_class;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (GIMP_TYPE_BRUSH);
object_class->destroy = gimp_brush_generated_destroy;
}
void
gimp_brush_generated_init(GimpBrushGenerated *brush)
{
brush->radius = 5.0;
brush->hardness = 0.0;
brush->angle = 0.0;
brush->aspect_ratio = 1.0;
}
guint gimp_brush_generated_get_type(void)
{
static GtkType type;
if(!type){
GtkTypeInfo info={
"GimpBrushGenerated",
sizeof(GimpBrushGenerated),
sizeof(GimpBrushGeneratedClass),
(GtkClassInitFunc)gimp_brush_generated_class_init,
(GtkObjectInitFunc)gimp_brush_generated_init,
NULL,
NULL };
type=gtk_type_unique(GIMP_TYPE_BRUSH, &info);
}
return type;
}
GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
float angle, float aspect_ratio)
{
GimpBrushGenerated *brush;
/* set up normal brush data */
brush = GIMP_BRUSH_GENERATED(gimp_type_new(gimp_brush_generated_get_type ()));
GIMP_BRUSH(brush)->name = g_strdup ("AAAGenerated");
GIMP_BRUSH(brush)->spacing = 20;
/* set up gimp_brush_generated data */
brush->radius = radius;
brush->hardness = hardness;
brush->angle = angle;
brush->aspect_ratio = aspect_ratio;
/* render brush mask */
gimp_brush_generated_generate(brush);
/* add brush to brush list */
/* FIXME: Get rid of this */
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
select_brush(GIMP_BRUSH(brush));
return brush;
}
void
gimp_brush_generated_generate(GimpBrushGenerated *brush)
{
register GimpBrush *gbrush = NULL;
register int x, y;
register guchar *centerp;
register double d;
register double exponent;
register guchar a;
register int length;
register char *lookup;
double buffer[OVERSAMPLING];
register double sum, c, s, tx, ty;
int width, height;
if (!GIMP_IS_BRUSH_GENERATED(brush))
{
g_message("call to gimp_brush_generated_generate on non generated brush");
return;
}
gbrush = GIMP_BRUSH(brush);
if (gbrush->mask)
{
temp_buf_free(gbrush->mask);
}
#define D_TO_R M_PI/180
/* compute the range of the brush, should do a better job than this */
s = sin(brush->angle*M_PI/180);
c = cos(brush->angle*M_PI/180);
tx = MAXIMUM(fabs(c*ceil(brush->radius) - s*ceil(brush->radius)
/brush->aspect_ratio),
fabs(c*ceil(brush->radius) + s*ceil(brush->radius)
/brush->aspect_ratio));
ty = MAXIMUM(fabs(s*ceil(brush->radius) + c*ceil(brush->radius)
/brush->aspect_ratio),
fabs(s*ceil(brush->radius) - c*ceil(brush->radius)
/brush->aspect_ratio));
if (brush->radius > tx)
width = ceil(tx);
else
width = ceil(brush->radius+1);
if (brush->radius > ty)
height = ceil(ty);
else
height = ceil(brush->radius);
gbrush->mask = temp_buf_new(width*2 + 1,
height*2 + 1,
1, width, height, 0);
centerp = &gbrush->mask->data[height*gbrush->mask->width + width];
if ((1.0 - brush->hardness) < 0.000001)
exponent = 1000000;
else
exponent = 1/(1.0 - brush->hardness);
/* set up lookup table */
length = ceil(sqrt(2*ceil(brush->radius+1)*ceil(brush->radius+1))+1) * OVERSAMPLING;
lookup = g_malloc(length);
sum = 0.0;
for (x = 0; x < OVERSAMPLING; x++)
{
d = fabs((x+.5)/OVERSAMPLING - .5);
if (d > brush->radius)
buffer[x] = 0.0;
else
buffer[x] = (1.0 - pow(d/brush->radius, exponent));
sum += buffer[x];
}
for (x = 0; d < brush->radius || sum > .00001; d += 1.0/OVERSAMPLING)
{
sum -= buffer[x%OVERSAMPLING];
if (d > brush->radius)
buffer[x%OVERSAMPLING] = 0.0;
else
buffer[x%OVERSAMPLING] = (1.0 - pow(d/brush->radius, exponent));
sum += buffer[x%OVERSAMPLING];
lookup[x++] = rint(sum*(255.0/OVERSAMPLING));
}
while (x < length)
{
lookup[x++] = 0;
}
/* compute one half and mirror it */
for (y = 0; y <= height; y++)
{
for (x = -width; x <= width; x++)
{
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
d = sqrt(tx*tx + ty*ty);
if (d < brush->radius+1)
a = lookup[(int)rint(d*OVERSAMPLING)];
else
a = 0;
centerp[ y*gbrush->mask->width + x] = a;
centerp[-1*y*gbrush->mask->width - x] = a;
/* centerp[-1*y*brush->mask->width + x] = a;
centerp[-1*y*brush->mask->width - x] = a;
centerp[ x*brush->mask->width + y] = a;
centerp[ x*brush->mask->width - y] = a;
centerp[-1*x*brush->mask->width + y] = a;
centerp[-1*x*brush->mask->width - y] = a;*/
}
}
g_free (lookup);
/* gtk_signal_emit_by_name(brush, "dirty"); */
brush_changed_notify(GIMP_BRUSH(brush));
}
float
gimp_brush_generated_set_radius (GimpBrushGenerated* brush, float radius)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (radius < 0.0)
radius = 0.0;
else if(radius > 32767.0)
radius = 32767.0;
brush->radius = radius;
return brush->radius;
}
float
gimp_brush_generated_set_hardness (GimpBrushGenerated* brush, float hardness)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (hardness < 0.0)
hardness = 0.0;
else if(hardness > 1.0)
hardness = 1.0;
brush->hardness = hardness;
return brush->hardness;
}
float
gimp_brush_generated_set_angle (GimpBrushGenerated* brush, float angle)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (angle < 0.0)
angle = -1.0 * fmod(angle, 180.0);
else if(angle > 180.0)
angle = fmod(angle, 180.0);
brush->angle = angle;
return brush->angle;
}
float
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated* brush, float ratio)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (ratio < 1.0)
ratio = 1.0;
else if(ratio > 1000)
ratio = 1000;
brush->aspect_ratio = ratio;
return brush->aspect_ratio;
}
float
gimp_brush_generated_get_radius (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->radius;
}
float
gimp_brush_generated_get_hardness (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->hardness;
}
float
gimp_brush_generated_get_angle (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->angle;
}
float
gimp_brush_generated_get_aspect_ratio (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->aspect_ratio;
}

View File

@ -0,0 +1,285 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimp_brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 "appenv.h"
#include "gimpbrushgenerated.h"
#include "gimpbrushlist.h"
#include "paint_core.h"
#include <math.h>
#define OVERSAMPLING 5
static GimpObjectClass* parent_class;
static void
gimp_brush_generated_destroy(GimpBrushGenerated *object)
{
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
static void
gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
{
GtkObjectClass *object_class;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (GIMP_TYPE_BRUSH);
object_class->destroy = gimp_brush_generated_destroy;
}
void
gimp_brush_generated_init(GimpBrushGenerated *brush)
{
brush->radius = 5.0;
brush->hardness = 0.0;
brush->angle = 0.0;
brush->aspect_ratio = 1.0;
}
guint gimp_brush_generated_get_type(void)
{
static GtkType type;
if(!type){
GtkTypeInfo info={
"GimpBrushGenerated",
sizeof(GimpBrushGenerated),
sizeof(GimpBrushGeneratedClass),
(GtkClassInitFunc)gimp_brush_generated_class_init,
(GtkObjectInitFunc)gimp_brush_generated_init,
NULL,
NULL };
type=gtk_type_unique(GIMP_TYPE_BRUSH, &info);
}
return type;
}
GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
float angle, float aspect_ratio)
{
GimpBrushGenerated *brush;
/* set up normal brush data */
brush = GIMP_BRUSH_GENERATED(gimp_type_new(gimp_brush_generated_get_type ()));
GIMP_BRUSH(brush)->name = g_strdup ("AAAGenerated");
GIMP_BRUSH(brush)->spacing = 20;
/* set up gimp_brush_generated data */
brush->radius = radius;
brush->hardness = hardness;
brush->angle = angle;
brush->aspect_ratio = aspect_ratio;
/* render brush mask */
gimp_brush_generated_generate(brush);
/* add brush to brush list */
/* FIXME: Get rid of this */
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
select_brush(GIMP_BRUSH(brush));
return brush;
}
void
gimp_brush_generated_generate(GimpBrushGenerated *brush)
{
register GimpBrush *gbrush = NULL;
register int x, y;
register guchar *centerp;
register double d;
register double exponent;
register guchar a;
register int length;
register char *lookup;
double buffer[OVERSAMPLING];
register double sum, c, s, tx, ty;
int width, height;
if (!GIMP_IS_BRUSH_GENERATED(brush))
{
g_message("call to gimp_brush_generated_generate on non generated brush");
return;
}
gbrush = GIMP_BRUSH(brush);
if (gbrush->mask)
{
temp_buf_free(gbrush->mask);
}
#define D_TO_R M_PI/180
/* compute the range of the brush, should do a better job than this */
s = sin(brush->angle*M_PI/180);
c = cos(brush->angle*M_PI/180);
tx = MAXIMUM(fabs(c*ceil(brush->radius) - s*ceil(brush->radius)
/brush->aspect_ratio),
fabs(c*ceil(brush->radius) + s*ceil(brush->radius)
/brush->aspect_ratio));
ty = MAXIMUM(fabs(s*ceil(brush->radius) + c*ceil(brush->radius)
/brush->aspect_ratio),
fabs(s*ceil(brush->radius) - c*ceil(brush->radius)
/brush->aspect_ratio));
if (brush->radius > tx)
width = ceil(tx);
else
width = ceil(brush->radius+1);
if (brush->radius > ty)
height = ceil(ty);
else
height = ceil(brush->radius);
gbrush->mask = temp_buf_new(width*2 + 1,
height*2 + 1,
1, width, height, 0);
centerp = &gbrush->mask->data[height*gbrush->mask->width + width];
if ((1.0 - brush->hardness) < 0.000001)
exponent = 1000000;
else
exponent = 1/(1.0 - brush->hardness);
/* set up lookup table */
length = ceil(sqrt(2*ceil(brush->radius+1)*ceil(brush->radius+1))+1) * OVERSAMPLING;
lookup = g_malloc(length);
sum = 0.0;
for (x = 0; x < OVERSAMPLING; x++)
{
d = fabs((x+.5)/OVERSAMPLING - .5);
if (d > brush->radius)
buffer[x] = 0.0;
else
buffer[x] = (1.0 - pow(d/brush->radius, exponent));
sum += buffer[x];
}
for (x = 0; d < brush->radius || sum > .00001; d += 1.0/OVERSAMPLING)
{
sum -= buffer[x%OVERSAMPLING];
if (d > brush->radius)
buffer[x%OVERSAMPLING] = 0.0;
else
buffer[x%OVERSAMPLING] = (1.0 - pow(d/brush->radius, exponent));
sum += buffer[x%OVERSAMPLING];
lookup[x++] = rint(sum*(255.0/OVERSAMPLING));
}
while (x < length)
{
lookup[x++] = 0;
}
/* compute one half and mirror it */
for (y = 0; y <= height; y++)
{
for (x = -width; x <= width; x++)
{
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
d = sqrt(tx*tx + ty*ty);
if (d < brush->radius+1)
a = lookup[(int)rint(d*OVERSAMPLING)];
else
a = 0;
centerp[ y*gbrush->mask->width + x] = a;
centerp[-1*y*gbrush->mask->width - x] = a;
/* centerp[-1*y*brush->mask->width + x] = a;
centerp[-1*y*brush->mask->width - x] = a;
centerp[ x*brush->mask->width + y] = a;
centerp[ x*brush->mask->width - y] = a;
centerp[-1*x*brush->mask->width + y] = a;
centerp[-1*x*brush->mask->width - y] = a;*/
}
}
g_free (lookup);
/* gtk_signal_emit_by_name(brush, "dirty"); */
brush_changed_notify(GIMP_BRUSH(brush));
}
float
gimp_brush_generated_set_radius (GimpBrushGenerated* brush, float radius)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (radius < 0.0)
radius = 0.0;
else if(radius > 32767.0)
radius = 32767.0;
brush->radius = radius;
return brush->radius;
}
float
gimp_brush_generated_set_hardness (GimpBrushGenerated* brush, float hardness)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (hardness < 0.0)
hardness = 0.0;
else if(hardness > 1.0)
hardness = 1.0;
brush->hardness = hardness;
return brush->hardness;
}
float
gimp_brush_generated_set_angle (GimpBrushGenerated* brush, float angle)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (angle < 0.0)
angle = -1.0 * fmod(angle, 180.0);
else if(angle > 180.0)
angle = fmod(angle, 180.0);
brush->angle = angle;
return brush->angle;
}
float
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated* brush, float ratio)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (ratio < 1.0)
ratio = 1.0;
else if(ratio > 1000)
ratio = 1000;
brush->aspect_ratio = ratio;
return brush->aspect_ratio;
}
float
gimp_brush_generated_get_radius (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->radius;
}
float
gimp_brush_generated_get_hardness (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->hardness;
}
float
gimp_brush_generated_get_angle (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->angle;
}
float
gimp_brush_generated_get_aspect_ratio (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->aspect_ratio;
}

View File

@ -0,0 +1,72 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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_GENERATED_H__
#define __GIMP_BRUSH_GENERATED_H__
#include "gimpbrush.h"
typedef struct _GimpBrushGenerated
{
GimpBrush gbrush;
float radius;
float hardness; /* 0.0 - 1.0 */
float angle; /* in degrees */
float aspect_ratio; /* y/x */
/*GSpline *profile_curve */ /* Some lazy day... */
} GimpBrushGenerated;
typedef struct _GimpBrushGeneratedClass
{
GimpBrushClass parent_class;
void (* generate) (GimpBrushGenerated *brush);
} GimpBrushGeneratedClass;
/* object stuff */
#define GIMP_TYPE_BRUSH_GENERATED (gimp_brush_generated_get_type ())
#define GIMP_BRUSH_GENERATED(obj) (GIMP_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_GENERATED, GimpBrushGenerated))
#define GIMP_IS_BRUSH_GENERATED(obj) (GIMP_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH_GENERATED))
guint gimp_brush_generated_get_type (void);
/* normal stuff */
GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
float angle, float aspect_ratio);
void gimp_brush_generated_generate (GimpBrushGenerated *brush);
float gimp_brush_generated_set_radius (GimpBrushGenerated* brush,
float radius);
float gimp_brush_generated_set_hardness (GimpBrushGenerated* brush,
float hardness);
float gimp_brush_generated_set_angle (GimpBrushGenerated* brush,
float angle);
float gimp_brush_generated_set_aspect_ratio(GimpBrushGenerated* brush,
float ratio);
float gimp_brush_generated_get_radius (GimpBrushGenerated* brush);
float gimp_brush_generated_get_hardness (GimpBrushGenerated* brush);
float gimp_brush_generated_get_angle (GimpBrushGenerated* brush);
float gimp_brush_generated_get_aspect_ratio (GimpBrushGenerated* brush);
#endif /* __GIMP_BRUSH_GENERATED_H__ */

View File

@ -19,7 +19,7 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "floating_sel.h"
@ -638,8 +638,8 @@ gimage_mask_stroke_paint_func (paint_core, drawable, state)
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), SOFT, CONSTANT);
return NULL;
}

View File

@ -13,6 +13,14 @@
guint gimp_object_get_type(void);
/* hacks to fake a gimp object lib */
#define GIMP_CHECK_CAST GTK_CHECK_CAST
#define GIMP_CHECK_TYPE GTK_CHECK_TYPE
#define gimp_type_new gtk_type_new
#define gimp_object_destroy(obj) gtk_object_destroy(GTK_OBJECT(obj))
#define gimp_object_ref(obj) gtk_object_ref(GTK_OBJECT(obj))
#define gimp_object_unref(obj) gtk_object_unref(GTK_OBJECT(obj))
#endif

View File

@ -20,7 +20,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -44,7 +44,7 @@ struct _DeviceInfo {
gint num_keys;
GdkDeviceKey *keys;
GBrushP brush;
GimpBrushP brush;
ToolType tool;
unsigned char foreground[3];
};
@ -201,7 +201,7 @@ devices_rc_update (gchar *name, DeviceValues values,
{
GList *tmp_list;
DeviceInfo *device_info;
GBrushP brushp;
GimpBrushP brushp;
/* Find device if we have it */
@ -299,27 +299,9 @@ devices_rc_update (gchar *name, DeviceValues values,
if (values & (DEVICE_BRUSH | DEVICE_TOOL | DEVICE_FOREGROUND))
device_info->is_init = TRUE;
/* FIXME: this should probably be left in brushes.c */
if (values & DEVICE_BRUSH)
{
GSList *list;
device_info->brush = NULL;
list = brush_list;
while (list)
{
brushp = (GBrushP) list->data;
if (!strcmp (brushp->name, brush_name))
{
device_info->brush = brushp;
break;
}
list = g_slist_next (list);
}
device_info->brush = gimp_brush_list_get_brush(brush_list, brush_name);
}
if (values & DEVICE_TOOL)

View File

@ -5,7 +5,6 @@
#include "actionarea.h"
#include "app_procs.h"
#include "brightness_contrast.h"
#include "brushes.h"
#include "by_color_select.h"
#include "channels_dialog.h"
#include "colormaps.h"

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -179,11 +179,11 @@ eraser_motion (PaintCore *paint_core, GimpDrawable *drawable, gboolean hard, gbo
/* color the pixels */
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
opacity = 255 * get_brush_opacity() * (paint_core->curpressure / 0.5);
opacity = 255 * gimp_brush_get_opacity() * (paint_core->curpressure / 0.5);
if(opacity > OPAQUE_OPACITY) opacity=OPAQUE_OPACITY;
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, opacity,
(int) (get_brush_opacity () * 255),
(int) (gimp_brush_get_opacity () * 255),
ERASE_MODE, hard? HARD : SOFT, incremental ? INCREMENTAL : CONSTANT);
}

View File

@ -19,7 +19,7 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "floating_sel.h"
@ -638,8 +638,8 @@ gimage_mask_stroke_paint_func (paint_core, drawable, state)
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), SOFT, CONSTANT);
return NULL;
}

228
app/gimpbrush.c Normal file
View File

@ -0,0 +1,228 @@
/* The GIMP -- an 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "gimpbrush.h"
#include "gimpbrushlist.h"
#include "gimpsignal.h"
#include "gimprc.h"
#include "brush_header.h"
enum{
DIRTY,
RENAME,
LAST_SIGNAL
};
static guint gimp_brush_signals[LAST_SIGNAL];
static GimpObjectClass* parent_class;
static void
gimp_brush_destroy(GtkObject *object)
{
GimpBrush* brush=GIMP_BRUSH(object);
if (brush->filename)
g_free(brush->filename);
if (brush->name)
g_free(brush->name);
if (brush->mask)
temp_buf_free(brush->mask);
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
static void
gimp_brush_class_init (GimpBrushClass *klass)
{
GtkObjectClass *object_class;
GtkType type;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (gimp_object_get_type ());
type=object_class->type;
object_class->destroy = gimp_brush_destroy;
gimp_brush_signals[DIRTY] =
gimp_signal_new ("dirty", 0, type, 0, gimp_sigtype_void);
gimp_brush_signals[RENAME] =
gimp_signal_new ("rename", 0, type, 0, gimp_sigtype_void);
gtk_object_class_add_signals (object_class, gimp_brush_signals, LAST_SIGNAL);
}
void
gimp_brush_init(GimpBrush *brush)
{
brush->filename = NULL;
brush->name = NULL;
brush->spacing = 20;
brush->index = 0;
brush->mask = NULL;
}
GtkType gimp_brush_get_type(void)
{
static GtkType type;
if(!type){
GtkTypeInfo info={
"GimpBrush",
sizeof(GimpBrush),
sizeof(GimpBrushClass),
(GtkClassInitFunc)gimp_brush_class_init,
(GtkObjectInitFunc)gimp_brush_init,
NULL,
NULL };
type=gtk_type_unique(gimp_object_get_type(), &info);
}
return type;
}
GimpBrush *
gimp_brush_new (char *filename)
{
GimpBrush *brush=GIMP_BRUSH(gtk_type_new(gimp_brush_get_type ()));
gimp_brush_load(brush, filename);
return brush;
}
TempBuf *
gimp_brush_get_mask (GimpBrush *brush)
{
g_return_val_if_fail(GIMP_IS_BRUSH(brush), NULL);
return brush->mask;
}
void
gimp_brush_load(GimpBrush *brush, char *filename)
{
FILE * fp;
int bn_size;
unsigned char buf [sz_BrushHeader];
BrushHeader header;
unsigned int * hp;
int i;
brush->filename = g_strdup (filename);
/* Open the requested file */
if (! (fp = fopen (filename, "r")))
{
gimp_object_destroy (brush);
return;
}
/* Read in the header size */
if ((fread (buf, 1, sz_BrushHeader, fp)) < sz_BrushHeader)
{
fclose (fp);
gimp_object_destroy (brush);
return;
}
/* rearrange the bytes in each unsigned int */
hp = (unsigned int *) &header;
for (i = 0; i < (sz_BrushHeader / 4); i++)
hp [i] = (buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]);
/* Check for correct file format */
if (header.magic_number != GBRUSH_MAGIC)
{
/* One thing that can save this error is if the brush is version 1 */
if (header.version != 1)
{
fclose (fp);
gimp_object_destroy (brush);
return;
}
}
if (header.version == 1)
{
/* If this is a version 1 brush, set the fp back 8 bytes */
fseek (fp, -8, SEEK_CUR);
header.header_size += 8;
/* spacing is not defined in version 1 */
header.spacing = 25;
}
/* Read in the brush name */
if ((bn_size = (header.header_size - sz_BrushHeader)))
{
brush->name = (char *) g_malloc (sizeof (char) * bn_size);
if ((fread (brush->name, 1, bn_size, fp)) < bn_size)
{
g_message ("Error in GIMP brush file...aborting.");
fclose (fp);
gimp_object_destroy (brush);
return;
}
}
else
brush->name = g_strdup ("Unnamed");
switch(header.version)
{
case 1:
case 2:
/* Get a new brush mask */
brush->mask = temp_buf_new (header.width, header.height, header.bytes,
0, 0, NULL);
brush->spacing = header.spacing;
/* Read the brush mask data */
if ((fread (temp_buf_data (brush->mask), 1, header.width * header.height,
fp)) < header.width * header.height)
g_message ("GIMP brush file appears to be truncated.");
break;
case 3:
fprintf(stderr, "loading generated brush\n");
fprintf(stderr, "currently unimplemeted expect a crash to occur any second\n");
fprintf(stderr, "finished loading generated brush\n");
break;
default:
g_message ("Unknown brush format version #%d in \"%s\"\n",
header.version, filename);
fclose (fp);
gimp_object_destroy (brush);
return;
}
/* Clean up */
fclose (fp);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (brush->mask);
/* TODO: get rid of this call */
gimp_brush_list_add(brush_list, brush);
/* Check if the current brush is the default one */
/* lets see if it works with out this for now */
/* if (strcmp(default_brush, prune_filename(filename)) == 0) {
active_brush = brush;
have_default_brush = 1;
}*/ /* if */
}

55
app/gimpbrush.h Normal file
View File

@ -0,0 +1,55 @@
/* The GIMP -- an 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 __GIMPBRUSH_H__
#define __GIMPBRUSH_H__
#include "gimpobjectP.h"
#include "temp_buf.h"
typedef struct _GimpBrush GimpBrush, * GimpBrushP;
struct _GimpBrush
{
GimpObject gobject;
char * filename; /* actual filename--brush's location on disk */
char * name; /* brush's name--for brush selection dialog */
int spacing; /* brush's spacing */
int index; /* brush's index... */
TempBuf * mask; /* the actual mask... */
};
struct _GimpBrushClass
{
GimpObjectClass parent_class;
};
typedef struct _GimpBrushClass GimpBrushClass;
#define BRUSH_CLASS(klass) \
GTK_CHECK_CLASS_CAST (klass, gimp_brush_get_type(), GimpBrushClass)
#define GIMP_TYPE_BRUSH (gimp_brush_get_type ())
#define GIMP_BRUSH(obj) (GIMP_CHECK_CAST ((obj), GIMP_TYPE_BRUSH, GimpBrush))
#define GIMP_IS_BRUSH(obj) (GIMP_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH))
GimpBrush * gimp_brush_new (char *filename);
void gimp_brush_load (GimpBrush *brush, char *filename);
GtkType gimp_brush_get_type (void);
TempBuf * gimp_brush_get_mask (GimpBrush *brush);
#endif /* __GIMPBRUSH_H__ */

285
app/gimpbrushgenerated.c Normal file
View File

@ -0,0 +1,285 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimp_brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 "appenv.h"
#include "gimpbrushgenerated.h"
#include "gimpbrushlist.h"
#include "paint_core.h"
#include <math.h>
#define OVERSAMPLING 5
static GimpObjectClass* parent_class;
static void
gimp_brush_generated_destroy(GimpBrushGenerated *object)
{
GTK_OBJECT_CLASS(parent_class)->destroy (object);
}
static void
gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
{
GtkObjectClass *object_class;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (GIMP_TYPE_BRUSH);
object_class->destroy = gimp_brush_generated_destroy;
}
void
gimp_brush_generated_init(GimpBrushGenerated *brush)
{
brush->radius = 5.0;
brush->hardness = 0.0;
brush->angle = 0.0;
brush->aspect_ratio = 1.0;
}
guint gimp_brush_generated_get_type(void)
{
static GtkType type;
if(!type){
GtkTypeInfo info={
"GimpBrushGenerated",
sizeof(GimpBrushGenerated),
sizeof(GimpBrushGeneratedClass),
(GtkClassInitFunc)gimp_brush_generated_class_init,
(GtkObjectInitFunc)gimp_brush_generated_init,
NULL,
NULL };
type=gtk_type_unique(GIMP_TYPE_BRUSH, &info);
}
return type;
}
GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
float angle, float aspect_ratio)
{
GimpBrushGenerated *brush;
/* set up normal brush data */
brush = GIMP_BRUSH_GENERATED(gimp_type_new(gimp_brush_generated_get_type ()));
GIMP_BRUSH(brush)->name = g_strdup ("AAAGenerated");
GIMP_BRUSH(brush)->spacing = 20;
/* set up gimp_brush_generated data */
brush->radius = radius;
brush->hardness = hardness;
brush->angle = angle;
brush->aspect_ratio = aspect_ratio;
/* render brush mask */
gimp_brush_generated_generate(brush);
/* add brush to brush list */
/* FIXME: Get rid of this */
gimp_brush_list_add(brush_list, GIMP_BRUSH(brush));
select_brush(GIMP_BRUSH(brush));
return brush;
}
void
gimp_brush_generated_generate(GimpBrushGenerated *brush)
{
register GimpBrush *gbrush = NULL;
register int x, y;
register guchar *centerp;
register double d;
register double exponent;
register guchar a;
register int length;
register char *lookup;
double buffer[OVERSAMPLING];
register double sum, c, s, tx, ty;
int width, height;
if (!GIMP_IS_BRUSH_GENERATED(brush))
{
g_message("call to gimp_brush_generated_generate on non generated brush");
return;
}
gbrush = GIMP_BRUSH(brush);
if (gbrush->mask)
{
temp_buf_free(gbrush->mask);
}
#define D_TO_R M_PI/180
/* compute the range of the brush, should do a better job than this */
s = sin(brush->angle*M_PI/180);
c = cos(brush->angle*M_PI/180);
tx = MAXIMUM(fabs(c*ceil(brush->radius) - s*ceil(brush->radius)
/brush->aspect_ratio),
fabs(c*ceil(brush->radius) + s*ceil(brush->radius)
/brush->aspect_ratio));
ty = MAXIMUM(fabs(s*ceil(brush->radius) + c*ceil(brush->radius)
/brush->aspect_ratio),
fabs(s*ceil(brush->radius) - c*ceil(brush->radius)
/brush->aspect_ratio));
if (brush->radius > tx)
width = ceil(tx);
else
width = ceil(brush->radius+1);
if (brush->radius > ty)
height = ceil(ty);
else
height = ceil(brush->radius);
gbrush->mask = temp_buf_new(width*2 + 1,
height*2 + 1,
1, width, height, 0);
centerp = &gbrush->mask->data[height*gbrush->mask->width + width];
if ((1.0 - brush->hardness) < 0.000001)
exponent = 1000000;
else
exponent = 1/(1.0 - brush->hardness);
/* set up lookup table */
length = ceil(sqrt(2*ceil(brush->radius+1)*ceil(brush->radius+1))+1) * OVERSAMPLING;
lookup = g_malloc(length);
sum = 0.0;
for (x = 0; x < OVERSAMPLING; x++)
{
d = fabs((x+.5)/OVERSAMPLING - .5);
if (d > brush->radius)
buffer[x] = 0.0;
else
buffer[x] = (1.0 - pow(d/brush->radius, exponent));
sum += buffer[x];
}
for (x = 0; d < brush->radius || sum > .00001; d += 1.0/OVERSAMPLING)
{
sum -= buffer[x%OVERSAMPLING];
if (d > brush->radius)
buffer[x%OVERSAMPLING] = 0.0;
else
buffer[x%OVERSAMPLING] = (1.0 - pow(d/brush->radius, exponent));
sum += buffer[x%OVERSAMPLING];
lookup[x++] = rint(sum*(255.0/OVERSAMPLING));
}
while (x < length)
{
lookup[x++] = 0;
}
/* compute one half and mirror it */
for (y = 0; y <= height; y++)
{
for (x = -width; x <= width; x++)
{
tx = c*x - s*y;
ty = c*y + s*x;
ty *= brush->aspect_ratio;
d = sqrt(tx*tx + ty*ty);
if (d < brush->radius+1)
a = lookup[(int)rint(d*OVERSAMPLING)];
else
a = 0;
centerp[ y*gbrush->mask->width + x] = a;
centerp[-1*y*gbrush->mask->width - x] = a;
/* centerp[-1*y*brush->mask->width + x] = a;
centerp[-1*y*brush->mask->width - x] = a;
centerp[ x*brush->mask->width + y] = a;
centerp[ x*brush->mask->width - y] = a;
centerp[-1*x*brush->mask->width + y] = a;
centerp[-1*x*brush->mask->width - y] = a;*/
}
}
g_free (lookup);
/* gtk_signal_emit_by_name(brush, "dirty"); */
brush_changed_notify(GIMP_BRUSH(brush));
}
float
gimp_brush_generated_set_radius (GimpBrushGenerated* brush, float radius)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (radius < 0.0)
radius = 0.0;
else if(radius > 32767.0)
radius = 32767.0;
brush->radius = radius;
return brush->radius;
}
float
gimp_brush_generated_set_hardness (GimpBrushGenerated* brush, float hardness)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (hardness < 0.0)
hardness = 0.0;
else if(hardness > 1.0)
hardness = 1.0;
brush->hardness = hardness;
return brush->hardness;
}
float
gimp_brush_generated_set_angle (GimpBrushGenerated* brush, float angle)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (angle < 0.0)
angle = -1.0 * fmod(angle, 180.0);
else if(angle > 180.0)
angle = fmod(angle, 180.0);
brush->angle = angle;
return brush->angle;
}
float
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated* brush, float ratio)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
if (ratio < 1.0)
ratio = 1.0;
else if(ratio > 1000)
ratio = 1000;
brush->aspect_ratio = ratio;
return brush->aspect_ratio;
}
float
gimp_brush_generated_get_radius (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->radius;
}
float
gimp_brush_generated_get_hardness (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->hardness;
}
float
gimp_brush_generated_get_angle (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->angle;
}
float
gimp_brush_generated_get_aspect_ratio (GimpBrushGenerated* brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED(brush), -1.0);
return brush->aspect_ratio;
}

72
app/gimpbrushgenerated.h Normal file
View File

@ -0,0 +1,72 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* brush_generated module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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_GENERATED_H__
#define __GIMP_BRUSH_GENERATED_H__
#include "gimpbrush.h"
typedef struct _GimpBrushGenerated
{
GimpBrush gbrush;
float radius;
float hardness; /* 0.0 - 1.0 */
float angle; /* in degrees */
float aspect_ratio; /* y/x */
/*GSpline *profile_curve */ /* Some lazy day... */
} GimpBrushGenerated;
typedef struct _GimpBrushGeneratedClass
{
GimpBrushClass parent_class;
void (* generate) (GimpBrushGenerated *brush);
} GimpBrushGeneratedClass;
/* object stuff */
#define GIMP_TYPE_BRUSH_GENERATED (gimp_brush_generated_get_type ())
#define GIMP_BRUSH_GENERATED(obj) (GIMP_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_GENERATED, GimpBrushGenerated))
#define GIMP_IS_BRUSH_GENERATED(obj) (GIMP_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH_GENERATED))
guint gimp_brush_generated_get_type (void);
/* normal stuff */
GimpBrushGenerated *gimp_brush_generated_new(float radius, float hardness,
float angle, float aspect_ratio);
void gimp_brush_generated_generate (GimpBrushGenerated *brush);
float gimp_brush_generated_set_radius (GimpBrushGenerated* brush,
float radius);
float gimp_brush_generated_set_hardness (GimpBrushGenerated* brush,
float hardness);
float gimp_brush_generated_set_angle (GimpBrushGenerated* brush,
float angle);
float gimp_brush_generated_set_aspect_ratio(GimpBrushGenerated* brush,
float ratio);
float gimp_brush_generated_get_radius (GimpBrushGenerated* brush);
float gimp_brush_generated_get_hardness (GimpBrushGenerated* brush);
float gimp_brush_generated_get_angle (GimpBrushGenerated* brush);
float gimp_brush_generated_get_aspect_ratio (GimpBrushGenerated* brush);
#endif /* __GIMP_BRUSH_GENERATED_H__ */

View File

@ -23,7 +23,8 @@
#include <sys/stat.h>
#include <sys/types.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "gimpbrushgenerated.h"
#include "brush_header.h"
#include "brush_select.h"
#include "buildmenu.h"
@ -33,13 +34,16 @@
#include "errors.h"
#include "general.h"
#include "gimprc.h"
#include "gimpsignal.h"
#include "menus.h"
#include "paint_core.h"
#include "gimpset.h"
#include "gimpsetP.h"
/* global variables */
GBrushP active_brush = NULL;
GSList * brush_list = NULL;
int num_brushes = 0;
GimpBrushP active_brush = NULL;
GimpBrushList * brush_list = NULL;
double opacity = 1.0;
int paint_mode = 0;
@ -54,45 +58,73 @@ static Argument *return_args;
static int have_default_brush = 0;
/* static function prototypes */
static GSList * insert_brush_in_list (GSList *, GBrushP);
static void create_default_brush (void);
static void load_brush (char *filename);
static void free_brush (GBrushP);
static void brushes_free_one (gpointer, gpointer);
static gint brush_compare_func (gconstpointer,
gconstpointer);
/* function declarations */
void
brushes_init (int no_data)
static void gimp_brush_list_recalc_indexes(GimpBrushList *brush_list);
static void gimp_brush_list_uniquefy_names(GimpBrushList *brush_list);
/* class functions */
static GimpObjectClass* parent_class;
static void
gimp_brush_list_class_init (GimpBrushListClass *klass)
{
GSList * list;
GBrushP gb_start = NULL;
GtkObjectClass *object_class;
object_class = GTK_OBJECT_CLASS(klass);
parent_class = gtk_type_class (gimp_object_get_type ());
}
void
gimp_brush_list_init(GimpBrushList *list)
{
list->num_brushes = 0;
}
GtkType gimp_brush_list_get_type(void)
{
static GtkType type;
if(!type)
{
GtkTypeInfo info={
"GimpBrushList",
sizeof(GimpBrushList),
sizeof(GimpBrushListClass),
(GtkClassInitFunc)gimp_brush_list_class_init,
(GtkObjectInitFunc)gimp_brush_list_init,
NULL,
NULL };
type=gtk_type_unique(gimp_set_get_type(), &info);
}
return type;
}
GimpBrushList *
gimp_brush_list_new ()
{
GimpBrushList *list=GIMP_BRUSH_LIST(gtk_type_new(gimp_brush_list_get_type()));
GIMP_SET(list)->type = GIMP_TYPE_BRUSH;
GIMP_SET(list)->weak = 0;
return list;
}
void gimp_brush_list_uniquefy_names(GimpBrushList *blist)
{
GSList *list = GIMP_SET(blist)->list;
GimpBrushP gb_start = NULL;
gint gb_count = 0;
if (brush_list)
brushes_free();
brush_list = NULL;
num_brushes = 0;
if (!brush_path)
create_default_brush ();
if(!no_data)
datafiles_read_directories (brush_path, load_brush, 0);
/* assign indexes to the loaded brushes */
list = brush_list;
while (list) {
/* Set the brush index */
/* ALT make names unique */
GBrushP gb = (GBrushP)list->data;
gb->index = num_brushes++;
while (list)
{
GimpBrushP gb = (GimpBrushP)list->data;
list = g_slist_next(list);
if(list) {
GBrushP gb2 = (GBrushP)list->data;
GimpBrushP gb2 = (GimpBrushP)list->data;
if(gb_start == NULL) {
gb_start = gb;
@ -122,19 +154,39 @@ brushes_init (int no_data)
}
}
/* function declarations */
void
brushes_init (int no_data)
{
if (brush_list)
brushes_free();
brush_list = NULL;
brush_list = gimp_brush_list_new();
if (!brush_path)
create_default_brush ();
if(!no_data)
datafiles_read_directories (brush_path, gimp_brush_new, 0);
gimp_brush_list_recalc_indexes(brush_list);
gimp_brush_list_uniquefy_names(brush_list);
}
static void
brushes_free_one (gpointer data, gpointer dummy)
{
free_brush ((GBrushP) data);
gimp_object_unref (GIMP_OBJECT(data));
}
static gint
brush_compare_func (gconstpointer first, gconstpointer second)
{
return strcmp (((const GBrushP)first)->name,
((const GBrushP)second)->name);
return strcmp (((const GimpBrushP)first)->name,
((const GimpBrushP)second)->name);
}
@ -142,13 +194,12 @@ void
brushes_free ()
{
if (brush_list) {
g_slist_foreach (brush_list, brushes_free_one, NULL);
g_slist_free (brush_list);
gimp_set_foreach (brush_list, brushes_free_one, NULL);
gimp_object_destroy(GIMP_OBJECT(brush_list));
}
have_default_brush = 0;
active_brush = NULL;
num_brushes = 0;
brush_list = NULL;
}
@ -164,7 +215,7 @@ brush_select_dialog_free ()
}
GBrushP
GimpBrushP
get_active_brush ()
{
if (have_default_brush)
@ -174,14 +225,15 @@ get_active_brush ()
fatal_error ("Specified default brush not found!");
}
else if (! active_brush && brush_list)
active_brush = (GBrushP) brush_list->data;
/* need a gimp_set_get_first() type function */
active_brush = (GimpBrushP) GIMP_SET(brush_list)->list->data;
return active_brush;
}
static GSList *
insert_brush_in_list (GSList *list, GBrushP brush)
insert_brush_in_list (GSList *list, GimpBrushP brush)
{
return g_slist_insert_sorted (list, brush, brush_compare_func);
}
@ -189,156 +241,56 @@ insert_brush_in_list (GSList *list, GBrushP brush)
static void
create_default_brush ()
{
GBrushP brush;
gchar filled[] = { 255 };
GimpBrushGenerated *brush;
brush = g_new (GBrush, 1);
brush->filename = NULL;
brush->name = g_strdup ("Default");
brush->mask = temp_buf_new (1, 1, 1, 0, 0, (unsigned char *)filled);
brush->spacing = 25;
brush = gimp_brush_generated_new(5.0, .5, 0.0, 1.0);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (brush->mask);
brush_list = insert_brush_in_list(brush_list, brush);
temp_buf_swap (GIMP_BRUSH(brush)->mask);
/* Make this the default, active brush */
active_brush = brush;
active_brush = GIMP_BRUSH(brush);
have_default_brush = 1;
}
static void
load_brush(char *filename)
{
GBrushP brush;
FILE * fp;
int bn_size;
unsigned char buf [sz_BrushHeader];
BrushHeader header;
unsigned int * hp;
int i;
brush = (GBrushP) g_malloc (sizeof (GBrush));
brush->filename = g_strdup (filename);
brush->name = NULL;
brush->mask = NULL;
/* Open the requested file */
if (! (fp = fopen (filename, "r")))
{
free_brush (brush);
return;
}
/* Read in the header size */
if ((fread (buf, 1, sz_BrushHeader, fp)) < sz_BrushHeader)
{
fclose (fp);
free_brush (brush);
return;
}
/* rearrange the bytes in each unsigned int */
hp = (unsigned int *) &header;
for (i = 0; i < (sz_BrushHeader / 4); i++)
hp [i] = (buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]);
/* Check for correct file format */
if (header.magic_number != GBRUSH_MAGIC)
{
/* One thing that can save this error is if the brush is version 1 */
if (header.version != 1)
{
fclose (fp);
free_brush (brush);
return;
}
}
/* Check for correct version */
if (header.version != FILE_VERSION)
{
/* If this is a version 1 brush, set the fp back 8 bytes */
if (header.version == 1)
{
fseek (fp, -8, SEEK_CUR);
header.header_size += 8;
/* spacing is not defined in version 1 */
header.spacing = 25;
}
else
{
g_message ("Unknown GIMP version #%d in \"%s\"\n", header.version,
filename);
fclose (fp);
free_brush (brush);
return;
}
}
/* Get a new brush mask */
brush->mask = temp_buf_new (header.width, header.height, header.bytes, 0, 0, NULL);
brush->spacing = header.spacing;
/* Read in the brush name */
if ((bn_size = (header.header_size - sz_BrushHeader)))
{
brush->name = (char *) g_malloc (sizeof (char) * bn_size);
if ((fread (brush->name, 1, bn_size, fp)) < bn_size)
{
g_message ("Error in GIMP brush file...aborting.");
fclose (fp);
free_brush (brush);
return;
}
}
else
brush->name = g_strdup ("Unnamed");
/* Read the brush mask data */
/* Read the image data */
if ((fread (temp_buf_data (brush->mask), 1, header.width * header.height, fp)) <
header.width * header.height)
g_message ("GIMP brush file appears to be truncated.");
/* Clean up */
fclose (fp);
/* Swap the brush to disk (if we're being stingy with memory) */
if (stingy_memory_use)
temp_buf_swap (brush->mask);
brush_list = insert_brush_in_list(brush_list, brush);
/* Check if the current brush is the default one */
if (strcmp(default_brush, prune_filename(filename)) == 0) {
active_brush = brush;
have_default_brush = 1;
} /* if */
}
GBrushP
GimpBrushP
get_brush_by_index (int index)
{
GSList *list;
GBrushP brush = NULL;
list = g_slist_nth (brush_list, index);
GimpBrushP brush = NULL;
/* fix me: make a gimp_set function that does this */
list = g_slist_nth (GIMP_SET(brush_list)->list, index);
if (list)
brush = (GBrushP) list->data;
brush = (GimpBrushP) list->data;
return brush;
}
static void gimp_brush_do_indexes(GimpBrush *brush, int *index)
{
brush->index = (*index)++;
}
static void
gimp_brush_list_recalc_indexes(GimpBrushList *brush_list)
{
int index = 0;
gimp_set_foreach (GIMP_SET(brush_list), gimp_brush_do_indexes, &index);
}
void
select_brush (GBrushP brush)
gimp_brush_list_add (GimpBrushList *brush_list, GimpBrushP brush)
{
gimp_set_add(GIMP_SET(brush_list), brush);
brush_list->num_brushes++;
gimp_brush_list_recalc_indexes(brush_list);
}
void
select_brush (GimpBrushP brush)
{
/* Make sure the active brush is swapped before we get a new one... */
if (stingy_memory_use)
@ -378,63 +330,15 @@ create_brush_dialog ()
}
static void
free_brush (brush)
GBrushP brush;
{
if (brush->mask)
temp_buf_free (brush->mask);
if (brush->filename)
g_free (brush->filename);
if (brush->name)
g_free (brush->name);
g_free (brush);
}
double
get_brush_opacity ()
{
return opacity;
}
int
get_brush_spacing ()
{
if (active_brush)
return active_brush->spacing;
else
return 0;
}
int
get_brush_paint_mode ()
{
return paint_mode;
}
void
set_brush_opacity (opac)
double opac;
brush_changed_notify (GimpBrushP brush)
{
opacity = opac;
}
void
set_brush_spacing (spac)
int spac;
{
if (active_brush)
active_brush->spacing = spac;
}
void
set_brush_paint_mode (pm)
int pm;
{
paint_mode = pm;
if (brush)
{
paint_core_invalidate_cache(brush->mask);
if (brush_select_dialog)
brush_select_brush_changed(brush_select_dialog, brush);
}
}
@ -444,7 +348,7 @@ set_brush_paint_mode (pm)
static Argument *
brushes_get_brush_invoker (Argument *args)
{
GBrushP brushp;
GimpBrushP brushp;
success = (brushp = get_active_brush ()) != NULL;
@ -549,72 +453,53 @@ ProcRecord brushes_refresh_brush_proc =
{ { brushes_refresh_brush_invoker } },
};
/***********************/
/* BRUSHES_SET_BRUSH */
static Argument *
brushes_set_brush_invoker (Argument *args)
/* access functions */
double
gimp_brush_get_opacity ()
{
GBrushP brushp;
GSList *list;
char *name;
success = (name = (char *) args[0].value.pdb_pointer) != NULL;
if (success)
{
list = brush_list;
success = FALSE;
while (list)
{
brushp = (GBrushP) list->data;
if (!strcmp (brushp->name, name))
{
success = TRUE;
select_brush (brushp);
break;
}
list = g_slist_next (list);
}
}
return procedural_db_return_args (&brushes_set_brush_proc, success);
return opacity;
}
/* The procedure definition */
ProcArg brushes_set_brush_args[] =
int
gimp_brush_get_spacing ()
{
{ PDB_STRING,
"name",
"the brush name"
}
};
if (active_brush)
return active_brush->spacing;
else
return 0;
}
ProcRecord brushes_set_brush_proc =
int
gimp_brush_get_paint_mode ()
{
"gimp_brushes_set_brush",
"Set the specified brush as the active brush",
"This procedure allows the active brush mask to be set by specifying its name. The name is simply a string which corresponds to one of the names of the installed brushes. If there is no matching brush found, this procedure will return an error. Otherwise, the specified brush becomes active and will be used in all subsequent paint operations.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1995-1996",
PDB_INTERNAL,
return paint_mode;
}
/* Input arguments */
1,
brushes_set_brush_args,
void
gimp_brush_set_opacity (opac)
double opac;
{
opacity = opac;
}
/* Output arguments */
0,
NULL,
void
gimp_brush_set_spacing (spac)
int spac;
{
if (active_brush)
active_brush->spacing = spac;
}
/* Exec method */
{ { brushes_set_brush_invoker } },
};
void
gimp_brush_set_paint_mode (pm)
int pm;
{
paint_mode = pm;
}
/****************************/
/* PDB Interface To Brushes */
/****************************/
/*************************/
/* BRUSHES_GET_OPACITY */
@ -623,7 +508,7 @@ static Argument *
brushes_get_opacity_invoker (Argument *args)
{
return_args = procedural_db_return_args (&brushes_get_opacity_proc, TRUE);
return_args[1].value.pdb_float = get_brush_opacity () * 100.0;
return_args[1].value.pdb_float = gimp_brush_get_opacity () * 100.0;
return return_args;
}
@ -672,7 +557,7 @@ brushes_set_opacity_invoker (Argument *args)
success = (opacity >= 0.0 && opacity <= 100.0);
if (success)
set_brush_opacity (opacity / 100.0);
gimp_brush_set_opacity (opacity / 100.0);
return procedural_db_return_args (&brushes_set_opacity_proc, success);
}
@ -716,7 +601,7 @@ static Argument *
brushes_get_spacing_invoker (Argument *args)
{
return_args = procedural_db_return_args (&brushes_get_spacing_proc, TRUE);
return_args[1].value.pdb_int = get_brush_spacing ();
return_args[1].value.pdb_int = gimp_brush_get_spacing ();
return return_args;
}
@ -765,7 +650,7 @@ brushes_set_spacing_invoker (Argument *args)
success = (spacing >= 0 && spacing <= 1000);
if (success)
set_brush_spacing (spacing);
gimp_brush_set_spacing (spacing);
return procedural_db_return_args (&brushes_set_spacing_proc, success);
}
@ -809,7 +694,7 @@ static Argument *
brushes_get_paint_mode_invoker (Argument *args)
{
return_args = procedural_db_return_args (&brushes_get_paint_mode_proc, TRUE);
return_args[1].value.pdb_int = get_brush_paint_mode ();
return_args[1].value.pdb_int = gimp_brush_get_paint_mode ();
return return_args;
}
@ -858,7 +743,7 @@ brushes_set_paint_mode_invoker (Argument *args)
success = (paint_mode >= NORMAL_MODE && paint_mode <= VALUE_MODE);
if (success)
set_brush_paint_mode (paint_mode);
gimp_brush_set_paint_mode (paint_mode);
return procedural_db_return_args (&brushes_set_paint_mode_proc, success);
}
@ -895,25 +780,105 @@ ProcRecord brushes_set_paint_mode_proc =
};
GimpBrushP
gimp_brush_list_get_brush(GimpBrushListP blist, char *name)
{
GimpBrushP brushp;
GSList *list;
list = GIMP_SET(brush_list)->list;
success = FALSE;
while (list)
{
brushp = (GimpBrushP) list->data;
if (!strcmp (brushp->name, name))
{
return brushp;
}
list = g_slist_next (list);
}
return NULL;
}
/***********************/
/* BRUSHES_SET_BRUSH */
static Argument *
brushes_set_brush_invoker (Argument *args)
{
GimpBrushP brushp;
char *name;
success = (name = (char *) args[0].value.pdb_pointer) != NULL;
if (success)
{
brushp = gimp_brush_list_get_brush(brush_list, name);
if (brushp)
select_brush(brushp);
else
success = 0;
}
return procedural_db_return_args (&brushes_set_brush_proc, success);
}
/* The procedure definition */
ProcArg brushes_set_brush_args[] =
{
{ PDB_STRING,
"name",
"the brush name"
}
};
ProcRecord brushes_set_brush_proc =
{
"gimp_brushes_set_brush",
"Set the specified brush as the active brush",
"This procedure allows the active brush mask to be set by specifying its name. The name is simply a string which corresponds to one of the names of the installed brushes. If there is no matching brush found, this procedure will return an error. Otherwise, the specified brush becomes active and will be used in all subsequent paint operations.",
"Spencer Kimball & Peter Mattis",
"Spencer Kimball & Peter Mattis",
"1995-1996",
PDB_INTERNAL,
/* Input arguments */
1,
brushes_set_brush_args,
/* Output arguments */
0,
NULL,
/* Exec method */
{ { brushes_set_brush_invoker } },
};
/******************/
/* BRUSHES_LIST */
static Argument *
brushes_list_invoker (Argument *args)
{
GBrushP brushp;
GimpBrushP brushp;
GSList *list;
char **brushes;
int i;
brushes = (char **) g_malloc (sizeof (char *) * num_brushes);
brushes = (char **) g_malloc (sizeof (char *) * brush_list->num_brushes);
success = (list = brush_list) != NULL;
success = (list = GIMP_SET(brush_list)->list) != NULL;
i = 0;
while (list)
{
brushp = (GBrushP) list->data;
brushp = (GimpBrushP) list->data;
brushes[i++] = g_strdup (brushp->name);
list = g_slist_next (list);
@ -923,7 +888,7 @@ brushes_list_invoker (Argument *args)
if (success)
{
return_args[1].value.pdb_int = num_brushes;
return_args[1].value.pdb_int = brush_list->num_brushes;
return_args[2].value.pdb_pointer = brushes;
}

97
app/gimpbrushlist.h Normal file
View File

@ -0,0 +1,97 @@
/* The GIMP -- an 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 __GIMPBRUSHELIST_H__
#define __GIMPBRUSHELIST_H__
#include <glib.h>
#include "procedural_db.h"
#include "temp_buf.h"
#include "gimpbrush.h"
#include "gimpset.h"
#include "gimpsetP.h"
typedef struct _GimpBrushList GimpBrushList, * GimpBrushListP;
struct _GimpBrushList
{
GimpSet gimpset;
int num_brushes;
};
typedef struct _GimpBrushListClass GimpBrushListClass;
struct _GimpBrushListClass
{
GimpSetClass parent_class;
};
#define BRUSH_LIST_CLASS(klass) \
GTK_CHECK_CLASS_CAST (klass, gimp_brush_list_get_type(), GimpBrushListClass)
#define GIMP_TYPE_BRUSH_LIST (gimp_brush_list_get_type ())
#define GIMP_BRUSH_LIST(obj) (GIMP_CHECK_CAST ((obj), GIMP_TYPE_BRUSH_LIST, GimpBrushList))
#define GIMP_IS_BRUSH_LIST(obj) (GIMP_CHECK_TYPE ((obj), GIMP_TYPE_BRUSH_LIST))
GimpBrushListP gimp_brush_list_new (void);
GtkType gimp_brush_list_get_type (void);
void gimp_brush_list_add (GimpBrushListP list,
GimpBrushP brush);
GimpBrushP gimp_brush_list_get_brush(GimpBrushListP list, char *name);
/* global variables */
extern GimpBrushList *brush_list;
/* function declarations */
void brushes_init (int no_data);
void brushes_free (void);
void brush_select_dialog_free (void);
void select_brush (GimpBrushP);
GimpBrushP get_brush_by_index (int);
GimpBrushP get_active_brush (void);
/* TODO: {re}move these functions */
void create_brush_dialog (void);
void brush_changed_notify (GimpBrushP);
/* access functions */
/* TODO: move opacity and paint_mode into individual tools? */
/* TODO: move spacing into gimpbrush */
double gimp_brush_get_opacity (void);
int gimp_brush_get_spacing (void);
int gimp_brush_get_paint_mode (void);
void gimp_brush_set_opacity (double);
void gimp_brush_set_spacing (int);
void gimp_brush_set_paint_mode (int);
/* Brush procedures */
extern ProcRecord brushes_get_opacity_proc;
extern ProcRecord brushes_set_opacity_proc;
extern ProcRecord brushes_get_spacing_proc;
extern ProcRecord brushes_set_spacing_proc;
extern ProcRecord brushes_get_paint_mode_proc;
extern ProcRecord brushes_set_paint_mode_proc;
extern ProcRecord brushes_get_brush_proc;
extern ProcRecord brushes_set_brush_proc;
extern ProcRecord brushes_list_proc;
extern ProcRecord brushes_refresh_brush_proc;
#endif /* __GIMPBRUSHELIST_H__ */

View File

@ -13,6 +13,14 @@
guint gimp_object_get_type(void);
/* hacks to fake a gimp object lib */
#define GIMP_CHECK_CAST GTK_CHECK_CAST
#define GIMP_CHECK_TYPE GTK_CHECK_TYPE
#define gimp_type_new gtk_type_new
#define gimp_object_destroy(obj) gtk_object_destroy(GTK_OBJECT(obj))
#define gimp_object_ref(obj) gtk_object_ref(GTK_OBJECT(obj))
#define gimp_object_unref(obj) gtk_object_unref(GTK_OBJECT(obj))
#endif

205
app/gui/brush-editor.c Normal file
View File

@ -0,0 +1,205 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* brush_edit module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 "appenv.h"
#include "gimpbrushgenerated.h"
#include "brush_edit.h"
static void
update_brush_callback (GtkAdjustment *adjustment,
BrushEditGeneratedWindow *begw)
{
if (begw->brush &&
((begw->radius_data->value
!= gimp_brush_generated_get_radius(begw->brush))
|| (begw->hardness_data->value
!= gimp_brush_generated_get_hardness(begw->brush))
|| (begw->aspect_ratio_data->value
!= gimp_brush_generated_get_aspect_ratio(begw->brush))
|| (begw->angle_data->value
!=gimp_brush_generated_get_angle(begw->brush))))
{
gimp_brush_generated_set_radius (begw->brush,
begw->radius_data->value);
gimp_brush_generated_set_hardness (begw->brush,
begw->hardness_data->value);
gimp_brush_generated_set_aspect_ratio (begw->brush,
begw->aspect_ratio_data->value);
gimp_brush_generated_set_angle (begw->brush,
begw->angle_data->value);
gimp_brush_generated_generate(begw->brush);
}
}
static int
brush_edit_delete_callback (GtkWidget *w,
BrushEditGeneratedWindow *begw)
{
if (GTK_WIDGET_VISIBLE (w))
gtk_widget_hide (w);
return TRUE;
}
void
brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
GimpBrush *gbrush)
{
GimpBrushGenerated *brush = 0;
if (!GIMP_IS_BRUSH_GENERATED(gbrush))
return;
brush = GIMP_BRUSH_GENERATED(gbrush);
if (begw)
{
begw->brush = NULL;
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->radius_data),
gimp_brush_generated_get_radius (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->hardness_data),
gimp_brush_generated_get_hardness (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->angle_data),
gimp_brush_generated_get_angle (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->aspect_ratio_data),
gimp_brush_generated_get_aspect_ratio(brush));
begw->brush = brush;
}
}
BrushEditGeneratedWindow *
brush_edit_generated_new ()
{
BrushEditGeneratedWindow *begw ;
GtkWidget *vbox;
GtkWidget *sbar;
GtkWidget *label;
GtkWidget *slider;
GtkWidget *table;
GtkWidget *button1, *button2;
begw = g_malloc (sizeof (BrushEditGeneratedWindow));
begw->redraw = TRUE;
begw->shell = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (begw->shell), "generatedbrusheditor",
"Gimp");
gtk_window_set_title (GTK_WINDOW (begw->shell), "Brush Editor");
gtk_window_set_policy(GTK_WINDOW(begw->shell), FALSE, TRUE, FALSE);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_border_width (GTK_CONTAINER (vbox), 2);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (begw->shell)->vbox), vbox,
TRUE, TRUE, 0);
/* handle the wm close signal */
gtk_signal_connect (GTK_OBJECT (begw->shell), "delete_event",
GTK_SIGNAL_FUNC (brush_edit_delete_callback),
begw);
/* Populate the window with some widgets */
/* brush's preview widget w/frame */
begw->frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (begw->frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (vbox), begw->frame, TRUE, TRUE, 0);
begw->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (begw->preview), 100, 100);
gtk_container_add (GTK_CONTAINER (begw->frame), begw->preview);
gtk_widget_show(begw->preview);
gtk_widget_show(begw->frame);
/* table for sliders/labels */
table = gtk_table_new(2, 4, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* brush radius scale */
label = gtk_label_new ("Radius:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 0, 1, 0, 0, 0, 0);
begw->radius_data = GTK_ADJUSTMENT (gtk_adjustment_new (10.0, 0.0, 100.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->radius_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 0, 1);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->radius_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush hardness scale */
label = gtk_label_new ("Hardness:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 1, 2, 0, 0, 0, 0);
begw->hardness_data = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.01, 0.0));
slider = gtk_hscale_new (begw->hardness_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 1, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->hardness_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush aspect ratio scale */
label = gtk_label_new ("Aspect Ratio:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 2, 3, 0, 0, 0, 0);
begw->aspect_ratio_data = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 20.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->aspect_ratio_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 2, 3);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->aspect_ratio_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush angle scale */
label = gtk_label_new ("Angle:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 3, 4, 0, 0, 0, 0);
begw->angle_data = GTK_ADJUSTMENT (gtk_adjustment_new (00.0, 0.0, 180.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->angle_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 3, 4);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->angle_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
gtk_table_set_row_spacings(GTK_TABLE (table), 3);
gtk_table_set_col_spacing(GTK_TABLE (table), 0, 3);
gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (begw->shell);
return begw;
}

49
app/gui/brush-editor.h Normal file
View File

@ -0,0 +1,49 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* brush_edit module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 __BRUSH_EDIT_H__
#define __BRUSH_EDIT_H__
#include "gimpbrushgenerated.h"
typedef struct _BrushEditGeneratedWindow
{
GtkWidget *shell;
GtkWidget *frame;
GtkWidget *preview;
GtkWidget *options_box;
GtkAdjustment *radius_data;
GtkAdjustment *hardness_data;
GtkAdjustment *angle_data;
GtkAdjustment *aspect_ratio_data;
int width, height;
int cell_width, cell_height;
int redraw;
/* Brush preview */
GtkWidget *brush_preview;
GimpBrushGenerated *brush;
} BrushEditGeneratedWindow;
void brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
GimpBrush *brush);
BrushEditGeneratedWindow *brush_edit_generated_new ();
#endif /* __BRUSH_EDIT_H__ */

View File

@ -20,7 +20,12 @@
#include <string.h>
#include "appenv.h"
#include "actionarea.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "gimpset.h"
#include "gimpsetP.h" /* FIXME: get rid of this include */
#include "gimpbrushgenerated.h"
#include "brush_edit.h"
#include "brush_select.h"
#include "brush_select.h"
#include "buildmenu.h"
#include "colormaps.h"
@ -48,14 +53,18 @@
GDK_ENTER_NOTIFY_MASK
/* local function prototypes */
static void brush_popup_open (BrushSelectP, int, int, GBrushP);
static void brush_popup_open (BrushSelectP, int, int, GimpBrushP);
static void brush_popup_close (BrushSelectP);
static void display_brush (BrushSelectP, GBrushP, int, int);
static void display_brush (BrushSelectP, GimpBrushP, int, int);
static void display_brushes (BrushSelectP);
static void display_setup (BrushSelectP);
static void preview_calc_scrollbar (BrushSelectP);
static void brush_select_show_selected (BrushSelectP, int, int);
static void update_active_brush_field (BrushSelectP);
static gint edit_brush_callback (GtkWidget *w, GdkEvent *e,
gpointer data);
static gint new_brush_callback (GtkWidget *w, GdkEvent *e,
gpointer data);
static void brush_select_close_callback (GtkWidget *, gpointer);
static void brush_select_refresh_callback(GtkWidget *, gpointer);
static void paint_mode_menu_callback (GtkWidget *, gpointer);
@ -99,6 +108,7 @@ static ActionAreaItem action_items[] =
static double old_opacity;
static int old_spacing;
static int old_paint_mode;
static BrushEditGeneratedWindow *brush_edit_generated_dialog;
int NUM_BRUSH_COLUMNS=5;
int NUM_BRUSH_ROWS=5;
@ -131,7 +141,8 @@ brush_select_new ()
GtkWidget *util_box;
GtkWidget *option_menu;
GtkWidget *slider;
GBrushP active;
GimpBrushP active;
GtkWidget *button1, *button2;
bsp = g_malloc (sizeof (_BrushSelect));
bsp->redraw = TRUE;
@ -209,7 +220,7 @@ brush_select_new ()
gtk_widget_show (util_box);
/* Create the paint mode option menu */
old_paint_mode = get_brush_paint_mode ();
old_paint_mode = gimp_brush_get_paint_mode ();
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 0);
@ -225,7 +236,7 @@ brush_select_new ()
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
/* Create the opacity scale widget */
old_opacity = get_brush_opacity ();
old_opacity = gimp_brush_get_opacity ();
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 0);
@ -244,7 +255,7 @@ brush_select_new ()
gtk_widget_show (util_box);
/* Create the brush spacing scale widget */
old_spacing = get_brush_spacing ();
old_spacing = gimp_brush_get_spacing ();
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 0);
@ -262,6 +273,25 @@ brush_select_new ()
gtk_widget_show (slider);
gtk_widget_show (util_box);
/* Create the edit/new buttons */
util_box = gtk_hbox_new (FALSE, 2);
gtk_box_pack_start (GTK_BOX (bsp->options_box), util_box, FALSE, FALSE, 0);
button1 = gtk_button_new_with_label ("Edit Brush");
gtk_signal_connect (GTK_OBJECT (button1), "clicked",
(GtkSignalFunc) edit_brush_callback,
NULL);
gtk_box_pack_start (GTK_BOX (util_box), button1, TRUE, TRUE, 5);
button2 = gtk_button_new_with_label ("New Brush");
gtk_signal_connect (GTK_OBJECT (button2), "clicked",
(GtkSignalFunc) new_brush_callback,
NULL);
gtk_box_pack_start (GTK_BOX (util_box), button2, TRUE, TRUE, 5);
gtk_widget_show (button1);
gtk_widget_show (button2);
gtk_widget_show (util_box);
/* The action area */
action_items[0].user_data = bsp;
action_items[1].user_data = bsp;
@ -322,6 +352,24 @@ brush_select_free (BrushSelectP bsp)
}
}
void
brush_select_brush_changed(BrushSelectP bsp, GimpBrushP brush)
{
/* TODO: be smarter here and only update the part of the preview
* that has changed */
if (bsp)
{
display_brushes(bsp);
gtk_widget_draw (bsp->preview, NULL);
}
}
void
brush_select_brush_dirty_callback(GimpBrushP brush, BrushSelectP bsp)
{
brush_select_brush_changed(bsp, brush);
}
/*
* Local functions
@ -330,7 +378,7 @@ static void
brush_popup_open (BrushSelectP bsp,
int x,
int y,
GBrushP brush)
GimpBrushP brush)
{
gint x_org, y_org;
gint scr_w, scr_h;
@ -399,9 +447,10 @@ brush_popup_close (BrushSelectP bsp)
if (bsp->brush_popup != NULL)
gtk_widget_hide (bsp->brush_popup);
}
static void
display_brush (BrushSelectP bsp,
GBrushP brush,
GimpBrushP brush,
int col,
int row)
{
@ -477,9 +526,10 @@ display_setup (BrushSelectP bsp)
static void
display_brushes (BrushSelectP bsp)
{
GSList * list = brush_list; /* the global brush list */
/* FIXME: use gimp_set_foreach?? */
GSList * list = GIMP_SET(brush_list)->list; /* the global brush list */
int row, col;
GBrushP brush;
GimpBrushP brush;
/* If there are no brushes, insensitize widgets */
if (brush_list == NULL)
@ -497,7 +547,7 @@ display_brushes (BrushSelectP bsp)
row = col = 0;
while (list)
{
brush = (GBrushP) list->data;
brush = (GimpBrushP) list->data;
/* Display the brush */
display_brush (bsp, brush, col, row);
@ -610,7 +660,8 @@ preview_calc_scrollbar (BrushSelectP bsp)
/* int rowy; */
offs = bsp->scroll_offset;
num_rows = (num_brushes + NUM_BRUSH_COLUMNS - 1) / NUM_BRUSH_COLUMNS;
num_rows = (brush_list->num_brushes + NUM_BRUSH_COLUMNS - 1)
/ NUM_BRUSH_COLUMNS;
max = num_rows * bsp->cell_width;
if (!num_rows) num_rows = 1;
page_size = bsp->preview->allocation.height;
@ -640,7 +691,7 @@ brush_select_resize (GtkWidget *widget,
BrushSelectP bsp)
{
NUM_BRUSH_COLUMNS = (gint)((widget->allocation.width - 4) / STD_CELL_WIDTH);
NUM_BRUSH_ROWS = (num_brushes + NUM_BRUSH_COLUMNS - 1) / NUM_BRUSH_COLUMNS;
NUM_BRUSH_ROWS = (brush_list->num_brushes + NUM_BRUSH_COLUMNS - 1) / NUM_BRUSH_COLUMNS;
bsp->width = widget->allocation.width - 4;
bsp->height = widget->allocation.height - 4;
@ -663,7 +714,7 @@ brush_select_resize (GtkWidget *widget,
static void
update_active_brush_field (BrushSelectP bsp)
{
GBrushP brush;
GimpBrushP brush;
char buf[32];
brush = get_active_brush ();
@ -679,7 +730,7 @@ update_active_brush_field (BrushSelectP bsp)
gtk_label_set (GTK_LABEL (bsp->brush_size), buf);
/* Set brush spacing */
bsp->spacing_data->value = get_brush_spacing ();
bsp->spacing_data->value = gimp_brush_get_spacing ();
gtk_signal_emit_by_name (GTK_OBJECT (bsp->spacing_data), "value_changed");
}
@ -690,7 +741,7 @@ brush_select_events (GtkWidget *widget,
BrushSelectP bsp)
{
GdkEventButton *bevent;
GBrushP brush;
GimpBrushP brush;
int row, col, index;
switch (event->type)
@ -718,6 +769,9 @@ brush_select_events (GtkWidget *widget,
/* Make this brush the active brush */
select_brush (brush);
if (brush_edit_generated_dialog)
brush_edit_generated_set_brush(brush_edit_generated_dialog,
get_active_brush());
/* Show the brush popup window if the brush is too large */
if (brush->mask->width > bsp->cell_width ||
@ -750,6 +804,39 @@ brush_select_events (GtkWidget *widget,
return FALSE;
}
static gint
edit_brush_callback (GtkWidget *w, GdkEvent *e, gpointer data)
{
if (GIMP_IS_BRUSH_GENERATED(get_active_brush()))
{
if (!brush_edit_generated_dialog)
{
/* Create the dialog... */
brush_edit_generated_dialog = brush_edit_generated_new();
brush_edit_generated_set_brush(brush_edit_generated_dialog,
get_active_brush());
}
else
{
/* Popup the dialog */
if (!GTK_WIDGET_VISIBLE (brush_edit_generated_dialog->shell))
gtk_widget_show (brush_edit_generated_dialog->shell);
else
gdk_window_raise(brush_edit_generated_dialog->shell->window);
}
}
else
g_message("We are all out of brush editors today, please try again tomorrow\n");
return TRUE;
}
static gint
new_brush_callback (GtkWidget *w, GdkEvent *e, gpointer data)
{
brush_changed_notify(GIMP_BRUSH(gimp_brush_generated_new(10, .5, 0.0, 1.0)));
return TRUE;
}
static gint
brush_select_delete_callback (GtkWidget *w, GdkEvent *e, gpointer data)
{
@ -766,9 +853,9 @@ brush_select_close_callback (GtkWidget *w,
bsp = (BrushSelectP) client_data;
old_paint_mode = get_brush_paint_mode ();
old_opacity = get_brush_opacity ();
old_spacing = get_brush_spacing ();
old_paint_mode = gimp_brush_get_paint_mode ();
old_opacity = gimp_brush_get_opacity ();
old_spacing = gimp_brush_get_spacing ();
if (GTK_WIDGET_VISIBLE (bsp->shell))
gtk_widget_hide (bsp->shell);
@ -780,7 +867,7 @@ brush_select_refresh_callback (GtkWidget *w,
gpointer client_data)
{
BrushSelectP bsp;
GBrushP active;
GimpBrushP active;
bsp = (BrushSelectP) client_data;
@ -811,7 +898,7 @@ preview_scroll_update (GtkAdjustment *adjustment,
gpointer data)
{
BrushSelectP bsp;
GBrushP active;
GimpBrushP active;
int row, col;
bsp = data;
@ -838,7 +925,7 @@ static void
paint_mode_menu_callback (GtkWidget *w,
gpointer client_data)
{
set_brush_paint_mode ((long) client_data);
gimp_brush_set_paint_mode ((long) client_data);
}
@ -846,7 +933,7 @@ static void
opacity_scale_update (GtkAdjustment *adjustment,
gpointer data)
{
set_brush_opacity (adjustment->value / 100.0);
gimp_brush_set_opacity (adjustment->value / 100.0);
}
@ -854,5 +941,5 @@ static void
spacing_scale_update (GtkAdjustment *adjustment,
gpointer data)
{
set_brush_spacing ((int) adjustment->value);
gimp_brush_set_spacing ((int) adjustment->value);
}

View File

@ -19,6 +19,7 @@
#define __BRUSH_SELECT_H__
#include "buildmenu.h"
#include "gimpbrush.h"
typedef struct _BrushSelect _BrushSelect, *BrushSelectP;
@ -44,6 +45,8 @@ struct _BrushSelect {
BrushSelectP brush_select_new (void);
void brush_select_select (BrushSelectP, int);
void brush_select_free (BrushSelectP);
void brush_select_brush_changed(BrushSelectP bsp,
GimpBrushP brush);
/* An interface to other dialogs which need to create a paint mode menu */
GtkWidget * create_paint_mode_menu (MenuItemCallback);

View File

@ -23,7 +23,7 @@
#include "actionarea.h"
#include "app_procs.h"
#include "brightness_contrast.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "by_color_select.h"
#include "channels_dialog.h"
#include "colormaps.h"

View File

@ -20,7 +20,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -44,7 +44,7 @@ struct _DeviceInfo {
gint num_keys;
GdkDeviceKey *keys;
GBrushP brush;
GimpBrushP brush;
ToolType tool;
unsigned char foreground[3];
};
@ -201,7 +201,7 @@ devices_rc_update (gchar *name, DeviceValues values,
{
GList *tmp_list;
DeviceInfo *device_info;
GBrushP brushp;
GimpBrushP brushp;
/* Find device if we have it */
@ -299,27 +299,9 @@ devices_rc_update (gchar *name, DeviceValues values,
if (values & (DEVICE_BRUSH | DEVICE_TOOL | DEVICE_FOREGROUND))
device_info->is_init = TRUE;
/* FIXME: this should probably be left in brushes.c */
if (values & DEVICE_BRUSH)
{
GSList *list;
device_info->brush = NULL;
list = brush_list;
while (list)
{
brushp = (GBrushP) list->data;
if (!strcmp (brushp->name, brush_name))
{
device_info->brush = brushp;
break;
}
list = g_slist_next (list);
}
device_info->brush = gimp_brush_list_get_brush(brush_list, brush_name);
}
if (values & DEVICE_TOOL)

View File

@ -23,7 +23,7 @@
#include "actionarea.h"
#include "app_procs.h"
#include "brightness_contrast.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "by_color_select.h"
#include "channels_dialog.h"
#include "colormaps.h"

View File

@ -20,7 +20,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -44,7 +44,7 @@ struct _DeviceInfo {
gint num_keys;
GdkDeviceKey *keys;
GBrushP brush;
GimpBrushP brush;
ToolType tool;
unsigned char foreground[3];
};
@ -201,7 +201,7 @@ devices_rc_update (gchar *name, DeviceValues values,
{
GList *tmp_list;
DeviceInfo *device_info;
GBrushP brushp;
GimpBrushP brushp;
/* Find device if we have it */
@ -299,27 +299,9 @@ devices_rc_update (gchar *name, DeviceValues values,
if (values & (DEVICE_BRUSH | DEVICE_TOOL | DEVICE_FOREGROUND))
device_info->is_init = TRUE;
/* FIXME: this should probably be left in brushes.c */
if (values & DEVICE_BRUSH)
{
GSList *list;
device_info->brush = NULL;
list = brush_list;
while (list)
{
brushp = (GBrushP) list->data;
if (!strcmp (brushp->name, brush_name))
{
device_info->brush = brushp;
break;
}
list = g_slist_next (list);
}
device_info->brush = gimp_brush_list_get_brush(brush_list, brush_name);
}
if (values & DEVICE_TOOL)

View File

@ -5,7 +5,6 @@
#include "actionarea.h"
#include "app_procs.h"
#include "brightness_contrast.h"
#include "brushes.h"
#include "by_color_select.h"
#include "channels_dialog.h"
#include "colormaps.h"

View File

@ -16,10 +16,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "appenv.h"
#include "brushes.h"
#include "drawable.h"
#include "draw_core.h"
#include "gimage_mask.h"
#include "gimpbrushlist.h"
#include "ink.h"
#include "tools.h"
#include "undo.h"
@ -908,8 +908,8 @@ ink_paste (InkTool *ink_tool,
/* apply the paint area to the gimage */
gimage_apply_image (gimage, drawable, &srcPR,
FALSE,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode(),
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode(),
undo_tiles, /* specify an alternative src1 */
canvas_buf->x, canvas_buf->y);

View File

@ -24,7 +24,7 @@
#include "blend.h"
#include "bucket_fill.h"
#include "brightness_contrast.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "by_color_select.h"
#include "channel_cmds.h"
#include "channel_ops.h"

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -143,7 +143,7 @@ airbrush_paint_func (PaintCore *paint_core,
GimpDrawable *drawable,
int state)
{
GBrushP brush;
GimpBrushP brush;
if (!drawable)
return NULL;
@ -267,8 +267,8 @@ airbrush_motion (PaintCore *paint_core,
/* paste the newly painted area to the image */
paint_core_paste_canvas (paint_core, drawable,
opacity,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (),
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (),
SOFT, CONSTANT);
}

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -447,8 +447,8 @@ clone_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), SOFT, CONSTANT);
}
static void

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <stdio.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "convolve.h"
@ -329,7 +329,7 @@ convolve_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_replace_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
(int) (gimp_brush_get_opacity () * 255),
SOFT, INCREMENTAL);
}

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -179,11 +179,11 @@ eraser_motion (PaintCore *paint_core, GimpDrawable *drawable, gboolean hard, gbo
/* color the pixels */
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
opacity = 255 * get_brush_opacity() * (paint_core->curpressure / 0.5);
opacity = 255 * gimp_brush_get_opacity() * (paint_core->curpressure / 0.5);
if(opacity > OPAQUE_OPACITY) opacity=OPAQUE_OPACITY;
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, opacity,
(int) (get_brush_opacity () * 255),
(int) (gimp_brush_get_opacity () * 255),
ERASE_MODE, hard? HARD : SOFT, incremental ? INCREMENTAL : CONSTANT);
}

View File

@ -16,10 +16,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "appenv.h"
#include "brushes.h"
#include "drawable.h"
#include "draw_core.h"
#include "gimage_mask.h"
#include "gimpbrushlist.h"
#include "ink.h"
#include "tools.h"
#include "undo.h"
@ -908,8 +908,8 @@ ink_paste (InkTool *ink_tool,
/* apply the paint area to the gimage */
gimage_apply_image (gimage, drawable, &srcPR,
FALSE,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode(),
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode(),
undo_tiles, /* specify an alternative src1 */
canvas_buf->x, canvas_buf->y);

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -114,8 +114,8 @@ pencil_motion (paint_core, drawable)
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), HARD, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), HARD, CONSTANT);
}

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -447,8 +447,8 @@ clone_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), SOFT, CONSTANT);
}
static void

View File

@ -19,7 +19,7 @@
#include <string.h>
#include <math.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "channels_dialog.h"
#include "drawable.h"
#include "errors.h"
@ -399,7 +399,7 @@ paint_core_init (paint_core, drawable, x, y)
GimpDrawable *drawable;
double x, y;
{
GBrushP brush;
GimpBrushP brush;
paint_core->curx = x;
paint_core->cury = y;
@ -418,7 +418,7 @@ paint_core_init (paint_core, drawable, x, y)
paint_core->spacing =
(double) MAXIMUM (brush->mask->width, brush->mask->height) *
((double) get_brush_spacing () / 100.0);
((double) gimp_brush_get_spacing () / 100.0);
if (paint_core->spacing < 1.0)
paint_core->spacing = 1.0;
paint_core->brush_mask = brush->mask;
@ -714,6 +714,22 @@ paint_core_replace_canvas (paint_core, drawable, brush_opacity, image_opacity,
brush_opacity, image_opacity, mode);
}
/* This is a hack to make sure we don't cache data for a brush that
* has changed. Do it the right way when signals get put in.
*/
static MaskBuf *last_brush = NULL;
static int cache_invalid = 0;
int paint_core_invalidate_cache(MaskBuf *buf)
{
if (last_brush == buf)
{
cache_invalid = 1;
return 1;
}
return 0;
}
/************************************************************
* LOCAL FUNCTION DEFINITIONS *
************************************************************/
@ -723,7 +739,7 @@ paint_core_subsample_mask (mask, x, y)
MaskBuf * mask;
double x, y;
{
static MaskBuf *last_brush = NULL;
/* static MaskBuf *last_brush = NULL; */
MaskBuf * dest;
double left;
unsigned char * m, * d;
@ -744,9 +760,9 @@ paint_core_subsample_mask (mask, x, y)
kernel = subsample[index2][index1];
if ((mask == last_brush) && kernel_brushes[index2][index1])
if ((mask == last_brush) && kernel_brushes[index2][index1] && !cache_invalid)
return kernel_brushes[index2][index1];
else if (mask != last_brush)
else if (mask != last_brush || cache_invalid)
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
{
@ -756,6 +772,7 @@ paint_core_subsample_mask (mask, x, y)
}
last_brush = mask;
cache_invalid = 0;
kernel_brushes[index2][index1] = mask_buf_new (mask->width + 2, mask->height + 2);
dest = kernel_brushes[index2][index1];

View File

@ -111,5 +111,7 @@ TempBuf * paint_core_get_orig_image (PaintCore *, GimpDrawable *, int, in
void paint_core_paste_canvas (PaintCore *, GimpDrawable *, int, int, int, int, int);
void paint_core_replace_canvas (PaintCore *, GimpDrawable *, int, int, int, int);
/* ugly hacks */
int paint_core_invalidate_cache(MaskBuf *);
#endif /* __PAINT_CORE_H__ */

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <math.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -223,8 +223,8 @@ paintbrush_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, blend,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), PRESSURE,
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), PRESSURE,
incremental ? INCREMENTAL : CONSTANT);
}
}

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -114,8 +114,8 @@ pencil_motion (paint_core, drawable)
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), HARD, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), HARD, CONSTANT);
}

View File

@ -5,7 +5,6 @@
#include "actionarea.h"
#include "app_procs.h"
#include "brightness_contrast.h"
#include "brushes.h"
#include "by_color_select.h"
#include "channels_dialog.h"
#include "colormaps.h"

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -143,7 +143,7 @@ airbrush_paint_func (PaintCore *paint_core,
GimpDrawable *drawable,
int state)
{
GBrushP brush;
GimpBrushP brush;
if (!drawable)
return NULL;
@ -267,8 +267,8 @@ airbrush_motion (PaintCore *paint_core,
/* paste the newly painted area to the image */
paint_core_paste_canvas (paint_core, drawable,
opacity,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (),
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (),
SOFT, CONSTANT);
}

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -447,8 +447,8 @@ clone_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), SOFT, CONSTANT);
}
static void

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <stdio.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "convolve.h"
@ -329,7 +329,7 @@ convolve_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_replace_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
(int) (gimp_brush_get_opacity () * 255),
SOFT, INCREMENTAL);
}

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -179,11 +179,11 @@ eraser_motion (PaintCore *paint_core, GimpDrawable *drawable, gboolean hard, gbo
/* color the pixels */
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
opacity = 255 * get_brush_opacity() * (paint_core->curpressure / 0.5);
opacity = 255 * gimp_brush_get_opacity() * (paint_core->curpressure / 0.5);
if(opacity > OPAQUE_OPACITY) opacity=OPAQUE_OPACITY;
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, opacity,
(int) (get_brush_opacity () * 255),
(int) (gimp_brush_get_opacity () * 255),
ERASE_MODE, hard? HARD : SOFT, incremental ? INCREMENTAL : CONSTANT);
}

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -143,7 +143,7 @@ airbrush_paint_func (PaintCore *paint_core,
GimpDrawable *drawable,
int state)
{
GBrushP brush;
GimpBrushP brush;
if (!drawable)
return NULL;
@ -267,8 +267,8 @@ airbrush_motion (PaintCore *paint_core,
/* paste the newly painted area to the image */
paint_core_paste_canvas (paint_core, drawable,
opacity,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (),
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (),
SOFT, CONSTANT);
}

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -447,8 +447,8 @@ clone_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), SOFT, CONSTANT);
}
static void

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <stdio.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "convolve.h"
@ -329,7 +329,7 @@ convolve_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_replace_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
(int) (gimp_brush_get_opacity () * 255),
SOFT, INCREMENTAL);
}

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -179,11 +179,11 @@ eraser_motion (PaintCore *paint_core, GimpDrawable *drawable, gboolean hard, gbo
/* color the pixels */
color_pixels (temp_buf_data (area), col,
area->width * area->height, area->bytes);
opacity = 255 * get_brush_opacity() * (paint_core->curpressure / 0.5);
opacity = 255 * gimp_brush_get_opacity() * (paint_core->curpressure / 0.5);
if(opacity > OPAQUE_OPACITY) opacity=OPAQUE_OPACITY;
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, opacity,
(int) (get_brush_opacity () * 255),
(int) (gimp_brush_get_opacity () * 255),
ERASE_MODE, hard? HARD : SOFT, incremental ? INCREMENTAL : CONSTANT);
}

View File

@ -16,10 +16,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "appenv.h"
#include "brushes.h"
#include "drawable.h"
#include "draw_core.h"
#include "gimage_mask.h"
#include "gimpbrushlist.h"
#include "ink.h"
#include "tools.h"
#include "undo.h"
@ -908,8 +908,8 @@ ink_paste (InkTool *ink_tool,
/* apply the paint area to the gimage */
gimage_apply_image (gimage, drawable, &srcPR,
FALSE,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode(),
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode(),
undo_tiles, /* specify an alternative src1 */
canvas_buf->x, canvas_buf->y);

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -114,8 +114,8 @@ pencil_motion (paint_core, drawable)
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), HARD, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), HARD, CONSTANT);
}

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -447,8 +447,8 @@ clone_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), SOFT, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), SOFT, CONSTANT);
}
static void

View File

@ -16,10 +16,10 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "appenv.h"
#include "brushes.h"
#include "drawable.h"
#include "draw_core.h"
#include "gimage_mask.h"
#include "gimpbrushlist.h"
#include "ink.h"
#include "tools.h"
#include "undo.h"
@ -908,8 +908,8 @@ ink_paste (InkTool *ink_tool,
/* apply the paint area to the gimage */
gimage_apply_image (gimage, drawable, &srcPR,
FALSE,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode(),
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode(),
undo_tiles, /* specify an alternative src1 */
canvas_buf->x, canvas_buf->y);

View File

@ -19,7 +19,7 @@
#include <string.h>
#include <math.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "channels_dialog.h"
#include "drawable.h"
#include "errors.h"
@ -399,7 +399,7 @@ paint_core_init (paint_core, drawable, x, y)
GimpDrawable *drawable;
double x, y;
{
GBrushP brush;
GimpBrushP brush;
paint_core->curx = x;
paint_core->cury = y;
@ -418,7 +418,7 @@ paint_core_init (paint_core, drawable, x, y)
paint_core->spacing =
(double) MAXIMUM (brush->mask->width, brush->mask->height) *
((double) get_brush_spacing () / 100.0);
((double) gimp_brush_get_spacing () / 100.0);
if (paint_core->spacing < 1.0)
paint_core->spacing = 1.0;
paint_core->brush_mask = brush->mask;
@ -714,6 +714,22 @@ paint_core_replace_canvas (paint_core, drawable, brush_opacity, image_opacity,
brush_opacity, image_opacity, mode);
}
/* This is a hack to make sure we don't cache data for a brush that
* has changed. Do it the right way when signals get put in.
*/
static MaskBuf *last_brush = NULL;
static int cache_invalid = 0;
int paint_core_invalidate_cache(MaskBuf *buf)
{
if (last_brush == buf)
{
cache_invalid = 1;
return 1;
}
return 0;
}
/************************************************************
* LOCAL FUNCTION DEFINITIONS *
************************************************************/
@ -723,7 +739,7 @@ paint_core_subsample_mask (mask, x, y)
MaskBuf * mask;
double x, y;
{
static MaskBuf *last_brush = NULL;
/* static MaskBuf *last_brush = NULL; */
MaskBuf * dest;
double left;
unsigned char * m, * d;
@ -744,9 +760,9 @@ paint_core_subsample_mask (mask, x, y)
kernel = subsample[index2][index1];
if ((mask == last_brush) && kernel_brushes[index2][index1])
if ((mask == last_brush) && kernel_brushes[index2][index1] && !cache_invalid)
return kernel_brushes[index2][index1];
else if (mask != last_brush)
else if (mask != last_brush || cache_invalid)
for (i = 0; i < 5; i++)
for (j = 0; j < 5; j++)
{
@ -756,6 +772,7 @@ paint_core_subsample_mask (mask, x, y)
}
last_brush = mask;
cache_invalid = 0;
kernel_brushes[index2][index1] = mask_buf_new (mask->width + 2, mask->height + 2);
dest = kernel_brushes[index2][index1];

View File

@ -111,5 +111,7 @@ TempBuf * paint_core_get_orig_image (PaintCore *, GimpDrawable *, int, in
void paint_core_paste_canvas (PaintCore *, GimpDrawable *, int, int, int, int, int);
void paint_core_replace_canvas (PaintCore *, GimpDrawable *, int, int, int, int);
/* ugly hacks */
int paint_core_invalidate_cache(MaskBuf *);
#endif /* __PAINT_CORE_H__ */

View File

@ -18,7 +18,7 @@
#include <stdlib.h>
#include <math.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -223,8 +223,8 @@ paintbrush_motion (PaintCore *paint_core,
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, blend,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), PRESSURE,
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), PRESSURE,
incremental ? INCREMENTAL : CONSTANT);
}
}

View File

@ -17,7 +17,7 @@
*/
#include <stdlib.h>
#include "appenv.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "drawable.h"
#include "errors.h"
#include "gdisplay.h"
@ -114,8 +114,8 @@ pencil_motion (paint_core, drawable)
/* paste the newly painted canvas to the gimage which is being worked on */
paint_core_paste_canvas (paint_core, drawable, OPAQUE_OPACITY,
(int) (get_brush_opacity () * 255),
get_brush_paint_mode (), HARD, CONSTANT);
(int) (gimp_brush_get_opacity () * 255),
gimp_brush_get_paint_mode (), HARD, CONSTANT);
}

View File

@ -0,0 +1,205 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* brush_edit module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 "appenv.h"
#include "gimpbrushgenerated.h"
#include "brush_edit.h"
static void
update_brush_callback (GtkAdjustment *adjustment,
BrushEditGeneratedWindow *begw)
{
if (begw->brush &&
((begw->radius_data->value
!= gimp_brush_generated_get_radius(begw->brush))
|| (begw->hardness_data->value
!= gimp_brush_generated_get_hardness(begw->brush))
|| (begw->aspect_ratio_data->value
!= gimp_brush_generated_get_aspect_ratio(begw->brush))
|| (begw->angle_data->value
!=gimp_brush_generated_get_angle(begw->brush))))
{
gimp_brush_generated_set_radius (begw->brush,
begw->radius_data->value);
gimp_brush_generated_set_hardness (begw->brush,
begw->hardness_data->value);
gimp_brush_generated_set_aspect_ratio (begw->brush,
begw->aspect_ratio_data->value);
gimp_brush_generated_set_angle (begw->brush,
begw->angle_data->value);
gimp_brush_generated_generate(begw->brush);
}
}
static int
brush_edit_delete_callback (GtkWidget *w,
BrushEditGeneratedWindow *begw)
{
if (GTK_WIDGET_VISIBLE (w))
gtk_widget_hide (w);
return TRUE;
}
void
brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
GimpBrush *gbrush)
{
GimpBrushGenerated *brush = 0;
if (!GIMP_IS_BRUSH_GENERATED(gbrush))
return;
brush = GIMP_BRUSH_GENERATED(gbrush);
if (begw)
{
begw->brush = NULL;
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->radius_data),
gimp_brush_generated_get_radius (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->hardness_data),
gimp_brush_generated_get_hardness (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->angle_data),
gimp_brush_generated_get_angle (brush));
gtk_adjustment_set_value(GTK_ADJUSTMENT(begw->aspect_ratio_data),
gimp_brush_generated_get_aspect_ratio(brush));
begw->brush = brush;
}
}
BrushEditGeneratedWindow *
brush_edit_generated_new ()
{
BrushEditGeneratedWindow *begw ;
GtkWidget *vbox;
GtkWidget *sbar;
GtkWidget *label;
GtkWidget *slider;
GtkWidget *table;
GtkWidget *button1, *button2;
begw = g_malloc (sizeof (BrushEditGeneratedWindow));
begw->redraw = TRUE;
begw->shell = gtk_dialog_new ();
gtk_window_set_wmclass (GTK_WINDOW (begw->shell), "generatedbrusheditor",
"Gimp");
gtk_window_set_title (GTK_WINDOW (begw->shell), "Brush Editor");
gtk_window_set_policy(GTK_WINDOW(begw->shell), FALSE, TRUE, FALSE);
vbox = gtk_vbox_new (FALSE, 1);
gtk_container_border_width (GTK_CONTAINER (vbox), 2);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (begw->shell)->vbox), vbox,
TRUE, TRUE, 0);
/* handle the wm close signal */
gtk_signal_connect (GTK_OBJECT (begw->shell), "delete_event",
GTK_SIGNAL_FUNC (brush_edit_delete_callback),
begw);
/* Populate the window with some widgets */
/* brush's preview widget w/frame */
begw->frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (begw->frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (vbox), begw->frame, TRUE, TRUE, 0);
begw->preview = gtk_preview_new (GTK_PREVIEW_GRAYSCALE);
gtk_preview_size (GTK_PREVIEW (begw->preview), 100, 100);
gtk_container_add (GTK_CONTAINER (begw->frame), begw->preview);
gtk_widget_show(begw->preview);
gtk_widget_show(begw->frame);
/* table for sliders/labels */
table = gtk_table_new(2, 4, FALSE);
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
/* brush radius scale */
label = gtk_label_new ("Radius:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 0, 1, 0, 0, 0, 0);
begw->radius_data = GTK_ADJUSTMENT (gtk_adjustment_new (10.0, 0.0, 100.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->radius_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 0, 1);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->radius_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush hardness scale */
label = gtk_label_new ("Hardness:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 1, 2, 0, 0, 0, 0);
begw->hardness_data = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 1.0, 0.01, 0.01, 0.0));
slider = gtk_hscale_new (begw->hardness_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 1, 2);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->hardness_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush aspect ratio scale */
label = gtk_label_new ("Aspect Ratio:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 2, 3, 0, 0, 0, 0);
begw->aspect_ratio_data = GTK_ADJUSTMENT (gtk_adjustment_new (1.0, 1.0, 20.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->aspect_ratio_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 2, 3);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->aspect_ratio_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
/* brush angle scale */
label = gtk_label_new ("Angle:");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE (table), label, 0, 1, 3, 4, 0, 0, 0, 0);
begw->angle_data = GTK_ADJUSTMENT (gtk_adjustment_new (00.0, 0.0, 180.0, 0.1, 1.0, 0.0));
slider = gtk_hscale_new (begw->angle_data);
gtk_table_attach_defaults(GTK_TABLE (table), slider, 1, 2, 3, 4);
gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
gtk_signal_connect (GTK_OBJECT (begw->angle_data), "value_changed",
(GtkSignalFunc) update_brush_callback, begw);
gtk_widget_show (label);
gtk_widget_show (slider);
gtk_table_set_row_spacings(GTK_TABLE (table), 3);
gtk_table_set_col_spacing(GTK_TABLE (table), 0, 3);
gtk_widget_show (table);
gtk_widget_show (vbox);
gtk_widget_show (begw->shell);
return begw;
}

View File

@ -0,0 +1,49 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* brush_edit module Copyright 1998 Jay Cox <jaycox@earthlink.net>
*
* 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 __BRUSH_EDIT_H__
#define __BRUSH_EDIT_H__
#include "gimpbrushgenerated.h"
typedef struct _BrushEditGeneratedWindow
{
GtkWidget *shell;
GtkWidget *frame;
GtkWidget *preview;
GtkWidget *options_box;
GtkAdjustment *radius_data;
GtkAdjustment *hardness_data;
GtkAdjustment *angle_data;
GtkAdjustment *aspect_ratio_data;
int width, height;
int cell_width, cell_height;
int redraw;
/* Brush preview */
GtkWidget *brush_preview;
GimpBrushGenerated *brush;
} BrushEditGeneratedWindow;
void brush_edit_generated_set_brush(BrushEditGeneratedWindow *begw,
GimpBrush *brush);
BrushEditGeneratedWindow *brush_edit_generated_new ();
#endif /* __BRUSH_EDIT_H__ */

View File

@ -20,7 +20,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -44,7 +44,7 @@ struct _DeviceInfo {
gint num_keys;
GdkDeviceKey *keys;
GBrushP brush;
GimpBrushP brush;
ToolType tool;
unsigned char foreground[3];
};
@ -201,7 +201,7 @@ devices_rc_update (gchar *name, DeviceValues values,
{
GList *tmp_list;
DeviceInfo *device_info;
GBrushP brushp;
GimpBrushP brushp;
/* Find device if we have it */
@ -299,27 +299,9 @@ devices_rc_update (gchar *name, DeviceValues values,
if (values & (DEVICE_BRUSH | DEVICE_TOOL | DEVICE_FOREGROUND))
device_info->is_init = TRUE;
/* FIXME: this should probably be left in brushes.c */
if (values & DEVICE_BRUSH)
{
GSList *list;
device_info->brush = NULL;
list = brush_list;
while (list)
{
brushp = (GBrushP) list->data;
if (!strcmp (brushp->name, brush_name))
{
device_info->brush = brushp;
break;
}
list = g_slist_next (list);
}
device_info->brush = gimp_brush_list_get_brush(brush_list, brush_name);
}
if (values & DEVICE_TOOL)

View File

@ -20,7 +20,7 @@
#include "appenv.h"
#include "actionarea.h"
#include "brushes.h"
#include "gimpbrushlist.h"
#include "devices.h"
#include "interface.h"
#include "gimprc.h"
@ -44,7 +44,7 @@ struct _DeviceInfo {
gint num_keys;
GdkDeviceKey *keys;
GBrushP brush;
GimpBrushP brush;
ToolType tool;
unsigned char foreground[3];
};
@ -201,7 +201,7 @@ devices_rc_update (gchar *name, DeviceValues values,
{
GList *tmp_list;
DeviceInfo *device_info;
GBrushP brushp;
GimpBrushP brushp;
/* Find device if we have it */
@ -299,27 +299,9 @@ devices_rc_update (gchar *name, DeviceValues values,
if (values & (DEVICE_BRUSH | DEVICE_TOOL | DEVICE_FOREGROUND))
device_info->is_init = TRUE;
/* FIXME: this should probably be left in brushes.c */
if (values & DEVICE_BRUSH)
{
GSList *list;
device_info->brush = NULL;
list = brush_list;
while (list)
{
brushp = (GBrushP) list->data;
if (!strcmp (brushp->name, brush_name))
{
device_info->brush = brushp;
break;
}
list = g_slist_next (list);
}
device_info->brush = gimp_brush_list_get_brush(brush_list, brush_name);
}
if (values & DEVICE_TOOL)