gimp/app/core/gimpscanconvert.c

881 lines
25 KiB
C
Raw Normal View History

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995-1999 Spencer Kimball and Peter Mattis
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
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
#include <string.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>
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
#include <libart_lgpl/libart.h>
#include <libart_lgpl/art_svp_intersect.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/pixel-region.h"
#include "base/tile-manager.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 "gimpscanconvert.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
struct _GimpScanConvert
{
gdouble ratio_xy;
gboolean clip;
gint clip_x;
gint clip_y;
gint clip_w;
gint clip_h;
/* stuff necessary for the _add_polygons API... :-/ */
gboolean got_first;
gboolean need_closing;
GimpVector2 first;
GimpVector2 prev;
gboolean have_open;
guint num_nodes;
ArtVpath *vpath;
ArtSVP *svp; /* Sorted vector path
(extension no longer possible) */
/* stuff necessary for the rendering callback */
GimpChannelOps op;
guchar *buf;
gint rowstride;
gint x0, x1;
gboolean antialias;
gboolean value;
};
/* private functions */
static void gimp_scan_convert_render_internal (GimpScanConvert *sc,
GimpChannelOps op,
TileManager *tile_manager,
gint off_x,
gint off_y,
gboolean antialias,
guchar value);
static void gimp_scan_convert_finish (GimpScanConvert *sc);
static void gimp_scan_convert_close_add_points (GimpScanConvert *sc);
static void gimp_scan_convert_render_callback (gpointer user_data,
gint y,
gint start_value,
ArtSVPRenderAAStep *steps,
gint n_steps);
static void gimp_scan_convert_compose_callback (gpointer user_data,
gint y,
gint start_value,
ArtSVPRenderAAStep *steps,
gint n_steps);
/* public functions */
/**
* gimp_scan_convert_new:
*
* Create a new scan conversion context.
*
* Return value: a newly allocated #GimpScanConvert context.
*/
GimpScanConvert *
gimp_scan_convert_new (void)
{
GimpScanConvert *sc = g_slice_new0 (GimpScanConvert);
sc->ratio_xy = 1.0;
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
return sc;
}
/**
* gimp_scan_convert_free:
* @sc: a #GimpScanConvert context
*
* Frees the resources allocated for @sc.
*/
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
void
gimp_scan_convert_free (GimpScanConvert *sc)
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
{
g_return_if_fail (sc != NULL);
if (sc->vpath)
art_free (sc->vpath);
if (sc->svp)
art_svp_free (sc->svp);
g_slice_free (GimpScanConvert, sc);
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
}
/**
* gimp_scan_convert_set_pixel_ratio:
* @sc: a #GimpScanConvert context
* @ratio_xy: the aspect ratio of the major coordinate axes
*
* Sets the pixel aspect ratio.
*/
void
gimp_scan_convert_set_pixel_ratio (GimpScanConvert *sc,
gdouble ratio_xy)
{
g_return_if_fail (sc != NULL);
/* we only need the relative resolution */
sc->ratio_xy = ratio_xy;
}
/**
* gimp_scan_convert_set_clip_rectangle
* @sc: a #GimpScanConvert context
* @x: horizontal offset of clip rectangle
* @y: vertical offset of clip rectangle
* @width: width of clip rectangle
* @height: height of clip rectangle
*
* Sets a clip rectangle on @sc. Subsequent render operations will be
* restricted to this area.
*/
void
gimp_scan_convert_set_clip_rectangle (GimpScanConvert *sc,
gint x,
gint y,
gint width,
gint height)
{
g_return_if_fail (sc != NULL);
sc->clip = TRUE;
sc->clip_x = x;
sc->clip_y = y;
sc->clip_w = width;
sc->clip_h = height;
}
/**
* gimp_scan_convert_add_points:
* @sc: a #GimpScanConvert context
* @n_points: number of points to add
* @points: array of points to add
* @new_polygon: whether to start a new polygon or append to the last one
*
* Adds @n_points from @points to the polygon currently being
* described by @sc. This function is DEPRECATED, please use
* gimp_scan_convert_add_polyline() instead.
*/
void
gimp_scan_convert_add_points (GimpScanConvert *sc,
guint n_points,
GimpVector2 *points,
gboolean new_polygon)
{
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
gint i;
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
g_return_if_fail (sc != NULL);
g_return_if_fail (points != NULL);
g_return_if_fail (n_points > 0);
g_return_if_fail (sc->svp == NULL);
/* We need an extra nodes to end the path */
sc->vpath = art_renew (sc->vpath, ArtVpath, sc->num_nodes + n_points + 1);
if (sc->num_nodes == 0 || new_polygon)
{
if (sc->need_closing)
gimp_scan_convert_close_add_points (sc);
sc->got_first = FALSE;
}
/* We have to compress multiple identical coordinates */
for (i = 0; i < n_points; i++)
{
if (sc->got_first == FALSE ||
sc->prev.x != points[i].x || sc->prev.y != points[i].y)
{
sc->vpath[sc->num_nodes].code = ((! sc->got_first) || new_polygon) ?
ART_MOVETO : ART_LINETO;
sc->vpath[sc->num_nodes].x = points[i].x;
sc->vpath[sc->num_nodes].y = points[i].y;
sc->num_nodes++;
sc->prev = points[i];
if (!sc->got_first)
{
sc->got_first = TRUE;
sc->first = points[i];
}
}
}
sc->need_closing = TRUE;
sc->vpath[sc->num_nodes].code = ART_END;
sc->vpath[sc->num_nodes].x = 0.0;
sc->vpath[sc->num_nodes].y = 0.0;
}
static void
gimp_scan_convert_close_add_points (GimpScanConvert *sc)
{
if (sc->need_closing &&
(sc->prev.x != sc->first.x || sc->prev.y != sc->first.y))
{
sc->vpath = art_renew (sc->vpath, ArtVpath, sc->num_nodes + 2);
sc->vpath[sc->num_nodes].code = ART_LINETO;
sc->vpath[sc->num_nodes].x = sc->first.x;
sc->vpath[sc->num_nodes].y = sc->first.y;
sc->num_nodes++;
sc->vpath[sc->num_nodes].code = ART_END;
sc->vpath[sc->num_nodes].x = 0.0;
sc->vpath[sc->num_nodes].y = 0.0;
}
sc->need_closing = FALSE;
}
/**
* gimp_scan_convert_add_polyline:
* @sc: a #GimpScanConvert context
* @n_points: number of points to add
* @points: array of points to add
* @closed: whether to close the polyline and make it a polygon
*
* Add a polyline with @n_points @points that may be open or closed.
* It is not recommended to mix gimp_scan_convert_add_polyline() with
* gimp_scan_convert_add_points().
*
* Please note that you should use gimp_scan_convert_stroke() if you
* specify open polygons.
*/
void
gimp_scan_convert_add_polyline (GimpScanConvert *sc,
guint n_points,
GimpVector2 *points,
gboolean closed)
{
GimpVector2 prev = { 0.0, 0.0, };
gint i;
g_return_if_fail (sc != NULL);
g_return_if_fail (points != NULL);
g_return_if_fail (n_points > 0);
g_return_if_fail (sc->svp == NULL);
if (sc->need_closing)
gimp_scan_convert_close_add_points (sc);
if (!closed)
sc->have_open = TRUE;
/* make sure that we have enough space for the nodes */
sc->vpath = art_renew (sc->vpath, ArtVpath,
sc->num_nodes + n_points + 2);
for (i = 0; i < n_points; i++)
{
/* compress multiple identical coordinates */
if (i == 0 ||
prev.x != points[i].x ||
prev.y != points[i].y)
{
sc->vpath[sc->num_nodes].code = (i == 0 ? (closed ?
ART_MOVETO :
ART_MOVETO_OPEN) :
ART_LINETO);
sc->vpath[sc->num_nodes].x = points[i].x;
sc->vpath[sc->num_nodes].y = points[i].y;
sc->num_nodes++;
prev = points[i];
}
}
/* close the polyline when needed */
if (closed && (prev.x != points[0].x ||
prev.y != points[0].y))
{
sc->vpath[sc->num_nodes].x = points[0].x;
sc->vpath[sc->num_nodes].y = points[0].y;
sc->vpath[sc->num_nodes].code = ART_LINETO;
sc->num_nodes++;
}
sc->vpath[sc->num_nodes].code = ART_END;
sc->vpath[sc->num_nodes].x = 0.0;
sc->vpath[sc->num_nodes].y = 0.0;
/* If someone wants to mix this function with _add_points ()
* try to do something reasonable...
*/
sc->got_first = FALSE;
}
/**
* gimp_scan_convert_stroke:
* @sc: a #GimpScanConvert context
* @width: line width in pixels
* @join: how lines should be joined
* @cap: how to render the end of lines
* @miter: convert a mitered join to a bevelled join if the miter would
* extend to a distance of more than @miter times @width from
* the actual join point
* @dash_offset: offset to apply on the dash pattern
* @dash_info: dash pattern or %NULL for a solid line
*
* Stroke the content of a GimpScanConvert. The next
* gimp_scan_convert_render() will result in the outline of the
* polygon defined with the commands above.
*
* You cannot add additional polygons after this command.
*
* Note that if you have nonstandard resolution, "width" gives the
* width (in pixels) for a vertical stroke, i.e. use the X resolution
* to calculate the width of a stroke when operating with real world
* units.
*/
void
gimp_scan_convert_stroke (GimpScanConvert *sc,
gdouble width,
GimpJoinStyle join,
GimpCapStyle cap,
gdouble miter,
gdouble dash_offset,
GArray *dash_info)
{
ArtSVP *stroke;
ArtPathStrokeJoinType artjoin = 0;
ArtPathStrokeCapType artcap = 0;
g_return_if_fail (sc->svp == NULL);
if (sc->need_closing)
gimp_scan_convert_close_add_points (sc);
switch (join)
{
case GIMP_JOIN_MITER:
artjoin = ART_PATH_STROKE_JOIN_MITER;
break;
case GIMP_JOIN_ROUND:
artjoin = ART_PATH_STROKE_JOIN_ROUND;
break;
case GIMP_JOIN_BEVEL:
artjoin = ART_PATH_STROKE_JOIN_BEVEL;
break;
}
switch (cap)
{
case GIMP_CAP_BUTT:
artcap = ART_PATH_STROKE_CAP_BUTT;
break;
case GIMP_CAP_ROUND:
artcap = ART_PATH_STROKE_CAP_ROUND;
break;
case GIMP_CAP_SQUARE:
artcap = ART_PATH_STROKE_CAP_SQUARE;
break;
}
if (sc->ratio_xy != 1.0)
{
gint i;
for (i = 0; i < sc->num_nodes; i++)
sc->vpath[i].x *= sc->ratio_xy;
}
if (dash_info && dash_info->len >= 2)
{
ArtVpath *dash_vpath;
ArtVpathDash dash;
gdouble *dashes;
gint i;
dash.offset = dash_offset * MAX (width, 1.0);
dashes = g_new (gdouble, dash_info->len);
for (i = 0; i < dash_info->len ; i++)
dashes[i] = MAX (width, 1.0) * g_array_index (dash_info, gdouble, i);
dash.n_dash = dash_info->len;
dash.dash = dashes;
/* correct 0.0 in the first element (starts with a gap) */
if (dash.dash[0] == 0.0)
{
gdouble first;
first = dash.dash[1];
/* shift the pattern to really starts with a dash and
* use the offset to skip into it.
*/
for (i = 0; i < dash_info->len - 2; i++)
{
dash.dash[i] = dash.dash[i+2];
dash.offset += dash.dash[i];
}
if (dash_info->len % 2 == 1)
{
dash.dash[dash_info->len - 2] = first;
dash.n_dash --;
}
else
{
if (dash_info->len < 3)
{
/* empty stroke */
art_free (sc->vpath);
sc->vpath = NULL;
}
else
{
dash.dash [dash_info->len - 3] += first;
dash.n_dash -= 2;
}
}
}
/* correct odd number of dash specifiers */
if (dash.n_dash % 2 == 1)
{
gdouble last;
last = dash.dash[dash.n_dash - 1];
dash.dash[0] += last;
dash.offset += last;
dash.n_dash --;
}
if (sc->vpath)
{
dash_vpath = art_vpath_dash (sc->vpath, &dash);
art_free (sc->vpath);
sc->vpath = dash_vpath;
}
g_free (dashes);
}
if (sc->vpath)
{
stroke = art_svp_vpath_stroke (sc->vpath, artjoin, artcap,
width, miter, 0.2);
if (sc->ratio_xy != 1.0)
{
ArtSVPSeg *segment;
ArtPoint *point;
gint i, j;
for (i = 0; i < stroke->n_segs; i++)
{
segment = stroke->segs + i;
segment->bbox.x0 /= sc->ratio_xy;
segment->bbox.x1 /= sc->ratio_xy;
for (j = 0; j < segment->n_points; j++)
{
point = segment->points + j;
point->x /= sc->ratio_xy;
}
}
}
sc->svp = stroke;
}
}
/**
* gimp_scan_convert_render:
* @sc: a #GimpScanConvert context
* @tile_manager: the #TileManager to render to
* @off_x: horizontal offset into the @tile_manager
* @off_y: vertical offset into the @tile_manager
* @antialias: whether to apply antialiasiing
*
* Actually renders the @sc to a mask. This function expects a tile
* manager of depth 1.
*
* You cannot add additional polygons after this command.
*/
void
gimp_scan_convert_render (GimpScanConvert *sc,
TileManager *tile_manager,
gint off_x,
gint off_y,
gboolean antialias)
{
g_return_if_fail (sc != NULL);
g_return_if_fail (tile_manager != NULL);
gimp_scan_convert_render_internal (sc, GIMP_CHANNEL_OP_REPLACE,
tile_manager, off_x, off_y,
antialias, 255);
}
/**
* gimp_scan_convert_render_value:
* @sc: a #GimpScanConvert context
* @tile_manager: the #TileManager to render to
* @off_x: horizontal offset into the @tile_manager
* @off_y: vertical offset into the @tile_manager
* @value: value to use for covered pixels
*
* A variant of gimp_scan_convert_render() that doesn't do
* antialiasing but gives control over the value that should be used
* for pixels covered by the scan conversion . Uncovered pixels are
* set to zero.
*
* You cannot add additional polygons after this command.
*/
void
gimp_scan_convert_render_value (GimpScanConvert *sc,
TileManager *tile_manager,
gint off_x,
gint off_y,
guchar value)
{
g_return_if_fail (sc != NULL);
g_return_if_fail (tile_manager != NULL);
gimp_scan_convert_render_internal (sc, GIMP_CHANNEL_OP_REPLACE,
tile_manager, off_x, off_y,
FALSE, value);
}
/**
* gimp_scan_convert_compose:
* @sc: a #GimpScanConvert context
* @tile_manager: the #TileManager to render to
* @off_x: horizontal offset into the @tile_manager
* @off_y: vertical offset into the @tile_manager
*
* This is a variant of gimp_scan_convert_render() that composes the
* (aliased) scan conversion with the content of the @tile_manager.
*
* You cannot add additional polygons after this command.
*/
void
gimp_scan_convert_compose (GimpScanConvert *sc,
GimpChannelOps op,
TileManager *tile_manager,
gint off_x,
gint off_y)
{
g_return_if_fail (sc != NULL);
g_return_if_fail (tile_manager != NULL);
gimp_scan_convert_render_internal (sc, op,
tile_manager, off_x, off_y,
FALSE, 255);
}
static void
gimp_scan_convert_render_internal (GimpScanConvert *sc,
GimpChannelOps op,
TileManager *tile_manager,
gint off_x,
gint off_y,
gboolean antialias,
guchar value)
{
PixelRegion maskPR;
gpointer pr;
gpointer callback;
gint x, y;
gint width, height;
gimp_scan_convert_finish (sc);
if (!sc->svp)
return;
x = 0;
y = 0;
width = tile_manager_width (tile_manager);
height = tile_manager_height (tile_manager);
if (sc->clip &&
! gimp_rectangle_intersect (x, y, width, height,
sc->clip_x, sc->clip_y,
sc->clip_w, sc->clip_h,
&x, &y, &width, &height))
return;
pixel_region_init (&maskPR, tile_manager, x, y, width, height, TRUE);
g_return_if_fail (maskPR.bytes == 1);
sc->antialias = antialias;
sc->value = value;
sc->op = op;
callback = (op == GIMP_CHANNEL_OP_REPLACE ?
gimp_scan_convert_render_callback :
gimp_scan_convert_compose_callback);
for (pr = pixel_regions_register (1, &maskPR);
pr != NULL;
pr = pixel_regions_process (pr))
{
sc->buf = maskPR.data;
sc->rowstride = maskPR.rowstride;
sc->x0 = off_x + maskPR.x;
sc->x1 = off_x + maskPR.x + maskPR.w;
art_svp_render_aa (sc->svp,
sc->x0, off_y + maskPR.y,
sc->x1, off_y + maskPR.y + maskPR.h,
callback, sc);
}
}
/* private function to convert the vpath to a svp when not using
* gimp_scan_convert_stroke
*/
static void
gimp_scan_convert_finish (GimpScanConvert *sc)
{
ArtSVP *svp, *svp2;
ArtSvpWriter *swr;
/* return gracefully on empty path */
if (!sc->vpath)
return;
if (sc->need_closing)
gimp_scan_convert_close_add_points (sc);
if (sc->svp)
return; /* We already have a valid SVP */
/* Debug output of libart path */
/* {
* gint i;
* for (i = 0; i < sc->num_nodes + 1; i++)
* {
* g_printerr ("X: %f, Y: %f, Type: %d\n", sc->vpath[i].x,
* sc->vpath[i].y,
* sc->vpath[i].code );
* }
* }
*/
if (sc->have_open)
{
gint i;
for (i = 0; i < sc->num_nodes; i++)
if (sc->vpath[i].code == ART_MOVETO_OPEN)
{
g_printerr ("Fixing ART_MOVETO_OPEN - result might be incorrect\n");
sc->vpath[i].code = ART_MOVETO;
}
}
svp = art_svp_from_vpath (sc->vpath);
swr = art_svp_writer_rewind_new (ART_WIND_RULE_ODDEVEN);
art_svp_intersector (svp, swr);
svp2 = art_svp_writer_rewind_reap (swr); /* this also frees swr */
art_svp_free (svp);
sc->svp = svp2;
}
/*
* private function to render libart SVPRenderAASteps into the pixel region
*
* A function pretty similiar to this could be used to implement a
* lookup table for the values (just change VALUE_TO_PIXEL).
*
* from the libart documentation:
*
* The value 0x8000 represents 0% coverage by the polygon, while
* 0xff8000 represents 100% coverage. This format is designed so that
* >> 16 results in a standard 0x00..0xff value range, with nice
* rounding.
*/
static void
gimp_scan_convert_render_callback (gpointer user_data,
gint y,
gint start_value,
ArtSVPRenderAAStep *steps,
gint n_steps)
{
GimpScanConvert *sc = user_data;
gint cur_value = start_value;
gint run_x0;
gint run_x1;
gint k;
#define VALUE_TO_PIXEL(x) (sc->antialias ? \
((x) >> 16) : \
(((x) & (1 << 23) ? sc->value : 0)))
if (n_steps > 0)
{
run_x1 = steps[0].x;
if (run_x1 > sc->x0)
memset (sc->buf,
VALUE_TO_PIXEL (cur_value),
run_x1 - sc->x0);
for (k = 0; k < n_steps - 1; k++)
{
cur_value += steps[k].delta;
run_x0 = run_x1;
run_x1 = steps[k + 1].x;
if (run_x1 > run_x0)
memset (sc->buf + run_x0 - sc->x0,
VALUE_TO_PIXEL (cur_value),
run_x1 - run_x0);
}
cur_value += steps[k].delta;
if (sc->x1 > run_x1)
memset (sc->buf + run_x1 - sc->x0,
VALUE_TO_PIXEL (cur_value),
sc->x1 - run_x1);
}
else
{
memset (sc->buf,
VALUE_TO_PIXEL (cur_value),
sc->x1 - sc->x0);
}
sc->buf += sc->rowstride;
#undef VALUE_TO_PIXEL
}
static inline void
compose (GimpChannelOps op,
guchar *buf,
guchar value,
gint len)
{
switch (op)
{
case GIMP_CHANNEL_OP_ADD:
if (value)
memset (buf, value, len);
break;
case GIMP_CHANNEL_OP_SUBTRACT:
if (value)
memset (buf, 0, len);
break;
case GIMP_CHANNEL_OP_REPLACE:
memset (buf, value, len);
break;
case GIMP_CHANNEL_OP_INTERSECT:
do
{
if (*buf)
*buf = value;
buf++;
}
while (--len);
break;
}
}
static void
gimp_scan_convert_compose_callback (gpointer user_data,
gint y,
gint start_value,
ArtSVPRenderAAStep *steps,
gint n_steps)
{
GimpScanConvert *sc = user_data;
gint cur_value = start_value;
gint k, run_x0, run_x1;
#define VALUE_TO_PIXEL(x) (((x) & (1 << 23) ? 255 : 0))
if (n_steps > 0)
{
run_x1 = steps[0].x;
if (run_x1 > sc->x0)
compose (sc->op, sc->buf,
VALUE_TO_PIXEL (cur_value),
run_x1 - sc->x0);
for (k = 0; k < n_steps - 1; k++)
{
cur_value += steps[k].delta;
run_x0 = run_x1;
run_x1 = steps[k + 1].x;
if (run_x1 > run_x0)
compose (sc->op, sc->buf + run_x0 - sc->x0,
VALUE_TO_PIXEL (cur_value),
run_x1 - run_x0);
}
cur_value += steps[k].delta;
if (sc->x1 > run_x1)
compose (sc->op, sc->buf + run_x1 - sc->x0,
VALUE_TO_PIXEL (cur_value),
sc->x1 - run_x1);
}
else
{
compose (sc->op, sc->buf,
VALUE_TO_PIXEL (cur_value),
sc->x1 - sc->x0);
}
sc->buf += sc->rowstride;
#undef VALUE_TO_PIXEL
}