home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-06-19 | 41.0 KB | 1,574 lines |
- Path: j.cc.purdue.edu!mentor.cc.purdue.edu!noose.ecn.purdue.edu!samsung!zaphod.mps.ohio-state.edu!usc!apple!bbn.com!papaya.bbn.com!rsalz
- From: rsalz@bbn.com (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v23i017: Tools for creating TeX documents with portable graphics, Part04/06
- Message-ID: <2814@litchi.bbn.com>
- Date: 31 Aug 90 13:43:20 GMT
- Organization: BBN Systems and Technologies, Cambridge MA
- Lines: 1562
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: ae3f8421 b1d964da adbd526c 6f318e10
-
- Submitted-by: Micah Beck <beck@cs.cornell.edu>
- Posting-number: Volume 23, Issue 17
- Archive-name: transfig/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 6)."
- # Contents: transfig/fig2dev/dev/genlatex.c
- # transfig/fig2dev/dev/genps.c
- # Wrapped by beck@rocky on Thu May 17 15:56:13 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'transfig/fig2dev/dev/genlatex.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genlatex.c'\"
- else
- echo shar: Extracting \"'transfig/fig2dev/dev/genlatex.c'\" \(20332 characters\)
- sed "s/^X//" >'transfig/fig2dev/dev/genlatex.c' <<'END_OF_FILE'
- X/*
- X * genlatex.c : LaTeX driver for fig2dev
- X *
- X * Author: Frank Schmuck, Cornell University 6/88
- X * Converted from fig2latex 5/89 by Micah Beck
- X *
- X*/
- X#ifdef hpux
- X#include <sys/types.h>
- X#endif
- X#include <sys/file.h>
- X#include <stdio.h>
- X#include <math.h>
- X#include "object.h"
- X#include "fig2dev.h"
- X#include "texfonts.h"
- X
- Xextern char *strchr();
- Xextern void printf(), fprintf();
- Xextern double rad2deg, sin(), cos(), acos(), fabs(), atan();
- X
- X#ifdef hpux
- X#define rint(a) floor((a)+0.5) /* close enough? */
- X#endif
- X
- X#ifdef gould
- X#define rint(a) floor((a)+0.5) /* close enough? */
- X#endif
- X
- X/*
- X * Installation dependent constants:
- X *
- X * THINDOT latex command for generating a dot if line width = \thinlines
- X * THICKDOT latex command for generating a dot if line width = \thicklines
- X * MIN_LEN shortest slanted line that latex can produce; shorter lines will
- X * we translated into a sequence of dots generated by \multiput.
- X * THICK_LDOT latex command for generating the dot for making short slanted
- X * lines if line width = \thinlines
- X * THIN_LDOT ... if line width = \thicklines
- X */
- X#define THICKDOT "\\tenrm ."
- X#define THINDOT "\\sevrm ."
- Xdouble THIN_XOFF = (0.1/72.0);
- Xdouble THIN_YOFF = (0.7/72.0);
- Xdouble THICK_XOFF = (0.4/72.0);
- Xdouble THICK_YOFF = (0.6/72.0);
- X#define THICK_LDOT "\\sevrm ."
- X#define THIN_LDOT "\\fivrm ."
- Xdouble THIN_LXOFF = (0.1/72.0);
- Xdouble THIN_LYOFF = (0.7/72.0);
- Xdouble THICK_LXOFF = (0.4/72.0);
- Xdouble THICK_LYOFF = (0.6/72.0);
- X#define MIN_LEN (13.0/72.0) /* 13 points */
- X
- X/*
- X * other constants and macros
- X */
- X#define TOP 840
- X#define THINLINES 1
- X#define THICKLINES 2
- X
- X/*
- X * Cornell DVI-to-IP has trouble with circles of radius greater than 8pt.
- X */
- X#ifdef CORNELL
- X#define MAXCIRCLEDIA 16
- X#else
- X#define MAXCIRCLEDIA 80
- X#endif
- X#define MAXCIRCLERAD ((MAXCIRCLEDIA-0.5)/(2*72.27))
- X
- X#define SWAP(x,y) {tmp=x; x=y; y=tmp;}
- X#define TRANS(x,y) (*translate_coordinates)(&x,&y)
- X#define TRANS2(x1,y1,x2,y2) (*translate_coordinates)(&x1,&y1); \
- X (*translate_coordinates)(&x2,&y2)
- X#define TRANSD(x,y) (*translate_coordinates_d)(&x,&y)
- X#define MIN(x,y) (((x) <= (y))? (x): (y))
- X#define MAX(x,y) (((x) >= (y))? (x): (y))
- X#define ABS(x) (((x) >= 0)? (x): -(x))
- X#define round(x) ((int) ((x) + ((x >= 0)? 0.5: -0.5)))
- X#define round4(x) ((round(10000.0*(x))/10000.0))
- X
- Xchar thindot [] = THINDOT;
- Xchar thickdot[] = THICKDOT;
- Xchar thin_ldot [] = THIN_LDOT;
- Xchar thick_ldot[] = THICK_LDOT;
- X
- Xint coord_system;
- Xint verbose = 0;
- Xdouble dash_mag = 1.0;
- Xint thick_width = 1;
- Xdouble tolerance = 2.0;
- Xdouble arc_tolerance = 1.0;
- Xint (*translate_coordinates)() = NULL;
- Xint (*translate_coordinates_d)() = NULL;
- Xdouble unitlength;
- Xint cur_thickness = -1;
- Xdouble ldot_diameter = 1.0/72.0;
- Xchar *dot_cmd = thindot;
- Xchar *ldot_cmd = thin_ldot;
- Xdouble dot_xoffset;
- Xdouble dot_yoffset;
- Xdouble ldot_xoffset;
- Xdouble ldot_yoffset;
- X
- Xstatic translate1(xp, yp)
- Xint *xp, *yp;
- X{
- X *xp = *xp + 1;
- X *yp = *yp + 1;
- X }
- X
- Xstatic translate2(xp, yp)
- Xint *xp, *yp;
- X{
- X *xp = *xp + 1;
- X *yp = TOP - *yp -1;
- X }
- X
- Xstatic translate1_d(xp, yp)
- Xdouble *xp, *yp;
- X{
- X *xp = *xp + 1.0;
- X *yp = *yp + 1.0;
- X }
- X
- Xstatic translate2_d(xp, yp)
- Xdouble *xp, *yp;
- X{
- X *xp = *xp + 1.0;
- X *yp = (double)TOP - *yp -1.0;
- X }
- X
- Xvoid genlatex_option(opt, optarg)
- Xchar opt, *optarg;
- X{
- X switch (opt) {
- X case 'f': /* set default text font */
- X { int i;
- X
- X for ( i = 1; i <= MAXFONT + 1; i++ )
- X if ( !strcmp(optarg, fontnames[i]) ) break;
- X
- X if ( i > MAXFONT + 1 )
- X fprintf(stderr,
- X "warning: non-standard font name %s\n", optarg);
- X }
- X
- X fontnames[0] = fontnames[1] = optarg;
- X break;
- X
- X case 'l': /* set thin/thick line threshold */
- X thick_width = atoi(optarg);
- X break;
- X
- X case 'd':
- X dash_mag = atof(optarg); /* set dash magnification */
- X break;
- X
- X case 'v':
- X verbose = 1; /* verbose mode */
- X break;
- X
- X case 's':
- X if (font_size <= 0 || font_size > MAXFONTSIZE) {
- X fprintf(stderr,
- X "warning: font size %d out of bounds\n", font_size);
- X }
- X break;
- X
- X case 'm':
- X case 'L':
- X break;
- X
- X default:
- X put_msg(Err_badarg, opt, "latex");
- X exit(1);
- X break;
- X }
- X}
- X
- Xvoid genlatex_start(objects)
- XF_compound *objects;
- X{
- X int tmp;
- X
- X fontsizes[0] = fontsizes[1] = TEXFONTSIZE(font_size);
- X
- X coord_system = objects->nwcorner.y;
- X unitlength = mag/objects->nwcorner.x;
- X
- X switch (coord_system) {
- X case 1:
- X translate_coordinates = translate1;
- X translate_coordinates_d = translate1_d;
- X break;
- X case 2:
- X translate_coordinates = translate2;
- X translate_coordinates_d = translate2_d;
- X break;
- X default:
- X fprintf(stderr, "Wrong coordinate system; cannot continue\n");
- X return;
- X }
- X
- X TRANS2(llx, lly, urx, ury);
- X if (llx > urx) SWAP(llx, urx)
- X if (lly > ury) SWAP(lly, ury)
- X
- X /* LaTeX start */
- X fprintf(tfp, "\\setlength{\\unitlength}{%.4fin}%%\n",
- X round4(unitlength));
- X fprintf(tfp, "\\begin{picture}(%d,%d)(%d,%d)\n",
- X urx-llx, ury-lly, llx, lly);
- X}
- X
- Xvoid genlatex_end()
- X{
- X /* LaTeX ending */
- X fprintf(tfp, "\\end{picture}\n");
- X}
- X
- Xstatic set_linewidth(w)
- Xint w;
- X{
- X int latex_w;
- X
- X if (w == 0) return;
- X /* latex only knows thin lines or thick lines */
- X latex_w = (w >= thick_width)? THICKLINES: THINLINES;
- X if (latex_w != cur_thickness) {
- X cur_thickness = latex_w;
- X if (cur_thickness == THICKLINES) {
- X fprintf(tfp, "\\thicklines\n");
- X dot_cmd = thickdot;
- X dot_xoffset = round4(THICK_XOFF/unitlength);
- X dot_yoffset = round4(THICK_YOFF/unitlength);
- X ldot_cmd = thick_ldot;
- X ldot_xoffset = round4(THICK_LXOFF/unitlength);
- X ldot_yoffset = round4(THICK_LYOFF/unitlength);
- X }
- X else {
- X fprintf(tfp, "\\thinlines\n");
- X dot_cmd = thin_ldot;
- X dot_xoffset = round4(THIN_XOFF/unitlength);
- X dot_yoffset = round4(THIN_YOFF/unitlength);
- X ldot_cmd = thin_ldot;
- X ldot_xoffset = round4(THIN_LXOFF/unitlength);
- X ldot_yoffset = round4(THIN_LYOFF/unitlength);
- X }
- X }
- X }
- X
- Xvoid genlatex_line(l)
- XF_line *l;
- X{
- X F_point *p, *q;
- X int x, y, llx, lly, urx, ury, arrow;
- X
- X if (verbose) fprintf(tfp, "%%\n%% Fig POLYLINE object\n%%\n");
- X
- X set_linewidth(l->thickness);
- X
- X p = l->points;
- X q = p->next;
- X
- X if (q == NULL) { /* A single point line */
- X x = p->x; y = p->y;
- X TRANS(x, y);
- X fprintf(tfp, "\\put(%3d,%3d){\\makebox(%.4f,%.4f){%s}}\n",
- X x, y, dot_xoffset, dot_yoffset, dot_cmd);
- X return;
- X }
- X
- X if (l->type == T_BOX) { /* A box */
- X x = p->x; y = p->y;
- X TRANS(x, y);
- X llx = urx = x;
- X lly = ury = y;
- X while (q != NULL) {
- X x = q->x; y = q->y;
- X TRANS(x, y);
- X if (x < llx) llx = x;
- X if (y < lly) lly = y;
- X if (x > urx) urx = x;
- X if (y > ury) ury = y;
- X q = q->next;
- X }
- X put_box (llx, lly, urx, ury, l->style, l->style_val);
- X return;
- X }
- X
- X while (q != NULL) {
- X arrow = 0;
- X if (l->for_arrow && q->next == NULL)
- X arrow = 1;
- X if (l->back_arrow && p == l->points)
- X arrow = (arrow)? 2: -1;
- X single_line(p->x, p->y, q->x, q->y, arrow, l->style, l->style_val);
- X p = q;
- X q = q->next;
- X }
- X
- X if (l->area_fill && (int)l->area_fill != DEFAULT)
- X fprintf(stderr, "Line area fill not implemented\n");
- X }
- X
- Xstatic single_line (x1, y1, x2, y2, arrow, style, val)
- Xint x1, y1, x2, y2, arrow, style;
- Xdouble val;
- X{
- X int dx, dy, sx, sy;
- X double l, m, deviation;
- X
- X TRANS2(x1, y1, x2, y2);
- X dx = x2-x1;
- X dy = y2-y1;
- X /*** compute direction vector ***/
- X get_slope(dx, dy, &sx, &sy, arrow);
- X /*** compute line length in x-direction ***/
- X if (sx == 0) {
- X l = (double)abs(dy);
- X } else {
- X m = (double)abs(sy) / (double)abs(sx);
- X l = ((double)abs(dx) + m*(double)abs(dy)) / (1.0 + m*m);
- X deviation = fabs(l-abs(dx)) + fabs(m*l-abs(dy));
- X if (deviation > tolerance)
- X fprintf(stderr,
- X "Not a LaTeX slope (%d, %d), deviation %.1f pixels\n",
- X dx, dy, deviation);
- X }
- X l = round4(l);
- X /*** output letex command ***/
- X switch (style) {
- X case SOLID_LINE:
- X put_solidline(x1, y1, sx, sy, l, arrow);
- X break;
- X case DASH_LINE:
- X put_dashline(x1, y1, sx, sy, l, arrow, val);
- X break;
- X case DOTTED_LINE:
- X put_dotline(x1, y1, sx, sy, l, arrow, val);
- X break;
- X }
- X }
- X
- X
- X/*
- X * draw box
- X */
- Xstatic put_box (llx, lly, urx, ury, style, val)
- Xint llx, lly, urx, ury, style;
- Xdouble val;
- X{
- X int dlen;
- X
- X switch (style) {
- X case SOLID_LINE:
- X fprintf(tfp, "\\put(%3d,%3d){\\framebox(%d,%d){}}\n",
- X llx, lly, urx-llx, ury-lly);
- X break;
- X case DASH_LINE:
- X dlen = round(val*dash_mag);
- X fprintf(tfp, "\\put(%3d,%3d){\\dashbox{%d}(%d,%d){}}\n",
- X llx, lly, dlen, urx-llx, ury-lly);
- X break;
- X case DOTTED_LINE:
- X put_dotline (llx, lly, 1, 0, (double)(urx-llx), 0, val);
- X put_dotline (llx, ury, 1, 0, (double)(urx-llx), 0, val);
- X put_dotline (llx, lly, 0, 1, (double)(ury-lly), 0, val);
- X put_dotline (urx, lly, 0, 1, (double)(ury-lly), 0, val);
- X break;
- X }
- X return;
- X }
- X
- X/*
- X * draw a solid line given latex slope
- X */
- Xstatic put_solidline (x, y, sx, sy, l, arrow)
- Xint x, y, sx, sy, arrow;
- Xdouble l;
- X{
- X double cosine; /* cosine of line angle */
- X double dx, dy;
- X int x2, y2, n;
- X
- X if (sx) {
- X cosine = (double)abs(sx) / hypot((double)sx, (double)sy);
- X x2 = (sx >= 0)? x + round(l): x - round(l);
- X y2 = y + round( ((sx>=0)? l: -l) * (double)sy / (double)sx);
- X }
- X else {
- X cosine = 1.0;
- X x2 = x;
- X y2 = (sy >= 0)? y + round(l): y - round(l);
- X }
- X if (sx == 0 || sy == 0 || (l/cosine)*unitlength >= MIN_LEN) {
- X switch (arrow) {
- X case 0: /* simple line */
- X fprintf(tfp, "\\put(%3d,%3d){\\line(%2d,%2d)", x, y, sx,sy);
- X break;
- X case 1: /* forward arrow */
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d)", x, y, sx,sy);
- X break;
- X case -1: /* backward arrow */
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d)", x2, y2, -sx,-sy);
- X break;
- X case 2: /* double arrow */
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){ 0}}\n", x,y,-sx,-sy);
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d)", x, y, sx, sy);
- X break;
- X }
- X if (l == floor(l))
- X fprintf(tfp, "{%3.0f}}\n", l);
- X else
- X fprintf(tfp, "{%7.3f}}\n", l);
- X }
- X else {
- X n = 2 * (l/cosine) / (ldot_diameter/unitlength);
- X fprintf(stderr, "Line too short; will do %d dots\n", n);
- X dx = l / (double)n;
- X if (sx < 0) dx = -dx;
- X dy = dx * (double)sy / (double)sx;
- X fprintf(tfp,
- X "\\multiput(%3d,%3d)(%.5f,%.5f){%d}{\\makebox(%.4f,%.4f){%s}}\n",
- X x, y, dx, dy, n+1, ldot_xoffset, ldot_yoffset, ldot_cmd);
- X if (arrow == 1 || arrow == 2) /* forward arrow */
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x2,y2, sx,sy);
- X if (arrow == -1 || arrow == 2) /* backward arrow */
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x,y, -sx,-sy);
- X }
- X }
- X
- X/*
- X * draw a dashed line given latex slope
- X */
- Xstatic put_dashline (x, y, sx, sy, l, arrow, val)
- Xint x, y, sx, sy, arrow;
- Xdouble l;
- Xdouble val;
- X{
- X double cosine; /* cosine of line angle */
- X double nd; /* number of dashes and gaps fitting on line */
- X int n; /* nd rounded to the nearest odd integer */
- X double dl; /* actual x-length of each dash */
- X double dg; /* actual x-length of each gap */
- X double dx, dy; /* step between dashes */
- X int x2, y2;
- X
- X
- X if (sx) {
- X cosine = (double)abs(sx) / hypot((double)sx, (double)sy);
- X x2 = (sx >= 0)? x + round(l): x - round(l);
- X y2 = y + round( ((sx>=0)? l: -l) * (double)sy / (double)sx );
- X }
- X else {
- X cosine = 1.0;
- X x2 = x;
- X y2 = (sy >= 0)? y + round(l): y - round(l);
- X }
- X /*** compute number of dashes, length of dashes and gaps ***/
- X nd = l / (val*dash_mag*cosine);
- X n = (int) (rint((nd + 1.0)/2.0)*2 - 1);
- X dl = l / (double)n;
- X if (sx && sy && (dl/cosine)*unitlength < MIN_LEN) {
- X fprintf(stderr, "Dash too small; using larger dash\n");
- X dl = MIN_LEN/unitlength * cosine;
- X nd = l / dl;
- X n = (int) (rint((nd + 1.0)/2.0)*2 - 1);
- X }
- X if (2*dl >= l || (sx && sy && (l/cosine)*unitlength < MIN_LEN)) {
- X fprintf(stderr, "Dashed line too short; drawing solid line\n");
- X put_solidline (x, y, sx, sy, l, arrow);
- X return;
- X }
- X dg = (l - (n/2+1)*dl) / (double)(n/2);
- X if (sx) {
- X dx = dl+dg;
- X if (sx < 0) dx = -dx;
- X dy = dx * (double)sy / (double)sx;
- X }
- X else {
- X dx = 0.0;
- X dy = dl+dg;
- X if (sy < 0) dy = -dy;
- X }
- X /*** draw dashed line ***/
- X fprintf(tfp, "\\multiput(%3d,%3d)(%.5f,%.5f){%d}{\\line(%2d,%2d){%7.3f}}\n",
- X x, y, dx, dy, n/2+1, sx, sy, dl);
- X /*** draw arrow heads ***/
- X if (arrow == 1 || arrow == 2)
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x2, y2, sx, sy);
- X if (arrow == -1 || arrow == 2)
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x, y, -sx, -sy);
- X }
- X
- X/*
- X * draw a dotted line given latex slope
- X */
- Xstatic put_dotline (x, y, sx, sy, l, arrow, val)
- Xint x, y, sx, sy, arrow;
- Xdouble l;
- Xdouble val;
- X{
- X double cosine; /* cosine of line angle */
- X double nd; /* number of dots fitting on line */
- X int n; /* nd rounded to the nearest integer */
- X double dx, dy; /* step between dashes */
- X int x2, y2;
- X
- X
- X cosine = (sx)? (double)abs(sx) / hypot((double)sx, (double)sy): 1.0;
- X /*** compute step width ***/
- X nd = l / (3*val*cosine);
- X n = rint(nd);
- X dx = l / (double)n;
- X if (sx) {
- X dx = l / (double)n;
- X if (sx < 0) dx = -dx;
- X dy = dx * (double)sy / (double)sx;
- X }
- X else {
- X dx = 0.0;
- X dy = l / (double)n;
- X if (sy < 0) dy = -dy;
- X }
- X /*** draw arrow heads ***/
- X if (arrow == 1 || arrow == 2) {
- X /* forward arrow */
- X if (sx) {
- X x2 = (sx >= 0)? x + round(l): x - round(l);
- X y2 = y + round( ((sx>=0)? l: -l) * (double)sy / (double)sx );
- X }
- X else {
- X x2 = x;
- X y2 = (sy >= 0)? y + round(l): y - round(l);
- X }
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x2, y2, sx, sy);
- X n--;
- X }
- X if (arrow == -1 || arrow == 2) {
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%2d,%2d){0}}\n", x, y, -sx, -sy);
- X x = round(x + dx);
- X y = round(y + dy);
- X n--;
- X }
- X /*** draw dotted line ***/
- X fprintf(tfp, "\\multiput(%3d,%3d)(%.5f,%.5f){%d}{\\makebox(%.4f,%.4f){%s}}\n",
- X x, y, dx, dy, n+1, dot_xoffset, dot_yoffset, dot_cmd);
- X }
- X
- Xvoid genlatex_spline(s)
- XF_spline *s;
- X{
- X fprintf(stderr, "Can't generate spline; omitting object\n");
- X }
- X
- Xvoid genlatex_ellipse(e)
- XF_ellipse *e;
- X{
- X int x, y, d, dx, dy;
- X
- X if (verbose) fprintf(tfp, "%%\n%% Fig ELLIPSE\n%%\n");
- X
- X set_linewidth(e->thickness);
- X switch (e->style) {
- X case SOLID_LINE:
- X break;
- X case DASH_LINE:
- X fprintf(stderr, "Dashed circles and elipses not supported\n");
- X break;
- X case DOTTED_LINE:
- X fprintf(stderr, "Dotted circles and elipses not supported\n");
- X break;
- X }
- X
- X x = e->center.x;
- X y = e->center.y;
- X TRANS(x, y);
- X if ((e->type == T_CIRCLE_BY_RAD || e->type == T_CIRCLE_BY_DIA)
- X && e->radiuses.x*unitlength <= MAXCIRCLERAD) {
- X
- X d = 2 * e->radiuses.x;
- X if (e->area_fill == BLACK_FILL)
- X fprintf(tfp, "\\put(%3d,%3d){\\circle*{%d}}\n", x, y, d);
- X else {
- X fprintf(tfp, "\\put(%3d,%3d){\\circle{%d}}\n", x, y, d);
- X if (e->area_fill && (int)e->area_fill != DEFAULT)
- X fprintf(stderr, "Circle area fill not implemented\n");
- X }
- X
- X } else {
- X dx = 2 * e->radiuses.x;
- X dy = 2 * e->radiuses.y;
- X fprintf(tfp, "\\put(%3d,%3d){\\oval(%d,%d)}\n", x, y, dx, dy);
- X if (e->area_fill && (int)e->area_fill != DEFAULT)
- X fprintf(stderr, "Ellipse area fill not implemented\n");
- X }
- X }
- X
- Xvoid genlatex_text(t)
- XF_text *t;
- X{
- X int x, y;
- X char *tpos, *cp;
- X
- X if (verbose) fprintf(tfp, "%%\n%% Fig TEXT object\n%%\n");
- X
- X x = t->base_x;
- X y = t->base_y;
- X TRANS(x, y);
- X
- X switch (t->type) {
- X
- X case T_LEFT_JUSTIFIED:
- X case DEFAULT:
- X tpos = "[lb]";
- X break;
- X
- X case T_CENTER_JUSTIFIED:
- X tpos = "[b]";
- X break;
- X
- X case T_RIGHT_JUSTIFIED:
- X tpos = "[rb]";
- X break;
- X
- X default:
- X fprintf(stderr, "Text incorrectly positioned\n");
- X }
- X
- X /* raisebox is used to position text at baseline */
- X fprintf(tfp,
- X "\\put(%3d,%3d){\\makebox(0,0)%s{\\raisebox{0pt}[0pt][0pt]",
- X x, y, tpos);
- X fprintf(tfp, "{\\%s%s ", TEXFONTSIZE(t->size), TEXFONT(t->font));
- X
- X if (t->font && t->font !=DEFAULT)
- X
- X /* this loop escapes characters "$&%#_{}" */
- X /* and deleted characters "~^\" */
- X for(cp = t->cstring; *cp; cp++) {
- X if (strchr("$&%#_{}", *cp)) (void)fputc('\\', tfp);
- X if (strchr("~^\\", *cp))
- X fprintf(stderr,
- X "Bad character in text object '%c'\n" ,*cp);
- X else
- X (void)fputc(*cp, tfp);
- X }
- X else
- X fprintf(tfp, "%s", t->cstring);
- X
- X fprintf(tfp, "}}}\n");
- X }
- X
- Xvoid genlatex_arc(a)
- XF_arc *a;
- X/*
- X * Approximates an arc by a sequence of quarter ovals.
- X *
- X * Example:
- X *
- X * Arc with center at (0,0) and radius 10 from +45 degree to +225 degree
- X * (arc from p1 = (7.07, 7.07) to p2 = (-7.07, -7.07) counterclockwise).
- X * This arc is approximated by three quarter ovals, one for each quadrant
- X * through which the arc goes:
- X *
- X * 1. quarter oval from p1 to the intersection of arc and y-axis,
- X * i.e., from (7.07, 7.07) to (0, 10) in quadrant 0
- X *
- X * \put(0, 7.07){\oval(14.14, 5.86)[tr]}
- X *
- X * 2. quarter oval from intersection arc/y-axis to intersection arc/x-axis
- X * i.e., from (0, 10) to (-10, 0) in quadrant 1
- X *
- X * \put(0, 0){\oval(20,20)[tl]}
- X *
- X * 3. quarter oval from p1 to the intersection of arc and y-axis,
- X * i.e., from (-10, 0) to (-7.07, -7.07) in quadrant 2
- X *
- X * \put(-7.07, 0){\oval(5.86, 14.14)[bl]}
- X */
- X{
- X F_pos p1, p2, pq[4];
- X double cx, cy;
- X double v1x, v1y, v2x, v2y;
- X double r, angle1, angle2;
- X int q1, q2;
- X int p1_arrow, p2_arrow;
- X static char *ad1[4] = { " 0,-1", " 1, 0", " 0, 1", "-1, 0" };
- X static char *ad2[4] = { "-1, 0", " 0,-1", " 1, 0", " 0, 1" };
- X
- X set_linewidth(a->thickness);
- X switch (a->style) {
- X case SOLID_LINE:
- X break;
- X case DASH_LINE:
- X fprintf(stderr, "Dashed arcs not supported\n");
- X break;
- X case DOTTED_LINE:
- X fprintf(stderr, "Dotted arcs not supported\n");
- X break;
- X }
- X if (a->direction == 1) {
- X p1 = a->point[0];
- X p2 = a->point[2];
- X p1_arrow = (a->back_arrow != NULL);
- X p2_arrow = (a->for_arrow != NULL);
- X }
- X else {
- X p1 = a->point[2];
- X p2 = a->point[0];
- X p1_arrow = (a->for_arrow != NULL);
- X p2_arrow = (a->back_arrow != NULL);
- X }
- X cx = a->center.x;
- X cy = a->center.y;
- X TRANS2(p1.x, p1.y, p2.x, p2.y);
- X TRANSD(cx, cy);
- X /*** compute vectors and angles from arc center to p1, p2 ***/
- X v1x = (double)p1.x - cx;
- X v1y = (double)p1.y - cy;
- X v2x = (double)p2.x - cx;
- X v2y = (double)p2.y - cy;
- X angle1 = atan2(v1y, v1x) * rad2deg;
- X angle2 = atan2(v2y, v2x) * rad2deg;
- X if (angle1 < 0.0)
- X angle1 += 360.0;
- X if (angle2 < 0.0)
- X angle2 += 360.0;
- X /* compute arc radius */
- X r = hypot(v1x, v1y);
- X /*** compute intersection of arc with x and y axis (origin at cx, cy) */
- X pq[0].x = round(cx);
- X pq[0].y = round(cy + r);
- X pq[1].x = round(cx - r);
- X pq[1].y = round(cy);
- X pq[2].x = round(cx);
- X pq[2].y = round(cy - r);
- X pq[3].x = round(cx + r);
- X pq[3].y = round(cy);
- X /*** compute in which quadrants p1 and p2 are located ***/
- X q1 = (int)(angle1/90.0);
- X q2 = (int)(angle2/90.0);
- X if (fabs(angle1 - 90.0*q1) > arc_tolerance
- X || fabs(angle2 - 90.0*q2) > arc_tolerance)
- X fprintf(stderr, "Approximating arc by ovals\n");
- X /*** Draw arc ***/
- X if (p1_arrow)
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%s){0}}\n", p1.x, p1.y, ad1[q1]);
- X while (q1 != q2) {
- X put_quarter(p1, pq[q1], q1);
- X p1 = pq[q1];
- X q1 = (q1 + 1) % 4;
- X }
- X put_quarter(p1, p2, q1);
- X if (p2_arrow)
- X fprintf(tfp, "\\put(%3d,%3d){\\vector(%s){0}}\n", p2.x, p2.y, ad2[q2]);
- X
- X if (a->area_fill && (int)a->area_fill != DEFAULT)
- X fprintf(stderr, "Arc area fill not implemented\n");
- X }
- X
- Xstatic put_quarter(p1, p2, q)
- XF_pos p1, p2;
- Xint q;
- X/*
- X * Draw quarter oval from p1 to p2 in quadrant q
- X */
- X{
- X char *opt;
- X int px, py, dx, dy;
- X
- X dx = 2*ABS(p1.x - p2.x);
- X dy = 2*ABS(p1.y - p2.y);
- X if (dx == 0 && dy == 0)
- X return;
- X switch (q) {
- X case 0:
- X px = MIN(p1.x, p2.x);
- X py = MIN(p1.y, p2.y);
- X opt = "tr";
- X break;
- X case 1:
- X px = MAX(p1.x, p2.x);
- X py = MIN(p1.y, p2.y);
- X opt = "tl";
- X break;
- X case 2:
- X px = MAX(p1.x, p2.x);
- X py = MAX(p1.y, p2.y);
- X opt = "bl";
- X break;
- X case 3:
- X px = MIN(p1.x, p2.x);
- X py = MAX(p1.y, p2.y);
- X opt = "br";
- X break;
- X }
- X fprintf(tfp, "\\put(%3d,%3d){\\oval(%3d,%3d)[%s]}\n", px, py, dx, dy, opt);
- X }
- X
- Xstruct driver dev_latex = {
- X genlatex_option,
- X genlatex_start,
- X genlatex_arc,
- X genlatex_ellipse,
- X genlatex_line,
- X genlatex_spline,
- X genlatex_text,
- X genlatex_end,
- X EXCLUDE_TEXT
- X};
- END_OF_FILE
- if test 20332 -ne `wc -c <'transfig/fig2dev/dev/genlatex.c'`; then
- echo shar: \"'transfig/fig2dev/dev/genlatex.c'\" unpacked with wrong size!
- fi
- # end of 'transfig/fig2dev/dev/genlatex.c'
- fi
- if test -f 'transfig/fig2dev/dev/genps.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'transfig/fig2dev/dev/genps.c'\"
- else
- echo shar: Extracting \"'transfig/fig2dev/dev/genps.c'\" \(17407 characters\)
- sed "s/^X//" >'transfig/fig2dev/dev/genps.c' <<'END_OF_FILE'
- X/*
- X * genps.c: PostScript driver for fig2dev
- X *
- X*/
- X#ifdef hpux
- X#include <sys/types.h>
- X#endif
- X#include <sys/file.h>
- X#include <stdio.h>
- X#include <math.h>
- X#include "pi.h"
- X#include <pwd.h>
- X#include "object.h"
- X#include "fig2dev.h"
- X
- Xextern x_flag;
- X
- X#define PAGE_WIDTH 612 /* points; 8.5" */
- X#define PAGE_HEIGHT 792 /* points; 11" */
- X#define TRUE 1
- X#define FALSE 0
- X#define POINT_PER_INCH 72
- X#define ULIMIT_FONT_SIZE 300
- X
- Xint coord_system;
- Xint show_page = 0;
- Xint cur_thickness;
- Xint center = 0;
- Xint landscape = 0;
- X
- Xstatic char *fontnames_x[] = {
- X "Times-Roman", "Times-Roman", /* default */
- X "Times-Italic", /* italic */
- X "Times-Bold", /* bold */
- X "Times-BoldItalic",
- X "AvantGarde",
- X "AvantGarde-BookOblique",
- X "AvantGarde-Demi",
- X "AvantGarde-DemiOblique",
- X "Bookman-Light",
- X "Bookman-LightItalic",
- X "Bookman-Demi",
- X "Bookman-DemiItalic",
- X "Courier",
- X "Courier-Oblique",
- X "Courier-Bold",
- X "Courier-BoldItalic",
- X "Helvetica",
- X "Helvetica-Oblique",
- X "Helvetica-Bold",
- X "Helvetica-BoldOblique",
- X "Helvetica-Narrow",
- X "Helvetica-Narrow-Oblique",
- X "Helvetica-Narrow-Bold",
- X "Helvetica-Narrow-BoldOblique",
- X "NewCenturySchlbk-Roman",
- X "NewCenturySchlbk-Italic",
- X "NewCenturySchlbk-Bold",
- X "NewCenturySchlbk-BoldItalic",
- X "Palatino-Roman",
- X "Palatino-Italic",
- X "Palatino-Bold",
- X "Palatino-BoldItalic",
- X "Symbol",
- X "ZapfChancery-MediumItalic",
- X "ZapfDingbats"
- X };
- X
- Xstatic char *fontnames_sv[] = {
- X "Times-Roman", "Times-Roman", /* default */
- X "Times-Roman", /* roman */
- X "Times-Bold", /* bold */
- X "Times-Italic", /* italic */
- X "Helvetica", /* sans serif */
- X "Courier" /* typewriter */
- X };
- X#define MAXFONT (x_flag ? 35 : 5)
- X
- X#define PS_FONTNAMES (x_flag ? fontnames_x : fontnames_sv)
- X
- X#define PSFONT(F) \
- X ((F) <= MAXFONT ? PS_FONTNAMES[(F)+1] : PS_FONTNAMES[0])
- X
- X#define PSFONTSIZE(S) (((S) > 0 ? \
- X ((S) <= ULIMIT_FONT_SIZE ? \
- X (S) : \
- X ULIMIT_FONT_SIZE) : \
- X font_size)/mag)
- X
- X#define GRAYVAL(F) (x_flag ? ((int)(F) <= 21 ? \
- X (21 - (int)(F))/20.0 : 0.0) : \
- X ((int)(F) <= 5 ? ((int)(F) - 1)/4.0 : 0.0))
- X
- X#define BEGIN_PROLOG "\
- X/$F2psDict 32 dict def \
- X$F2psDict begin\
- X $F2psDict /mtrx matrix put\
- X"
- X#define ELLIPSE_PS " \
- X/DrawEllipse {\
- X /endangle exch def\
- X /startangle exch def\
- X /yrad exch def\
- X /xrad exch def\
- X /y exch def\
- X /x exch def\
- X /savematrix mtrx currentmatrix def\
- X x y translate xrad yrad scale 0 0 1 startangle endangle arc\
- X savematrix setmatrix\
- X } def\
- X"
- X/* The original PostScript definition for adding a spline section to the
- X * current path uses recursive bisection. The following definition using the
- X * curveto operator is more efficient since it executes at compiled rather
- X * than interpreted code speed. The Bezier control points are 2/3 of the way
- X * from z1 (and z3) to z2.
- X *
- X * ---Rene Llames, 21 July 1988.
- X */
- X#define SPLINE_PS " \
- X/DrawSplineSection {\
- X /y3 exch def\
- X /x3 exch def\
- X /y2 exch def\
- X /x2 exch def\
- X /y1 exch def\
- X /x1 exch def\
- X /xa x1 x2 x1 sub 0.666667 mul add def\
- X /ya y1 y2 y1 sub 0.666667 mul add def\
- X /xb x3 x2 x3 sub 0.666667 mul add def\
- X /yb y3 y2 y3 sub 0.666667 mul add def\
- X x1 y1 lineto\
- X xa ya xb yb x3 y3 curveto\
- X } def\
- X"
- X#define END_PROLOG "\
- X end\
- X /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def\
- X /$F2psEnd {$F2psEnteredState restore end} def\
- X %%EndProlog\
- X"
- X
- Xvoid genps_option(opt, optarg)
- Xchar opt;
- Xchar *optarg;
- X{
- X int i;
- X
- X switch (opt) {
- X
- X case 'f':
- X for ( i = 1; i <= MAXFONT + 1; i++ )
- X if ( !strcmp(optarg, PS_FONTNAMES[i]) ) break;
- X
- X if ( i > MAXFONT + 1 )
- X fprintf(stderr,
- X "warning: non-standard font name %s\n", optarg);
- X
- X fontnames_sv[0] = fontnames_sv[1] = optarg;
- X fontnames_x[0] = fontnames_x[1] = optarg;
- X break;
- X
- X case 'c':
- X center = 1;
- X break;
- X
- X case 's':
- X if (font_size <= 0 || font_size > ULIMIT_FONT_SIZE) {
- X fprintf(stderr,
- X "warning: font size %d out of bounds\n", font_size);
- X }
- X break;
- X
- X case 'P':
- X show_page = 1;
- X break;
- X
- X case 'm':
- X case 'L':
- X break;
- X
- X case 'l':
- X landscape = 1;
- X break;
- X
- X default:
- X put_msg(Err_badarg, opt, "ps");
- X exit(1);
- X break;
- X }
- X}
- X
- Xvoid genps_start(objects)
- XF_compound *objects;
- X{
- X char host[256];
- X struct passwd *who;
- X long when;
- X extern char *ctime(), *strcpy();
- X extern long time();
- X double tx, scalex, scaley;
- X double dx, dy, origx, origy;
- X int itmp;
- X
- X coord_system = objects->nwcorner.y;
- X scalex = scaley = mag * POINT_PER_INCH / (double)objects->nwcorner.x;
- X /* convert to point unit */
- X llx = (int)ceil(llx * scalex); lly = (int)ceil(lly * scaley);
- X urx = (int)ceil(urx * scalex); ury = (int)ceil(ury * scaley);
- X if (landscape) /* swap x,y */
- X {
- X itmp = llx; llx = lly; lly = itmp;
- X itmp = urx; urx = ury; ury = itmp;
- X }
- X if (center) {
- X dx = urx - llx;
- X dy = ury - lly;
- X tx = (PAGE_WIDTH - dx) / 2.0;
- X if (landscape)
- X origx=0;
- X else
- X origx = tx - llx;
- X urx = (llx=tx) + dx;
- X ury = (PAGE_HEIGHT + dy) / 2.0;
- X if (coord_system == 2)
- X origy = ury + lly;
- X else
- X origy = ury - dy - lly;
- X lly = ury - dy;
- X }
- X else {
- X origx = 0.0;
- X origy = PAGE_HEIGHT;
- X }
- X
- X if (coord_system == 2) scaley = -scaley;
- X
- X fprintf(tfp, "%%!\n"); /* PostScript magic strings */
- X who = getpwuid(getuid());
- X if (-1 == gethostname(host, sizeof(host)))
- X (void)strcpy(host, "unknown-host!?!?");
- X (void) time(&when);
- X fprintf(tfp, "%%%%Title: %s\n", ((from) ? from : "stdin"));
- X fprintf(tfp, "%%%%Creator: %s\n", prog);
- X fprintf(tfp, "%%%%CreationDate: %s", ctime(&when));
- X fprintf(tfp, "%%%%For: %s@%s (%s)\n",
- X who->pw_name, host, who->pw_gecos);
- X fprintf(tfp, "%%%%Pages: %d\n", show_page);
- X
- X if (show_page)
- X fprintf(tfp, "%%%%BoundingBox: %d %d %d %d\n", llx, lly, urx, ury);
- X else
- X fprintf(tfp, "%%%%BoundingBox: 0 0 %d %d\n", urx-llx, ury-lly);
- X
- X fprintf(tfp, "%%%%EndComments\n");
- X fprintf(tfp, "%s\n", BEGIN_PROLOG);
- X if (ellipse_exist(objects)) fprintf(tfp, "%s\n", ELLIPSE_PS);
- X if (normal_spline_exist(objects)) fprintf(tfp, "%s\n", SPLINE_PS);
- X fprintf(tfp, "%s\n", END_PROLOG);
- X fprintf(tfp, "$F2psBegin\n");
- X fprintf(tfp, "1 setlinecap 1 setlinejoin\n");
- X
- X if (!show_page) fprintf(tfp, "%d %d translate\n", -llx, lly);
- X fprintf(tfp, "%f %f translate %.3f %.3f scale\n",
- X origx, (show_page ? origy : ury-lly), scalex, scaley);
- X
- X /* **** Land scape mode ****/
- X if (landscape)
- X fprintf(tfp, "%d 0 translate 90 rotate\n", PAGE_WIDTH);
- X
- X /* if ((t = PAGE_HEIGHT / SCALE / WIDTH) < 1.0)
- X * fprintf(tfp, "%f %f scale\n", t, t);
- X * }
- X *else if ((t = PAGE_HEIGHT / SCALE / HEIGHT) < 1.0)
- X * fprintf(tfp, "%f %f scale\n", t, t);
- X */
- X
- X }
- X
- Xvoid genps_end()
- X{
- X if (show_page) fprintf(tfp, "showpage\n");
- X fprintf(tfp, "$F2psEnd\n");
- X }
- X
- Xstatic set_style(s, v)
- Xint s;
- Xdouble v;
- X{
- X if (s == DASH_LINE) {
- X if (v > 0.0) fprintf(tfp, "\t[%f] 0 setdash\n", v);
- X }
- X else if (s == DOTTED_LINE) {
- X if (v > 0.0) fprintf(tfp, "\t[1 %f] 0 setdash\n", v);
- X }
- X }
- X
- Xstatic reset_style(s, v)
- Xint s;
- Xdouble v;
- X{
- X if (s == DASH_LINE) {
- X if (v > 0.0) fprintf(tfp, "\t[] 0 setdash\n");
- X }
- X else if (s == DOTTED_LINE) {
- X if (v > 0.0) fprintf(tfp, "\t[] 0 setdash\n");
- X }
- X }
- X
- Xstatic set_linewidth(w)
- Xint w;
- X{
- X extern int cur_thickness;
- X
- X if (w != cur_thickness) {
- X cur_thickness = w;
- X fprintf(tfp, "%.3f setlinewidth\n", 1.0 * cur_thickness);
- X }
- X }
- X
- Xvoid genps_line(l)
- XF_line *l;
- X{
- X F_point *p, *q;
- X /* JNT */
- X int radius;
- X
- X set_linewidth(l->thickness);
- X radius = l->radius; /* radius of rounded-corner boxes */
- X p = l->points;
- X q = p->next;
- X if (q == NULL) { /* A single point line */
- X fprintf(tfp, "newpath %d %d moveto %d %d lineto stroke\n",
- X p->x, p->y, p->x, p->y);
- X return;
- X }
- X if (l->back_arrow)
- X draw_arrow_head((double)q->x, (double)q->y, (double)p->x,
- X (double)p->y, l->back_arrow->ht, l->back_arrow->wid);
- X set_style(l->style, l->style_val);
- X fprintf(tfp, "%% Polyline\n");
- X /* JNT */
- X if (l->type == T_ARC_BOX)
- X {
- X register int xmin,xmax,ymin,ymax;
- X
- X xmin = xmax = p->x;
- X ymin = ymax = p->y;
- X while (p->next != NULL) /* find lower left and upper right corne
- Xrs */
- X {
- X p=p->next;
- X if (xmin > p->x)
- X xmin = p->x;
- X else if (xmax < p->x)
- X xmax = p->x;
- X if (ymin > p->y)
- X ymin = p->y;
- X else if (ymax < p->y)
- X ymax = p->y;
- X }
- X fprintf(tfp, "newpath %d %d moveto",xmin+radius, ymin);
- X fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat",
- X xmin, ymin, xmin, ymax-radius, radius);
- X fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc thro
- Xugh bl to br */
- X xmin, ymax, xmax-radius, ymax, radius);
- X fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc thro
- Xugh br to tr */
- X xmax, ymax, xmax, ymin+radius, radius);
- X fprintf(tfp, " %d %d %d %d %d arcto 4 {pop} repeat", /* arc thro
- Xugh tr to tl */
- X xmax, ymin, xmin+radius, ymin, radius);
- X }
- X else
- X {
- X fprintf(tfp, "newpath %d %d moveto", p->x, p->y);
- X while (q->next != NULL) {
- X p = q;
- X q = q->next;
- X fprintf(tfp, " %d %d lineto", p->x, p->y);
- X }
- X }
- X if (l->type == T_POLYLINE)
- X fprintf(tfp, " %d %d lineto stroke\n", q->x, q->y);
- X else
- X fprintf(tfp, " closepath ");
- X if (l->area_fill && (int)l->area_fill != DEFAULT)
- X fprintf(tfp, "gsave %6.3f setgray fill grestore ",
- X GRAYVAL(l->area_fill));
- X fprintf(tfp, "stroke\n");
- X reset_style(l->style, l->style_val);
- X if (l->for_arrow)
- X draw_arrow_head((double)p->x, (double)p->y, (double)q->x,
- X (double)q->y, l->for_arrow->ht, l->for_arrow->wid);
- X }
- X
- Xvoid genps_spline(s)
- XF_spline *s;
- X{
- X if (int_spline(s))
- X genps_itp_spline(s);
- X else
- X genps_ctl_spline(s);
- X }
- X
- Xgenps_itp_spline(s)
- XF_spline *s;
- X{
- X F_point *p, *q;
- X F_control *a, *b;
- X
- X set_linewidth(s->thickness);
- X a = s->controls;
- X p = s->points;
- X if (s->back_arrow)
- X draw_arrow_head(a->rx, a->ry, (double)p->x,
- X (double)p->y, s->back_arrow->ht, s->back_arrow->wid);
- X
- X set_style(s->style, s->style_val);
- X fprintf(tfp, "%% Interpolated spline\n");
- X fprintf(tfp, "newpath %d %d moveto\n", p->x, p->y);
- X for (q = p->next; q != NULL; p = q, q = q->next) {
- X b = a->next;
- X fprintf(tfp, "\t%.3f %.3f %.3f %.3f %d %d curveto\n",
- X a->rx, a->ry, b->lx, b->ly, q->x, q->y);
- X a = b;
- X b = b->next;
- X }
- X if (closed_spline(s)) fprintf(tfp, " closepath ");
- X if (s->area_fill && (int)s->area_fill != DEFAULT)
- X fprintf(tfp, "gsave %6.3f setgray fill grestore ",
- X GRAYVAL(s->area_fill));
- X fprintf(tfp, " stroke\n");
- X reset_style(s->style, s->style_val);
- X
- X if (s->for_arrow)
- X draw_arrow_head(a->lx, a->ly, (double)p->x,
- X (double)p->y, s->for_arrow->ht, s->for_arrow->wid);
- X }
- X
- Xgenps_ctl_spline(s)
- XF_spline *s;
- X{
- X double a, b, c, d, x1, y1, x2, y2, x3, y3;
- X F_point *p, *q;
- X
- X /*
- X if (first) {
- X first = FALSE;
- X fprintf(tfp, "%s\n", SPLINE_PS);
- X }
- X */
- X
- X p = s->points;
- X x1 = p->x; y1 = p->y;
- X p = p->next;
- X c = p->x; d = p->y;
- X set_linewidth(s->thickness);
- X x3 = a = (x1 + c) / 2;
- X y3 = b = (y1 + d) / 2;
- X if (s->back_arrow) {
- X draw_arrow_head(c, d, x1, y1, s->back_arrow->ht, s->back_arrow->wid);
- X }
- X set_style(s->style, s->style_val);
- X if (! closed_spline(s)) {
- X fprintf(tfp, "%% Open spline\n");
- X fprintf(tfp, "newpath %.3f %.3f moveto %.3f %.3f lineto\n",
- X x1, y1, x3, y3);
- X }
- X else {
- X fprintf(tfp, "%% Closed spline\n");
- X fprintf(tfp, "newpath %.3f %.3f moveto\n", a, b);
- X }
- X for (q = p->next; q != NULL; p = q, q = q->next) {
- X x1 = x3; y1 = y3;
- X x2 = c; y2 = d;
- X c = q->x; d = q->y;
- X x3 = (x2 + c) / 2;
- X y3 = (y2 + d) / 2;
- X fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection\n",
- X x1, y1, x2, y2, x3, y3);
- X }
- X /*
- X * At this point, (x2,y2) and (c,d) are the position of the
- X * next-to-last and last point respectively, in the point list
- X */
- X if (closed_spline(s)) {
- X fprintf(tfp, "\t%.3f %.3f %.3f %.3f %.3f %.3f DrawSplineSection closepath ",
- X x3, y3, c, d, a, b);
- X }
- X else {
- X fprintf(tfp, "\t%.3f %.3f lineto ", c, d);
- X }
- X if (s->area_fill && (int)s->area_fill != DEFAULT)
- X fprintf(tfp, "gsave %6.3f setgray fill grestore ",
- X GRAYVAL(s->area_fill));
- X fprintf(tfp, "stroke\n");
- X reset_style(s->style, s->style_val);
- X if (s->for_arrow) {
- X draw_arrow_head(x2, y2, c, d, s->for_arrow->ht,
- X s->for_arrow->wid);
- X }
- X }
- X
- Xvoid genps_ellipse(e)
- XF_ellipse *e;
- X{
- X set_linewidth(e->thickness);
- X set_style(e->style, e->style_val);
- X if (e->angle == 0)
- X {
- X fprintf(tfp, "%% Ellipse\n");
- X fprintf(tfp, "newpath %d %d %d %d 0 360 DrawEllipse ",
- X e->center.x, e->center.y, e->radiuses.x, e->radiuses.y);
- X }
- X else
- X {
- X fprintf(tfp, "%% Rotated Ellipse\n");
- X fprintf(tfp, "gsave\n");
- X fprintf(tfp, "%d %d translate\n",e->center.x, e->center.y);
- X fprintf(tfp, "%6.3f rotate\n",e->angle*180/M_PI);
- X fprintf(tfp, "newpath 0 0 %d %d 0 360 DrawEllipse ",
- X e->radiuses.x, e->radiuses.y);
- X }
- X if (e->area_fill && (int)e->area_fill != DEFAULT)
- X fprintf(tfp, "gsave %6.3f setgray fill grestore ",
- X GRAYVAL(e->area_fill));
- X fprintf(tfp, "stroke\n");
- X if (e->angle != 0)
- X fprintf(tfp, "grestore\n");
- X reset_style(e->style, e->style_val);
- X }
- X
- X#define TEXT_PS "\
- X/%s findfont %.3f scalefont setfont\n\
- X"
- Xvoid genps_text(t)
- XF_text *t;
- X{
- X char *cp;
- X
- X fprintf(tfp, TEXT_PS, PSFONT(t->font), PSFONTSIZE(t->size));
- X
- X fprintf(tfp, "%d %d moveto \n", t->base_x, t->base_y);
- X if (coord_system == 2) fprintf(tfp, "1 -1 scale\n");
- X
- X /* this loop escapes characters '(', ')', and '\' */
- X fputc('(', tfp);
- X for(cp = t->cstring; *cp; cp++) {
- X if (strchr("()\\", *cp)) fputc('\\', tfp);
- X fputc(*cp, tfp);
- X }
- X fputc(')', tfp);
- X
- X if ((t->type == T_CENTER_JUSTIFIED) || (t->type == T_RIGHT_JUSTIFIED)){
- X
- X fprintf(tfp, "dup stringwidth pop ");
- X if (t->type == T_CENTER_JUSTIFIED) fprintf(tfp, "2 div ");
- X fprintf(tfp, "neg 0 rmoveto ");
- X }
- X
- X else if ((t->type != T_LEFT_JUSTIFIED) && (t->type != DEFAULT))
- X fprintf(stderr, "Text incorrectly positioned\n");
- X
- X fprintf(tfp, " gsave %6.3f rotate show grestore ", t->angle*180/M_PI);
- X if (coord_system == 2) fprintf(tfp, "1 -1 scale\n");
- X
- X }
- X
- Xvoid genps_arc(a)
- XF_arc *a;
- X{
- X double angle1, angle2, dx, dy, radius, x, y;
- X double cx, cy, sx, sy, ex, ey;
- X int direction;
- X
- X cx = a->center.x; cy = a->center.y;
- X sx = a->point[0].x; sy = a->point[0].y;
- X ex = a->point[2].x; ey = a->point[2].y;
- X
- X if (coord_system == 2)
- X direction = !a->direction;
- X else
- X direction = a->direction;
- X set_linewidth(a->thickness);
- X if (a->for_arrow) {
- X arc_tangent(cx, cy, ex, ey, direction, &x, &y);
- X draw_arrow_head(x, y, ex, ey, a->for_arrow->ht, a->for_arrow->wid);
- X }
- X if (a->back_arrow) {
- X arc_tangent(cx, cy, sx, sy, !direction, &x, &y);
- X draw_arrow_head(x, y, sx, sy, a->back_arrow->ht, a->back_arrow->wid);
- X }
- X dx = cx - sx;
- X dy = cy - sy;
- X radius = hypot(dx, dy);
- X angle1 = atan2(sy-cy, sx-cx) * 180 / M_PI;
- X angle2 = atan2(ey-cy, ex-cx) * 180 / M_PI;
- X /* direction = 1 -> Counterclockwise */
- X set_style(a->style, a->style_val);
- X fprintf(tfp, "newpath %.3f %.3f %.3f %.3f %.3f %s\n",
- X cx, cy, radius, angle1, angle2,
- X ((direction == 1) ? "arc" : "arcn"));
- X if (a->area_fill && (int)a->area_fill != DEFAULT)
- X fprintf(tfp, "gsave %6.3f setgray fill grestore ",
- X GRAYVAL(a->area_fill));
- X fprintf(tfp, "stroke\n");
- X reset_style(a->style, a->style_val);
- X }
- X
- Xstatic arc_tangent(x1, y1, x2, y2, direction, x, y)
- Xdouble x1, y1, x2, y2, *x, *y;
- Xint direction;
- X{
- X if (direction) { /* counter clockwise */
- X *x = x2 + (y2 - y1);
- X *y = y2 - (x2 - x1);
- X }
- X else {
- X *x = x2 - (y2 - y1);
- X *y = y2 + (x2 - x1);
- X }
- X }
- X
- X/* draw arrow heading from (x1, y1) to (x2, y2) */
- X
- Xstatic draw_arrow_head(x1, y1, x2, y2, arrowht, arrowwid)
- Xdouble x1, y1, x2, y2, arrowht, arrowwid;
- X{
- X double x, y, xb, yb, dx, dy, l, sina, cosa;
- X double xc, yc, xd, yd;
- X
- X dx = x2 - x1; dy = y1 - y2;
- X l = hypot(dx, dy);
- X sina = dy / l; cosa = dx / l;
- X xb = x2*cosa - y2*sina;
- X yb = x2*sina + y2*cosa;
- X x = xb - arrowht;
- X y = yb - arrowwid / 2;
- X xc = x*cosa + y*sina;
- X yc = -x*sina + y*cosa;
- X y = yb + arrowwid / 2;
- X xd = x*cosa + y*sina;
- X yd = -x*sina + y*cosa;
- X fprintf(tfp, "newpath %.3f %.3f moveto %.3f %.3f lineto %.3f %.3f lineto stroke\n",
- X xc, yc, x2, y2, xd, yd);
- X }
- X
- Xstatic ellipse_exist(ob)
- XF_compound *ob;
- X{
- X F_compound *c;
- X
- X if (NULL != ob->ellipses) return(1);
- X
- X for (c = ob->compounds; c != NULL; c = c->next) {
- X if (ellipse_exist(c)) return(1);
- X }
- X
- X return(0);
- X }
- X
- Xstatic normal_spline_exist(ob)
- XF_compound *ob;
- X{
- X F_spline *s;
- X F_compound *c;
- X
- X for (s = ob->splines; s != NULL; s = s->next) {
- X if (normal_spline(s)) return(1);
- X }
- X
- X for (c = ob->compounds; c != NULL; c = c->next) {
- X if (normal_spline_exist(c)) return(1);
- X }
- X
- X return(0);
- X }
- X
- Xstruct driver dev_ps = {
- X genps_option,
- X genps_start,
- X genps_arc,
- X genps_ellipse,
- X genps_line,
- X genps_spline,
- X genps_text,
- X genps_end,
- X INCLUDE_TEXT
- X};
- END_OF_FILE
- if test 17407 -ne `wc -c <'transfig/fig2dev/dev/genps.c'`; then
- echo shar: \"'transfig/fig2dev/dev/genps.c'\" unpacked with wrong size!
- fi
- # end of 'transfig/fig2dev/dev/genps.c'
- fi
- echo shar: End of archive 4 \(of 6\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 6 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
- Use a domain-based address or give alternate paths, or you may lose out.
-