1997-11-25 06:05:25 +08:00
|
|
|
/* 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
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
2000-12-17 05:37:03 +08:00
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
2000-12-29 23:22:01 +08:00
|
|
|
#include <gtk/gtk.h>
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2001-01-24 02:49:44 +08:00
|
|
|
#include "libgimpcolor/gimpcolor.h"
|
|
|
|
|
2000-12-17 05:37:03 +08:00
|
|
|
#include "apptypes.h"
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "drawable.h"
|
|
|
|
#include "gdisplay.h"
|
2000-12-29 23:22:01 +08:00
|
|
|
#include "gimpbrush.h"
|
|
|
|
#include "gimpcontext.h"
|
2001-02-11 03:35:29 +08:00
|
|
|
#include "gimpgradient.h"
|
2000-12-29 23:22:01 +08:00
|
|
|
#include "gimpimage.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "paint_funcs.h"
|
2001-01-25 06:36:18 +08:00
|
|
|
#include "selection.h"
|
|
|
|
#include "temp_buf.h"
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "paint_core.h"
|
1999-04-22 22:34:00 +08:00
|
|
|
#include "paint_options.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
#include "paintbrush.h"
|
|
|
|
#include "pencil.h"
|
2000-12-29 23:22:01 +08:00
|
|
|
#include "tool_options.h"
|
2001-01-25 06:36:18 +08:00
|
|
|
#include "tools.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-04-28 01:27:28 +08:00
|
|
|
|
2000-12-31 12:07:42 +08:00
|
|
|
#define PENCIL_INCREMENTAL_DEFAULT FALSE
|
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* the pencil tool options */
|
1999-08-31 14:13:30 +08:00
|
|
|
typedef struct _PencilOptions PencilOptions;
|
2000-01-14 20:41:00 +08:00
|
|
|
|
1999-08-31 14:13:30 +08:00
|
|
|
struct _PencilOptions
|
|
|
|
{
|
|
|
|
PaintOptions paint_options;
|
|
|
|
};
|
1999-09-09 09:47:54 +08:00
|
|
|
|
1999-04-09 06:25:54 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* forward function declarations */
|
2000-12-31 12:07:42 +08:00
|
|
|
static void pencil_motion (PaintCore *paint_core,
|
|
|
|
GimpDrawable *drawable,
|
|
|
|
PaintPressureOptions *pressure_options,
|
|
|
|
gboolean );
|
|
|
|
static gpointer pencil_paint_func (PaintCore *paint_core,
|
|
|
|
GimpDrawable *drawable,
|
|
|
|
PaintState state);
|
|
|
|
|
|
|
|
|
|
|
|
static PencilOptions *pencil_options = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-08-20 03:53:30 +08:00
|
|
|
static gboolean non_gui_incremental = FALSE;
|
1999-08-31 14:13:30 +08:00
|
|
|
static void pencil_options_reset (void);
|
1999-08-14 04:50:30 +08:00
|
|
|
|
1999-04-09 06:25:54 +08:00
|
|
|
|
|
|
|
/* functions */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-12-31 12:07:42 +08:00
|
|
|
gpointer
|
1999-04-09 06:25:54 +08:00
|
|
|
pencil_paint_func (PaintCore *paint_core,
|
|
|
|
GimpDrawable *drawable,
|
2000-12-31 12:07:42 +08:00
|
|
|
PaintState state)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
switch (state)
|
|
|
|
{
|
2000-01-14 20:41:00 +08:00
|
|
|
case INIT_PAINT:
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
2000-01-14 20:41:00 +08:00
|
|
|
case MOTION_PAINT:
|
1999-09-09 09:47:54 +08:00
|
|
|
pencil_motion (paint_core, drawable,
|
|
|
|
pencil_options->paint_options.pressure_options,
|
|
|
|
pencil_options->paint_options.incremental);
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
2000-01-14 20:41:00 +08:00
|
|
|
case FINISH_PAINT:
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
|
2000-01-14 20:41:00 +08:00
|
|
|
default:
|
1997-11-25 06:05:25 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
1999-08-31 14:13:30 +08:00
|
|
|
static PencilOptions *
|
|
|
|
pencil_options_new (void)
|
|
|
|
{
|
|
|
|
PencilOptions *options;
|
|
|
|
|
2000-01-14 20:41:00 +08:00
|
|
|
options = g_new (PencilOptions, 1);
|
1999-08-31 14:13:30 +08:00
|
|
|
paint_options_init ((PaintOptions *) options,
|
|
|
|
PENCIL,
|
|
|
|
pencil_options_reset);
|
2000-01-14 20:41:00 +08:00
|
|
|
|
1999-08-31 14:13:30 +08:00
|
|
|
return options;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
1999-04-22 22:34:00 +08:00
|
|
|
pencil_options_reset (void)
|
|
|
|
{
|
1999-08-31 14:13:30 +08:00
|
|
|
paint_options_reset ((PaintOptions *) pencil_options);
|
1999-04-22 22:34:00 +08:00
|
|
|
}
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
Tool *
|
1999-04-19 05:22:41 +08:00
|
|
|
tools_new_pencil (void)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
Tool * tool;
|
|
|
|
PaintCore * private;
|
|
|
|
|
1999-04-13 01:55:06 +08:00
|
|
|
/* The tool options */
|
1997-11-25 06:05:25 +08:00
|
|
|
if (!pencil_options)
|
1999-04-09 06:25:54 +08:00
|
|
|
{
|
1999-08-31 14:13:30 +08:00
|
|
|
pencil_options = pencil_options_new ();
|
1999-04-22 22:34:00 +08:00
|
|
|
tools_register (PENCIL, (ToolOptions *) pencil_options);
|
1999-08-31 14:13:30 +08:00
|
|
|
pencil_options_reset();
|
1999-04-09 06:25:54 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
tool = paint_core_new (PENCIL);
|
|
|
|
|
|
|
|
private = (PaintCore *) tool->private;
|
|
|
|
private->paint_func = pencil_paint_func;
|
1999-05-14 08:37:58 +08:00
|
|
|
private->pick_colors = TRUE;
|
1999-08-27 05:33:58 +08:00
|
|
|
private->flags |= TOOL_CAN_HANDLE_CHANGING_BRUSH;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
return tool;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
1999-04-09 06:25:54 +08:00
|
|
|
tools_free_pencil (Tool *tool)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
paint_core_free (tool);
|
|
|
|
}
|
|
|
|
|
1998-03-19 06:35:31 +08:00
|
|
|
static void
|
1999-09-09 09:47:54 +08:00
|
|
|
pencil_motion (PaintCore *paint_core,
|
|
|
|
GimpDrawable *drawable,
|
|
|
|
PaintPressureOptions *pressure_options,
|
|
|
|
gboolean increment)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-01-15 05:11:52 +08:00
|
|
|
GImage *gimage;
|
|
|
|
TempBuf *area;
|
|
|
|
guchar col[MAX_CHANNELS];
|
|
|
|
gint opacity;
|
|
|
|
gdouble scale;
|
|
|
|
PaintApplicationMode paint_appl_mode = increment ? INCREMENTAL : CONSTANT;
|
|
|
|
|
|
|
|
if (! (gimage = gimp_drawable_gimage (drawable)))
|
1997-11-25 06:05:25 +08:00
|
|
|
return;
|
|
|
|
|
1999-09-09 09:47:54 +08:00
|
|
|
if (pressure_options->size)
|
|
|
|
scale = paint_core->curpressure;
|
|
|
|
else
|
|
|
|
scale = 1.0;
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* Get a region which can be used to paint to */
|
1999-09-09 09:47:54 +08:00
|
|
|
if (! (area = paint_core_get_paint_area (paint_core, drawable, scale)))
|
1997-11-25 06:05:25 +08:00
|
|
|
return;
|
|
|
|
|
1999-11-13 09:02:27 +08:00
|
|
|
/* color the pixels */
|
|
|
|
if (pressure_options->color)
|
|
|
|
{
|
2001-01-21 00:28:05 +08:00
|
|
|
GimpRGB color;
|
2001-02-11 03:35:29 +08:00
|
|
|
|
|
|
|
gimp_gradient_get_color_at (gimp_context_get_gradient (NULL),
|
|
|
|
paint_core->curpressure, &color);
|
2001-01-21 00:28:05 +08:00
|
|
|
|
|
|
|
gimp_rgba_get_uchar (&color,
|
|
|
|
&col[RED_PIX],
|
|
|
|
&col[GREEN_PIX],
|
|
|
|
&col[BLUE_PIX],
|
|
|
|
&col[ALPHA_PIX]);
|
|
|
|
|
1999-11-13 09:02:27 +08:00
|
|
|
paint_appl_mode = INCREMENTAL;
|
|
|
|
color_pixels (temp_buf_data (area), col,
|
|
|
|
area->width * area->height, area->bytes);
|
|
|
|
}
|
Jens Lautenbacher <jtl@gimp.org>
2000-12-18 Sven Neumann <sven@gimp.org>
Jens Lautenbacher <jtl@gimp.org>
* app/Makefile.am
* app/gimpbrushlistP.h
* app/gimpbrushpipeP.h
* app/gimpobjectP.h: removed these three files
* app/parasitelistP.h
* app/channels_dialog.c
* app/docindex.c
* app/gimpdrawable.c
* app/gimpdrawableP.h
* app/gimpimage.c
* app/gimpimageP.h
* app/gimplist.[ch]
* app/gimpobject.c
* app/gimpobject.h
* app/gimpsetP.h: changed according to header removal
* app/airbrush.c
* app/brush_select.[ch]
* app/brushes_cmds.c
* app/gimpbrush.[ch]
* app/gimpbrushgenerated.[ch]
* app/gimpbrushlist.[ch]
* app/gimpbrushpipe.[ch]
* app/gimpcontextpreview.c
* app/paint_core.c
* app/paintbrush.c
* app/pencil.c
* tools/pdbgen/pdb/brushes.pdb: Big Brushes Cleanup.
The GimpBrush* object hierarchy and the file formats were broken by
"design". This made it overly difficult to read and write pixmap
brushes and brush pipes, leading to the situation that The GIMP was
not able to read it's very own file formats. Since the GimpBrush
format did support arbitrary color depths, the introduction of a
file format for pixmap brushes was unnecessary.
The GimpBrushPixmap object is dead. GimpBrush has an additional
pixmap temp_buf and handles pixmap brushes transparently. The file
format of pixmap brushes is not any longer a grayscale brush plus
a pattern, but a simple brush with RGBA data. The old brushes can
still be loaded, but the .gpb format is deprecated.
GimpBrushPipe derives from GimpBrush. The fileformat is still a text
header, followed by a number of brushes, but those brushes are stored
in the new GimpBrush format (no pattern anymore). The pipe does not
care about the depth of the contained GimpBrushes, so we get
grayscale BrushPipes for free. Since the brush loader still loads the
old format, old .gih files can also still be loaded.
Since the brushes in the GimpBrushPipe do not any longer contain a
pointer to the pipe object, we do only temporarily switch brushes
in the paint_core routines. This is not very elegant, but the best
we can do without a major redesign.
* app/patterns.[ch]: changed the loader to work with a filedescriptor
instead of a filehandle to make it work with the new brush loading
code.
* plug-ins/common/.cvsignore
* plug-ins/common/Makefile.am
* plug-ins/common/plugin-defs.pl
* plug-ins/common/gih.c: new plug-in that saves GIH files in the
new format (loader will follow soon)
* plug-ins/common/gpb.c: removed since Pixmap Brushes are no longer
supported as a special file format.
* plug-ins/common/gbr.c: load and save brushes in the new brush format
which allows RGBA brushes too.
* plug-ins/common/pat.c: load and save grayscale patterns too
2000-12-18 23:14:08 +08:00
|
|
|
else if (paint_core->brush && paint_core->brush->pixmap)
|
1999-08-14 04:50:30 +08:00
|
|
|
{
|
1999-09-09 09:47:54 +08:00
|
|
|
/* if its a pixmap, do pixmap stuff */
|
1999-09-10 03:11:38 +08:00
|
|
|
paint_core_color_area_with_pixmap (paint_core, gimage, drawable, area,
|
|
|
|
scale, HARD);
|
Actually use the enum types GimpImageType, GimpImageBaseType,
* app/*.[ch]: Actually use the enum types GimpImageType,
GimpImageBaseType, LayerModeEffects, PaintApplicationMode,
BrushApplicationMode, GimpFillType and ConvertPaletteType, instead
of just int or gint. Hopefully I catched most of the places
where these should be used.
Add an enum ConvolutionType, suffix the too general constants
NORMAL, ABSOLUTE and NEGATIVE with _CONVOL. Use NORMAL_MODE
instead of NORMAL in some places (this was what was intended). Fix
some minor gccisms.
* app/apptypes.h: New file. This file contains the above
enumeration types, and some opaque struct typedefs. It was
necessary to collect these in one header that doesn't include
other headers, because when we started using the above mentioned
types in the headers, all hell broke loose because of the
spaghetti-like cross-inclusion mess between headers.
(An example: Header A includes header B, which includes header C
which includes A. B uses a type defined in A. This is not defined,
because A hasn't defined it yet at the point where it includes B,
and A included from B of course is skipped as we already are
reading A.)
1999-08-19 07:41:39 +08:00
|
|
|
paint_appl_mode = INCREMENTAL;
|
1999-08-14 04:50:30 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-12-29 23:22:01 +08:00
|
|
|
gimp_image_get_foreground (gimage, drawable, col);
|
1999-11-13 09:02:27 +08:00
|
|
|
col[area->bytes - 1] = OPAQUE_OPACITY;
|
1999-08-14 04:50:30 +08:00
|
|
|
color_pixels (temp_buf_data (area), col,
|
|
|
|
area->width * area->height, area->bytes);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-09 09:47:54 +08:00
|
|
|
opacity = 255 * gimp_context_get_opacity (NULL);
|
|
|
|
if (pressure_options->opacity)
|
|
|
|
opacity = opacity * 2.0 * paint_core->curpressure;
|
1999-08-14 04:50:30 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/* paste the newly painted canvas to the gimage which is being worked on */
|
1999-09-09 09:47:54 +08:00
|
|
|
paint_core_paste_canvas (paint_core, drawable,
|
|
|
|
MIN (opacity, 255),
|
1999-07-06 23:18:25 +08:00
|
|
|
(int) (gimp_context_get_opacity (NULL) * 255),
|
|
|
|
gimp_context_get_paint_mode (NULL),
|
1999-09-09 09:47:54 +08:00
|
|
|
HARD, scale, paint_appl_mode);
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
|
|
|
|
2000-12-31 12:07:42 +08:00
|
|
|
static gpointer
|
1999-04-09 06:25:54 +08:00
|
|
|
pencil_non_gui_paint_func (PaintCore *paint_core,
|
1999-08-20 03:53:30 +08:00
|
|
|
GimpDrawable *drawable,
|
2000-12-31 12:07:42 +08:00
|
|
|
PaintState state)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-09-09 09:47:54 +08:00
|
|
|
pencil_motion (paint_core, drawable, &non_gui_pressure_options,
|
|
|
|
non_gui_incremental);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-04-19 05:22:41 +08:00
|
|
|
gboolean
|
|
|
|
pencil_non_gui (GimpDrawable *drawable,
|
1999-08-20 03:53:30 +08:00
|
|
|
int num_strokes,
|
|
|
|
double *stroke_array)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
1999-04-19 05:22:41 +08:00
|
|
|
if (paint_core_init (&non_gui_paint_core, drawable,
|
1999-07-06 23:18:25 +08:00
|
|
|
stroke_array[0], stroke_array[1]))
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-04-19 05:22:41 +08:00
|
|
|
/* Set the paint core's paint func */
|
1997-11-25 06:05:25 +08:00
|
|
|
non_gui_paint_core.paint_func = pencil_non_gui_paint_func;
|
|
|
|
|
|
|
|
non_gui_paint_core.startx = non_gui_paint_core.lastx = stroke_array[0];
|
|
|
|
non_gui_paint_core.starty = non_gui_paint_core.lasty = stroke_array[1];
|
|
|
|
|
1999-07-23 07:11:46 +08:00
|
|
|
pencil_non_gui_paint_func (&non_gui_paint_core, drawable, 0);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
for (i = 1; i < num_strokes; i++)
|
1999-05-14 08:37:58 +08:00
|
|
|
{
|
|
|
|
non_gui_paint_core.curx = stroke_array[i * 2 + 0];
|
|
|
|
non_gui_paint_core.cury = stroke_array[i * 2 + 1];
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-05-14 08:37:58 +08:00
|
|
|
paint_core_interpolate (&non_gui_paint_core, drawable);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-05-14 08:37:58 +08:00
|
|
|
non_gui_paint_core.lastx = non_gui_paint_core.curx;
|
|
|
|
non_gui_paint_core.lasty = non_gui_paint_core.cury;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-19 05:22:41 +08:00
|
|
|
/* Finish the painting */
|
1998-01-22 15:02:57 +08:00
|
|
|
paint_core_finish (&non_gui_paint_core, drawable, -1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-04-19 05:22:41 +08:00
|
|
|
/* Cleanup */
|
1997-11-25 06:05:25 +08:00
|
|
|
paint_core_cleanup ();
|
1999-04-19 05:22:41 +08:00
|
|
|
return TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|
1999-04-19 05:22:41 +08:00
|
|
|
else
|
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
}
|