Commit 8beb7c58 authored by BST 1999 Andy Thomas's avatar BST 1999 Andy Thomas Committed by Andy Thomas

configure.in plug-ins/Makefile.am plug-ins/sel2path/* <- New directory


Fri Jul  9 22:24:53 BST 1999 Andy Thomas <alt@gimp.org>

	* configure.in
	* plug-ins/Makefile.am
	* plug-ins/sel2path/* <- New directory
	* app/paths_dialog.c
	* pixmap/topath.xpm

	New function implemented by a plugin.
	Will convert a selection into a path. Please
	see the README in sel2path directory for more
	details (especially where the underlying algorithms/code
	were obtained from).
parent b13dd4fd
Fri Jul 9 22:24:53 BST 1999 Andy Thomas <alt@gimp.org>
* configure.in
* plug-ins/Makefile.am
* plug-ins/sel2path/* <- New directory
* app/paths_dialog.c
* pixmap/topath.xpm
New function implemented by a plugin.
Will convert a selection into a path. Please
see the README in sel2path directory for more
details (especially where the underlying algorithms/code
were obtained from).
Fri Jul 9 20:12:12 MEST 1999 Sven Neumann <sven@gimp.org>
* app/app_procs.c: applied a (modified) patch from
......
......@@ -31,9 +31,11 @@
#include "drawable.h"
#include "errors.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "gimage.h"
#include "gimpimage.h"
#include "gimpdrawable.h"
#include "gimage_mask.h"
#include "gdisplay.h"
#include "gimprc.h"
#include "gimpset.h"
#include "general.h"
......@@ -52,6 +54,7 @@
#include "session.h"
#include "undo.h"
#include "drawable_pvt.h"
#include "libgimp/gimpintl.h"
#include "pixmaps/new.xpm"
......@@ -63,6 +66,7 @@
#include "pixmaps/penedit.xpm"
#include "pixmaps/penstroke.xpm"
#include "pixmaps/toselection.xpm"
#include "pixmaps/topath.xpm"
#include "pixmaps/path.xbm"
#include "pixmaps/locked.xbm"
......@@ -143,6 +147,10 @@ static void paths_dialog_new_point_callback (GtkWidget *, gpointer);
static void paths_dialog_add_point_callback (GtkWidget *, gpointer);
static void paths_dialog_delete_point_callback (GtkWidget *, gpointer);
static void paths_dialog_edit_point_callback (GtkWidget *, gpointer);
static void paths_dialog_sel_to_path_callback (GtkWidget *, gpointer);
static void paths_dialog_advanced_to_path_callback (GtkWidget *, gpointer);
static void paths_dialog_null_callback (GtkWidget *, gpointer);
static void path_close(PATHP);
#define NEW_PATH_BUTTON 1
......@@ -153,11 +161,21 @@ static void path_close(PATHP);
#define COPY_PATH_BUTTON 8
#define PASTE_PATH_BUTTON 9
/* the ops buttons */
static OpsButtonCallback to_path_ext_callbacks[] =
{
paths_dialog_advanced_to_path_callback, /* SHIFT */
paths_dialog_null_callback, /* CTRL */
paths_dialog_null_callback, /* MOD1 */
paths_dialog_null_callback, /* SHIFT + CTRL */
};
static OpsButton paths_ops_buttons[] =
{
{ new_xpm, paths_dialog_new_path_callback, NULL, N_("New Path"), NULL, 0 },
{ duplicate_xpm, paths_dialog_dup_path_callback, NULL, N_("Duplicate Path"), NULL, 0 },
{ toselection_xpm, paths_dialog_path_to_sel_callback, NULL, N_("Path to Selection"), NULL, 0 },
{ topath_xpm, paths_dialog_sel_to_path_callback, to_path_ext_callbacks, N_("Selection to Path"), NULL, 0 },
{ penstroke_xpm, paths_dialog_stroke_path_callback, NULL, N_("Stroke Path"), NULL, 0 },
{ delete_xpm, paths_dialog_delete_path_callback, NULL, N_("Delete Path"), NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
......@@ -197,11 +215,11 @@ paths_ops_button_set_sensitive (gint but,
break;
case STROKE_PATH_BUTTON:
menus_set_sensitive_locale ("<Paths>", N_("/Stroke Path"), sensitive);
gtk_widget_set_sensitive(paths_ops_buttons[3].widget,sensitive);
gtk_widget_set_sensitive(paths_ops_buttons[4].widget,sensitive);
break;
case DEL_PATH_BUTTON:
menus_set_sensitive_locale ("<Paths>", N_("/Delete Path"), sensitive);
gtk_widget_set_sensitive(paths_ops_buttons[4].widget,sensitive);
gtk_widget_set_sensitive(paths_ops_buttons[5].widget,sensitive);
break;
case COPY_PATH_BUTTON:
menus_set_sensitive_locale ("<Paths>", N_("/Copy Path"), sensitive);
......@@ -1511,6 +1529,75 @@ paths_dialog_dup_path_callback (GtkWidget * widget, gpointer udata)
paths_dialog->current_path_list->last_selected_row = tmprow;
}
static void paths_dialog_advanced_to_path_callback (GtkWidget *widget,
gpointer udata)
{
ProcRecord *proc_rec;
Argument *args;
GimpImage *gimage;
/* find the sel2path PDB record */
if ((proc_rec = procedural_db_lookup ("plug_in_sel2path_advanced")) == NULL)
{
g_message (_("Selection to path (advanced) procedure lookup failed"));
return;
}
gimage = paths_dialog->gimage;
/* plug-in arguments as if called by <Image>/Filters/... */
args = g_new (Argument, 3);
args[0].arg_type = PDB_INT32;
args[0].value.pdb_int = RUN_INTERACTIVE;
args[1].arg_type = PDB_IMAGE;
args[1].value.pdb_int = (gint32) pdb_image_to_id (gimage);
args[2].arg_type = PDB_DRAWABLE;
args[2].value.pdb_int = (gint32) (gimage_active_drawable (gimage))->ID;
plug_in_run (proc_rec, args, 3, FALSE, TRUE, (gimage_active_drawable (gimage))->ID);
g_free (args);
}
static void paths_dialog_null_callback (GtkWidget *widget,
gpointer udata)
{
/* Maybe some more here later? */
}
void
paths_dialog_sel_to_path_callback (GtkWidget * widget, gpointer udata)
{
ProcRecord *proc_rec;
Argument *args;
GimpImage *gimage;
/* find the sel2path PDB record */
if ((proc_rec = procedural_db_lookup ("plug_in_sel2path")) == NULL)
{
g_message (_("Selection to path procedure lookup failed"));
return;
}
gimage = paths_dialog->gimage;
/* plug-in arguments as if called by <Image>/Filters/... */
args = g_new (Argument, 3);
args[0].arg_type = PDB_INT32;
args[0].value.pdb_int = RUN_INTERACTIVE;
args[1].arg_type = PDB_IMAGE;
args[1].value.pdb_int = (gint32) pdb_image_to_id (gimage);
args[2].arg_type = PDB_DRAWABLE;
args[2].value.pdb_int = (gint32) (gimage_active_drawable (gimage))->ID;
plug_in_run (proc_rec, args, 3, FALSE, TRUE, (gimage_active_drawable (gimage))->ID);
g_free (args);
}
void
paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
{
......
......@@ -31,9 +31,11 @@
#include "drawable.h"
#include "errors.h"
#include "floating_sel.h"
#include "gdisplay.h"
#include "gimage.h"
#include "gimpimage.h"
#include "gimpdrawable.h"
#include "gimage_mask.h"
#include "gdisplay.h"
#include "gimprc.h"
#include "gimpset.h"
#include "general.h"
......@@ -52,6 +54,7 @@
#include "session.h"
#include "undo.h"
#include "drawable_pvt.h"
#include "libgimp/gimpintl.h"
#include "pixmaps/new.xpm"
......@@ -63,6 +66,7 @@
#include "pixmaps/penedit.xpm"
#include "pixmaps/penstroke.xpm"
#include "pixmaps/toselection.xpm"
#include "pixmaps/topath.xpm"
#include "pixmaps/path.xbm"
#include "pixmaps/locked.xbm"
......@@ -143,6 +147,10 @@ static void paths_dialog_new_point_callback (GtkWidget *, gpointer);
static void paths_dialog_add_point_callback (GtkWidget *, gpointer);
static void paths_dialog_delete_point_callback (GtkWidget *, gpointer);
static void paths_dialog_edit_point_callback (GtkWidget *, gpointer);
static void paths_dialog_sel_to_path_callback (GtkWidget *, gpointer);
static void paths_dialog_advanced_to_path_callback (GtkWidget *, gpointer);
static void paths_dialog_null_callback (GtkWidget *, gpointer);
static void path_close(PATHP);
#define NEW_PATH_BUTTON 1
......@@ -153,11 +161,21 @@ static void path_close(PATHP);
#define COPY_PATH_BUTTON 8
#define PASTE_PATH_BUTTON 9
/* the ops buttons */
static OpsButtonCallback to_path_ext_callbacks[] =
{
paths_dialog_advanced_to_path_callback, /* SHIFT */
paths_dialog_null_callback, /* CTRL */
paths_dialog_null_callback, /* MOD1 */
paths_dialog_null_callback, /* SHIFT + CTRL */
};
static OpsButton paths_ops_buttons[] =
{
{ new_xpm, paths_dialog_new_path_callback, NULL, N_("New Path"), NULL, 0 },
{ duplicate_xpm, paths_dialog_dup_path_callback, NULL, N_("Duplicate Path"), NULL, 0 },
{ toselection_xpm, paths_dialog_path_to_sel_callback, NULL, N_("Path to Selection"), NULL, 0 },
{ topath_xpm, paths_dialog_sel_to_path_callback, to_path_ext_callbacks, N_("Selection to Path"), NULL, 0 },
{ penstroke_xpm, paths_dialog_stroke_path_callback, NULL, N_("Stroke Path"), NULL, 0 },
{ delete_xpm, paths_dialog_delete_path_callback, NULL, N_("Delete Path"), NULL, 0 },
{ NULL, NULL, NULL, NULL, NULL, 0 }
......@@ -197,11 +215,11 @@ paths_ops_button_set_sensitive (gint but,
break;
case STROKE_PATH_BUTTON:
menus_set_sensitive_locale ("<Paths>", N_("/Stroke Path"), sensitive);
gtk_widget_set_sensitive(paths_ops_buttons[3].widget,sensitive);
gtk_widget_set_sensitive(paths_ops_buttons[4].widget,sensitive);
break;
case DEL_PATH_BUTTON:
menus_set_sensitive_locale ("<Paths>", N_("/Delete Path"), sensitive);
gtk_widget_set_sensitive(paths_ops_buttons[4].widget,sensitive);
gtk_widget_set_sensitive(paths_ops_buttons[5].widget,sensitive);
break;
case COPY_PATH_BUTTON:
menus_set_sensitive_locale ("<Paths>", N_("/Copy Path"), sensitive);
......@@ -1511,6 +1529,75 @@ paths_dialog_dup_path_callback (GtkWidget * widget, gpointer udata)
paths_dialog->current_path_list->last_selected_row = tmprow;
}
static void paths_dialog_advanced_to_path_callback (GtkWidget *widget,
gpointer udata)
{
ProcRecord *proc_rec;
Argument *args;
GimpImage *gimage;
/* find the sel2path PDB record */
if ((proc_rec = procedural_db_lookup ("plug_in_sel2path_advanced")) == NULL)
{
g_message (_("Selection to path (advanced) procedure lookup failed"));
return;
}
gimage = paths_dialog->gimage;
/* plug-in arguments as if called by <Image>/Filters/... */
args = g_new (Argument, 3);
args[0].arg_type = PDB_INT32;
args[0].value.pdb_int = RUN_INTERACTIVE;
args[1].arg_type = PDB_IMAGE;
args[1].value.pdb_int = (gint32) pdb_image_to_id (gimage);
args[2].arg_type = PDB_DRAWABLE;
args[2].value.pdb_int = (gint32) (gimage_active_drawable (gimage))->ID;
plug_in_run (proc_rec, args, 3, FALSE, TRUE, (gimage_active_drawable (gimage))->ID);
g_free (args);
}
static void paths_dialog_null_callback (GtkWidget *widget,
gpointer udata)
{
/* Maybe some more here later? */
}
void
paths_dialog_sel_to_path_callback (GtkWidget * widget, gpointer udata)
{
ProcRecord *proc_rec;
Argument *args;
GimpImage *gimage;
/* find the sel2path PDB record */
if ((proc_rec = procedural_db_lookup ("plug_in_sel2path")) == NULL)
{
g_message (_("Selection to path procedure lookup failed"));
return;
}
gimage = paths_dialog->gimage;
/* plug-in arguments as if called by <Image>/Filters/... */
args = g_new (Argument, 3);
args[0].arg_type = PDB_INT32;
args[0].value.pdb_int = RUN_INTERACTIVE;
args[1].arg_type = PDB_IMAGE;
args[1].value.pdb_int = (gint32) pdb_image_to_id (gimage);
args[2].arg_type = PDB_DRAWABLE;
args[2].value.pdb_int = (gint32) (gimage_active_drawable (gimage))->ID;
plug_in_run (proc_rec, args, 3, FALSE, TRUE, (gimage_active_drawable (gimage))->ID);
g_free (args);
}
void
paths_dialog_path_to_sel_callback (GtkWidget * widget, gpointer udata)
{
......
......@@ -655,6 +655,7 @@ plug-ins/mosaic/Makefile
plug-ins/pagecurl/Makefile
plug-ins/print/Makefile
plug-ins/rcm/Makefile
plug-ins/sel2path/Makefile
plug-ins/sgi/Makefile
plug-ins/sinus/Makefile
plug-ins/struc/Makefile
......
/* XPM */
static char * topath_xpm[] = {
"18 18 5 1",
" c None",
". c #000000",
"+ c #BCBABC",
"@ c #DEDADE",
"# c #FFFFFF",
" .. ..",
" ............... ",
" .. ... ..",
" +@@#. ",
" #.@@@@@.# ",
" .+@@@@@@@++ ",
" #@@@@@@@@@. ",
" .@@@@@@@@@@@# ",
" +@@@@@@@@@@@+ ",
" #@@@@@@@@@@@. ",
" .@@@@@@@@@@@+ ",
" +@@@@@@@@@@@# ",
" .@@@@@@@@@+ ",
" ++@@@@@@@.# ",
" #.@@@@@#+ ",
" .+#.+ ",
" . ... . ",
" ................."};
......@@ -31,6 +31,7 @@ SUBDIRS = \
print \
rcm \
sgi \
sel2path \
sinus \
struc \
unsharp \
......
Makefile.in
Makefile
.deps
_libs
.libs
sel2path
## Process this file with automake to produce Makefile.in
libexecdir = $(gimpplugindir)/plug-ins
EXTRA_DIST = README \
README.limn
libexec_PROGRAMS = sel2path
sel2path_SOURCES = \
bitmap.h \
bounding-box.h \
curve.c \
curve.h \
edge.c \
edge.h \
fit.c \
fit.h \
global.h \
math.c \
pxl-outline.c \
pxl-outline.h \
sel2path.c \
sel2path_adv_dialog.c \
sel2path.h \
spline.c \
spline.h \
types.h \
vector.c \
vector.h
INCLUDES = \
-I$(top_srcdir) \
$(GTK_CFLAGS) \
-I$(includedir)
AM_CPPFLAGS = \
-DLOCALEDIR=\""$(localedir)"\"
LDADD = \
$(top_builddir)/libgimp/libgimp.la \
$(top_builddir)/plug-ins/libgck/gck/libgck.la \
$(GTK_LIBS) \
$(INTLLIBS)
.PHONY: files
files:
@files=`ls $(DISTFILES) 2> /dev/null`; for p in $$files; do \
echo $$p; \
done
Andy Thomas (alt@gimp.org) 9th July 1999
This plug-in will take a selection and convert it into a path.
For the purpose of the plug-in the selection boundary is defined
in a similar manner to that worked out for the "marching ants" markers
of the selection. I think this gives the best user feel/feedback since
the created path "follows" the "marching ants".
I cannot claim responsibility for the underlying algorithms. These
were taken directly from the GNU font utilities (the "limn" program
in particular) written by Karl Berry and Kathryn Hargreaves.
Their email addresses quoted in the README are:-
Karl Berry karl@cs.umb.edu
Kathryn Hargreaves letters@cs.umb.edu
Please see fontutils-0.6 package for more details. I have included the
README from the limn part of the package.
I thank Karl & Kathryn for producing such a well written set of utilites.
I have just added a gimp front-end onto them.
How to use it.
~~~~~~~~~~~~~~
Simply select an area and then select either "<Image>/Selection/To Path"
menu item or the "Selection To Image" button in the paths dialog. The new
path will be created. Currently if the LCP dialog has not been activated
then the path will not be visible... A bug I have just found - simply
bring up the LCP dialog and select the Paths tab to see the newly created
path.
An additional function can be obtained by having the "Shift" modifier pressed
while using the button in the paths dialog. This will pop-up a "power-users"
menu where the parameters to the underlying algorithms can be modified.
WARING:- Some values may cause the plugin to enter extremely long operations.
You have been warned.
Have fun!
Andy.
PS. Please direct any bugs etc found in this plugin to either
myself or the gimp-developer mailing list. Thank.
This program converts bitmap fonts to a homegrown outline format, bezier
(BZR). The program `bzrto' converts that format to something usable for
typesetting.
We used two main sources in writing the program:
@mastersthesis{Schneider:PIC-88,
author = "Philip J. Schneider",
title = "Phoenix: An Interactive Curve Design System Based on the
Automatic Fitting of Hand-Sketched Curves",
school = inst-u-wash,
year = 1988,
}
@article{Plass:CG-17-229,
author = "Michael Plass and Maureen Stone",
title = "Curve-fitting with Piecewise Parametric Cubics",
journal = j-comp-graphics,
year = 1983,
volume = 17,
number = 3,
month = jul,
pages = "229-239",
}
We had access to the code for Phoenix, thanks to Philip, but none of our
code is based on his (mostly because his task was allow interactive
sketching, and ours to fit bitmap characters, and the two require
different data structures). The general outline of the fitting
algorithm does come from Phoenix.
We also found this article helpful:
@Inproceedings{Gonczarowski:RIDT91-1,
author = "Jakob Gonczarowski",
title = "A Fast Approach to Auto-tracing (with Parametric
Cubics)",
pages = "1--15",
crossref = "Morris:RIDT91",
acknowledgement = ack-kb,
}
@String{proc-RIDT91 = "Raster Imaging and Digital Typography II"}
@Proceedings{Morris:RIDT91,
title = proc-RIDT91,
booktitle = proc-RIDT91,
year = "1991",
editor = "Robert A. Morris and Jacques Andr{\'e}",
publisher = pub-CUP,
address = pub-CUP:adr,
acknowledgement = ack-kb,
}
(These BibTeX entries are from the type.bib and ep.bib files on
math.utah.edu:pub/tex/bib.)
/* bitmap.h: definition for a bitmap type. No packing is done by
default; each pixel is represented by an entire byte. Among other
things, this means the type can be used for both grayscale and binary
images.
Copyright (C) 1992 Free Software Foundation, Inc.
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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef BITMAP_H
#define BITMAP_H
#include <stdio.h>
#include "bounding-box.h"
#include "types.h"
/* If the bitmap holds 8-bit values, rather than one-bit, the
definition of BLACK here is wrong. So don't use it in that case! */
#define WHITE 0
#define BLACK 1
/* The basic structure and macros to access it. */
typedef struct
{
dimensions_type dimensions;
one_byte *bitmap;
} bitmap_type;
/* The dimensions of the bitmap, in pixels. */
#define BITMAP_DIMENSIONS(b) ((b).dimensions)
/* The pixels, represented as an array of bytes (in contiguous storage).
Each pixel is a single byte, even for binary fonts. */
#define BITMAP_BITS(b) ((b).bitmap)
/* These are convenient abbreviations for geting inside the members. */
#define BITMAP_WIDTH(b) DIMENSIONS_WIDTH (BITMAP_DIMENSIONS (b))
#define BITMAP_HEIGHT(b) DIMENSIONS_HEIGHT (BITMAP_DIMENSIONS (b))
/* This is the address of the first pixel in the row ROW. */
#define BITMAP_ROW(b, row) (BITMAP_BITS (b) + (row) * BITMAP_WIDTH (b))
/* This is the pixel at [ROW,COL]. */
#define BITMAP_PIXEL(b, row, col) \
(*(BITMAP_BITS (b) + (row) * BITMAP_WIDTH (b) + (col)))
#define BITMAP_VALID_PIXEL(b, row, col) \
(0 <= (row) && (row) < BITMAP_HEIGHT (b) \
&& 0 <= (col) && (col) < BITMAP_WIDTH (b))
/* Assume that the pixel at [ROW,COL] itself is black. */
#define BITMAP_INTERIOR_PIXEL(b, row, col) \
(0 != (row) && (row) != BITMAP_HEIGHT (b) - 1 \
&& 0 != (col) && (col) != BITMAP_WIDTH (b) - 1 \
&& BITMAP_PIXEL (b, row - 1, col - 1) == BLACK \
&& BITMAP_PIXEL (b, row - 1, col) == BLACK \
&& BITMAP_PIXEL (b, row - 1, col + 1) == BLACK \
&& BITMAP_PIXEL (b, row, col - 1) == BLACK \
&& BITMAP_PIXEL (b, row, col + 1) == BLACK \
&& BITMAP_PIXEL (b, row + 1, col - 1) == BLACK \
&& BITMAP_PIXEL (b, row + 1, col) == BLACK \
&& BITMAP_PIXEL (b, row + 1, col + 1) == BLACK)
/* Allocate storage for the bits, set them all to white, and return an
initialized structure. */
extern bitmap_type new_bitmap (dimensions_type);
/* Free that storage. */
extern void free_bitmap (bitmap_type *);
/* Make a fresh copy of BITMAP in a new structure, and return it. */
extern bitmap_type copy_bitmap (bitmap_type bitmap);
/* Return the pixels in the bitmap B enclosed by the bounding box BB.
The result is put in newly allocated storage. */
extern bitmap_type extract_subbitmap (bitmap_type b, bounding_box_type bb);
/* Consider the dimensions of a bitmap as a bounding box. The bounding
box returned is in bitmap coordinates, rather than Cartesian, and
refers to pixels, rather than edges. Specifically, this means that
the maximum column is one less than results from `dimensions_to_bb
(BITMAP_DIMENSIONS ())'. */
extern const bounding_box_type bitmap_to_bb (const bitmap_type);
/* Return a vector of zero-based column numbers marking transitions from
black to white or white to black in ROW, which is of length WIDTH.
The end of the vector is marked with an element of length WIDTH + 1.
The first element always marks a white-to-black transition (or it's
0, if the first pixel in ROW is black). */
extern unsigned *bitmap_find_transitions (const one_byte *row, unsigned width);
/* Print part of or all of a bitmap. */
extern void print_bounded_bitmap (FILE *, bitmap_type, bounding_box_type);
extern void print_bitmap (FILE *, bitmap_type);
#endif /* not BITMAP_H */
/* bounding-box.h: operations on both real- and integer-valued bounding boxes.
Copyright (C) 1992 Free Software Foundation, Inc.
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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef BOUNDING_BOX_H
#define BOUNDING_BOX_H
#include "types.h"
/* The bounding box's numbers are usually in Cartesian/Metafont
coordinates: (0,0) is towards the lower left. */
typedef struct
{
signed_4_bytes min_row, max_row;
signed_4_bytes min_col, max_col;
} bounding_box_type;
typedef struct
{
real min_row, max_row;
real min_col, max_col;
} real_bounding_box_type;
/* These accessing macros work for both types of bounding boxes, since
the member names are the same. */
#define MIN_ROW(bb) ((bb).min_row)
#define MAX_ROW(bb) ((bb).max_row)
#define MIN_COL(bb) ((bb).min_col)
#define MAX_COL(bb) ((bb).max_col)
/* See the comments at `get_character_bitmap' in gf_input.c for why the
width and height are treated asymetrically. */
#define BB_WIDTH(bb) (MAX_COL (bb) - MIN_COL (bb))
#define BB_HEIGHT(bb) (MAX_ROW (bb) - MIN_ROW (bb) + 1)
/* Convert a dimensions structure to an integer bounding box, and vice
versa. */
extern const bounding_box_type dimensions_to_bb (dimensions_type);
extern const dimensions_type bb_to_dimensions (bounding_box_type);
/* Update the bounding box BB from the point P. */
extern void update_real_bounding_box (real_bounding_box_type *bb,
real_coordinate_type p);
extern void update_bounding_box (bounding_box_type *bb, coordinate_type p);
#endif /* not BOUNDING_BOX_H */
/* curve.c: operations on the lists of pixels and lists of curves.
Copyright (C) 1992 Free Software Foundation, Inc.
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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <malloc.h>
#include "config.h"
#include "global.h"
#include "curve.h"
/* Return an entirely empty curve. */
curve_type
new_curve ()
{
curve_type curve = malloc (sizeof (struct curve));
curve->point_list = NULL;
CURVE_LENGTH (curve) = 0;
CURVE_CYCLIC (curve) = false;
CURVE_START_TANGENT (curve) = CURVE_END_TANGENT (curve) = NULL;
PREVIOUS_CURVE (curve) = NEXT_CURVE (curve) = NULL;