gimp/app/core/gimpbrushgenerated.c

810 lines
26 KiB
C
Raw Normal View History

/* GIMP - The GNU 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 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
an evil temp_hack which lets GimpContext managing the active display 2001-08-14 Michael Natterer <mitch@gimp.org> * app/gdisplay.h: an evil temp_hack which lets GimpContext managing the active display withoug including "gdisplay.h". Will go away as soon ad context properties are registered dynamically. * app/module_db.c: cleaned up the object code in preparation of moving it to core/. * app/path.c: connect to GimpImage's * app/core/gimpobject.[ch]: derive it from GObject, not from GtkObject any more (yeah :-) * app/core/*.c: #include <glib-object.h> instead of <gtk/gtk.h>, removed some remaining GtkObject-isms. (left in a few #include <gtk/gtk.h> where bigger changes are needed to get rid of the UI dependency). * app/core/core-types.h: #include <gdk-pixbuf/gdk-pixbuf.h> here temporarily. * app/core/gimp.c (gimp_create_display): unref the image after creating it's first display. * app/core/gimpbrush.[ch]: disabled the parts of the code which depend on GimpPaintTool. * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c: changed accordingly. * app/core/gimpcontext.[ch]: evil hack (see above) to manage the active display without including "gdisplay.h" * app/core/gimpimage-mask.[ch]: pass a context to gimage_mask_stroke() and get the current tool's PDB string from there. * app/core/gimpedit.c: changed accordingly. * app/core/gimpimage.c: use gimp_image_update() instead of gdisplays_update_full(). * app/gui/color-area.c * app/gui/colormap-dialog.c * app/gui/dialogs-constructors.c * app/gui/edit-commands.c * app/gui/image-commands.c * app/gui/toolbox.c: changed accordingly (don't use Gtk methods on GObjects). * app/gui/menus.c: fix some const warnings by explicit casting. * app/tools/*.[ch]: ported all tools to GObject, some minor cleanup while i was on it. * app/widgets/gimpdialogfactory.[ch]: ported to GObject. * app/widgets/gimplayerlistview.h: added FOO_GET_CLASS() macro. * tools/pdbgen/app.pl: added a "widgets_eek" hack like "tools_eek" which inserts #include "widgets/widgets-types.h" before ordinary includes. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/edit.pdb * app/pdb/brush_select_cmds.c * app/pdb/edit_cmds.c: changed according to the stuff above.
2001-08-14 22:53:55 +08:00
#include <glib-object.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpmath/gimpmath.h"
#include "core-types.h"
new directory app/base/ 2001-05-15 Michael Natterer <mitch@gimp.org> * configure.in: new directory app/base/ * app/Makefile.am * app/boundary.[ch] * app/brush_scale.[ch] * app/gimpchecks.h * app/gimplut.[ch] * app/pixel_processor.[ch] * app/pixel_region.[ch] * app/pixel_surround.[ch] * app/temp_buf.[ch] * app/tile.[ch] * app/tile_cache.[ch] * app/tile_manager.[ch] * app/tile_manager_pvt.h * app/tile_pvt.h * app/tile_swap.[ch]: moved to base/ * app/base/Makefile.am * app/base/base-types.h * app/base/*: new directory for the sub-object pixel maniplation and storage stuff. Does not include Gtk+ or anything outside base/. Did some cleanup in all files. * app/appenums.h * app/apptypes.h * app/core/gimpimage.h: removed types which are now in base/base-types.h. * app/base/base-config.[ch] * app/gimprc.[ch]: put the config variables for base/ to their own file so base/ doesn not have to include gimprc.h (does not yet work, i.e. the variables are un-configurable right now) * app/main.c: set a log handler for "Gimp-Base". * app/paint-funcs/Makefile.am * app/paint-funcs/paint-funcs.[ch]: removed the color hash which maps RGB to color indices because it's a totally standalone system which has nothing to do with the paint-funcs and introduced a GimpImage dependency. paint-funcs/ should be considered on the same sub-object (glib-only) level as base/, only in a different directory. * app/core/Makefile.am * app/core/gimpimage-colorhash.[ch]: put the color hash here. * app/gimage.c: don't invalidate the color hash here... * app/core/gimpimage.c: ... but in the colormap_changed() default inplementation. Initialize the hash in class_init(). * tools/pdbgen/Makefile.am: scan app/base/base-types.h for enums. * tools/pdbgen/enums.pl: regenerated. * app/[lots] * app/core/[of] * app/gui/[files] * app/pdb/[all] * app/tools/[over] * app/widgets/[the] * tools/pdbgen/pdb/[place]: changed #includes accordingly. And use base_config->value instead of the stuff from gimprc.h.
2001-05-15 19:25:25 +08:00
#include "base/temp-buf.h"
#include "gimpbrushgenerated.h"
#include "gimpbrushgenerated-load.h"
#include "gimpbrushgenerated-save.h"
#include "gimp-intl.h"
app/Makefile.am app/channel_pvt.h app/drawable_pvt.h app/gdisplayF.h 2000-12-29 Michael Natterer <mitch@gimp.org> * app/Makefile.am * app/channel_pvt.h * app/drawable_pvt.h * app/gdisplayF.h * app/gimpdrawableP.h * app/gimpimageP.h * app/layer_pvt.h * app/toolsF.h: removed these files. * app/apptypes.h * tools/pdbgen/enums.pl: added tons of opaque typedefs and enums. * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/channel.pdb * tools/pdbgen/pdb/color.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/display.pdb * tools/pdbgen/pdb/drawable.pdb * tools/pdbgen/pdb/fileops.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/help.pdb * tools/pdbgen/pdb/image.pdb * tools/pdbgen/pdb/layer.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb * tools/pdbgen/pdb/selection.pdb * tools/pdbgen/pdb/tools.pdb * app/*: chainsaw #include cleanup: - Never (never!!) include stuff in header files except where we need access to structures' contents (like derived objects). - Added prototypes and proper formating in many files. - The #include order in *all* *.c files is as follows: #include "config.h" #include <system stuff> #include <gtk/gtk.h> #include "apptypes.h" #include "gimp stuff" #include "libgimp stuff" #include "libgimp/gimpintl.h" By following this scheme we can easily see a file's dependencies from it's #include's and can grep for the inclusion to find out where a file is used. * tools/pdbgen/app.pl: changed to follow the include scheme above. * libgimp/Makefile.am * libgimp/gimpuitypes.h: new file, included from libgimp/gimpui.h and from app/apptypes.h. * libgimp/gimpcolorbutton.[ch] * libgimp/gimpdialog.[ch] * libgimp/gimphelpui.[ch] * libgimp/gimpparasite.[ch] * libgimp/gimppatheditor.[ch] * libgimp/gimpprotocol.c * libgimp/gimpquerybox.[ch] * libgimp/gimpsizeentry.[ch] * libgimp/gimptypes.h * libgimp/gimpui.h * libgimp/gimpunit.h * libgimp/gimpunitmenu.[ch] * libgimp/gimpwidgets.[ch]: changed accordingly. * plug-ins/FractalExplorer/Dialogs.c * plug-ins/gdyntext/message_window.c * plug-ins/imagemap/imap_default_dialog.c * plug-ins/imagemap/imap_file.c: these files used to include "libgimp/gimpui.h" without including "libgimp/gimp.h". This is no longer possible because the libgimpui headers don't inlcude "libgimp/gimpunit.h" any more.
2000-12-29 23:22:01 +08:00
#define OVERSAMPLING 4
enum
{
PROP_0,
PROP_SHAPE,
PROP_RADIUS,
PROP_SPIKES,
PROP_HARDNESS,
PROP_ASPECT_RATIO,
PROP_ANGLE
};
/* local function prototypes */
static void gimp_brush_generated_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_brush_generated_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_brush_generated_dirty (GimpData *data);
static const gchar * gimp_brush_generated_get_extension (GimpData *data);
static GimpData * gimp_brush_generated_duplicate (GimpData *data);
static void gimp_brush_generated_transform_size(GimpBrush *gbrush,
2009-04-26 01:53:09 +08:00
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gint *width,
gint *height);
static TempBuf * gimp_brush_generated_transform_mask(GimpBrush *gbrush,
2009-04-26 01:53:09 +08:00
gdouble scale,
gdouble aspect_ratio,
gdouble angle);
static TempBuf * gimp_brush_generated_calc (GimpBrushGenerated *brush,
GimpBrushGeneratedShape shape,
gfloat radius,
gint spikes,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
GimpVector2 *xaxis,
GimpVector2 *yaxis);
static void gimp_brush_generated_get_half_size (GimpBrushGenerated *gbrush,
GimpBrushGeneratedShape shape,
gfloat radius,
gint spikes,
gfloat hardness,
gfloat aspect_ratio,
gdouble angle_in_degrees,
gint *half_width,
gint *half_height,
gdouble *_s,
gdouble *_c,
GimpVector2 *_x_axis,
GimpVector2 *_y_axis);
G_DEFINE_TYPE (GimpBrushGenerated, gimp_brush_generated, GIMP_TYPE_BRUSH)
#define parent_class gimp_brush_generated_parent_class
static void
gimp_brush_generated_class_init (GimpBrushGeneratedClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpDataClass *data_class = GIMP_DATA_CLASS (klass);
GimpBrushClass *brush_class = GIMP_BRUSH_CLASS (klass);
object_class->set_property = gimp_brush_generated_set_property;
object_class->get_property = gimp_brush_generated_get_property;
data_class->save = gimp_brush_generated_save;
data_class->dirty = gimp_brush_generated_dirty;
data_class->get_extension = gimp_brush_generated_get_extension;
data_class->duplicate = gimp_brush_generated_duplicate;
brush_class->transform_size = gimp_brush_generated_transform_size;
brush_class->transform_mask = gimp_brush_generated_transform_mask;
g_object_class_install_property (object_class, PROP_SHAPE,
g_param_spec_enum ("shape", NULL,
_("Brush Shape"),
GIMP_TYPE_BRUSH_GENERATED_SHAPE,
GIMP_BRUSH_GENERATED_CIRCLE,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_RADIUS,
g_param_spec_double ("radius", NULL,
_("Brush Radius"),
0.1, 4000.0, 5.0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_SPIKES,
g_param_spec_int ("spikes", NULL,
_("Brush Spikes"),
2, 20, 2,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_HARDNESS,
g_param_spec_double ("hardness", NULL,
_("Brush Hardness"),
0.0, 1.0, 0.0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_ASPECT_RATIO,
g_param_spec_double ("aspect-ratio",
NULL,
_("Brush Aspect Ratio"),
1.0, 20.0, 1.0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class, PROP_ANGLE,
g_param_spec_double ("angle", NULL,
_("Brush Angle"),
0.0, 180.0, 0.0,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
}
static void
gimp_brush_generated_init (GimpBrushGenerated *brush)
{
brush->shape = GIMP_BRUSH_GENERATED_CIRCLE;
brush->radius = 5.0;
brush->hardness = 0.0;
brush->aspect_ratio = 1.0;
brush->angle = 0.0;
}
static void
gimp_brush_generated_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (object);
switch (property_id)
{
case PROP_SHAPE:
gimp_brush_generated_set_shape (brush, g_value_get_enum (value));
break;
case PROP_RADIUS:
gimp_brush_generated_set_radius (brush, g_value_get_double (value));
break;
case PROP_SPIKES:
gimp_brush_generated_set_spikes (brush, g_value_get_int (value));
break;
case PROP_HARDNESS:
gimp_brush_generated_set_hardness (brush, g_value_get_double (value));
break;
case PROP_ASPECT_RATIO:
gimp_brush_generated_set_aspect_ratio (brush, g_value_get_double (value));
break;
case PROP_ANGLE:
gimp_brush_generated_set_angle (brush, g_value_get_double (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_brush_generated_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (object);
switch (property_id)
{
case PROP_SHAPE:
g_value_set_enum (value, brush->shape);
break;
case PROP_RADIUS:
g_value_set_double (value, brush->radius);
break;
case PROP_SPIKES:
g_value_set_int (value, brush->spikes);
break;
case PROP_HARDNESS:
g_value_set_double (value, brush->hardness);
break;
case PROP_ASPECT_RATIO:
g_value_set_double (value, brush->aspect_ratio);
break;
case PROP_ANGLE:
g_value_set_double (value, brush->angle);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_brush_generated_dirty (GimpData *data)
{
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data);
GimpBrush *gbrush = GIMP_BRUSH (brush);
if (gbrush->mask)
temp_buf_free (gbrush->mask);
gbrush->mask = gimp_brush_generated_calc (brush,
brush->shape,
brush->radius,
brush->spikes,
brush->hardness,
brush->aspect_ratio,
brush->angle,
&gbrush->x_axis,
&gbrush->y_axis);
GIMP_DATA_CLASS (parent_class)->dirty (data);
}
static const gchar *
gimprc.in user_install user_install.bat app/gimprc.[ch] removed the 2001-02-13 Michael Natterer <mitch@gimp.org> * gimprc.in * user_install * user_install.bat * app/gimprc.[ch] * app/preferences_dialog.c: removed the "brush_vbr_path" variable, because all data types will be editable and saveable soon. * app/Makefile.am * app/apptypes.h * app/gimpdatafactory.[ch]: new object which holds a data list and knows how to create, edit, duplicate etc. the items in it. Will completely replace the brushes.[ch], patterns.[ch], ... files soon. * po/POTFILES.in * app/gimpdatacontainerview.[ch]: removed. * app/gimpdatafactoryview.[ch]: added. A view on the GimpDataFactory with a GUI for creating, editing, deleting etc. items (mostly unimplemented). * app/context_manager.[ch]: replaced the global data lists by global data factories. * app/brush_select.c * app/brushes.[ch] * app/commands.c * app/convert.c * app/devices.c * app/gimpbrush.[ch] * app/gimpbrushgenerated.c * app/gimpcontext.c * app/gimpdata.[ch] * app/gimpdatalist.[ch] * app/gimpdnd.c * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch] * app/gradient_editor.c * app/gradient_select.c * app/gradients.[ch] * app/indicator_area.c * app/palette.c * app/palette_import.c * app/palette_select.c * app/palettes.[ch] * app/pattern_select.c * app/patterns.[ch] * app/pdb/brush_select_cmds.c * app/pdb/brushes_cmds.c * app/pdb/convert_cmds.c * app/pdb/gradient_select_cmds.c * app/pdb/gradients_cmds.c * app/pdb/pattern_select_cmds.c * app/pdb/patterns_cmds.c * tools/pdbgen/pdb/brush_select.pdb * tools/pdbgen/pdb/brushes.pdb * tools/pdbgen/pdb/convert.pdb * tools/pdbgen/pdb/gradient_select.pdb * tools/pdbgen/pdb/gradients.pdb * tools/pdbgen/pdb/pattern_select.pdb * tools/pdbgen/pdb/patterns.pdb: changed accordingly.
2001-02-14 03:53:07 +08:00
gimp_brush_generated_get_extension (GimpData *data)
{
return GIMP_BRUSH_GENERATED_FILE_EXTENSION;
}
static GimpData *
gimp_brush_generated_duplicate (GimpData *data)
{
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (data);
return gimp_brush_generated_new (gimp_object_get_name (brush),
brush->shape,
brush->radius,
brush->spikes,
brush->hardness,
brush->aspect_ratio,
brush->angle);
}
static void
gimp_brush_generated_transform_size (GimpBrush *gbrush,
2009-04-26 01:53:09 +08:00
gdouble scale,
gdouble aspect_ratio,
gdouble angle,
gint *width,
gint *height)
{
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (gbrush);
gint half_width;
gint half_height;
2009-04-26 01:53:09 +08:00
/* Since generated brushes are symmetric the dont have intput
* for aspect ratios < 1.0. its same as rotate by 90 degrees and
* 1 / ratio. So we fix the input up for this case. */
if (aspect_ratio < 1.0)
{
aspect_ratio = 1.0 / aspect_ratio;
angle = angle + 0.25;
}
gimp_brush_generated_get_half_size (brush,
brush->shape,
2009-04-26 01:53:09 +08:00
brush->radius * scale,
brush->spikes,
brush->hardness,
brush->aspect_ratio * aspect_ratio,
(brush->angle + 360 * angle),
&half_width, &half_height,
NULL, NULL, NULL, NULL);
*width = half_width * 2 + 1;
*height = half_height * 2 + 1;
}
static TempBuf *
gimp_brush_generated_transform_mask (GimpBrush *gbrush,
2009-04-26 01:53:09 +08:00
gdouble scale,
gdouble aspect_ratio,
gdouble angle)
{
GimpBrushGenerated *brush = GIMP_BRUSH_GENERATED (gbrush);
2009-04-26 01:53:09 +08:00
/* Since generated brushes are symmetric the dont have intput
* for aspect ratios < 1.0. its same as rotate by 90 degrees and
* 1 / ratio. So we fix the input up for this case. */
if (aspect_ratio < 1.0)
{
aspect_ratio = 1.0 / aspect_ratio;
angle = angle + 0.25;
}
return gimp_brush_generated_calc (brush,
brush->shape,
2009-04-26 01:53:09 +08:00
brush->radius * scale ,
brush->spikes,
brush->hardness,
brush->aspect_ratio * aspect_ratio,
(brush->angle + 360 * angle),
NULL, NULL);
}
/* the actual brush rendering functions */
static gdouble
1999-10-27 02:27:27 +08:00
gauss (gdouble f)
libgimpwidgets/gimpquerybox.c configure the labels in the message dialog 2003-11-14 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpquerybox.c * app/widgets/gimpwidgets-utils.c: configure the labels in the message dialog and the query boxes to do automatic word wrapping to be HIG compliant. * app/app_procs.c * app/batch.c * app/config/gimpconfig-deserialize.c * app/config/gimpconfig-path.c * app/config/gimpconfig-utils.c * app/config/gimpconfigwriter.c * app/config/gimpscanner.c * app/core/gimpbrush.c * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c * app/core/gimpdatafactory.c * app/core/gimpgradient.c * app/core/gimpimage-merge.c * app/core/gimpimage.c * app/core/gimpimagefile.c * app/core/gimplayer-floating-sel.c * app/core/gimppalette.c * app/core/gimppattern.c * app/core/gimpselection.c * app/display/gimpdisplayshell.c * app/file/file-utils.c * app/gui/brush-select.c * app/gui/dialogs-commands.c * app/gui/drawable-commands.c * app/gui/edit-commands.c * app/gui/file-commands.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-select.c * app/gui/gui.c * app/gui/image-commands.c * app/gui/layers-commands.c * app/gui/palette-select.c * app/gui/palettes-commands.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/select-commands.c * app/gui/stroke-dialog.c * app/gui/tool-options-menu.c * app/gui/vectors-commands.c * app/gui/view-commands.c * app/plug-in/plug-in-message.c * app/plug-in/plug-in.c * app/plug-in/plug-ins.c * app/text/gimptextlayer-xcf.c * app/text/gimptextlayer.c * app/tools/gimpcurvestool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/tools/gimptransformtool.c * app/vectors/gimpvectors-export.c * app/widgets/gimpdatafactoryview.c * app/widgets/gimphelp.c * app/widgets/gimptemplateview.c * app/widgets/gimptooloptionseditor.c * app/xcf/xcf.c * tools/pdbgen/pdb/image.pdb: removed explicit newlines from messages. Reduced number of translatable strings by making many file error messages the same. Quote single words and filenames with 'foo', not "foo". Replaced some more "drawable" by "layer". General message cleanup and consistency check. * app/pdb/image_cmds.c: regenerated.
2003-11-14 23:33:40 +08:00
{
1999-10-27 02:27:27 +08:00
/* this aint' a real gauss function */
if (f < -0.5)
{
f = -1.0 - f;
return (2.0 * f*f);
}
if (f < 0.5)
return (1.0 - 2.0 * f*f);
f = 1.0 - f;
return (2.0 * f*f);
}
/* set up lookup table */
static guchar *
gimp_brush_generated_calc_lut (gdouble radius,
gdouble hardness)
{
guchar *lookup;
gint length;
gint x;
gdouble d;
gdouble sum;
gdouble exponent;
gdouble buffer[OVERSAMPLING];
length = OVERSAMPLING * ceil (1 + sqrt (2 * SQR (ceil (radius + 1.0))));
lookup = g_malloc (length);
sum = 0.0;
if ((1.0 - hardness) < 0.0000004)
libgimpwidgets/gimpquerybox.c configure the labels in the message dialog 2003-11-14 Michael Natterer <mitch@gimp.org> * libgimpwidgets/gimpquerybox.c * app/widgets/gimpwidgets-utils.c: configure the labels in the message dialog and the query boxes to do automatic word wrapping to be HIG compliant. * app/app_procs.c * app/batch.c * app/config/gimpconfig-deserialize.c * app/config/gimpconfig-path.c * app/config/gimpconfig-utils.c * app/config/gimpconfigwriter.c * app/config/gimpscanner.c * app/core/gimpbrush.c * app/core/gimpbrushgenerated.c * app/core/gimpbrushpipe.c * app/core/gimpdatafactory.c * app/core/gimpgradient.c * app/core/gimpimage-merge.c * app/core/gimpimage.c * app/core/gimpimagefile.c * app/core/gimplayer-floating-sel.c * app/core/gimppalette.c * app/core/gimppattern.c * app/core/gimpselection.c * app/display/gimpdisplayshell.c * app/file/file-utils.c * app/gui/brush-select.c * app/gui/dialogs-commands.c * app/gui/drawable-commands.c * app/gui/edit-commands.c * app/gui/file-commands.c * app/gui/file-new-dialog.c * app/gui/font-select.c * app/gui/gradient-select.c * app/gui/gui.c * app/gui/image-commands.c * app/gui/layers-commands.c * app/gui/palette-select.c * app/gui/palettes-commands.c * app/gui/pattern-select.c * app/gui/preferences-dialog.c * app/gui/select-commands.c * app/gui/stroke-dialog.c * app/gui/tool-options-menu.c * app/gui/vectors-commands.c * app/gui/view-commands.c * app/plug-in/plug-in-message.c * app/plug-in/plug-in.c * app/plug-in/plug-ins.c * app/text/gimptextlayer-xcf.c * app/text/gimptextlayer.c * app/tools/gimpcurvestool.c * app/tools/gimphuesaturationtool.c * app/tools/gimplevelstool.c * app/tools/gimptransformtool.c * app/vectors/gimpvectors-export.c * app/widgets/gimpdatafactoryview.c * app/widgets/gimphelp.c * app/widgets/gimptemplateview.c * app/widgets/gimptooloptionseditor.c * app/xcf/xcf.c * tools/pdbgen/pdb/image.pdb: removed explicit newlines from messages. Reduced number of translatable strings by making many file error messages the same. Quote single words and filenames with 'foo', not "foo". Replaced some more "drawable" by "layer". General message cleanup and consistency check. * app/pdb/image_cmds.c: regenerated.
2003-11-14 23:33:40 +08:00
exponent = 1000000.0;
else
exponent = 0.4 / (1.0 - hardness);
for (x = 0; x < OVERSAMPLING; x++)
1999-10-27 02:27:27 +08:00
{
d = fabs ((x + 0.5) / OVERSAMPLING - 0.5);
if (d > radius)
buffer[x] = 0.0;
else
buffer[x] = gauss (pow (d / radius, exponent));
sum += buffer[x];
}
for (x = 0; d < radius || sum > 0.00001; d += 1.0 / OVERSAMPLING)
{
sum -= buffer[x % OVERSAMPLING];
if (d > radius)
buffer[x % OVERSAMPLING] = 0.0;
1999-10-27 02:27:27 +08:00
else
buffer[x % OVERSAMPLING] = gauss (pow (d / radius, exponent));
sum += buffer[x % OVERSAMPLING];
lookup[x++] = RINT (sum * (255.0 / OVERSAMPLING));
1999-10-27 02:27:27 +08:00
}
while (x < length)
1999-10-27 02:27:27 +08:00
{
lookup[x++] = 0;
}
return lookup;
}
static TempBuf *
gimp_brush_generated_calc (GimpBrushGenerated *brush,
GimpBrushGeneratedShape shape,
gfloat radius,
gint spikes,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle,
GimpVector2 *xaxis,
GimpVector2 *yaxis)
{
guchar *centerp;
guchar *lookup;
guchar a;
gint half_width = 0;
gint half_height = 0;
gint x, y;
gdouble c, s, cs, ss;
GimpVector2 x_axis;
GimpVector2 y_axis;
TempBuf *mask;
gimp_brush_generated_get_half_size (brush,
shape,
radius,
spikes,
hardness,
aspect_ratio,
angle,
&half_width, &half_height,
&s, &c, &x_axis, &y_axis);
mask = temp_buf_new (half_width * 2 + 1,
half_height * 2 + 1,
1, half_width, half_height, NULL);
centerp = temp_buf_get_data (mask) + half_height * mask->width + half_width;
lookup = gimp_brush_generated_calc_lut (radius, hardness);
cs = cos (- 2 * G_PI / spikes);
ss = sin (- 2 * G_PI / spikes);
/* for an even number of spikes compute one half and mirror it */
for (y = (spikes % 2 ? -half_height : 0); y <= half_height; y++)
{
for (x = -half_width; x <= half_width; x++)
{
gdouble d = 0;
gdouble tx = c * x - s * y;
gdouble ty = fabs (s * x + c * y);
if (spikes > 2)
{
gdouble angle = atan2 (ty, tx);
while (angle > G_PI / spikes)
{
gdouble sx = tx;
gdouble sy = ty;
tx = cs * sx - ss * sy;
ty = ss * sx + cs * sy;
angle -= 2 * G_PI / spikes;
}
}
ty *= aspect_ratio;
switch (shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
d = sqrt (SQR (tx) + SQR (ty));
break;
case GIMP_BRUSH_GENERATED_SQUARE:
d = MAX (fabs (tx), fabs (ty));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
d = fabs (tx) + fabs (ty);
break;
}
if (d < radius + 1)
a = lookup[(gint) RINT (d * OVERSAMPLING)];
else
a = 0;
centerp[y * mask->width + x] = a;
if (spikes % 2 == 0)
centerp[-1 * y * mask->width - x] = a;
}
}
g_free (lookup);
if (xaxis)
*xaxis = x_axis;
if (yaxis)
*yaxis = y_axis;
return mask;
}
/* This function is shared between gimp_brush_generated_transform_size and
* gimp_brush_generated_calc, therefore we provide a bunch of optional
* pointers for returnvalues.
*/
static void
gimp_brush_generated_get_half_size (GimpBrushGenerated *gbrush,
GimpBrushGeneratedShape shape,
gfloat radius,
gint spikes,
gfloat hardness,
gfloat aspect_ratio,
gdouble angle_in_degrees,
gint *half_width,
gint *half_height,
gdouble *_s,
gdouble *_c,
GimpVector2 *_x_axis,
GimpVector2 *_y_axis)
{
gdouble c, s;
gdouble short_radius;
GimpVector2 x_axis;
GimpVector2 y_axis;
s = sin (gimp_deg_to_rad (angle_in_degrees));
c = cos (gimp_deg_to_rad (angle_in_degrees));
short_radius = radius / aspect_ratio;
x_axis.x = c * radius;
x_axis.y = -1.0 * s * radius;
y_axis.x = s * short_radius;
y_axis.y = c * short_radius;
switch (shape)
{
case GIMP_BRUSH_GENERATED_CIRCLE:
*half_width = ceil (sqrt (x_axis.x * x_axis.x + y_axis.x * y_axis.x));
*half_height = ceil (sqrt (x_axis.y * x_axis.y + y_axis.y * y_axis.y));
break;
case GIMP_BRUSH_GENERATED_SQUARE:
*half_width = ceil (fabs (x_axis.x) + fabs (y_axis.x));
*half_height = ceil (fabs (x_axis.y) + fabs (y_axis.y));
break;
case GIMP_BRUSH_GENERATED_DIAMOND:
*half_width = ceil (MAX (fabs (x_axis.x), fabs (y_axis.x)));
*half_height = ceil (MAX (fabs (x_axis.y), fabs (y_axis.y)));
break;
}
if (spikes > 2)
{
/* could be optimized by respecting the angle */
*half_width = *half_height = ceil (sqrt (radius * radius +
short_radius * short_radius));
y_axis.x = s * radius;
y_axis.y = c * radius;
}
/* These will typically be set then this function is called by
* gimp_brush_generated_calc, which needs the values in its algorithms.
*/
if (_s != NULL)
*_s = s;
if (_c != NULL)
*_c = c;
if (_x_axis != NULL)
*_x_axis = x_axis;
if (_y_axis != NULL)
*_y_axis = y_axis;
}
/* public functions */
added a note about apptype.h and about not including headers in headers. 2001-02-14 Michael Natterer <mitch@gimp.org> * HACKING: added a note about apptype.h and about not including headers in headers. * app/apptypes.h: added GimpTool and BitmapCursor. * app/cursorutil.h * app/devices.h * app/draw_core.h * app/tools/color_picker.h * app/tools/tool.h * app/tools/tool_options.h * app/gimpcontext.h: removed includes of "tools/tool.h" * app/gimprc.[ch]: indentadion cleanup, added "module_db_load_inhibit". * app/module_db.c: removed the above variable here. * app/gimpdata.[ch]: added a vitrual "duplicate" method. * app/gimpbrush.[ch] * app/gimpbrushgenerated.[ch] * app/gimpbrushpipe.[ch] * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch]: all "load", "new" and "get_standard" functions return a GimpData pointer now. * app/gimpdatafactory.[ch]: made some stuff const. * app/gimpdatafactoryview.c: activate the "duplicate" button and set the initial button sensitivity correctly. * app/brush_select.c * app/gradient_select.c * app/pattern_select.c: use the new GimpDataFactoryView. * libgimp/Makefile.am: grouped the file to sort out what _may_ go to subdirs or separate libs. * libgimp/gimpenv.[ch]: added many "const". * app/app_procs.c * app/brush_edit.c * app/gimpcontext.c * app/gimpdnd.c * app/gradient_editor.c * app/palette.c * app/palette_import.c * app/user_install.c: many related changes. * libgimpmath/gimpmathtypes.h * libgimpmath/gimpvector.[ch]: minor cleanups. * plug-ins/script-fu/script-fu.c: gimp_data_directory() is const now.
2001-02-14 22:57:14 +08:00
GimpData *
gimp_brush_generated_new (const gchar *name,
GimpBrushGeneratedShape shape,
gfloat radius,
gint spikes,
gfloat hardness,
gfloat aspect_ratio,
gfloat angle)
{
GimpBrushGenerated *brush;
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (*name != '\0', NULL);
brush = g_object_new (GIMP_TYPE_BRUSH_GENERATED,
"name", name,
"mime-type", "application/x-gimp-brush-generated",
"spacing", 20.0,
"shape", shape,
"radius", radius,
"spikes", spikes,
"hardness", hardness,
"aspect-ratio", aspect_ratio,
"angle", angle,
NULL);
added a note about apptype.h and about not including headers in headers. 2001-02-14 Michael Natterer <mitch@gimp.org> * HACKING: added a note about apptype.h and about not including headers in headers. * app/apptypes.h: added GimpTool and BitmapCursor. * app/cursorutil.h * app/devices.h * app/draw_core.h * app/tools/color_picker.h * app/tools/tool.h * app/tools/tool_options.h * app/gimpcontext.h: removed includes of "tools/tool.h" * app/gimprc.[ch]: indentadion cleanup, added "module_db_load_inhibit". * app/module_db.c: removed the above variable here. * app/gimpdata.[ch]: added a vitrual "duplicate" method. * app/gimpbrush.[ch] * app/gimpbrushgenerated.[ch] * app/gimpbrushpipe.[ch] * app/gimpgradient.[ch] * app/gimppalette.[ch] * app/gimppattern.[ch]: all "load", "new" and "get_standard" functions return a GimpData pointer now. * app/gimpdatafactory.[ch]: made some stuff const. * app/gimpdatafactoryview.c: activate the "duplicate" button and set the initial button sensitivity correctly. * app/brush_select.c * app/gradient_select.c * app/pattern_select.c: use the new GimpDataFactoryView. * libgimp/Makefile.am: grouped the file to sort out what _may_ go to subdirs or separate libs. * libgimp/gimpenv.[ch]: added many "const". * app/app_procs.c * app/brush_edit.c * app/gimpcontext.c * app/gimpdnd.c * app/gradient_editor.c * app/palette.c * app/palette_import.c * app/user_install.c: many related changes. * libgimpmath/gimpmathtypes.h * libgimpmath/gimpvector.[ch]: minor cleanups. * plug-ins/script-fu/script-fu.c: gimp_data_directory() is const now.
2001-02-14 22:57:14 +08:00
return GIMP_DATA (brush);
}
GimpBrushGeneratedShape
gimp_brush_generated_set_shape (GimpBrushGenerated *brush,
GimpBrushGeneratedShape shape)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush),
GIMP_BRUSH_GENERATED_CIRCLE);
if (brush->shape != shape)
{
brush->shape = shape;
g_object_notify (G_OBJECT (brush), "shape");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->shape;
}
1999-10-27 02:27:27 +08:00
gfloat
gimp_brush_generated_set_radius (GimpBrushGenerated *brush,
gfloat radius)
{
1999-10-27 02:27:27 +08:00
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
radius = CLAMP (radius, 0.0, 32767.0);
if (brush->radius != radius)
{
brush->radius = radius;
g_object_notify (G_OBJECT (brush), "radius");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->radius;
}
gint
gimp_brush_generated_set_spikes (GimpBrushGenerated *brush,
gint spikes)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1);
spikes = CLAMP (spikes, 2, 20);
if (brush->spikes != spikes)
{
brush->spikes = spikes;
g_object_notify (G_OBJECT (brush), "spikes");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->spikes;
}
1999-10-27 02:27:27 +08:00
gfloat
gimp_brush_generated_set_hardness (GimpBrushGenerated *brush,
gfloat hardness)
{
1999-10-27 02:27:27 +08:00
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
hardness = CLAMP (hardness, 0.0, 1.0);
if (brush->hardness != hardness)
{
brush->hardness = hardness;
g_object_notify (G_OBJECT (brush), "hardness");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->hardness;
}
1999-10-27 02:27:27 +08:00
gfloat
gimp_brush_generated_set_aspect_ratio (GimpBrushGenerated *brush,
gfloat ratio)
{
1999-10-27 02:27:27 +08:00
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
ratio = CLAMP (ratio, 1.0, 1000.0);
if (brush->aspect_ratio != ratio)
{
brush->aspect_ratio = ratio;
g_object_notify (G_OBJECT (brush), "aspect-ratio");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->aspect_ratio;
}
1999-10-27 02:27:27 +08:00
gfloat
gimp_brush_generated_set_angle (GimpBrushGenerated *brush,
gfloat angle)
{
1999-10-27 02:27:27 +08:00
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);
if (brush->angle != angle)
{
brush->angle = angle;
g_object_notify (G_OBJECT (brush), "angle");
gimp_data_dirty (GIMP_DATA (brush));
}
return brush->angle;
}
GimpBrushGeneratedShape
gimp_brush_generated_get_shape (const GimpBrushGenerated *brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush),
GIMP_BRUSH_GENERATED_CIRCLE);
return brush->shape;
}
1999-10-27 02:27:27 +08:00
gfloat
gimp_brush_generated_get_radius (const GimpBrushGenerated *brush)
{
1999-10-27 02:27:27 +08:00
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
return brush->radius;
}
gint
gimp_brush_generated_get_spikes (const GimpBrushGenerated *brush)
{
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1);
return brush->spikes;
}
1999-10-27 02:27:27 +08:00
gfloat
gimp_brush_generated_get_hardness (const GimpBrushGenerated *brush)
{
1999-10-27 02:27:27 +08:00
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
return brush->hardness;
}
1999-10-27 02:27:27 +08:00
gfloat
gimp_brush_generated_get_aspect_ratio (const GimpBrushGenerated *brush)
{
1999-10-27 02:27:27 +08:00
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
return brush->aspect_ratio;
}
1999-10-27 02:27:27 +08:00
gfloat
gimp_brush_generated_get_angle (const GimpBrushGenerated *brush)
{
1999-10-27 02:27:27 +08:00
g_return_val_if_fail (GIMP_IS_BRUSH_GENERATED (brush), -1.0);
return brush->angle;
}