v04i069: xpic -- pic previewer for X11, Part04/15
Dan Heller
argv at island.uu.net
Fri Jul 21 05:16:38 AEST 1989
Submitted-by: Mark Moraes <moraes at ai.toronto.edu>
Posting-number: Volume 4, Issue 69
Archive-name: xpic/part04
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 4 (of 15)."
# Contents: xpic/Imakefile xpic/arc.c xpic/defs.h xpic/hash.c
# xpic/make.out xpic/obj_circ.c xpic/obj_ell.c xpic/test/rayan.ps
# xpic/test/testtext.ps
# Wrapped by moraes at neat.ai on Thu Jul 13 22:36:07 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'xpic/Imakefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/Imakefile'\"
else
echo shar: Extracting \"'xpic/Imakefile'\" \(5800 characters\)
sed "s/^X//" >'xpic/Imakefile' <<'END_OF_FILE'
X/* Using inlining with gcc means you must not use the -traditional flag */
XCC=gcc
X
X/*
X * We use a few math library functions - cos, sin, sqrt, atan2. On Suns with
X * SunOS3.5 or greater, and with gcc, it is possible to inline these calls for
X * considerable speed improvement, and reduction in binary size.
X */
X
X# For SunOS3.5, Sun3 with f68881 installed
X#INLINELIBM=/usr/lib/f68881.il
X
X# For SunOS4.0, Sun3 with f68881 installed
X#INLINELIBM=/usr/lib/f68881/libm.il
X
X#ifdef CSRIToronto
X# For a machine with a 68881 using gcc - ../fastmath is where we keep
X# our inline math library for gcc. Collect that by anonymous ftp from
X# ai.toronto.edu:pub/moraes/fastmath.tar.Z
XINLINELIBM=-I../fastmath
X#endif /* CSRIToronto */
X
X# Where are the HP widgets - this is used with a -I option. If you have them
X# installed.
XXWSRC=$(CONTRIBSRC)/widgets/Xhp
XXWINC=-I$(XWSRC)
X
X# Note - You need the HP widgets (Xw) for the X11 Toolkit
X# These should be defined in an Imake.tmpl - except that the
X# normal Imake.tmpl insists on these being compiled in the
X# X directory tree.
X#XWLIB=$(XWSRC)/Xw/libXw.a
XXWLIB=$(USRLIBDIR)/libXw.a
X
X# The documents go in $(DOCDIR)/xpic - see the install target.
X# At CSRI, we use a logical link to the source, so we don't
X# install this. You must still keep this accurate, because
X# it's put into the man page. Change the install target appropriately.
XDOCDIR=/local/doc/X11
X# the directory in which xpic saves the current buffer
X# in case it dies on a signal
XDUMPDIR=/tmp
X
X# -DXWINDOWS is used by the filename completion code is ask.c and util.c
X# to include the Xos.h header file if compiled in an X program for
X# greater portability.
X# -DMAGIC will include code that puts a '#! $(BINDIR)/xpic'
X# header on the saved xpic files, and make them executable, so
X# you can just execute the saved xpic file and it starts up
X# xpic.
X# -DFASTARCS means your X server can draw arcs fast. Do *NOT* define this
X# for the MIT R3 sample server running on anything less than a
X# MIPS-based workstation.
X# -DDEBUG turns on debugging output - do you really want that?!
X# -DDRAWBBOX is also for debugging - it draws the bounding box
X# of all gels.
X# -DGRAB should be defined if XtAddGrab and XtRemoveGrab can be
X# made to work in Minibuf.c and input.c - I can't seem to get them
X# to work.
X# -DTYPEOUT includes the typeout code
XDEFINES = -DXWINDOWS -DMAGIC -DTYPEOUT # -DDEBUG
X
X# Define USLEEP if your system lacks a usleep (eg) Ultrix.
XUSLEEP=usleep.o
X
X########################################################################
X# You should not have to modify the rest of this file
X
XCDEBUGFLAGS = -O
XINCLUDES = $(XWINC) -I$(TOP) -Ibitmaps $(INLINELIBM)
XXPICLIBDIR=$(LIBDIR)/xpic
X
X# Sigh - we use sin(), cos(), atan2() for arrow, and for ellipses
X# If inlining is chosen (see INLINELIBM), then the mathlib on won't be
X# used, saving a whopping 55K on Suns.
XMATHLIB=-lm
X
X# /usr/lib/debug/malloc.o is Sun's debugging malloc() - it
X# provides the malloc_debug() and malloc_verify() calls.
X# malloc.o is a first-fit malloc with debugging ASSERTs. Finds
X# heap corruption fast. Not defining this will use libc.
X#MALLOC = /usr/lib/debug/malloc.o
X#MALLOC = malloc.o
XMALLOC =
X
XOBJS1 = main.o windows.o xpic.o handlers.o input.o \
X event.o grid.o error.o spline.o arrow.o newfonts.o \
X util.o gels.o null.o obj_line.o obj_spline.o obj_text.o \
X obj_box.o obj_circ.o obj_ell.o obj_block.o obj_elem.o \
X updown.o text.o isqrt.o ask.o xtypeout.o Minibuf.o Window.o \
X arc.o box.o focus.o line.o $(USLEEP)
X
XSRCS1 = main.c windows.c xpic.c handlers.c input.c \
X event.c grid.c error.c spline.c arrow.c newfonts.c \
X util.c gels.c null.c obj_line.c obj_spline.c obj_text.c \
X obj_box.c obj_circ.c obj_ell.c obj_block.c obj_elem.c \
X updown.c text.c isqrt.c ask.c xtypeout.c Minibuf.c Window.c \
X arc.c box.c focus.c line.c
X
XOBJS2 = x2pic.o hash.o
XSRCS2 = x2pic.c hash.c
X
XOBJS3 = x2ps.o hash.o
XSRCS3 = x2ps.c hash.c
X
XOBJS4 = x2tpic.o xtp.o hash.o
XSRCS4 = x2tpic.c xtp.c hash.c
X
XPROGRAMS = xpic x2ps x2pic x2tpic
X
X.SUFFIXES: .manX .man
X
X.manX.man:
X sed -e 's?DOCDIR?$(DOCDIR)/xpic?g'\
X -e 's?XPICLIBDIR?$(XPICLIBDIR)?g' $*.manX > $*.man
X
XComplexProgramTarget_1(xpic,$(MYXTSTUFF) $(MALLOC) $(XWLIB) $(XTOOLLIB) $(XLIB),$(MATHLIB))
X/* Imake rules allow for only 3 SRCS */
XSRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4)
X
XSingleProgramTarget(x2pic,$(OBJS2),,)
XInstallProgram(x2pic, $(BINDIR))
XInstallManPage(x2pic, $(MANDIR))
X
XSingleProgramTarget(x2ps,$(OBJS3),,$(MATHLIB))
XInstallProgram(x2ps, $(BINDIR))
XInstallManPage(x2ps, $(MANDIR))
X
XSingleProgramTarget(x2tpic,$(OBJS4),,)
XInstallProgram(x2tpic, $(BINDIR))
XInstallManPage(x2tpic, $(MANDIR))
X
XInstallScript(x2tex, $(BINDIR))
XInstallManPage(x2tex, $(MANDIR))
X
Xlint:
X (lint -abz $(SRCS1) -lXw -lXt -lX11 -lm $(LINTFLAGS); \
X lint -abz $(SRCS2) $(LINTFLAGS); \
X lint -abz $(SRCS3) -lm $(LINTFLAGS); \
X lint -abz $(SRCS4) $(LINTFLAGS)) | \
X ./xlint
X
Xclean::
X $(RM) tune.h.new xpic.man x2ps.man x2pic.man x2tpic.man x2tex.man
X
Xid: tags
X mkid *.[ch]
X
Xinstall::
X -mkdir $(XPICLIBDIR)
X $(INSTALL) -c $(INSTAPPFLAGS) x2ps.pro $(XPICLIBDIR)
X $(INSTALL) -c $(INSTAPPFLAGS) x2ps.tra $(XPICLIBDIR)
X -mkdir $(XPICLIBDIR)/fontdesc
X $(INSTALL) -c $(INSTAPPFLAGS) fontdesc/xpic $(XPICLIBDIR)/fontdesc
X $(INSTALL) -c $(INSTAPPFLAGS) fontdesc/x2pic $(XPICLIBDIR)/fontdesc
X $(INSTALL) -c $(INSTAPPFLAGS) fontdesc/x2tpic $(XPICLIBDIR)/fontdesc
X $(INSTALL) -c $(INSTAPPFLAGS) fontdesc/x2ps $(XPICLIBDIR)/fontdesc
X
Xinstall::
X -rm -r $(DOCDIR)/xpic
X -cp -r doc $(DOCDIR)/xpic
X
Xtar:
X cd ..; tar cvfX - xpic/ExcludeFiles xpic | compress > xpic.tar.Z
X
Xtune.h: Makefile
X echo \#define LIBDIR \"$(XPICLIBDIR)\" > tune.h.new
X echo \#define PROGRAMNAME \"$(BINDIR)/xpic\" >> tune.h.new
X echo \#define DUMPDIR \"$(DUMPDIR)\" >> tune.h.new
X -cmp -s tune.h.new tune.h || cp tune.h.new tune.h
END_OF_FILE
if test 5800 -ne `wc -c <'xpic/Imakefile'`; then
echo shar: \"'xpic/Imakefile'\" unpacked with wrong size!
fi
# end of 'xpic/Imakefile'
fi
if test -f 'xpic/arc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/arc.c'\"
else
echo shar: Extracting \"'xpic/arc.c'\" \(4811 characters\)
sed "s/^X//" >'xpic/arc.c' <<'END_OF_FILE'
X#ifndef FASTARCS
X
X#include <X11/Xlib.h>
X#include <math.h>
X
X/*
X * The R3 miarc.c code, which is used to draw arcs in the X server is very
X * slow, on Suns and uVaxen at least. (It uses iterative solution of
X * transcendentals to try to be faithful to the protocol) Instead, we use a
X * fast approximation that computes upto MAXPOINTS points on an arc and draws
X * a lines between them. Two calls each to sin(), cos(), and some floating
X * point math (could probably be done in fixed point or integer if you don't
X * have a math chip). These arcs don't follow the X protocol precisely, but
X * look reasonable.
X */
X/* Author: D. A. Cahlander, <dac at earth.cray.com> 89/02/21 */
X/*
X * Last Modified: Mark Moraes, <moraes at csri.toronto.edu> 89/03/23 to
X * generalize for elliptical arc drawing as a plug compatible
X * substitute for Xlib XDrawArc()/XFillArc()/XDrawArcs()/XFillArcs()
X */
X
X/* Basic idea: By representing a ellipse as:
X
X x = a * cos(t)
X y = b * sin(t)
X
X t can be divided into a small number of lines and represent the arc to
X "display precision" with 15-20 lines. (More than 20 if it was a large
X arc.)
X
X let dt be the delta angle
X dc = cos(dt)
X ds = sin(dt)
X
X x1 dc -ds x0
X = x
X y1 ds dc y0
X
X or
X x(i+1) = dc*x(i) - ds*y(i)
X y(i+1) = ds*x(i) + dc*y(i)
X
X with the actual (x,y) being:
X
X x = xc + x(i)
X y = yc + y(i)
X */
X
X
X#define MAXPOINTS 99
X
Xstatic drawarc(dpy, d, gc, x1, y1, width, height, angle1, angle2, fill)
XDisplay *dpy;
XDrawable d;
XGC gc;
Xint x1, y1;
Xunsigned int width, height;
Xint angle1, angle2;
Xint fill;
X{
X XPoint points[MAXPOINTS + 2];
X int npoints;
X int i;
X double xc, yc;
X double ang;
X#ifdef ELLIPSE_WITHIN_BBOX
X double delta;
X#endif /* ELLIPSE_WITHIN_BBOX */
X double t, xt, yt, dc, ds;
X double xr, yr;
X
X#define DEG_180 (180*64)
X#define DEG_360 (360*64)
X#define DEG_720 (720*64)
X
X if (angle2 > DEG_360)
X angle2 = DEG_360;
X
X /*
X * compute number of points needed for "good" display precision
X */
X npoints = M_PI * sqrt((double) (width + height) / 2.0);
X npoints = npoints < 8 ? 8 : npoints;
X npoints = (npoints * ((angle2 < 0) ? -angle2 : angle2) + DEG_720 - 1)
X / DEG_360;
X npoints = npoints > MAXPOINTS ? MAXPOINTS : npoints;
X /* angle between polygon points */
X ang = angle2 * M_PI / (DEG_180 * (npoints - 1));
X dc = cos(ang);
X ds = - sin(ang);
X
X if (angle1 == 0) {
X xt = 1.0;
X yt = 0.0;
X } else {
X ang = angle1 * M_PI / DEG_180; /* start angle vector */
X xt = cos(ang);
X yt = - sin(ang);
X }
X
X#ifdef ELLIPSE_WITHIN_BBOX
X /*
X * Warning - possibly non-portable code. Uses internal details of GC
X * struct
X */
X delta = gc->values.line_width / 2.0;
X#endif /* ELLIPSE_WITHIN_BBOX */
X
X /* radius of arc */
X xr = width / 2.0;
X yr = height / 2.0;
X
X /* center of arc */
X xc = x1 + xr;
X yc = y1 + yr;
X
X#ifdef ELLIPSE_WITHIN_BBOX
X xr = (xr > delta) ? xr - delta : delta;
X yr = (yr > delta) ? yr - delta : delta;
X#endif /* ELLIPSE_WITHIN_BBOX */
X
X i = 0;
X
X /*
X * Warning - possibly non-portable code. Uses internal details of GC
X * struct
X */
X if (fill && angle2 != DEG_360 && gc->values.arc_mode == ArcPieSlice) {
X points[i].x = xc;
X points[i].y = yc;
X i++;
X }
X
X for (; i < npoints; i ++) { /* compute polygon points */
X points[i].x = xc + xr * xt + (xt >= 0. ? .5 : -.5);
X points[i].y = yc + yr * yt + (yt >= 0. ? .5 : -.5);
X t = dc * xt - ds * yt; /* rotate vector */
X yt = ds * xt + dc * yt;
X xt = t;
X }
X
X if (fill)
X XFillPolygon(dpy, d, gc, points, npoints, Convex,
X CoordModeOrigin);
X else
X XDrawLines(dpy, d, gc, points, npoints, CoordModeOrigin);
X#undef DEG_180
X#undef DEG_360
X#undef DEG_720
X}
X
XXDrawArc(dpy, d, gc, x1, y1, width, height, angle1, angle2)
XDisplay *dpy;
XDrawable d;
XGC gc;
Xint x1, y1;
Xunsigned int width, height;
Xint angle1, angle2;
X{
X drawarc(dpy, d, gc, x1, y1, width, height, angle1, angle2, 0);
X}
X
XXDrawArcs(dpy, d, gc, arcs, n_arcs)
XDisplay *dpy;
XDrawable d;
XGC gc;
XXArc *arcs;
Xint n_arcs;
X{
X register XArc *arcp;
X
X for(arcp = arcs; n_arcs > 0; n_arcs--)
X drawarc(dpy, d, gc, (int) (arcp->x), (int) (arcp->y),
X (unsigned int) (arcp->width), (unsigned int) (arcp->height),
X (int) (arcp->angle1), (int) (arcp->angle2), 0);
X}
X
XXFillArc(dpy, d, gc, x1, y1, width, height, angle1, angle2)
XDisplay *dpy;
XDrawable d;
XGC gc;
Xint x1, y1;
Xunsigned int width, height;
Xint angle1, angle2;
X{
X drawarc(dpy, d, gc, x1, y1, width, height, angle1, angle2, 1);
X}
X
XXFillArcs(dpy, d, gc, arcs, n_arcs)
XDisplay *dpy;
XDrawable d;
XGC gc;
XXArc *arcs;
Xint n_arcs;
X{
X register XArc *arcp;
X
X for(arcp = arcs; n_arcs > 0; n_arcs--)
X drawarc(dpy, d, gc, (int) (arcp->x), (int) (arcp->y),
X (unsigned int) (arcp->width), (unsigned int) (arcp->height),
X (int) (arcp->angle1), (int) (arcp->angle2), 1);
X}
X#endif /* FASTARCS */
END_OF_FILE
if test 4811 -ne `wc -c <'xpic/arc.c'`; then
echo shar: \"'xpic/arc.c'\" unpacked with wrong size!
fi
# end of 'xpic/arc.c'
fi
if test -f 'xpic/defs.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/defs.h'\"
else
echo shar: Extracting \"'xpic/defs.h'\" \(5138 characters\)
sed "s/^X//" >'xpic/defs.h' <<'END_OF_FILE'
X#ifndef __XPIC_DEFS_H__
X#define __XPIC_DEFS_H__
X/*
X * Some basic functions
X */
X#ifndef MAX
X#define MAX(x,y) (((x) > (y)) ? (x) : (y))
X#endif
X#ifndef MIN
X#define MIN(x,y) (((x) < (y)) ? (x) : (y))
X#endif
X#ifndef ABS
X#define ABS(x) (((x) >= 0) ? (x) : -(x))
X#endif
X#ifndef SGN
X#define SGN(x) (((x) > 0) ? 1 : (((x) < 0) ? -1 : 0))
X#endif
X/*
X * Modulo function giving non-negative result
X */
X#ifndef IMOD
X#define IMOD(x,y) (((x) % (y)) >= 0 ? ((x) % (y)) : ((x) % (y)) + (y))
X#endif
X
X/*
X * Range checking - between lo & hi, inclusive
X */
X#define IN_RANGE(x, lo, hi) ((lo) <= (x) && (x) <= (hi))
X
X/*
X * Two different strings are often different on the first char.
X */
X#define STREQ(s1, s2) ((*s1)==(*s2) && strcmp(s1, s2) == 0)
X#define STRLT(s1, s2) (strcmp(s1, s2) < 0)
X#define STRGT(s1, s2) (strcmp(s1, s2) > 0)
X
X#define BOOL int
X
X#define YES 1
X#define NO 0
X#define ABORT -1 /* Returned by the get_input routine */
X
X#ifndef TRUE
X#define TRUE 1
X#endif
X#ifndef FALSE
X#define FALSE 0
X#endif
X
X#define MAXSTR 64
X
X/* 'snap' rounds x to the nearest number divisible by dx */
X#define snap(x, dx) (((int) (((x) + (dx / 2)) / dx)) * dx)
X
X/*
X * The basic unit of scale is the separation of the grid points on the
X * screen. Crosses are spaced every five grid points. I'm assuming the
X * crosses to be 0.5 inches apart, and determine sizes from that by
X * calculation. This simplifies drawing and re-scaling, I hope. It also
X * allows pictures displayed on a high-resolution screen to be displayed
X * on a screen of different resolution without changing the "snap". The
X * use of that bizarre unit - the inch - is purely because that's how
X * most of us still think of paper sizes.
X */
X
X#define DEFAULTSPACING 8 /*
X * For high resolution displays, it is
X * better to use 10, for low res, try 6
X */
X#define MINSPACING 2
X
X/* Letter size LaserWriter(tm) imaging area size, actually */
X#define DEFAULTPAGEHEIGHT 105 /* inches * 10 :-) */
X#define DEFAULTPAGEWIDTH 80
X#define MINPAGEHEIGHT 60 /* Paper can't get smaller than 6x6" */
X#define MINPAGEWIDTH 60
X
X/*
X * Defaults almost fill the screen of a Sun-3/50 Gives a nice round scale
X * factor, with 8 pixel spacing of grid points, 40 pixel spacing of the
X * crosses. Note that fonts are scaled for this grid spacing.
X */
X
X#define DEFAULTPICHEIGHT DEFAULTPAGEHEIGHT * DEFAULTSPACING;
X#define DEFAULTPICWIDTH DEFAULTPAGEWIDTH * DEFAULTSPACING;
X
X
X/*
X * This font MUST be available, or else xpic won't start up. Doesn't
X * really matter what it is though
X */
X
X#define DEFAULT_FONT "fixed"
X
X#define INC_VERTS 128 /* The blocks in which the verts buffer is increased */
X
X/* Increment in which a Buf increments itself */
X#define BUF_CHUNK 128
X
X/* Various types of gels */
X#define CELL 0
X#define LINE 1
X#define SPLINE 2
X#define BOX 3
X#define CIRCLE 4
X#define ELLIPSE 5
X#define TEXT 6
X/* Pseudo-objects - we use them during edit operations */
X#define BLOCK 7
X#define ELEMENT 8
X
X/* Using one nybble per attribute should leave enough room for expansion */
X#define getlinestyle(x) (x & 0x000f)
X#define SOLID 0x0000
X#define DOTTED 0x0001
X#define SDASH 0x0002
X#define LDASH 0x0003
X#define DDASH 0x0004
X#define NSTYLES 5
X
X#define getlinearrow(x) ((x & 0x00f0) >> 4)
X#define NO_ARROW 0x0000
X#define ST_ARROW 0x0010
X#define EN_ARROW 0x0020
X
X/* !!
X * Implementing this implies taking care of object ordering - what gets
X * drawn on top of what. Not yet done.
X */
X#define getfillstyle(x) ((x & 0x0f00) >> 8)
X#define EMPTY 0x0000
X#define GRAY0 0x0000
X#define GRAY1 0x0100
X#define GRAY2 0x0200
X#define GRAY3 0x0300
X#define GRAY4 0x0400
X#define GRAY5 0x0500
X#define GRAY6 0x0600
X#define GRAY7 0x0700
X#define GRAY8 0x0800
X#define GRAY9 0x0900
X#define NFILLSTYLES 10
X
X/* Text alignment is in two bits */
X#define HALIGN 0x3000
X#define gettext_halign(x) ((x & HALIGN) >> 12)
X#define CENTRE 0x0000
X#define LJUST 0x1000
X#define RJUST 0x2000
X
X#define VALIGN 0xc000
X#define gettext_valign(x) ((x & VALIGN) >> 14)
X#define MIDLINE 0x0000
X#define TOPLINE 0x4000
X#define BOTLINE 0x8000
X
X/* Marks the elements in a gel list which have been selected and discarded */
X#define SELECTED 0x0001
X/* Marks a hilited gel - makes unhilite safer! */
X#define HILITED 0x0002
X
X/* Cell.saved flags */
X#define SAVED 0x00
X#define MODIFIED 0x01
X#define NEWFILE 0x10
X
X/* These are or'ed with the event codes to give the event type */
X#define START_MODE 0x100
X#define END_MODE 0x200
X#define DRAG_MODE 0x300
X#define ASK_MODE 0x400
X
X/* Event codes */
X#define REDRAW 0x01
X#define MOTION 0x02
X#define LEFT 0x03
X#define RIGHT 0x04
X#define MIDDLE 0x05
X
X/* Various editing functions - either BLOCK or ELEMENT */
X#define COPY 1
X#define MOVE 2
X#define DELETE 3
X#define PASTE 4
X#define GET 5
X#define PUT 6
X#define ADJUST 7
X#define ROTATE 8
X#define SCALE 9
X#define CHANGE_ATTRIBUTE 10
X
X/* DrawGel can draw a Gel in one of these modes */
X#define DRAW 1
X#define ERASE 2
X#define INVERT 3
X#define HILITE 4
X
X#define MAKEPATTERN(style, dashlist) \
X ((style).pattern = (dashlist), (style).len = strlen(dashlist))
X
X#endif /* __XPIC_DEFS_H__ */ /* Do not add anything after this line */
END_OF_FILE
if test 5138 -ne `wc -c <'xpic/defs.h'`; then
echo shar: \"'xpic/defs.h'\" unpacked with wrong size!
fi
# end of 'xpic/defs.h'
fi
if test -f 'xpic/hash.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/hash.c'\"
else
echo shar: Extracting \"'xpic/hash.c'\" \(5105 characters\)
sed "s/^X//" >'xpic/hash.c' <<'END_OF_FILE'
X/*
X * A simple insertion-only hash routine for managing a single hash
X * table. Heavily modified and tuned from a piece of code by Ron Unrau
X * (ron at godzilla.ele.toronto.edu). Thanks Ron! It could be easily
X * generalized to do multiple hashtables simply by having InitHash
X * return a pointer to HashTable rather than maintain state in static
X * variables, and have the Insert and Search routines take that
X * pointer. Ron's hash function is pretty good for strings - it seems
X * to stand up well to small dense tables.
X */
X/*
X Compile with -DTEST to make it a standalone test program.
X Compile with -DPRINTHASH for information on the hash function
X Compile with -DHSTATS for information on collisions
X */
X#ifndef lint
Xstatic char *rcsid = "$Header: hash.c,v 1.2 88/08/31 23:42:21 moraes Exp $";
X#endif
X
X#include <stdio.h>
X#ifdef XPIC
X#include <X11/Xos.h>
X#endif
X
X#define STREQ(s1, s2) ((*s1)==(*s2) && strcmp(s1, s2) == 0)
X/* A hash table smaller than this is pretty worthless */
X#define MINSIZE 17
X#define MAXSTR 128
X
Xextern char *malloc();
Xextern char *realloc();
Xextern char *calloc();
X
X/*
X * The calling routines must malloc space for the key and datum - the
X * hash table just stores pointers
X */
Xtypedef struct {
X char *key;
X char *datum;
X} HashRec;
X
Xtypedef struct {
X HashRec *hashtable;
X int hashsize;
X int hashprobe;
X} HashTable;
X
Xstatic HashRec *hashtable = NULL;
Xstatic int hashsize;
Xstatic int hashprobe;
Xextern char *calloc();
Xextern char *malloc();
X
Xstatic hashindex (s)
Xregister char *s;
X{
X register int shift = 0;
X register int index = 0;
X
X#ifdef PRINTHASH
X (void) fprintf(stderr, "\"%s\" hashes to ", s);
X#endif
X while (*s != '\0') {
X index ^= *(s++) << shift;
X shift = (shift == 0) ? 8 : 0;
X }
X
X#ifdef PRINTHASH
X (void) fprintf(stderr, "%d ", index);
X#endif
X return index;
X}
X
X
X/* size should be a prime number */
XHashInit(size)
X{
X hashsize = (size < MINSIZE) ? MINSIZE : size;
X hashprobe = hashsize / 3;
X if (hashprobe * 3 == hashsize)
X hashprobe--;
X if (hashprobe % 2 == 0)
X hashprobe--;
X#ifdef HSTATS
X (void) fprintf(stderr, "size = %d probe = %d\n", hashsize, hashprobe);
X#endif
X if (hashtable)
X hashtable = (HashRec *) realloc((char *) hashtable,
X (unsigned) (hashsize * sizeof(HashRec)));
X else
X hashtable = (HashRec *) calloc((unsigned) size, sizeof(HashRec));
X if (hashtable)
X return;
X else {
X (void) fprintf(stderr, "Couldn't allocate %d bytes for hash table\n",
X size * sizeof(HashRec));
X exit(-1);
X }
X}
X
X/*
X * Will insert datum keyed by key in the table if key isn't already in
X * the table - otherwise, it will replace teh datum already in the
X * table for key with the new datum. It doesn't bother to free the old
X * datum, so this is a search of garbage, if the stuff was malloced.
X * Maybe we should return the old datum, so the caller can free it?
X */
XHashInsert (key, datum)
Xchar *key;
Xchar *datum;
X{
X register int hashval;
X register int index;
X register HashRec *hashptr = hashtable;
X register int countdown = hashsize;
X
X hashval = hashindex (key);
X index = hashval % hashsize;
X hashptr += index;
X while (hashptr->key && !STREQ(hashptr->key, key) && --countdown) {
X index = (index + hashprobe) % hashsize;
X hashptr = hashtable + index;
X }
X if (!hashptr->key) {
X hashptr->key = key;
X hashptr->datum = datum;
X#ifdef HSTATS
X (void) fprintf(stderr, "%d probes\n", hashsize - countdown);
X#endif
X } else if (countdown) {
X /* replace current value with new one */
X hashptr->datum = datum;
X#ifdef HSTATS
X (void) fprintf(stderr, "%d probes - replacing\n", hashsize-countdown);
X#endif
X } else {
X (void) fprintf(stderr, "Can't insert in hash table - help\n");
X exit(1);
X }
X}
X
Xchar *HashSearch (key)
Xchar *key;
X{
X register int hashval;
X register int index;
X register HashRec *hashptr = hashtable;
X register int countdown = hashsize;
X
X hashval = hashindex (key);
X index = hashval % hashsize;
X
X hashptr += index;
X while (hashptr->key && !STREQ (hashptr->key, key) && --countdown) {
X index = (index + hashprobe) % hashsize;
X hashptr = hashtable + index;
X }
X#ifdef HSTATS
X (void) fprintf(stderr, "%d probes - %s\n", hashsize - countdown,
X (hashptr->key && countdown) ? "found" : "not found");
X#endif
X if (hashptr->key && countdown)
X return (hashptr->datum);
X else
X return((char *) 0);
X}
X
Xchar *strsave(s)
Xchar *s;
X{
X char *s1 = malloc((unsigned) (strlen(s) + 1));
X
X if (s1)
X (void) strcpy(s1, s);
X return(s1);
X}
X
X
X#ifdef TEST
X#define prompt() if(prompt_p) printf(":"); else ;
Xmain()
X{
X char s1[8], s2[MAXSTR], s3[MAXSTR];
X char *result;
X int prompt_p;
X
X HashInit(128);
X prompt_p = isatty(fileno(stdin));
X prompt();
X while(scanf(" %s %s", s1, s2) == 2) {
X switch (*s1) {
X case 'a':
X scanf(" %s", s3);
X HashInsert(strsave(s2), strsave(s3));
X break;
X case 's':
X if (result = HashSearch(s2))
X printf("found %s\n", result);
X else
X printf("no match\n");
X break;
X case 'i':
X HashInit(atoi(s2));
X break;
X default:
X printf("'a string1 string2' inserts datum (string2) keyed by string1\n");
X printf("'s string1' prints the datum associated with string1 if any\n");
X break;
X }
X prompt();
X }
X}
X#endif
END_OF_FILE
if test 5105 -ne `wc -c <'xpic/hash.c'`; then
echo shar: \"'xpic/hash.c'\" unpacked with wrong size!
fi
# end of 'xpic/hash.c'
fi
if test -f 'xpic/make.out' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/make.out'\"
else
echo shar: Extracting \"'xpic/make.out'\" \(4879 characters\)
sed "s/^X//" >'xpic/make.out' <<'END_OF_FILE'
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c main.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c windows.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c xpic.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c handlers.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c input.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c event.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c grid.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c error.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c spline.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c newfonts.c
Xnewfonts.c: In function addfont:
Xnewfonts.c:186: warning: `addfont' was declared `extern' and later `static'
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c util.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c null.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c obj_line.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c obj_spline.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c obj_text.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c obj_box.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c obj_circ.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c obj_ell.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c obj_block.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c obj_elem.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c updown.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c text.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c ask.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c xtypeout.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c Minibuf.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c arc.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c box.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c focus.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c line.c
Xrm -f xpic
Xgcc -o xpic main.o windows.o xpic.o handlers.o input.o event.o grid.o error.o spline.o arrow.o newfonts.o util.o gels.o null.o obj_line.o obj_spline.o obj_text.o obj_box.o obj_circ.o obj_ell.o obj_block.o obj_elem.o updown.o text.o isqrt.o ask.o xtypeout.o Minibuf.o Window.o arc.o box.o focus.o line.o usleep.o /local/lib/X11/libXw.a /local/lib/X11/libXt.a /local/lib/X11/libX11.a -O -lm
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c x2ps.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c hash.c
Xrm -f x2ps
Xgcc -o x2ps x2ps.o hash.o -O -lm
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c x2pic.c
Xrm -f x2pic
Xgcc -o x2pic x2pic.o hash.o -O
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c x2tpic.c
Xgcc -O -I/csri3/X.V11R3/contrib/widgets/Xhp -I/csri3/X.V11R3 -Ibitmaps -I../fastmath -DXPIC -DMAGIC -DTYPEOUT -c xtp.c
Xrm -f x2tpic
Xgcc -o x2tpic x2tpic.o xtp.o hash.o -O
END_OF_FILE
if test 4879 -ne `wc -c <'xpic/make.out'`; then
echo shar: \"'xpic/make.out'\" unpacked with wrong size!
fi
# end of 'xpic/make.out'
fi
if test -f 'xpic/obj_circ.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/obj_circ.c'\"
else
echo shar: Extracting \"'xpic/obj_circ.c'\" \(4942 characters\)
sed "s/^X//" >'xpic/obj_circ.c' <<'END_OF_FILE'
X/* $Header: obj_circ.c,v 1.4 89/02/23 02:47:56 xwindows Exp $ */
X/*
X * The circle object routines
X */
X#include <math.h>
X
X#include "xpic.h"
X#include "windows.h"
X#include "spline.h"
X#include "gels.h"
X#include "draw.h"
X#include "input.h"
X#include "newfonts.h"
X#include "assert.h"
X
Xstatic int xmin, xmax, ymin, ymax; /* Bounding box */
Xstatic int xc, yc, xr, yr; /* centre, radius of circles, ellipse */
Xstatic int rad; /* radius of circle */
X
Xcircle_event(evtype, mx, my)
X{
X switch(evtype) {
X case MOTION | START_MODE:
X case RIGHT | START_MODE:
X case MIDDLE | START_MODE:
X case REDRAW | START_MODE:
X case RIGHT | END_MODE:
X break;
X case MOTION | END_MODE:
X ellipse(picWin, xc, yc, rad, rad, gcInvert);
X xr = mx - xc;
X yr = my - yc;
X rad = snap(isqrt(xr*xr + yr*yr), mouseResolution);
X if (rad == 0)
X rad = mouseResolution;
X ellipse(picWin, xc, yc, rad, rad, gcInvert);
X break;
X case LEFT | START_MODE:
X xc = mx;
X yc = my;
X rad = mouseResolution;
X drawingMode = END_MODE;
X ellipse(picWin, xc, yc, rad, rad, gcInvert);
X break;
X case LEFT | END_MODE:
X ellipse(picWin, xc, yc, rad, rad, gcInvert);
X xr = mx - xc;
X yr = my - yc;
X rad = snap(isqrt(xr*xr + yr*yr), mouseResolution);
X if (rad == 0)
X rad = mouseResolution;
X xmin = xc - rad;
X xmax = xc + rad;
X ymin = yc - rad;
X ymax = yc + rad;
X ellipse(picWin, xc, yc, rad, rad, gcNormal);
X AddConicGel(&(CurrentCell->gelList), CIRCLE, xc, yc, rad, rad,
X line_type | fill_type, xmin, ymin, xmax, ymax, lineThickness);
X FreeGel(CurrentCell->undoList);
X CurrentCell->undoList = NULL;
X CurrentCell->undo = 1;
X CurrentCell->saved |= MODIFIED;
X drawingMode = START_MODE;
X break;
X case MIDDLE | END_MODE:
X ellipse(picWin, xc, yc, rad, rad, gcInvert);
X drawingMode = START_MODE;
X break;
X case REDRAW | END_MODE:
X ellipse(picWin, xc, yc, rad, rad, gcInvert);
X break;
X default:
X#ifdef DEBUG
X (void) sprintf(errstring, "Hey! Unknown CIRCLE mode %d", drawingMode);
X message(errstring);
X#endif
X break;
X }
X ASSERT(allock(), "circle_event");
X}
X
X
Xcircle_abort()
X{
X circle_event((MIDDLE | drawingMode), 0, 0);
X}
X
X
Xcircle_adj(evtype, gel, mx, my)
Xint evtype;
XGel *gel;
Xint mx, my;
X{
X static Gel *circgel;
X /*
X * Will not need to process MOTION|START_MODE, RIGHT|START_MODE,
X * REDRAW|START_MODE - these are taken care of in
X * the adj_element routine.
X */
X switch(evtype) {
X case MOTION | END_MODE:
X ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X xr = mx - xc;
X yr = my - yc;
X rad = snap(isqrt(xr*xr + yr*yr), mouseResolution);
X if (rad == 0)
X rad = mouseResolution;
X ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X break;
X case LEFT | START_MODE:
X xc = ((Conic *)gel->data)->centre.x;
X yc = ((Conic *)gel->data)->centre.y;
X rad = ((Conic *)gel->data)->xrad;
X circgel = gel;
X drawingMode = END_MODE;
X setwidth(tmpGcNormal, circgel->linewidth);
X setwidth(tmpGcInvert, circgel->linewidth);
X SETDASHES(tmpGcNormal, getlinestyle(circgel->attributes))
X SETDASHES(tmpGcInvert, getlinestyle(circgel->attributes))
X ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X break;
X case LEFT | END_MODE:
X ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X xr = mx - xc;
X yr = my - yc;
X rad = snap(isqrt(xr*xr + yr*yr), mouseResolution);
X if (rad == 0)
X rad = mouseResolution;
X xmin = xc - rad;
X xmax = xc + rad;
X ymin = yc - rad;
X ymax = yc + rad;
X ellipse(picWin, xc, yc, rad, rad, tmpGcNormal);
X AddConicGel(&(CurrentCell->gelList), CIRCLE, xc, yc, rad, rad,
X circgel->attributes, xmin, ymin, xmax, ymax, circgel->linewidth);
X FreeGel(CurrentCell->undoList);
X CurrentCell->undoList = circgel;
X circgel = NULL;
X CurrentCell->undo = 1;
X CurrentCell->saved |= MODIFIED;
X drawingMode = START_MODE;
X break;
X case RIGHT | END_MODE:
X case MIDDLE | END_MODE:
X ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X GelDraw(circgel, DRAW);
X (void) PushUnderUndo(&(CurrentCell->gelList), circgel,
X CurrentCell->undo);
X circgel = NULL;
X if (evtype == (MIDDLE | END_MODE))
X ClearGelFlags(CurrentCell->gelList);
X drawingMode = START_MODE;
X break;
X case MIDDLE | START_MODE:
X ClearGelFlags(CurrentCell->gelList);
X break;
X case REDRAW | END_MODE:
X ellipse(picWin, xc, yc, rad, rad, tmpGcInvert);
X break;
X default:
X#ifdef DEBUG
X (void) sprintf(errstring, "Hey! Unknown mode %d in circle_adj",
X evtype);
X message(errstring);
X#endif
X break;
X }
X ASSERT(allock(), "circle_adj");
X}
X
X/*
X * Finds distance of point from an circle. This is the distance to the
X * intersection of the line from the point to the centre of the circle.
X */
Xint
Xcircle_distance(gel, xp, yp)
XGel *gel;
Xint xp, yp;
X{
X int dist;
X Conic *conic = (Conic *) gel->data;
X double r = conic->xrad;
X int dy = (yp - conic->centre.y);
X int dx = (xp - conic->centre.x);
X
X if (dx == 0) {
X dist = ABS(dy) - conic->yrad;
X } else if (dy == 0) {
X dist = ABS(dx) - conic->xrad;
X } else {
X dist = sqrt((double) (dx * dx + dy * dy)) - r;
X }
X dist = ABS(dist);
X return(dist);
X}
END_OF_FILE
if test 4942 -ne `wc -c <'xpic/obj_circ.c'`; then
echo shar: \"'xpic/obj_circ.c'\" unpacked with wrong size!
fi
# end of 'xpic/obj_circ.c'
fi
if test -f 'xpic/obj_ell.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/obj_ell.c'\"
else
echo shar: Extracting \"'xpic/obj_ell.c'\" \(5859 characters\)
sed "s/^X//" >'xpic/obj_ell.c' <<'END_OF_FILE'
X/* $Header: obj_ell.c,v 1.3 89/02/23 02:48:02 xwindows Exp $ */
X/*
X * The ellipse object routines
X */
X#include <math.h>
X
X#include "xpic.h"
X#include "windows.h"
X#include "gels.h"
X#include "draw.h"
X#include "assert.h"
X
Xstatic int x_1, y_1, x_2, y_2; /* Corners of box, ellipse, ends of line */
Xstatic int xmin, xmax, ymin, ymax; /* Bounding box */
Xstatic int xc, yc, xr, yr; /* centre, radius of circles, ellipse */
X
Xellipse_event(evtype, mx, my)
X{
X switch(evtype) {
X case MOTION | START_MODE:
X case RIGHT | START_MODE:
X case MIDDLE | START_MODE:
X case REDRAW | START_MODE:
X case RIGHT | END_MODE:
X break;
X case MOTION | END_MODE:
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X ellipse(picWin, xc, yc, xr, yr, gcInvert);
X x_2 = mx;
X y_2 = my;
X xc = (x_2 + x_1) / 2;
X yc = (y_2 + y_1) / 2;
X xr = ABS(x_2 - xc);
X yr = ABS(y_2 - yc);
X ellipse(picWin, xc, yc, xr, yr, gcInvert);
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X break;
X case LEFT | START_MODE:
X x_1 = x_2 = xc = mx;
X y_1 = y_2 = yc = my;
X xr = yr = 0;
X drawingMode = END_MODE;
X ellipse(picWin, xc, yc, xr, yr, gcInvert);
X break;
X case LEFT | END_MODE:
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X ellipse(picWin, xc, yc, xr, yr, gcInvert);
X x_2 = mx;
X y_2 = my;
X xc = (x_2 + x_1) / 2;
X yc = (y_2 + y_1) / 2;
X xr = ABS(x_2 - xc);
X yr = ABS(y_2 - yc);
X xmin = MIN(x_1, mx);
X xmax = MAX(x_1, mx);
X ymin = MIN(y_1, my);
X ymax = MAX(y_1, my);
X ellipse(picWin, xc, yc, xr, yr, gcNormal);
X AddConicGel(&(CurrentCell->gelList), ELLIPSE, xc, yc, xr, yr,
X line_type | fill_type, xmin, ymin, xmax, ymax, lineThickness);
X FreeGel(CurrentCell->undoList);
X CurrentCell->undoList = NULL;
X CurrentCell->undo = 1;
X CurrentCell->saved |= MODIFIED;
X drawingMode = START_MODE;
X break;
X case MIDDLE | END_MODE:
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X ellipse(picWin, xc, yc, xr, yr, gcInvert);
X drawingMode = START_MODE;
X break;
X case REDRAW | END_MODE:
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X ellipse(picWin, xc, yc, xr, yr, gcInvert);
X break;
X default:
X#ifdef DEBUG
X (void) sprintf(errstring, "Unknown ELLIPSE mode %d", drawingMode);
X message(errstring);
X#endif
X break;
X }
X ASSERT(allock(), "ellipse_event");
X}
X
X
Xellipse_abort()
X{
X ellipse_event((MIDDLE | drawingMode), 0, 0);
X}
X
X
Xellipse_adj(evtype, gel, mx, my)
Xint evtype;
XGel *gel;
Xint mx, my;
X{
X static Gel *ellgel;
X /*
X * Will not need to process MOTION|START_MODE, RIGHT|START_MODE,
X * REDRAW|START_MODE - these are taken care of in
X * the adj_element routine.
X */
X switch(evtype) {
X case MOTION | END_MODE:
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X x_2 = mx;
X y_2 = my;
X xc = (x_2 + x_1) / 2;
X yc = (y_2 + y_1) / 2;
X xr = ABS(x_2 - xc);
X yr = ABS(y_2 - yc);
X ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X break;
X case LEFT | START_MODE:
X GetBoxCorners(&x_1, &y_1, &x_2, &y_2, &gel->b_box, mx, my);
X xc = (x_1 + x_2) / 2;
X yc = (y_1 + y_2) / 2;
X xr = ABS(x_2 - xc);
X yr = ABS(y_2 - yc);
X ellgel = gel;
X drawingMode = END_MODE;
X setwidth(tmpGcNormal, ellgel->linewidth);
X setwidth(tmpGcInvert, ellgel->linewidth);
X SETDASHES(tmpGcNormal, getlinestyle(ellgel->attributes))
X SETDASHES(tmpGcInvert, getlinestyle(ellgel->attributes))
X ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X break;
X case LEFT | END_MODE:
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X x_2 = mx;
X y_2 = my;
X xc = (x_2 + x_1) / 2;
X yc = (y_2 + y_1) / 2;
X xr = ABS(x_2 - xc);
X yr = ABS(y_2 - yc);
X xmin = MIN(x_1, mx);
X xmax = MAX(x_1, mx);
X ymin = MIN(y_1, my);
X ymax = MAX(y_1, my);
X ellipse(picWin, xc, yc, xr, yr, tmpGcNormal);
X AddConicGel(&(CurrentCell->gelList), ELLIPSE, xc, yc, xr, yr,
X ellgel->attributes, xmin, ymin, xmax, ymax, ellgel->linewidth);
X FreeGel(CurrentCell->undoList);
X CurrentCell->undoList = ellgel;
X ellgel = NULL;
X CurrentCell->undo = 1;
X CurrentCell->saved |= MODIFIED;
X drawingMode = START_MODE;
X break;
X case RIGHT | END_MODE:
X case MIDDLE | END_MODE:
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X GelDraw(ellgel, DRAW);
X (void) PushUnderUndo(&(CurrentCell->gelList), ellgel,
X CurrentCell->undo);
X ellgel = NULL;
X if (evtype == (MIDDLE | END_MODE))
X ClearGelFlags(CurrentCell->gelList);
X drawingMode = START_MODE;
X break;
X case MIDDLE | START_MODE:
X ClearGelFlags(CurrentCell->gelList);
X break;
X case REDRAW | END_MODE:
X box(picWin, x_1, y_1, x_2, y_2, gcBlock);
X ellipse(picWin, xc, yc, xr, yr, tmpGcInvert);
X break;
X default:
X#ifdef DEBUG
X (void) sprintf(errstring, "Unknown mode %d in ellipse_adj",
X evtype);
X message(errstring);
X#endif
X break;
X }
X ASSERT(allock(), "ellipse_adj");
X}
X
X/*
X * Finds distance of point from an ellipse. This is taken as distance to the
X * intersection of the line from the point to the centre of the ellipse. It's
X * a fudge, because I don't know of a closed form solution to the problem of
X * finding the perpendicular distance of a point from an ellipse, and I really
X * don't want to iterate.
X */
Xint
Xellipse_distance(gel, xp, yp)
XGel *gel;
Xint xp, yp;
X{
X int dist;
X Conic *conic = (Conic *) gel->data;
X double a = conic->xrad;
X double b = conic->yrad;
X double slope;
X int dy = (yp - conic->centre.y);
X int dx = (xp - conic->centre.x);
X double xm, ym;
X
X if (dx == 0) {
X dist = ABS(dy) - conic->yrad;
X dist = ABS(dist);
X } else if (dy == 0) {
X dist = ABS(dx) - conic->xrad;
X dist = ABS(dist);
X } else {
X slope = dy;
X slope /= dx;
X xm = 1.0 / sqrt(1.0 / (a * a) + (slope * slope) / (b * b));
X if (dx < 0)
X xm = -xm;
X ym = slope * xm + conic->centre.y;
X xm += conic->centre.x;
X dist = sqrt((xp - xm) * (xp - xm) + (yp - ym) * (yp - ym));
X }
X return(dist);
X}
END_OF_FILE
if test 5859 -ne `wc -c <'xpic/obj_ell.c'`; then
echo shar: \"'xpic/obj_ell.c'\" unpacked with wrong size!
fi
# end of 'xpic/obj_ell.c'
fi
if test -f 'xpic/test/rayan.ps' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/test/rayan.ps'\"
else
echo shar: Extracting \"'xpic/test/rayan.ps'\" \(5235 characters\)
sed "s/^X//" >'xpic/test/rayan.ps' <<'END_OF_FILE'
X%!
X%%Creator: root at bay.csri (Operator)
X%%Title: rayan.xpic (xpic)
X%%CreationDate: Wed May 4 23:51:39 1988
X%%Pages: 1
X%%DocumentFonts: (atend)
X%%BoundingBox: 28.8 28.8 561.6 669.6
X% (in inches) at 0.4 0.4, width 7.4, height 8.9
X%%EndComments
X% Prolog for xpic to PostScript converter
X% Author: Mark Moraes
X% $Header: x2ps.pro,v 1.2 88/03/19 16:50:09 moraes Exp
X% %d D - change style SOLID, DOTTED, SHORT-DASH, LONG-DASH, DOT-DASH
X% %d F - change font ROMAN, BOLD, ITALIC, SPECIAL
X% %d S - change size (font size in points)
X% (%s) rj %d t - text right just. (%d is TOPLINE, MIDLINE, BOTLINE)
X% (%s) lj %d t - text left just. (%d is TOPLINE, MIDLINE, BOTLINE)
X% (%s) ce %d t - text centered (%d is TOPLINE, MIDLINE, BOTLINE)
X% %d %d l - lineto
X% %d %d m - moveto
X% %d %d s - spline segment
X% x - flush line, spline
X% <wid> <ht> <x> <y> b - box
X% <wid> <ht> <x> <y> e - ellipse
X% %d ss - setscale
X% %d W - change linewidth
Xsave 50 dict begin /xpic exch def
X/StartXpic {newpath 0 0 moveto [] 0 setdash 0 setgray 1 setlinecap} def
X% Set defaults
X/fontname /Times-Roman def
X/ptsize 12 def
X% xpic has 4 fonts R, B, I, S
X/nfonts 4 def
X/fonts /Times-Roman /Times-Bold /Times-Italic /Symbol nfonts array astore def
X% halign has the values for MIDLINE, TOPLINE, BOTLINE
X/halign 3 array def
X/s {rcurveto} def
X/x {stroke} def
X/l {lineto} def
X/m {moveto} def
X/b {
X /ury exch def /urx exch def /lly exch def /llx exch def
X llx lly moveto urx lly lineto urx ury lineto
X llx ury lineto llx lly lineto stroke
X} def
X/mtrx matrix def
X/e {
X /yc exch def /xc exch def /yrad exch def /xrad exch def
X xc xrad add yc moveto
X /savematrix mtrx currentmatrix def
X xc yc translate
X xrad yrad scale
X 0 0 1 0 360 arc
X savematrix setmatrix stroke
X} def
X% The next three take the text string, and moveto the right horiz. position
X% leaving the string on the stack.
X/lj {} def
X/rj {dup stringwidth pop neg 0 rmoveto} def
X/ce {dup stringwidth pop 2 div neg 0 rmoveto} def
X% And this is invoked after one of the three above, and
X% computes the vert. pos, and then displays the string.
X/t {halign exch get 0 exch rmoveto show newpath} def
X% Store an array of patterns in /styles - a pattern is an array consisting
X% of an array and an offset. Corresp to xpic patterns
X% solid, dotted, short-dashed, long-dashed, dot-dashed
X/styles [ [] 0 ] [ [1 3] 0 ] [ [4 4] 0 ] [ [8 4] 0 ] [ [1 4 4 4] 0 ]
X 5 array astore def
X% change style to arg.
X/D {stroke styles exch get aload pop setdash newpath} def
X/W {stroke setlinewidth newpath} def
X% fontbox takes a fontname of the stack, and returns an array
X% containing the values of the bottom line of the bounding box, the
X% mid line of the bounding box, and the top line of the bounding box
X% of that font, taken from the baseline, scaled to a font of size 1
X/fontbox {
X findfont dup /FontMatrix get /fm exch def /FontBBox get aload pop
X /ytop exch def pop /ybot exch def pop
X /ymid ytop ybot sub 2 div def
X 0 ybot fm dtransform exch pop % botline
X dup neg exch % midline - this works better than (ytop-ybot)/2!
X 0 ytop fm dtransform exch pop exch %topline
X % now in the order midline, topline, botline.
X 3 array astore
X} def
X% fontboxes stores the fontbox of each of the fontnames in the 'fonts'
X% array
X/fontboxes nfonts array def
X0 1 nfonts 1 sub {
X fontboxes exch dup fonts exch get fontbox put
X} for
X% select font
X/F {
X dup fonts exch get /fontname exch def fontboxes exch get
X /thisfontbox exch def SF
X} def
X% set point size
X/S {/ptsize exch def SF} def
X% actually set font
X/SF {
X fontname findfont ptsize curscale div scalefont setfont
X thisfontbox aload pop
X 1 1 3 {
X pop ptsize mul curscale div neg 3 1 roll
X } for
X halign astore pop
X} def
X% sets the scale to 72 / n, where n is on the stack, and stores the value
X% in curscale for font scaling
X/curscale 1 def
X/ss {/curscale exch 72 exch div dup dup scale def} def
X/land {8.5 72 mul curscale div 0 translate 90 rotate} def
XStartXpic
X%%EndProlog
X1 1 scale
X80 ss
X0 D
X215 352 m
X0 D
X224 349 m
X215 352 l
X224 356 l
X0 D
X215 352 m
X447 352 l
X0 D
X439 356 m
X447 352 l
X439 349 l
X0 D
X447 352 m
Xx
X2 D
X47 224 m
X279 80 l
X0 D
X275 88 m
X279 80 l
X270 81 l
X2 D
X279 80 m
Xx
X1 D
X79 120 m
X0 D
X82 130 m
X79 120 l
X74 128 l
X1 D
X79 120 m
X47 320 l
Xx
X575 640 m
X511 520 l
X599 592 l
Xx
X3 D
X599 696 m
X607 424 l
X535 528 l
X631 568 l
X583 512 l
X583 568 l
X639 512 l
Xx
X0 D
X88 88 439 656 e
X287 624 m
X383 488 l
X447 504 l
Xx
X279 584 m
X375 448 l
X439 464 l
Xx
X311 680 m
X407 544 l
X471 560 l
Xx
X239 528 m
X335 392 l
X399 408 l
Xx
X135 576 m
X351 576 l
X479 392 l
Xx
X223 664 m
X0 0 17 -2 52 -8 s
X34 -5 61 -24 80 -56 s
X18 -32 -8 -70 -80 -116 s
X-72 -45 -114 -33 -128 36 s
X-13 69 -2 116 32 140 s
X34 24 52 21 52 -8 s
X0 -29 17 -30 52 -4 s
X34 26 78 21 132 -16 s
X53 -37 58 -76 16 -116 s
X-42 -40 -30 -58 36 -56 s
X66 2 84 -25 52 -84 s
X-32 -58 -102 -94 -212 -108 s
X-109 -13 -164 8 -164 64 s
X0 56 -9 86 -28 92 s
X-18 5 -32 -20 -40 -76 s
X-8 -56 68 -116 228 -180 s
Xx
X2 F
X20 S
X423 496 m
X(This is more text) ce 0 t
X295 296 527 144 b
X12 S
X327 312 m
X(This is a box) ce 0 t
X0 F
X319 72 m
X(This is an ellipsis) ce 0 t
X164 44 331 76 e
X215 392 447 240 b
X%%Trailer
Xshowpage
X% Trailer for xpic to PostScript converter
X% $Header: x2ps.tra,v 1.1 87/11/21 20:33:03 moraes Exp $
Xxpic end restore
X%%DocumentFonts: Times-Roman Times-Italic Times-Bold Special
END_OF_FILE
if test 5235 -ne `wc -c <'xpic/test/rayan.ps'`; then
echo shar: \"'xpic/test/rayan.ps'\" unpacked with wrong size!
fi
# end of 'xpic/test/rayan.ps'
fi
if test -f 'xpic/test/testtext.ps' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xpic/test/testtext.ps'\"
else
echo shar: Extracting \"'xpic/test/testtext.ps'\" \(4867 characters\)
sed "s/^X//" >'xpic/test/testtext.ps' <<'END_OF_FILE'
X%!
X%%Creator: root at bay.csri (Operator)
X%%Title: testtext.xpic (xpic)
X%%CreationDate: Wed May 4 23:51:57 1988
X%%Pages: 1
X%%DocumentFonts: (atend)
X%%BoundingBox: 9 23.4 450 120.6
X% (in inches) at 0.125 0.325, width 6.125, height 1.35
X%%EndComments
X% Prolog for xpic to PostScript converter
X% Author: Mark Moraes
X% $Header: x2ps.pro,v 1.2 88/03/19 16:50:09 moraes Exp
X% %d D - change style SOLID, DOTTED, SHORT-DASH, LONG-DASH, DOT-DASH
X% %d F - change font ROMAN, BOLD, ITALIC, SPECIAL
X% %d S - change size (font size in points)
X% (%s) rj %d t - text right just. (%d is TOPLINE, MIDLINE, BOTLINE)
X% (%s) lj %d t - text left just. (%d is TOPLINE, MIDLINE, BOTLINE)
X% (%s) ce %d t - text centered (%d is TOPLINE, MIDLINE, BOTLINE)
X% %d %d l - lineto
X% %d %d m - moveto
X% %d %d s - spline segment
X% x - flush line, spline
X% <wid> <ht> <x> <y> b - box
X% <wid> <ht> <x> <y> e - ellipse
X% %d ss - setscale
X% %d W - change linewidth
Xsave 50 dict begin /xpic exch def
X/StartXpic {newpath 0 0 moveto [] 0 setdash 0 setgray 1 setlinecap} def
X% Set defaults
X/fontname /Times-Roman def
X/ptsize 12 def
X% xpic has 4 fonts R, B, I, S
X/nfonts 4 def
X/fonts /Times-Roman /Times-Bold /Times-Italic /Symbol nfonts array astore def
X% halign has the values for MIDLINE, TOPLINE, BOTLINE
X/halign 3 array def
X/s {rcurveto} def
X/x {stroke} def
X/l {lineto} def
X/m {moveto} def
X/b {
X /ury exch def /urx exch def /lly exch def /llx exch def
X llx lly moveto urx lly lineto urx ury lineto
X llx ury lineto llx lly lineto stroke
X} def
X/mtrx matrix def
X/e {
X /yc exch def /xc exch def /yrad exch def /xrad exch def
X xc xrad add yc moveto
X /savematrix mtrx currentmatrix def
X xc yc translate
X xrad yrad scale
X 0 0 1 0 360 arc
X savematrix setmatrix stroke
X} def
X% The next three take the text string, and moveto the right horiz. position
X% leaving the string on the stack.
X/lj {} def
X/rj {dup stringwidth pop neg 0 rmoveto} def
X/ce {dup stringwidth pop 2 div neg 0 rmoveto} def
X% And this is invoked after one of the three above, and
X% computes the vert. pos, and then displays the string.
X/t {halign exch get 0 exch rmoveto show newpath} def
X% Store an array of patterns in /styles - a pattern is an array consisting
X% of an array and an offset. Corresp to xpic patterns
X% solid, dotted, short-dashed, long-dashed, dot-dashed
X/styles [ [] 0 ] [ [1 3] 0 ] [ [4 4] 0 ] [ [8 4] 0 ] [ [1 4 4 4] 0 ]
X 5 array astore def
X% change style to arg.
X/D {stroke styles exch get aload pop setdash newpath} def
X/W {stroke setlinewidth newpath} def
X% fontbox takes a fontname of the stack, and returns an array
X% containing the values of the bottom line of the bounding box, the
X% mid line of the bounding box, and the top line of the bounding box
X% of that font, taken from the baseline, scaled to a font of size 1
X/fontbox {
X findfont dup /FontMatrix get /fm exch def /FontBBox get aload pop
X /ytop exch def pop /ybot exch def pop
X /ymid ytop ybot sub 2 div def
X 0 ybot fm dtransform exch pop % botline
X dup neg exch % midline - this works better than (ytop-ybot)/2!
X 0 ytop fm dtransform exch pop exch %topline
X % now in the order midline, topline, botline.
X 3 array astore
X} def
X% fontboxes stores the fontbox of each of the fontnames in the 'fonts'
X% array
X/fontboxes nfonts array def
X0 1 nfonts 1 sub {
X fontboxes exch dup fonts exch get fontbox put
X} for
X% select font
X/F {
X dup fonts exch get /fontname exch def fontboxes exch get
X /thisfontbox exch def SF
X} def
X% set point size
X/S {/ptsize exch def SF} def
X% actually set font
X/SF {
X fontname findfont ptsize curscale div scalefont setfont
X thisfontbox aload pop
X 1 1 3 {
X pop ptsize mul curscale div neg 3 1 roll
X } for
X halign astore pop
X} def
X% sets the scale to 72 / n, where n is on the stack, and stores the value
X% in curscale for font scaling
X/curscale 1 def
X/ss {/curscale exch 72 exch div dup dup scale def} def
X/land {8.5 72 mul curscale div 0 translate 90 rotate} def
XStartXpic
X%%EndProlog
X1 1 scale
X80 ss
X0 F
X12 S
X295 40 m
X(hello world) rj 2 t
X215 40 m
X(hello world) rj 1 t
X135 40 m
X(hello world) rj 0 t
X0 D
X287 40 m
X303 40 l
X295 40 l
X295 48 l
X295 32 l
Xx
X207 40 m
X223 40 l
X215 40 l
X215 48 l
X215 32 l
Xx
X127 40 m
X143 40 l
X135 40 l
X135 48 l
X135 32 l
Xx
X455 120 m
X(hello world) lj 2 t
X375 120 m
X(hello world) lj 1 t
X367 120 m
X383 120 l
X375 120 l
X375 128 l
X375 112 l
Xx
X295 120 m
X(hello world) lj 0 t
X215 120 m
X(hello world) ce 2 t
X135 120 m
X(hello world) ce 1 t
X55 120 m
X(hello world) ce 0 t
X447 120 m
X463 120 l
X455 120 l
X455 128 l
X455 112 l
Xx
X287 120 m
X303 120 l
X295 120 l
X295 128 l
X295 112 l
Xx
X207 120 m
X223 120 l
X215 120 l
X215 128 l
X215 112 l
Xx
X127 120 m
X143 120 l
X135 120 l
X135 128 l
X135 112 l
Xx
X47 120 m
X63 120 l
X55 120 l
X55 128 l
X55 112 l
Xx
X%%Trailer
Xshowpage
X% Trailer for xpic to PostScript converter
X% $Header: x2ps.tra,v 1.1 87/11/21 20:33:03 moraes Exp $
Xxpic end restore
X%%DocumentFonts: Times-Roman Times-Italic Times-Bold Special
END_OF_FILE
if test 4867 -ne `wc -c <'xpic/test/testtext.ps'`; then
echo shar: \"'xpic/test/testtext.ps'\" unpacked with wrong size!
fi
# end of 'xpic/test/testtext.ps'
fi
echo shar: End of archive 4 \(of 15\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 15 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
More information about the Comp.sources.x
mailing list