gimp/plug-ins/gimpressionist/brush.c

650 lines
18 KiB
C
Raw Normal View History

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 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, see <https://www.gnu.org/licenses/>.
*/
derive from GtkDrawingArea instead of deprecated GtkPreview. 2002-01-30 Sven Neumann <sven@gimp.org> * libgimpwidgets/gimpcolorarea.[ch]: derive from GtkDrawingArea instead of deprecated GtkPreview. * app/nav_window.c * app/gui/brush-editor.c * app/gui/buffers-commands.c * app/gui/color-select.c * app/gui/colormap-dialog.c * app/gui/device-status-dialog.c * app/gui/dialogs-constructors.c * app/gui/file-open-dialog.c * app/gui/gradient-editor.c * app/gui/indicator-area.c * app/gui/info-window.c * app/gui/palette-editor.c * app/gui/palette-import-dialog.c * app/gui/palettes-commands.c * app/gui/test-commands.c * app/gui/tool-options-dialog.c * app/gui/toolbox.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpcurvestool.c * app/tools/gimphistogramtool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpdnd.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.c * app/widgets/gimpimagedock.c * app/widgets/gimpitemfactory.c * app/widgets/gimplayerlistitem.c * app/widgets/gimplistitem.c * app/widgets/gimpmenuitem.c * app/widgets/gimppreview.c * libgimp/gimpbrushmenu.c * libgimp/gimpgradientmenu.c * libgimp/gimpmenu.c * libgimp/gimppatternmenu.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/blinds.c * plug-ins/common/curve_bend.c * plug-ins/common/depthmerge.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/diffraction.c * plug-ins/common/emboss.c * plug-ins/common/exchange.c * plug-ins/common/flarefx.c * plug-ins/common/fractaltrace.c * plug-ins/common/glasstile.c * plug-ins/common/gqbist.c * plug-ins/common/grid.c * plug-ins/common/illusion.c * plug-ins/common/iwarp.c * plug-ins/common/jigsaw.c * plug-ins/common/mapcolor.c * plug-ins/common/max_rgb.c * plug-ins/common/newsprint.c * plug-ins/common/nlfilt.c * plug-ins/common/noisify.c * plug-ins/common/nova.c * plug-ins/common/plasma.c * plug-ins/common/polar.c * plug-ins/common/sample_colorize.c * plug-ins/common/scatter_hsv.c * plug-ins/common/sharpen.c * plug-ins/common/sinus.c * plug-ins/common/tileit.c * plug-ins/common/video.c * plug-ins/common/waves.c * plug-ins/common/whirlpinch.c * plug-ins/common/wind.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/gimpressionist/brush.c * plug-ins/mosaic/mosaic.c * plug-ins/rcm/rcm_dialog.c: define GTK_DISABLE_DEPRECATED to make it compile. We really need a generic plug-in preview system that doesn't use GtkPreview.
2002-01-30 22:54:27 +08:00
1999-08-27 06:29:37 +08:00
#include "config.h"
derive from GtkDrawingArea instead of deprecated GtkPreview. 2002-01-30 Sven Neumann <sven@gimp.org> * libgimpwidgets/gimpcolorarea.[ch]: derive from GtkDrawingArea instead of deprecated GtkPreview. * app/nav_window.c * app/gui/brush-editor.c * app/gui/buffers-commands.c * app/gui/color-select.c * app/gui/colormap-dialog.c * app/gui/device-status-dialog.c * app/gui/dialogs-constructors.c * app/gui/file-open-dialog.c * app/gui/gradient-editor.c * app/gui/indicator-area.c * app/gui/info-window.c * app/gui/palette-editor.c * app/gui/palette-import-dialog.c * app/gui/palettes-commands.c * app/gui/test-commands.c * app/gui/tool-options-dialog.c * app/gui/toolbox.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpcurvestool.c * app/tools/gimphistogramtool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpdnd.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.c * app/widgets/gimpimagedock.c * app/widgets/gimpitemfactory.c * app/widgets/gimplayerlistitem.c * app/widgets/gimplistitem.c * app/widgets/gimpmenuitem.c * app/widgets/gimppreview.c * libgimp/gimpbrushmenu.c * libgimp/gimpgradientmenu.c * libgimp/gimpmenu.c * libgimp/gimppatternmenu.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/blinds.c * plug-ins/common/curve_bend.c * plug-ins/common/depthmerge.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/diffraction.c * plug-ins/common/emboss.c * plug-ins/common/exchange.c * plug-ins/common/flarefx.c * plug-ins/common/fractaltrace.c * plug-ins/common/glasstile.c * plug-ins/common/gqbist.c * plug-ins/common/grid.c * plug-ins/common/illusion.c * plug-ins/common/iwarp.c * plug-ins/common/jigsaw.c * plug-ins/common/mapcolor.c * plug-ins/common/max_rgb.c * plug-ins/common/newsprint.c * plug-ins/common/nlfilt.c * plug-ins/common/noisify.c * plug-ins/common/nova.c * plug-ins/common/plasma.c * plug-ins/common/polar.c * plug-ins/common/sample_colorize.c * plug-ins/common/scatter_hsv.c * plug-ins/common/sharpen.c * plug-ins/common/sinus.c * plug-ins/common/tileit.c * plug-ins/common/video.c * plug-ins/common/waves.c * plug-ins/common/whirlpinch.c * plug-ins/common/wind.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/gimpressionist/brush.c * plug-ins/mosaic/mosaic.c * plug-ins/rcm/rcm_dialog.c: define GTK_DISABLE_DEPRECATED to make it compile. We really need a generic plug-in preview system that doesn't use GtkPreview.
2002-01-30 22:54:27 +08:00
1999-08-27 06:29:37 +08:00
#include <string.h>
derive from GtkDrawingArea instead of deprecated GtkPreview. 2002-01-30 Sven Neumann <sven@gimp.org> * libgimpwidgets/gimpcolorarea.[ch]: derive from GtkDrawingArea instead of deprecated GtkPreview. * app/nav_window.c * app/gui/brush-editor.c * app/gui/buffers-commands.c * app/gui/color-select.c * app/gui/colormap-dialog.c * app/gui/device-status-dialog.c * app/gui/dialogs-constructors.c * app/gui/file-open-dialog.c * app/gui/gradient-editor.c * app/gui/indicator-area.c * app/gui/info-window.c * app/gui/palette-editor.c * app/gui/palette-import-dialog.c * app/gui/palettes-commands.c * app/gui/test-commands.c * app/gui/tool-options-dialog.c * app/gui/toolbox.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpcurvestool.c * app/tools/gimphistogramtool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpdnd.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.c * app/widgets/gimpimagedock.c * app/widgets/gimpitemfactory.c * app/widgets/gimplayerlistitem.c * app/widgets/gimplistitem.c * app/widgets/gimpmenuitem.c * app/widgets/gimppreview.c * libgimp/gimpbrushmenu.c * libgimp/gimpgradientmenu.c * libgimp/gimpmenu.c * libgimp/gimppatternmenu.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/blinds.c * plug-ins/common/curve_bend.c * plug-ins/common/depthmerge.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/diffraction.c * plug-ins/common/emboss.c * plug-ins/common/exchange.c * plug-ins/common/flarefx.c * plug-ins/common/fractaltrace.c * plug-ins/common/glasstile.c * plug-ins/common/gqbist.c * plug-ins/common/grid.c * plug-ins/common/illusion.c * plug-ins/common/iwarp.c * plug-ins/common/jigsaw.c * plug-ins/common/mapcolor.c * plug-ins/common/max_rgb.c * plug-ins/common/newsprint.c * plug-ins/common/nlfilt.c * plug-ins/common/noisify.c * plug-ins/common/nova.c * plug-ins/common/plasma.c * plug-ins/common/polar.c * plug-ins/common/sample_colorize.c * plug-ins/common/scatter_hsv.c * plug-ins/common/sharpen.c * plug-ins/common/sinus.c * plug-ins/common/tileit.c * plug-ins/common/video.c * plug-ins/common/waves.c * plug-ins/common/whirlpinch.c * plug-ins/common/wind.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/gimpressionist/brush.c * plug-ins/mosaic/mosaic.c * plug-ins/rcm/rcm_dialog.c: define GTK_DISABLE_DEPRECATED to make it compile. We really need a generic plug-in preview system that doesn't use GtkPreview.
2002-01-30 22:54:27 +08:00
#include <libgimp/gimp.h>
#include <libgimp/gimpui.h>
#include <libgimpmath/gimpmath.h>
#include "gimpressionist.h"
#include "ppmtool.h"
#include "brush.h"
#include "presets.h"
derive from GtkDrawingArea instead of deprecated GtkPreview. 2002-01-30 Sven Neumann <sven@gimp.org> * libgimpwidgets/gimpcolorarea.[ch]: derive from GtkDrawingArea instead of deprecated GtkPreview. * app/nav_window.c * app/gui/brush-editor.c * app/gui/buffers-commands.c * app/gui/color-select.c * app/gui/colormap-dialog.c * app/gui/device-status-dialog.c * app/gui/dialogs-constructors.c * app/gui/file-open-dialog.c * app/gui/gradient-editor.c * app/gui/indicator-area.c * app/gui/info-window.c * app/gui/palette-editor.c * app/gui/palette-import-dialog.c * app/gui/palettes-commands.c * app/gui/test-commands.c * app/gui/tool-options-dialog.c * app/gui/toolbox.c * app/tools/gimpbycolorselecttool.c * app/tools/gimpcurvestool.c * app/tools/gimphistogramtool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/widgets/gimpchannellistview.c * app/widgets/gimpcomponentlistitem.c * app/widgets/gimpdnd.c * app/widgets/gimpdrawablelistitem.c * app/widgets/gimpdrawablelistview.c * app/widgets/gimpimagedock.c * app/widgets/gimpitemfactory.c * app/widgets/gimplayerlistitem.c * app/widgets/gimplistitem.c * app/widgets/gimpmenuitem.c * app/widgets/gimppreview.c * libgimp/gimpbrushmenu.c * libgimp/gimpgradientmenu.c * libgimp/gimpmenu.c * libgimp/gimppatternmenu.c * plug-ins/FractalExplorer/Dialogs.c * plug-ins/common/AlienMap.c * plug-ins/common/AlienMap2.c * plug-ins/common/CML_explorer.c * plug-ins/common/blinds.c * plug-ins/common/curve_bend.c * plug-ins/common/depthmerge.c * plug-ins/common/despeckle.c * plug-ins/common/destripe.c * plug-ins/common/diffraction.c * plug-ins/common/emboss.c * plug-ins/common/exchange.c * plug-ins/common/flarefx.c * plug-ins/common/fractaltrace.c * plug-ins/common/glasstile.c * plug-ins/common/gqbist.c * plug-ins/common/grid.c * plug-ins/common/illusion.c * plug-ins/common/iwarp.c * plug-ins/common/jigsaw.c * plug-ins/common/mapcolor.c * plug-ins/common/max_rgb.c * plug-ins/common/newsprint.c * plug-ins/common/nlfilt.c * plug-ins/common/noisify.c * plug-ins/common/nova.c * plug-ins/common/plasma.c * plug-ins/common/polar.c * plug-ins/common/sample_colorize.c * plug-ins/common/scatter_hsv.c * plug-ins/common/sharpen.c * plug-ins/common/sinus.c * plug-ins/common/tileit.c * plug-ins/common/video.c * plug-ins/common/waves.c * plug-ins/common/whirlpinch.c * plug-ins/common/wind.c * plug-ins/flame/flame.c * plug-ins/fp/fp_gtk.c * plug-ins/gimpressionist/brush.c * plug-ins/mosaic/mosaic.c * plug-ins/rcm/rcm_dialog.c: define GTK_DISABLE_DEPRECATED to make it compile. We really need a generic plug-in preview system that doesn't use GtkPreview.
2002-01-30 22:54:27 +08:00
#include <libgimp/stdplugins-intl.h>
1999-08-27 06:29:37 +08:00
static void update_brush_preview (const char *fn);
1999-08-27 06:29:37 +08:00
static GtkWidget *brush_preview = NULL;
static GtkListStore *brush_list_store = NULL;
1999-08-27 06:29:37 +08:00
static GtkWidget *brush_list = NULL;
static GtkWidget *brush_relief_scale = NULL;
static GtkWidget *brush_aspect_scale = NULL;
static GtkAdjustment *brush_gamma_adjust = NULL;
static gboolean brush_dont_update = FALSE;
static gchar *last_selected_brush = NULL;
static gint brush_from_file = 2;
static ppm_t brushppm = {0, 0, NULL};
void
brush_restore (void)
{
reselect (brush_list, pcvals.selected_brush);
gtk_adjustment_set_value (brush_gamma_adjust, pcvals.brushgamma);
gimp_label_spin_set_value (GIMP_LABEL_SPIN (brush_relief_scale), pcvals.brush_relief);
gimp_label_spin_set_value (GIMP_LABEL_SPIN (brush_aspect_scale), pcvals.brush_aspect);
}
void
brush_store (void)
{
pcvals.brushgamma = gtk_adjustment_get_value (brush_gamma_adjust);
}
void
brush_free (void)
{
g_free (last_selected_brush);
}
void brush_get_selected (ppm_t *p)
{
if (brush_from_file)
brush_reload (pcvals.selected_brush, p);
else
ppm_copy (&brushppm, p);
}
1999-08-27 06:29:37 +08:00
static gboolean
file_is_color (const char *fn)
1999-08-27 06:29:37 +08:00
{
return fn && strstr (fn, ".ppm");
1999-08-27 06:29:37 +08:00
}
void
set_colorbrushes (const gchar *fn)
{
pcvals.color_brushes = file_is_color (fn);
}
static const Babl *
get_u8_format (GimpDrawable *drawable)
{
if (gimp_drawable_is_rgb (drawable))
{
if (gimp_drawable_has_alpha (drawable))
return babl_format ("R'G'B'A u8");
else
return babl_format ("R'G'B' u8");
}
else
{
if (gimp_drawable_has_alpha (drawable))
return babl_format ("Y'A u8");
else
return babl_format ("Y' u8");
}
}
static void
brushdmenuselect (GtkWidget *widget,
gpointer data)
1999-08-27 06:29:37 +08:00
{
GeglBuffer *src_buffer;
const Babl *format;
guchar *src_row;
guchar *src;
gint bpp;
gint x, y;
ppm_t *p;
gint x1, y1, w, h;
gint row;
gint32 drawable_id = -1;
GimpDrawable *drawable;
gint rowstride;
gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), &drawable_id);
drawable = gimp_drawable_get_by_id (drawable_id);
if (! drawable)
return;
1999-08-27 06:29:37 +08:00
if (brush_from_file == 2)
return; /* Not finished GUI-building yet */
1999-08-27 06:29:37 +08:00
if (brush_from_file)
{
#if 0
unselectall (brush_list);
#endif
preset_save_button_set_sensitive (FALSE);
}
gtk_adjustment_set_value (brush_gamma_adjust, 1.0);
gimp_label_spin_set_value (GIMP_LABEL_SPIN (brush_aspect_scale), 0.0);
if (! gimp_drawable_mask_intersect (drawable, &x1, &y1, &w, &h))
return;
format = get_u8_format (drawable);
bpp = babl_format_get_bytes_per_pixel (format);
1999-08-27 06:29:37 +08:00
ppm_kill (&brushppm);
ppm_new (&brushppm, w, h);
1999-08-27 06:29:37 +08:00
p = &brushppm;
1999-08-30 05:06:26 +08:00
rowstride = p->width * 3;
src_row = g_new (guchar, w * bpp);
1999-08-27 06:29:37 +08:00
src_buffer = gimp_drawable_get_buffer (drawable);
if (bpp == 3)
{ /* RGB */
gint bpr = w * 3;
gint y2 = y1 + h;
for (row = 0, y = y1; y < y2; row++, y++)
{
gegl_buffer_get (src_buffer, GEGL_RECTANGLE (x1, y, w, 1), 1.0,
format, src_row,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
memcpy (p->col + row*rowstride, src_row, bpr);
}
1999-08-27 06:29:37 +08:00
}
else
{ /* RGBA (bpp > 3) GrayA (bpp == 2) or Gray */
gboolean is_gray = ((bpp > 3) ? TRUE : FALSE);
gint y2 = y1 + h;
for (row = 0, y = y1; y < y2; row++, y++)
{
guchar *tmprow_ptr;
guchar *tmprow = p->col + row * rowstride;
gint x2 = x1 + w;
gegl_buffer_get (src_buffer, GEGL_RECTANGLE (x1, y, w, 1), 1.0,
format, src_row,
GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
src = src_row;
tmprow_ptr = tmprow;
/* Possible micro-optimization here:
* src_end = src + src_rgn.bpp * w);
* for ( ; src < src_end ; src += src_rgn.bpp)
*/
for (x = x1; x < x2; x++)
{
*(tmprow_ptr++) = src[0];
*(tmprow_ptr++) = src[is_gray ? 1 : 0];
*(tmprow_ptr++) = src[is_gray ? 2 : 0];
src += bpp;
}
}
}
g_object_unref (src_buffer);
g_free (src_row);
1999-08-27 06:29:37 +08:00
if (bpp >= 3)
pcvals.color_brushes = 1;
else
pcvals.color_brushes = 0;
1999-08-27 06:29:37 +08:00
brush_from_file = 0;
update_brush_preview (NULL);
1999-08-27 06:29:37 +08:00
}
static void
brushlistrefresh (void)
1999-08-27 06:29:37 +08:00
{
gtk_list_store_clear (brush_list_store);
readdirintolist ("Brushes", brush_list, NULL);
1999-08-27 06:29:37 +08:00
}
static void
savebrush_response (GtkWidget *dialog,
gint response_id,
gpointer data)
1999-08-27 06:29:37 +08:00
{
if (response_id == GTK_RESPONSE_OK)
{
gchar *name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
ppm_save (&brushppm, name);
brushlistrefresh ();
g_free (name);
}
1999-08-27 06:29:37 +08:00
gtk_widget_destroy (dialog);
1999-08-27 06:29:37 +08:00
}
static void
savebrush (GtkWidget *wg,
gpointer data)
1999-08-27 06:29:37 +08:00
{
GtkWidget *dialog = NULL;
GList *thispath = parsepath ();
gchar *path;
if (! PPM_IS_INITED (&brushppm))
{
g_message ( _("Can only save drawables!"));
return;
}
1999-08-27 06:29:37 +08:00
dialog =
gtk_file_chooser_dialog_new (_("Save Brush"),
GTK_WINDOW (gtk_widget_get_toplevel (wg)),
GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Save"), GTK_RESPONSE_OK,
NULL);
1999-08-27 06:29:37 +08:00
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
GTK_RESPONSE_OK,
GTK_RESPONSE_CANCEL,
-1);
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
TRUE);
path = g_build_filename ((gchar *)thispath->data, "Brushes", NULL);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), path);
1999-08-27 06:29:37 +08:00
g_free (path);
g_signal_connect (dialog, "destroy",
G_CALLBACK (gtk_widget_destroyed),
&dialog);
g_signal_connect (dialog, "response",
G_CALLBACK (savebrush_response),
NULL);
1999-08-27 06:29:37 +08:00
gtk_widget_show (dialog);
1999-08-27 06:29:37 +08:00
}
static gboolean
validdrawable (GimpImage *image,
GimpItem *item,
gpointer data)
1999-08-27 06:29:37 +08:00
{
return (gimp_drawable_is_rgb (GIMP_DRAWABLE (item)) ||
gimp_drawable_is_gray (GIMP_DRAWABLE (item)));
1999-08-27 06:29:37 +08:00
}
/*
* This function caches the last result. Call it with fn as NULL, to
* free the arguments.
* */
void
brush_reload (const gchar *fn,
ppm_t *p)
1999-08-27 06:29:37 +08:00
{
static char lastfn[256] = "";
static ppm_t cache = {0, 0, NULL};
1999-08-27 06:29:37 +08:00
if (fn == NULL)
{
ppm_kill (&cache);
lastfn[0] = '\0';
return;
}
if (strcmp (fn, lastfn))
{
g_strlcpy (lastfn, fn, sizeof (lastfn));
ppm_kill (&cache);
ppm_load (fn, &cache);
}
ppm_copy (&cache, p);
set_colorbrushes (fn);
1999-08-27 06:29:37 +08:00
}
static void
padbrush (ppm_t *p,
gint width,
gint height)
1999-08-27 06:29:37 +08:00
{
guchar black[3] = {0, 0, 0};
int left = (width - p->width) / 2;
int right = (width - p->width) - left;
int top = (height - p->height) / 2;
1999-08-27 06:29:37 +08:00
int bottom = (height - p->height) - top;
ppm_pad (p, left, right, top, bottom, black);
1999-08-27 06:29:37 +08:00
}
static void
update_brush_preview (const gchar *fn)
1999-08-27 06:29:37 +08:00
{
gint i, j;
guchar *preview_image;
1999-08-27 06:29:37 +08:00
if (fn)
brush_from_file = 1;
1999-08-27 06:29:37 +08:00
preview_image = g_new0 (guchar, 100*100);
if (!fn && brush_from_file)
{
/* preview_image is already initialized to our liking. */
1999-08-27 06:29:37 +08:00
}
else
{
double sc;
ppm_t p = {0, 0, NULL};
guchar gammatable[256];
int newheight;
if (brush_from_file)
brush_reload (fn, &p);
else if (PPM_IS_INITED (&brushppm))
ppm_copy (&brushppm, &p);
set_colorbrushes (fn);
sc = gtk_adjustment_get_value (brush_gamma_adjust);
if (sc != 1.0)
for (i = 0; i < 256; i++)
gammatable[i] = pow (i / 255.0, sc) * 255;
else
for (i = 0; i < 256; i++)
gammatable[i] = i;
newheight = p.height *
pow (10, gimp_label_spin_get_value (GIMP_LABEL_SPIN (brush_aspect_scale)));
sc = p.width > newheight ? p.width : newheight;
sc = 100.0 / sc;
resize_fast (&p, p.width*sc,newheight*sc);
padbrush (&p, 100, 100);
for (i = 0; i < 100; i++)
{
int k = i * p.width * 3;
if (i < p.height)
for (j = 0; j < p.width; j++)
preview_image[i*100+j] = gammatable[p.col[k + j * 3]];
}
ppm_kill (&p);
}
gimp_preview_area_draw (GIMP_PREVIEW_AREA (brush_preview),
0, 0, 100, 100,
GIMP_GRAY_IMAGE,
preview_image,
100);
g_free (preview_image);
1999-08-27 06:29:37 +08:00
}
/*
* "force" implies here to change the brush even if it was the same.
* It is used for the initialization of the preview.
* */
static void
brush_select (GtkTreeSelection *selection, gboolean force)
1999-08-27 06:29:37 +08:00
{
GtkTreeIter iter;
GtkTreeModel *model;
gchar *fname = NULL;
gchar *brush = NULL;
1999-08-27 06:29:37 +08:00
if (brush_dont_update)
goto cleanup;
if (brush_from_file == 0)
{
update_brush_preview (NULL);
goto cleanup;
}
1999-08-27 06:29:37 +08:00
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
gtk_tree_model_get (model, &iter, 0, &brush, -1);
/* Check if the same brush was selected twice, and if so
* break. Otherwise, the brush gamma and stuff would have been
* reset.
* */
if (last_selected_brush == NULL)
{
last_selected_brush = g_strdup (brush);
}
else
{
if (!strcmp (last_selected_brush, brush))
{
if (!force)
{
goto cleanup;
}
}
else
{
g_free (last_selected_brush);
last_selected_brush = g_strdup (brush);
}
}
brush_dont_update = TRUE;
gtk_adjustment_set_value (brush_gamma_adjust, 1.0);
gimp_label_spin_set_value (GIMP_LABEL_SPIN (brush_aspect_scale), 0.0);
brush_dont_update = FALSE;
1999-08-27 06:29:37 +08:00
if (brush)
{
fname = g_build_filename ("Brushes", brush, NULL);
g_strlcpy (pcvals.selected_brush,
fname, sizeof (pcvals.selected_brush));
update_brush_preview (fname);
1999-08-27 06:29:37 +08:00
}
}
cleanup:
g_free (fname);
g_free (brush);
1999-08-27 06:29:37 +08:00
}
static void
brush_select_file (GtkTreeSelection *selection, gpointer data)
1999-08-27 06:29:37 +08:00
{
brush_from_file = 1;
preset_save_button_set_sensitive (TRUE);
brush_select (selection, FALSE);
}
static void
brush_preview_size_allocate (GtkWidget *preview)
{
GtkTreeSelection *selection;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (brush_list));
brush_select (selection, TRUE);
}
static void
brush_aspect_adjust_cb (GimpLabelSpin *scale,
gdouble *value)
{
gimpressionist_scale_entry_update_double (scale, value);
update_brush_preview (pcvals.selected_brush);
1999-08-27 06:29:37 +08:00
}
void
create_brushpage (GtkNotebook *notebook)
1999-08-27 06:29:37 +08:00
{
GtkWidget *box1, *box2, *box3, *thispage;
GtkWidget *view;
GtkWidget *tmpw, *grid;
GtkWidget *frame;
GtkWidget *combo;
GtkWidget *label;
GtkSizeGroup *group;
GtkTreeSelection *selection;
1999-08-27 06:29:37 +08:00
label = gtk_label_new_with_mnemonic (_("_Brush"));
1999-08-27 06:29:37 +08:00
2011-09-30 18:17:53 +08:00
thispage = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_container_set_border_width (GTK_CONTAINER (thispage), 12);
gtk_widget_show (thispage);
1999-08-27 06:29:37 +08:00
2011-09-30 18:17:53 +08:00
box1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
gtk_box_pack_start (GTK_BOX (thispage), box1, TRUE,TRUE,0);
1999-08-27 06:29:37 +08:00
gtk_widget_show (box1);
view = create_one_column_list (box1, brush_select_file);
brush_list = view;
brush_list_store =
GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
1999-08-27 06:29:37 +08:00
2011-09-30 18:17:53 +08:00
box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, FALSE, 0);
1999-08-27 06:29:37 +08:00
gtk_widget_show (box2);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_start (GTK_BOX (box2), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
1999-08-27 06:29:37 +08:00
brush_preview = tmpw = gimp_preview_area_new ();
gtk_widget_set_size_request (brush_preview, 100, 100);
gtk_container_add (GTK_CONTAINER (frame), tmpw);
gtk_widget_show (tmpw);
g_signal_connect (brush_preview, "size-allocate",
G_CALLBACK (brush_preview_size_allocate), NULL);
2011-09-30 18:17:53 +08:00
box3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
gtk_box_pack_end (GTK_BOX (box2), box3, FALSE, FALSE,0);
gtk_widget_show (box3);
1999-08-27 06:29:37 +08:00
tmpw = gtk_label_new (_("Gamma:"));
gtk_label_set_xalign (GTK_LABEL (tmpw), 0.0);
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE,0);
1999-08-27 06:29:37 +08:00
gtk_widget_show (tmpw);
brush_gamma_adjust = gtk_adjustment_new (pcvals.brushgamma,
0.5, 3.0, 0.1, 0.1, 1.0);
tmpw = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, brush_gamma_adjust);
gtk_widget_set_size_request (GTK_WIDGET (tmpw), 100, 30);
1999-08-27 06:29:37 +08:00
gtk_scale_set_draw_value (GTK_SCALE (tmpw), FALSE);
gtk_scale_set_digits (GTK_SCALE (tmpw), 2);
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
1999-08-27 06:29:37 +08:00
gtk_widget_show (tmpw);
g_signal_connect_swapped (brush_gamma_adjust, "value-changed",
G_CALLBACK (update_brush_preview),
pcvals.selected_brush);
gimp_help_set_help_data
(tmpw, _("Changes the gamma (brightness) of the selected brush"), NULL);
1999-08-27 06:29:37 +08:00
2011-09-30 18:17:53 +08:00
box3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
gtk_box_pack_start (GTK_BOX (thispage), box3, FALSE, FALSE,0);
gtk_widget_show (box3);
1999-08-27 06:29:37 +08:00
group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
tmpw = gtk_label_new (_("Select:"));
gtk_label_set_xalign (GTK_LABEL (tmpw), 0.0);
gtk_box_pack_start (GTK_BOX (box3), tmpw, FALSE, FALSE, 0);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gtk_widget_show (tmpw);
gtk_size_group_add_widget (group, tmpw);
g_object_unref (group);
combo = gimp_drawable_combo_box_new (validdrawable, NULL, NULL);
gimp_int_combo_box_connect (GIMP_INT_COMBO_BOX (combo), -1,
G_CALLBACK (brushdmenuselect),
NULL, NULL);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
gtk_box_pack_start (GTK_BOX (box3), combo, TRUE, TRUE, 0);
gtk_widget_show (combo);
removed our own action_area API and use GtkDialog's one. Create all 2003-11-06 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpdialog.[ch]: removed our own action_area API and use GtkDialog's one. Create all dialogs without separator. Changed almost everything else too. Fixes bug #125143. * libgimpwidgets/gimpquerybox.c * libgimpwidgets/gimpunitmenu.c: changed accordingly. * libgimp/gimpexport.[ch]: ditto. Renamed enum GimpExportReturnType to GimpExportReturn. * libgimp/gimpcompat.h: added a #define for the old name. * themes/Default/gtkrc: increased action_area border to 6 pixels. * app/display/gimpdisplayshell-filter-dialog.c * app/display/gimpdisplayshell-scale.c * app/display/gimpprogress.c * app/gui/brush-select.c * app/gui/channels-commands.c * app/gui/color-notebook.c * app/gui/convert-dialog.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-editor-commands.c * app/gui/gradient-select.c * app/gui/grid-dialog.c * app/gui/image-commands.c * app/gui/info-window.c * app/gui/layers-commands.c * app/gui/module-browser.c * app/gui/offset-dialog.c * app/gui/palette-import-dialog.c * app/gui/palette-select.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/qmask-commands.c * app/gui/resize-dialog.c * app/gui/resolution-calibrate-dialog.c * app/gui/stroke-dialog.c * app/gui/templates-commands.c * app/gui/user-install-dialog.c * app/gui/vectors-commands.c * app/tools/gimpcolorpickertool.c * app/tools/gimpcroptool.c * app/tools/gimpimagemaptool.c * app/tools/gimpmeasuretool.c * app/tools/gimptransformtool.c * app/widgets/gimptexteditor.c * app/widgets/gimptooldialog.[ch] * app/widgets/gimpviewabledialog.[ch] * app/widgets/gimpwidgets-utils.c: changed accordingly and increased the dialogs' outer borders to 6 pixels all over the place. * plug-ins/*/*.c: changed accordingly. The plug-ins may be arbitrarily broken, I tested none of them.
2003-11-06 23:27:05 +08:00
tmpw = gtk_button_new_with_mnemonic (_("Save _as"));
gtk_box_pack_start (GTK_BOX (box3),tmpw, FALSE, FALSE, 0);
g_signal_connect (tmpw, "clicked", G_CALLBACK (savebrush), NULL);
gtk_widget_show (tmpw);
1999-08-27 06:29:37 +08:00
grid = gtk_grid_new ();
gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
gtk_box_pack_start (GTK_BOX (thispage), grid, FALSE, FALSE, 0);
gtk_widget_show (grid);
brush_aspect_scale =
gimp_scale_entry_new (_("Aspect ratio:"), pcvals.brush_aspect, -1.0, 1.0, 2);
gimp_help_set_help_data (brush_aspect_scale,
_("Specifies the aspect ratio of the brush"),
NULL);
gtk_size_group_add_widget (group,
gimp_labeled_get_label (GIMP_LABELED (brush_aspect_scale)));
g_signal_connect (brush_aspect_scale, "value-changed",
G_CALLBACK (brush_aspect_adjust_cb),
&pcvals.brush_aspect);
gtk_grid_attach (GTK_GRID (grid), brush_aspect_scale, 0, 0, 3, 1);
gtk_widget_show (brush_aspect_scale);
brush_relief_scale =
gimp_scale_entry_new (_("Relief:"), pcvals.brush_relief, 0.0, 100.0, 1);
gimp_help_set_help_data (brush_relief_scale,
_("Specifies the amount of embossing to apply to the image (in percent)"),
NULL);
gtk_size_group_add_widget (group,
gimp_labeled_get_label (GIMP_LABELED (brush_relief_scale)));
g_signal_connect (brush_relief_scale, "value-changed",
G_CALLBACK (gimpressionist_scale_entry_update_double),
&pcvals.brush_relief);
gtk_grid_attach (GTK_GRID (grid), brush_relief_scale, 0, 1, 3, 1);
gtk_widget_show (brush_relief_scale);
1999-08-27 06:29:37 +08:00
brush_select (selection, FALSE);
readdirintolist ("Brushes", view, pcvals.selected_brush);
1999-08-27 06:29:37 +08:00
/*
* This is so the "changed signal won't get sent to the brushes' list
* and reset the gamma and stuff.
* */
gtk_widget_grab_focus (brush_list);
gtk_notebook_append_page_menu (notebook, thispage, label, NULL);
1999-08-27 06:29:37 +08:00
}