From ff32afa0643e21679a6da02608dcaf1e0e64edfd Mon Sep 17 00:00:00 2001 From: Jaap Akkerhuis Date: Tue, 23 Jul 1985 18:21:28 -0800 Subject: [PATCH] Edition 8 Version of pic (May 1985). Local hacks from jaap. SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/Makefile 1.2 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/arcgen.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/blockgen.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/boxgen.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/circgen.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/linegen.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/main.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/misc.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/movegen.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/pic.h 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/picl.l 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/picy.y 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/pltroff.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/print.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/symtab.c 2.1 SCCS-vsn: local/ditroff/ditroff.okeeffe/pic/textgen.c 2.1 --- .../ditroff/ditroff.okeeffe/pic/Makefile | 12 +- .../ditroff/ditroff.okeeffe/pic/arcgen.c | 126 ++- .../ditroff/ditroff.okeeffe/pic/blockgen.c | 96 +- .../ditroff/ditroff.okeeffe/pic/boxgen.c | 39 +- .../ditroff/ditroff.okeeffe/pic/circgen.c | 44 +- .../ditroff/ditroff.okeeffe/pic/linegen.c | 80 +- .../local/ditroff/ditroff.okeeffe/pic/main.c | 274 +++--- .../local/ditroff/ditroff.okeeffe/pic/misc.c | 227 +++-- .../ditroff/ditroff.okeeffe/pic/movegen.c | 31 +- .../local/ditroff/ditroff.okeeffe/pic/pic.h | 146 +-- .../local/ditroff/ditroff.okeeffe/pic/picl.l | 214 +++-- .../local/ditroff/ditroff.okeeffe/pic/picy.y | 250 +++-- .../ditroff/ditroff.okeeffe/pic/pltroff.c | 898 +++--------------- .../local/ditroff/ditroff.okeeffe/pic/print.c | 59 +- .../ditroff/ditroff.okeeffe/pic/symtab.c | 31 +- .../ditroff/ditroff.okeeffe/pic/textgen.c | 143 ++- 16 files changed, 1232 insertions(+), 1438 deletions(-) diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/Makefile b/usr/src/local/ditroff/ditroff.okeeffe/pic/Makefile index dd99bbd2b2..09c5642999 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/Makefile +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/Makefile @@ -1,17 +1,17 @@ # -# Makefile (CWI) 1.1 85/07/19 +# Makefile (CWI) 1.2 85/07/23 # -CFLAGS= -O +CFLAGS= -g YFLAGS= -d DESTDIR= BINDIR=/usr/local OFILES = main.o print.o misc.o symtab.o blockgen.o boxgen.o circgen.o \ - arcgen.o linegen.o movegen.o troffgen.o textgen.o \ - pic2.o pltroff.o + picy.o arcgen.o linegen.o movegen.o textgen.o \ + input.o for.o pltroff.o OLDOFILES = OLDmain.o print.o misc.o symtab.o blockgen.o boxgen.o circgen.o \ arcgen.o linegen.o movegen.o troffgen.o textgen.o \ pic2.o OLDpltroff.o -OBJECTS= pic pltroff vpic +OBJECTS= pic all: ${OBJECTS} @@ -19,9 +19,11 @@ pic: picy.o picl.o ${OFILES} cc -o pic picy.o picl.o ${OFILES} -lm pltroff: driver.o pltroff.o + @echo "not supported" cc -o pltroff pltroff.o driver.o -lm vpic: picy.o picl.o ${OLDOFILES} + @echo "not supported" cc -o vpic picy.o picl.o ${OLDOFILES} -lm OLDpltroff.o: pltroff.c diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/arcgen.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/arcgen.c index 118d6a5042..3d02092d59 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/arcgen.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/arcgen.c @@ -1,12 +1,12 @@ #ifndef lint -static char sccsid[] = "@(#)arcgen.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)arcgen.c 2.1 (CWI) 85/07/23"; #endif lint - #include +#include #include "pic.h" #include "y.tab.h" -struct obj *arcgen(type) /* handles circular and (eventually) elliptical arcs */ +obj *arcgen(type) /* handles circular and (eventually) elliptical arcs */ { static float prevw = HT10; static float prevh = HT5; @@ -16,57 +16,66 @@ struct obj *arcgen(type) /* handles circular and (eventually) elliptical arcs */ static int dctrx[2][4] ={ 0, -1, 0, 1, 0, 1, 0, -1 }; static int dctry[2][4] ={ 1, 0, -1, 0, -1, 0, 1, 0 }; static int nexthv[2][4] ={ U_DIR, L_DIR, D_DIR, R_DIR, D_DIR, R_DIR, U_DIR, L_DIR }; - double sqrt(), atan2(), sin(), cos(); - float dx2, dy2, ht, phi, r, d; - int i, head, to, at, cw, invis; - struct obj *p, *ppos; + float dx2, dy2, ht, phi, r, d, ddval; + int i, head, to, at, cw, invis, ddtype; + obj *p, *ppos; float fromx, fromy, tox, toy; + Attr *ap; prevrad = getfval("arcrad"); prevh = getfval("arrowht"); prevw = getfval("arrowwid"); fromx = curx; fromy = cury; - head = to = at = cw = invis = 0; + head = to = at = cw = invis = ddtype = 0; for (i = 0; i < nattr; i++) { - switch (attr[i].a_type) { - case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: - savetext(attr[i].a_type, attr[i].a_val.p); + ap = &attr[i]; + switch (ap->a_type) { + case TEXTATTR: + savetext(ap->a_sub, ap->a_val.p); break; case HEAD: - head += attr[i].a_val.i; + head += ap->a_val.i; break; case INVIS: invis = INVIS; break; + case DOT: + case DASH: + ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT; + if (ap->a_sub == DEFAULT) + ddval = getfval("dashwid"); + else + ddval = ap->a_val.f; + break; case HEIGHT: /* length of arrowhead */ - prevh = attr[i].a_val.f; + prevh = ap->a_val.f; break; case WIDTH: /* width of arrowhead */ - prevw = attr[i].a_val.f; + prevw = ap->a_val.f; break; case RADIUS: - prevrad = attr[i].a_val.f; + prevrad = ap->a_val.f; break; case DIAMETER: - prevrad = attr[i].a_val.f / 2; + prevrad = ap->a_val.f / 2; break; case CW: cw = 1; break; case FROM: /* start point of arc */ - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; fromx = ppos->o_x; fromy = ppos->o_y; break; case TO: /* end point of arc */ - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; tox = ppos->o_x; toy = ppos->o_y; to++; break; case AT: /* center of arc */ - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; curx = ppos->o_x; cury = ppos->o_y; at = 1; @@ -95,7 +104,9 @@ struct obj *arcgen(type) /* handles circular and (eventually) elliptical arcs */ else if (!at) { dx2 = (tox - fromx) / 2; dy2 = (toy - fromy) / 2; - phi = atan2(dy2, dx2) + (cw ? -PI2 : PI2); + phi = atan2(dy2, dx2) + (cw ? -PI/2 : PI/2); + if (prevrad <= 0.0) + prevrad = dx2*dx2+dy2*dy2; for (r=prevrad; (d = r*r - (dx2*dx2+dy2*dy2)) <= 0.0; r *= 2) ; /* this kludge gets around too-small radii */ prevrad = r; @@ -120,9 +131,7 @@ struct obj *arcgen(type) /* handles circular and (eventually) elliptical arcs */ head = HEAD1; } p = makenode(type, 7); - /* these are wrong in general */ - extreme(fromx, fromy); - extreme(tox, toy); + arc_extreme(fromx, fromy, tox, toy, curx, cury); p->o_val[0] = fromx; p->o_val[1] = fromy; p->o_val[2] = tox; @@ -137,9 +146,78 @@ struct obj *arcgen(type) /* handles circular and (eventually) elliptical arcs */ p->o_val[4] = prevw; p->o_val[5] = prevh; p->o_val[6] = prevrad; - p->o_attr = head | (cw ? CW_ARC : 0) | invis; + p->o_attr = head | (cw ? CW_ARC : 0) | invis | ddtype; + if (head) + p->o_nhead = getfval("arrowhead"); dprintf("arc rad %g at %g %g from %g %g to %g %g head %g %g\n", prevrad, p->o_x, p->o_y, p->o_val[0], p->o_val[1], p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5]); return(p); } + +/*************************************************************************** + bounding box of a circular arc Eric Grosse 24 May 84 + +Conceptually, this routine generates a list consisting of the start, +end, and whichever north, east, south, and west points lie on the arc. +The bounding box is then the range of this list. + list = {start,end} + j = quadrant(start) + k = quadrant(end) + if( j==k && long way 'round ) append north,west,south,east + else + while( j != k ) + append center+radius*[j-th of north,west,south,east unit vectors] + j += 1 (mod 4) + return( bounding box of list ) +The following code implements this, with simple optimizations. +***********************************************************************/ + + +arc_extreme(x0, y0, x1, y1, xc, yc) + double x0, y0, x1, y1, xc, yc; /* start, end, center */ +{ + /* assumes center isn't too far out */ + double r, x, y, xmin, ymin, xmax, ymax; + int j, k; + x0 -= xc; y0 -= yc; /* move to center */ + x1 -= xc; y1 -= yc; + xmin = (x0x1)?x0:x1; ymax = (y0>y1)?y0:y1; + r = sqrt(x0*x0 + y0*y0); + if (r > 0.0) { + j = quadrant(x0,y0); + k = quadrant(x1,y1); + if (j == k && y1*x0 < x1*y0) { + /* viewed as complex numbers, if Im(z1/z0)<0, arc is big */ + if( xmin > -r) xmin = -r; if( ymin > -r) ymin = -r; + if( xmax < r) xmax = r; if( ymax < r) ymax = r; + } else { + while (j != k) { + switch (j) { + case 1: if( ymax < r) ymax = r; break; /* north */ + case 2: if( xmin > -r) xmin = -r; break; /* west */ + case 3: if( ymin > -r) ymin = -r; break; /* south */ + case 4: if( xmax < r) xmax = r; break; /* east */ + } + j = j%4 + 1; + } + } + } + xmin += xc; ymin += yc; + xmax += xc; ymax += yc; + extreme(xmin, ymin); + extreme(xmax, ymax); +} + +quadrant(x,y) + double x, y; +{ + if ( x>=0.0 && y> 0.0) return(1); + else if( x< 0.0 && y>=0.0) return(2); + else if( x<=0.0 && y< 0.0) return(3); + else if( x> 0.0 && y<=0.0) return(4); + else + { fprintf(stderr,"can't happen: x,y=%g,%g",x,y); exit(1);} +} + diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/blockgen.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/blockgen.c index 6207752a54..6d421b6367 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/blockgen.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/blockgen.c @@ -1,61 +1,77 @@ #ifndef lint -static char sccsid[] = "@(#)blockgen.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)blockgen.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include "pic.h" #include "y.tab.h" +#define NBRACK 20 /* depth of [...] */ +#define NBRACE 20 /* depth of {...} */ -struct pushstack stack[20]; +struct pushstack stack[NBRACK]; int nstack = 0; +struct pushstack bracestack[NBRACE]; +int nbstack = 0; -struct obj *leftthing(c) /* called for {... or [... */ +obj *leftthing(c) /* called for {... or [... */ + /* really ought to be separate functions */ int c; { - struct obj *p; + obj *p; - stack[nstack].p_x = curx; - stack[nstack].p_y = cury; - stack[nstack].p_hvmode = hvmode; if (c == '[') { + if (nstack >= NBRACK) + fatal("[...] nested too deep"); + stack[nstack].p_x = curx; + stack[nstack].p_y = cury; + stack[nstack].p_hvmode = hvmode; curx = cury = 0; stack[nstack].p_xmin = xmin; stack[nstack].p_xmax = xmax; stack[nstack].p_ymin = ymin; stack[nstack].p_ymax = ymax; + nstack++; xmin = ymin = 30000; xmax = ymax = -30000; p = makenode(BLOCK, 7); p->o_val[4] = nobj; /* 1st item within [...] */ if (p->o_nobj != nobj-1) fprintf(stderr, "nobjs wrong%d %d\n", p->o_nobj, nobj); - } - else + } else { + if (nbstack >= NBRACK) + fatal("{...} nested too deep"); + bracestack[nbstack].p_x = curx; + bracestack[nbstack].p_y = cury; + bracestack[nbstack].p_hvmode = hvmode; + nbstack++; p = NULL; - nstack++; + } return(p); } -struct obj *rightthing(p, c) /* called for ... ] or ... } */ - struct obj *p; +obj *rightthing(p, c) /* called for ... ] or ... } */ + obj *p; { - struct obj *q; + obj *q; - nstack--; - curx = stack[nstack].p_x; - cury = stack[nstack].p_y; - hvmode = stack[nstack].p_hvmode; if (c == '}') { + nbstack--; + curx = bracestack[nbstack].p_x; + cury = bracestack[nbstack].p_y; + hvmode = bracestack[nbstack].p_hvmode; q = makenode(MOVE, 0); dprintf("M %g %g\n", curx, cury); } else { + nstack--; + curx = stack[nstack].p_x; + cury = stack[nstack].p_y; + hvmode = stack[nstack].p_hvmode; q = makenode(BLOCKEND, 7); q->o_val[4] = p->o_nobj + 1; /* back pointer */ p->o_val[5] = q->o_nobj - 1; /* forward pointer */ p->o_val[0] = xmin; p->o_val[1] = ymin; p->o_val[2] = xmax; p->o_val[3] = ymax; - p->o_dotdash = q->o_dotdash = (int) stack[nstack+1].p_symtab; + p->o_symtab = q->o_symtab = stack[nstack+1].p_symtab; xmin = stack[nstack].p_xmin; ymin = stack[nstack].p_ymin; xmax = stack[nstack].p_xmax; @@ -64,18 +80,15 @@ struct obj *rightthing(p, c) /* called for ... ] or ... } */ return(q); } -struct obj *blockgen(p, type, q) /* handles [...] */ - struct obj *p, *q; +obj *blockgen(p, type, q) /* handles [...] */ + obj *p, *q; int type; { - static float prevh = HT; - static float prevw = WID; /* golden mean, sort of */ - int i, invis, at, ddtype; - float ddval; - int with; - float h, w, xwith, ywith; + int i, invis, at, ddtype, with; + float ddval, h, w, xwith, ywith; float x0, y0, x1, y1, cx, cy; - struct obj *ppos; + obj *ppos; + Attr *ap; invis = at = 0; with = xwith = ywith = 0; @@ -86,28 +99,25 @@ struct obj *blockgen(p, type, q) /* handles [...] */ cy = (p->o_val[3] + p->o_val[1]) / 2; dprintf("cx,cy=%g,%g\n", cx, cy); for (i = 0; i < nattr; i++) { - switch (attr[i].a_type) { + ap = &attr[i]; + switch (ap->a_type) { case HEIGHT: - h = attr[i].a_val.f; + h = ap->a_val.f; break; case WIDTH: - w = attr[i].a_val.f; - break; - case SAME: - h = prevh; - w = prevw; + w = ap->a_val.f; break; case WITH: - with = attr[i].a_val.i; /* corner */ + with = ap->a_val.i; /* corner */ break; case PLACE: /* actually with position ... */ - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; xwith = cx - ppos->o_x; ywith = cy - ppos->o_y; with = PLACE; break; case AT: - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; curx = ppos->o_x; cury = ppos->o_y; at++; @@ -115,8 +125,8 @@ struct obj *blockgen(p, type, q) /* handles [...] */ case INVIS: invis = INVIS; break; - case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: - savetext(attr[i].a_type, attr[i].a_val.p); + case TEXTATTR: + savetext(ap->a_sub, ap->a_val.p); break; } } @@ -175,15 +185,13 @@ struct obj *blockgen(p, type, q) /* handles [...] */ q->o_val[i] = p->o_val[i]; stack[nstack+1].p_symtab = NULL; /* so won't be found again */ blockadj(p); /* fix up coords for enclosed blocks */ - prevh = h; - prevw = w; return(p); } blockadj(p) /* adjust coords in block starting at p */ - struct obj *p; + obj *p; { - struct obj *q; + obj *q; float dx, dy; int n, lev; diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/boxgen.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/boxgen.c index 769783e617..e58b3cd06b 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/boxgen.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/boxgen.c @@ -1,21 +1,19 @@ #ifndef lint -static char sccsid[] = "@(#)boxgen.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)boxgen.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include "pic.h" #include "y.tab.h" -struct obj *boxgen(type) +obj *boxgen(type) { static float prevh = HT; static float prevw = WID; /* golden mean, sort of */ - int i, invis, at, ddtype; + int i, invis, at, ddtype, with; float ddval, xwith, ywith; - int with; - float h, w; - float x0, y0, x1, y1; - struct obj *p, *ppos; + float h, w, x0, y0, x1, y1; + obj *p, *ppos; + Attr *ap; h = getfval("boxht"); w = getfval("boxwid"); @@ -23,22 +21,23 @@ struct obj *boxgen(type) with = xwith = ywith = 0; ddtype = ddval = 0; for (i = 0; i < nattr; i++) { - switch (attr[i].a_type) { + ap = &attr[i]; + switch (ap->a_type) { case HEIGHT: - h = attr[i].a_val.f; + h = ap->a_val.f; break; case WIDTH: - w = attr[i].a_val.f; + w = ap->a_val.f; break; case SAME: h = prevh; w = prevw; break; case WITH: - with = attr[i].a_val.i; /* corner */ + with = ap->a_val.i; /* corner */ break; case AT: - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; curx = ppos->o_x; cury = ppos->o_y; at++; @@ -48,13 +47,14 @@ struct obj *boxgen(type) break; case DOT: case DASH: - ddtype = attr[i].a_type; - ddval = attr[i].a_val.f; - if (ddval == 0) + ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT; + if (ap->a_sub == DEFAULT) ddval = getfval("dashwid"); + else + ddval = ap->a_val.f; break; - case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: - savetext(attr[i].a_type, attr[i].a_val.p); + case TEXTATTR: + savetext(ap->a_sub, ap->a_val.p); break; } } @@ -91,9 +91,8 @@ struct obj *boxgen(type) p = makenode(BOX, 2); p->o_val[0] = w; p->o_val[1] = h; - p->o_dotdash = ddtype; p->o_ddval = ddval; - p->o_attr = invis; + p->o_attr = invis | ddtype; dprintf("B %g %g %g %g at %g %g, h=%g, w=%g\n", x0, y0, x1, y1, curx, cury, h, w); if (isright(hvmode)) curx = x1; diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/circgen.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/circgen.c index 3d278d8b35..4a0f45a4f5 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/circgen.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/circgen.c @@ -1,22 +1,22 @@ #ifndef lint -static char sccsid[] = "@(#)circgen.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)circgen.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include "pic.h" #include "y.tab.h" -struct obj *circgen(type) +obj *circgen(type) { static float rad[2] = { HT2, WID2 }; static float rad2[2] = { HT2, HT2 }; static float x0, y0, x1, y1, x2, y2; - int i, at, t, invis, with; + int i, at, t, invis, ddtype, with; float xwith, ywith; - float r, r2; - struct obj *p, *ppos; + float r, r2, ddval; + obj *p, *ppos; + Attr *ap; - at = invis = 0; + at = invis = ddtype = 0; with = xwith = ywith = 0; t = (type == CIRCLE) ? 0 : 1; if (type == CIRCLE) @@ -25,30 +25,31 @@ struct obj *circgen(type) r = getfval("ellipsewid") / 2; r2 = getfval("ellipseht") / 2; } - for (i = 0; i < nattr; i++) - switch (attr[i].a_type) { - case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: - savetext(attr[i].a_type, attr[i].a_val.p); + for (i = 0; i < nattr; i++) { + ap = &attr[i]; + switch (ap->a_type) { + case TEXTATTR: + savetext(ap->a_sub, ap->a_val.p); break; case RADIUS: - r = attr[i].a_val.f; + r = ap->a_val.f; break; case DIAMETER: case WIDTH: - r = attr[i].a_val.f / 2; + r = ap->a_val.f / 2; break; case HEIGHT: - r2 = attr[i].a_val.f / 2; + r2 = ap->a_val.f / 2; break; case SAME: r = rad[t]; r2 = rad2[t]; break; case WITH: - with = attr[i].a_val.i; + with = ap->a_val.i; break; case AT: - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; curx = ppos->o_x; cury = ppos->o_y; at++; @@ -56,7 +57,16 @@ struct obj *circgen(type) case INVIS: invis = INVIS; break; + case DOT: + case DASH: + ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT; + if (ap->a_sub == DEFAULT) + ddval = getfval("dashwid"); + else + ddval = ap->a_val.f; + break; } + } if (type == CIRCLE) r2 = r; /* probably superfluous */ if (with) { @@ -89,7 +99,7 @@ struct obj *circgen(type) if (r <= 0 || r2 <= 0) { yyerror("%s has invalid radius %g\n", (type==CIRCLE) ? "circle" : "ellipse", ro_attr = invis; + p->o_attr = invis | ddtype; extreme(curx+r, cury+r2); extreme(curx-r, cury-r2); if (type == CIRCLE) diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/linegen.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/linegen.c index ed9631366d..87b35ad7d4 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/linegen.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/linegen.c @@ -1,28 +1,27 @@ #ifndef lint -static char sccsid[] = "@(#)linegen.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)linegen.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include "pic.h" #include "y.tab.h" -struct obj *linegen(type) +obj *linegen(type) { static float prevdx = HT; static float prevdy = 0; static float prevw = HT10; static float prevh = HT5; - int i, j, some, head, ddtype, invis; + int i, j, some, head, ddtype, invis, chop; float ddval, chop1, chop2, x0, y0, x1, y1; - int chop; double sin(), cos(), atan2(), theta; float defx, defy; - struct obj *p, *ppos; + obj *p, *ppos; static int xtab[] = { 1, 0, -1, 0 }; /* R=0, U=1, L=2, D=3 */ static int ytab[] = { 0, 1, 0, -1 }; float dx[50], dy[50]; int ndxy; float nx, ny; + Attr *ap; nx = curx; ny = cury; @@ -34,28 +33,30 @@ struct obj *linegen(type) chop = chop1 = chop2 = 0; ddtype = ddval = 0; for (i = 0; i < nattr; i++) { - switch (attr[i].a_type) { - case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: - savetext(attr[i].a_type, attr[i].a_val.p); + ap = &attr[i]; + switch (ap->a_type) { + case TEXTATTR: + savetext(ap->a_sub, ap->a_val.p); break; case HEAD: - head += attr[i].a_val.i; + head += ap->a_val.i; break; case INVIS: invis = INVIS; break; case CHOP: if (chop++ == 0) - chop1 = chop2 = attr[i].a_val.f; + chop1 = chop2 = ap->a_val.f; else - chop2 = attr[i].a_val.f; + chop2 = ap->a_val.f; break; case DOT: case DASH: - ddtype = attr[i].a_type; - ddval = attr[i].a_val.f; - if (ddval == 0) + ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT; + if (ap->a_sub == DEFAULT) ddval = getfval("dashwid"); + else + ddval = ap->a_val.f; break; case SAME: dx[ndxy] = prevdx; @@ -63,30 +64,30 @@ struct obj *linegen(type) some++; break; case LEFT: - dx[ndxy] -= (attr[i].a_val.f==0) ? defx : attr[i].a_val.f; + dx[ndxy] -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f; some++; hvmode = L_DIR; break; case RIGHT: - dx[ndxy] += (attr[i].a_val.f==0) ? defx : attr[i].a_val.f; + dx[ndxy] += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f; some++; hvmode = R_DIR; break; case UP: - dy[ndxy] += (attr[i].a_val.f==0) ? defy : attr[i].a_val.f; + dy[ndxy] += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f; some++; hvmode = U_DIR; break; case DOWN: - dy[ndxy] -= (attr[i].a_val.f==0) ? defy : attr[i].a_val.f; + dy[ndxy] -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f; some++; hvmode = D_DIR; break; case HEIGHT: /* length of arrowhead */ - prevh = attr[i].a_val.f; + prevh = ap->a_val.f; break; case WIDTH: /* width of arrowhead */ - prevw = attr[i].a_val.f; + prevw = ap->a_val.f; break; case TO: if (some) { @@ -101,7 +102,13 @@ struct obj *linegen(type) some++; break; case BY: - ppos = attr[i].a_val.o; + if (some) { + nx += dx[ndxy]; + ny += dy[ndxy]; + ndxy++; + dx[ndxy] = dy[ndxy] = some = 0; + } + ppos = ap->a_val.o; dx[ndxy] = ppos->o_x; dy[ndxy] = ppos->o_y; some++; @@ -116,7 +123,7 @@ struct obj *linegen(type) break; case FROM: case AT: - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; nx = curx = ppos->o_x; ny = cury = ppos->o_y; break; @@ -155,28 +162,42 @@ struct obj *linegen(type) dy[0] -= y0; dx[ndxy-1] -= x1; dy[ndxy-1] -= y1; - if(dbg)printf("chopping %g %g %g %g; cur=%g,%g end=%g,%g\n", + dprintf("chopping %g %g %g %g; cur=%g,%g end=%g,%g\n", x0, y0, x1, y1, curx, cury, nx, ny); } p = makenode(type, 5 + 2 * ndxy); curx = p->o_val[0] = nx; cury = p->o_val[1] = ny; if (head || type == ARROW) { + p->o_nhead = getfval("arrowhead"); p->o_val[2] = prevw; p->o_val[3] = prevh; if (head == 0) head = HEAD2; /* default arrow head */ } - p->o_attr = head | invis; + p->o_attr = head | invis | ddtype; p->o_val[4] = ndxy; nx = p->o_x; ny = p->o_y; for (i = 0, j = 5; i < ndxy; i++, j += 2) { p->o_val[j] = dx[i]; p->o_val[j+1] = dy[i]; - extreme(nx += dx[i], ny += dy[i]); + if (type == LINE) + extreme(nx += dx[i], ny += dy[i]); + else if (type == SPLINE && i < ndxy-1) { + /* to compute approx extreme of spline at p, + /* compute midway between p-1 and p+1, + /* then go 3/4 from there to p */ + float ex, ey, xi, yi, xi1, yi1; + xi = nx + dx[i]; yi = ny + dy[i]; /* p */ + xi1 = xi + dx[i+1]; yi1 = yi + dy[i+1]; /* p+1 */ + ex = (nx+xi1)/2; ey = (ny+yi1)/2; /* midway */ + ex += 0.75*(xi-ex); ey += 0.75*(yi-ey); + extreme(ex, ey); + nx = xi; ny = yi; + } + } - p->o_dotdash = ddtype; p->o_ddval = ddval; if (dbg) { printf("S or L from %g %g to %g %g with %d elements:\n", p->o_x, p->o_y, curx, cury, ndxy); @@ -187,8 +208,3 @@ struct obj *linegen(type) extreme(curx, cury); return(p); } - -struct obj *splinegen(type) -{ - linegen(type); -} diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/main.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/main.c index 46dce90ddf..b1833ad383 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/main.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/main.c @@ -1,18 +1,21 @@ #ifndef lint -static char sccsid[] = "@(#)main.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)main.c 2.1 (CWI) 85/07/23"; #endif lint - #include +#include #include "pic.h" #include "y.tab.h" -struct obj *objlist[MAXOBJ]; /* store the elements here */ +obj **objlist = 0; /* store the elements here */ +int nobjlist = 0; /* size of objlist array */ int nobj = 0; -struct attr attr[40]; /* attributes stored here as collected */ +Attr *attr; /* attributes stored here as collected */ +int nattrlist = 0; int nattr = 0; /* number of entries in attr_list */ -struct text text[MAXTEXT]; /* text strings stored here as collected */ +Text *text = 0; /* text strings stored here as collected */ +int ntextlist = 0; /* size of text[] array */ int ntext = 0; int ntext1 = 0; /* record ntext here on entry to each figure */ @@ -26,50 +29,10 @@ int codegen = 0; /* 1=>output for this picture; 0=>no output */ float deltx = 6; /* max x value in output, for scaling */ float delty = 6; /* max y value in output, for scaling */ int dbg = 0; -extern FILE *yyin, /* input file pointer */ - *skeldb; /* output pointer for dbg messeges */ int lineno = 0; char *filename = "-"; int synerr = 0; char *cmdname; -int crop = 1; /* trim off exterior white space if non-zero */ -extern int useDline; /* if set, use \D for all lines */ - -/* You may want to change this if you don't have a 202... */ - -/* - *#ifdef APS - * int devtype = DEVAPS; - * int res = 723; - * int DX = 3; - * int DY = 3; - * - *#ifdef 202 - * int devtype = DEV202; - * int res = 972; /* default is 202 * - * int DX = 4; /* used only for old-style troff * - * int DY = 4; - */ -#ifdef OLDTROFF -/* mandatory values for graphic systems CAT: */ -int devtype = DEVCAT; -int res = 432; -int DX = 3; -int DY = 3; -#else - int devtype = DEVHAR; - int res = 1445; /* default is HARRIS */ - int DX = 4; /* used only for old-style troff */ - int DY = 4; -#endif - -float hshift = 0; /* move this far left for text (in em's) */ -float vshift = 0.2; /* this far down */ - -float sxmin; /* lower limit from s command */ -float symin; -float sxmax = 4096; /* upper */ -float symax = 4096; float xmin = 30000; /* min values found in actual data */ float ymin = 30000; @@ -77,87 +40,94 @@ float xmax = -30000; /* max */ float ymax = -30000; main(argc, argv) - char **argv; + char *argv[]; { + char buf[20]; + extern int fpecatch(); + + signal(SIGFPE, fpecatch); cmdname = argv[0]; while (argc > 1 && *argv[1] == '-') { switch (argv[1][1]) { - case 'T': - if (strcmp(&argv[1][2], "aps") == 0) { - res = 723; - devtype = DEVAPS; - DX = DY = 1; - } else if (strcmp(&argv[1][2], "cat") == 0) { - res = 432; - devtype = DEVCAT; - DX = DY = 3; - } else if (strcmp(&argv[1][2], "ver") == 0) { - res = 200; - devtype = DEVVER; - DX = DY = 1; - } else if (strcmp(&argv[1][2], "450") == 0) { - res = 240; - devtype = DEV450; - } else if (strcmp(&argv[1][2], "har") == 0) { - res = 1445; - devtype = DEVHAR; - } else { - res = atoi(&argv[1][2]); - } - break; case 'd': - dbg = 1; - break; - case 'D': -# ifdef OLDTROFF - useDline = !useDline; -# endif + dbg = atoi(&argv[1][2]); + if (dbg == 0) + dbg = 1; break; } argc--; argv++; } -# ifndef OLDTROFF - useDline = 1; -# endif -# setdefaults(); + objlist = (obj **) grow(objlist, "objlist", nobjlist += 1000, sizeof(obj *)); + text = (Text *) grow(text, "text", ntextlist += 1000, sizeof(Text)); + attr = (Attr *) grow(attr, "attr", nattrlist += 100, sizeof(Attr)); + + sprintf(buf, "/%d/", getpid()); + pushsrc(String, buf); + definition("pid"); + + pushsrc(File, curfile = infile); if (argc <= 1) { - yyin = stdin; - getdata(yyin); + curfile->fin = stdin; + curfile->fname = tostring("-"); + getdata(curfile); } else while (argc-- > 1) { - if ((yyin = fopen(*++argv, "r")) == NULL) { - fprintf(stderr, "pic: can't open %s\n", *argv); + if ((curfile->fin = fopen(*++argv, "r")) == NULL) { + fprintf(stderr, "%s: can't open %s\n", cmdname, *argv); exit(1); } - filename = *argv; - getdata(yyin); - fclose(yyin); + curfile->fname = tostring(*argv); + getdata(curfile); + fclose(curfile->fin); + free(curfile->fname); } exit(0); } +fpecatch() +{ + fatal("floating point exception"); +} + +char *grow(ptr, name, num, size) /* make array bigger */ + char *ptr, *name; + int num, size; +{ + char *p; + + if (ptr == NULL) + p = malloc(num * size); + else + p = realloc(ptr, num * size); + if (p == NULL) + fatal("can't grow %s to %d", name, num * size); + return p; +} + static struct { char *name; float val; + short scalable; /* 1 => adjust when "scale" changes */ } defaults[] ={ - "scale", SCALE, - "lineht", HT, - "linewid", HT, - "moveht", HT, - "movewid", HT, - "dashwid", HT10, - "boxht", HT, - "boxwid", WID, - "circlerad", HT2, - "arcrad", HT2, - "ellipseht", HT, - "ellipsewid", WID, - "arrowht", HT5, - "arrowwid", HT10, - "textht", HT, - "textwid", WID, + "scale", SCALE, 1, + "lineht", HT, 1, + "linewid", HT, 1, + "moveht", HT, 1, + "movewid", HT, 1, + "dashwid", HT10, 1, + "boxht", HT, 1, + "boxwid", WID, 1, + "circlerad", HT2, 1, + "arcrad", HT2, 1, + "ellipseht", HT, 1, + "ellipsewid", WID, 1, + "arrowht", HT5, 1, + "arrowwid", HT10, 1, + "arrowhead", 2, 0, /* arrowhead style */ + "textht", 0.0, 1, /* 6 lines/inch is also a useful value */ + "textwid", 0.0, 1, NULL, 0 }; @@ -172,6 +142,23 @@ setdefaults() /* set default sizes for variables like boxht */ } } +resetvar() /* reset variables listed */ +{ + int i, j; + + if (nattr == 0) { /* none listed, so do all */ + setdefaults(); + return; + } + for (i = 0; i < nattr; i++) { + for (j = 0; defaults[j].name != NULL; j++) + if (strcmp(defaults[j].name, attr[i].a_val.p) == 0) { + setfval(defaults[j].name, defaults[j].val); + free(attr[i].a_val.p); + break; + } + } +} checkscale(s) /* if s is "scale", adjust default variables */ char *s; @@ -182,70 +169,70 @@ checkscale(s) /* if s is "scale", adjust default variables */ if (strcmp(s, "scale") == 0) { scale = getfval("scale"); for (i = 1; defaults[i].name != NULL; i++) - setfval(defaults[i].name, defaults[i].val * scale); + if (defaults[i].scalable) + setfval(defaults[i].name, defaults[i].val * scale); } } -getdata(fin) - register FILE *fin; +getdata() { - char buf[1000], buf1[50]; - FILE *svyyin; - int svlineno; - char *svfilename, *p; + char *p, buf[1000], buf1[100]; + int ln; - lineno = 0; - while (fgets(buf, sizeof buf, fin) != NULL) { - lineno++; + curfile->lineno = 0; + printf(".lf 1 %s\n", curfile->fname); + while (fgets(buf, sizeof buf, curfile->fin) != NULL) { + curfile->lineno++; if (*buf == '.' && *(buf+1) == 'P' && *(buf+2) == 'S') { for (p = &buf[3]; *p == ' '; p++) ; if (*p++ == '<') { - svyyin = yyin; - svlineno = lineno; - svfilename = filename; + Infile svfile; + svfile = *curfile; sscanf(p, "%s", buf1); - if ((yyin = fopen(buf1, "r")) == NULL) { - fprintf(stderr, "pic: can't open %s\n", buf1); - exit(1); - } - lineno = 0; - filename = p; - getdata(yyin); - fclose(yyin); - lineno = svlineno; - yyin = svyyin; - filename = svfilename; + if ((curfile->fin=fopen(buf1, "r")) == NULL) + fatal("can't open %s", buf1); + curfile->fname = tostring(buf1); + getdata(); + fclose(curfile->fin); + free(curfile->fname); + *curfile = svfile; + printf(".lf %d %s\n", curfile->lineno, curfile->fname); continue; } reset(); yyparse(); - /* yylval now contains 'E' or 'F' from .PE or .PF */ - if (buf[3] == ' ') /* assume next thing is width */ - deltx = delty = atof(&buf[4]); - else { - deltx = xmax - xmin; - if (deltx <= 0) - deltx = ymax - ymin; - deltx /= getfval("scale"); - delty = deltx; + /* yylval.i now contains 'E' or 'F' from .PE or .PF */ + + deltx = (xmax - xmin) / getfval("scale"); + delty = (ymax - ymin) / getfval("scale"); + if (buf[3] == ' ') { /* next things are wid & ht */ + if (sscanf(&buf[4],"%f%f",&deltx,&delty) < 2) + delty = deltx * (ymax-ymin) / (xmax-xmin); } - dprintf("deltx = %.3f\n", deltx); + dprintf("deltx = %g, delty = %g\n", deltx, delty); if (codegen && !synerr) { openpl(&buf[3]); /* puts out .PS, with ht & wid stuck in */ + printf(".lf %d\n", curfile->lineno+1); print(); /* assumes \n at end */ - closepl(yylval.p); /* does the .PE/F */ + closepl(yylval.i); /* does the .PE/F */ } + printf(".lf %d\n", curfile->lineno+1); fflush(stdout); - } - else + } else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') { + if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) { + free(curfile->fname); + printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = tostring(buf1)); + } else + printf(".lf %d\n", curfile->lineno = ln); + } else fputs(buf, stdout); } } reset() { - struct obj *op; + obj *op; int i; struct symtab *p; extern int nstack; @@ -253,20 +240,19 @@ reset() for (i = 0; i < nobj; i++) { op = objlist[i]; if (op->o_type == BLOCK) - freesymtab(op->o_dotdash); /* funny place */ + freesymtab(op->o_symtab); free(objlist[i]); } nobj = 0; nattr = 0; for (i = 0; i < ntext; i++) - free(text[i].t_val); + if (text[i].t_val) + free(text[i].t_val); ntext = ntext1 = 0; codegen = synerr = 0; nstack = 0; curx = cury = 0; hvmode = R_DIR; - sxmin = symin = 0; - sxmax = symax = 4096; xmin = ymin = 30000; xmax = ymax = -30000; } diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/misc.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/misc.c index 43614db26d..e1f8646e21 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/misc.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/misc.c @@ -1,12 +1,11 @@ #ifndef lint -static char sccsid[] = "@(#)misc.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)misc.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include "pic.h" #include "y.tab.h" -setdir(n) /* set direction from n */ +setdir(n) /* set direction (hvmode) from LEFT, RIGHT, etc. */ int n; { switch (n) { @@ -18,8 +17,18 @@ setdir(n) /* set direction from n */ return(hvmode); } +curdir() /* convert current dir (hvmode) to RIGHT, LEFT, etc. */ +{ + switch (hvmode) { + case R_DIR: return RIGHT; + case L_DIR: return LEFT; + case U_DIR: return UP; + case D_DIR: return DOWN; + } +} + float getcomp(p, t) /* return component of a position */ - struct obj *p; + obj *p; int t; { switch (t) { @@ -60,16 +69,86 @@ float getcomp(p, t) /* return component of a position */ } } -makeattr(type, val) /* add attribute type and val */ - int type; +float exprlist[100]; +int nexpr = 0; + +exprsave(f) + float f; +{ + exprlist[nexpr++] = f; +} + +char *sprintgen(fmt) + char *fmt; +{ + int i; + char buf[1000]; + + sprintf(buf, fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]); + nexpr = 0; + free(fmt); + return tostring(buf); +} + +makefattr(type, sub, f) /* float attr */ + int type, sub; + float f; +{ + YYSTYPE val; + val.f = f; + makeattr(type, sub, val); +} + +makeoattr(type, o) /* obj* attr */ + obj *o; +{ + YYSTYPE val; + val.o = o; + makeattr(type, 0, val); +} + +makeiattr(type, i) /* int attr */ + int i; +{ + YYSTYPE val; + val.i = i; + makeattr(type, 0, val); +} + +maketattr(sub, p) /* text attribute: takes two */ + char *p; +{ + YYSTYPE val; + val.p = p; + makeattr(TEXTATTR, sub, val); +} + +addtattr(sub) /* add text attrib to existing item */ +{ + attr[nattr-1].a_sub |= sub; +} + +makevattr(p) /* varname attribute */ + char *p; +{ + YYSTYPE val; + val.p = p; + makeattr(VARNAME, 0, val); +} + +makeattr(type, sub, val) /* add attribute type and val */ + int type, sub; YYSTYPE val; { if (type == 0 && val.i == 0) { /* clear table for next stat */ nattr = 0; return; } - dprintf("attr %d: %d %d\n", nattr, type, val.i); + if (nattr >= nattrlist) + attr = (Attr *) grow(attr, "attr", nattrlist += 100, sizeof(Attr)); + dprintf("attr %d: %d %d %d\n", nattr, type, sub, val.i); attr[nattr].a_type = type; + attr[nattr].a_sub = sub; attr[nattr].a_val = val; nattr++; } @@ -77,13 +156,13 @@ makeattr(type, val) /* add attribute type and val */ printexpr(f) /* print expression for debugging */ float f; { - dprintf("%g\n", f); + printf("%g\n", f); } printpos(p) /* print position for debugging */ - struct obj *p; + obj *p; { - dprintf("%g, %g\n", p->o_x, p->o_y); + printf("%g, %g\n", p->o_x, p->o_y); } char *tostring(s) @@ -100,10 +179,10 @@ char *tostring(s) return(p); } -struct obj *makepos(x, y) /* make a osition cell */ +obj *makepos(x, y) /* make a osition cell */ float x, y; { - struct obj *p; + obj *p; p = makenode(PLACE, 0); p->o_x = x; @@ -111,11 +190,11 @@ struct obj *makepos(x, y) /* make a osition cell */ return(p); } -struct obj *makebetween(f, p1, p2) /* make position between p1 and p2 */ +obj *makebetween(f, p1, p2) /* make position between p1 and p2 */ float f; - struct obj *p1, *p2; + obj *p1, *p2; { - struct obj *p; + obj *p; dprintf("fraction = %.2f\n", f); p = makenode(PLACE, 0); @@ -124,13 +203,25 @@ struct obj *makebetween(f, p1, p2) /* make position between p1 and p2 */ return(p); } -struct obj *getpos(p, corner) /* find position of point */ - struct obj *p; +obj *getpos(p, corner) /* find position of point */ + obj *p; + int corner; +{ + float x, y; + + whatpos(p, corner, &x, &y); + return makepos(x, y); +} + +whatpos(p, corner, px, py) /* what is the position (no side effect) */ + obj *p; int corner; + float *px, *py; { float x, y, x1, y1; + extern double sqrt(); - dprintf("getpos %o %d\n", p, corner); + dprintf("whatpos %o %d\n", p, corner); x = p->o_x; y = p->o_y; x1 = p->o_val[0]; @@ -151,12 +242,33 @@ struct obj *getpos(p, corner) /* find position of point */ case NW: x -= x1 / 2; y += y1 / 2; break; case START: if (p->o_type == BLOCK) - return getpos(objlist[(int)p->o_val[2]], START); + return whatpos(objlist[(int)p->o_val[2]], START, px, py); case END: if (p->o_type == BLOCK) - return getpos(objlist[(int)p->o_val[3]], END); + return whatpos(objlist[(int)p->o_val[3]], END, px, py); } break; + case ARC: + switch (corner) { + case START: + if (p->o_attr & CW_ARC) { + x = p->o_val[2]; y = p->o_val[3]; + } else { + x = x1; y = y1; + } + break; + case END: + if (p->o_attr & CW_ARC) { + x = x1; y = y1; + } else { + x = p->o_val[2]; y = p->o_val[3]; + } + break; + } + if (corner == START || corner == END) + break; + x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y)); + /* Fall Through! */ case CIRCLE: case ELLIPSE: switch (corner) { @@ -177,6 +289,7 @@ struct obj *getpos(p, corner) /* find position of point */ switch (corner) { case START: break; /* already in place */ case END: x = x1; y = y1; break; + default: /* change! */ case CENTER: x = (x+x1)/2; y = (y+y1)/2; break; case NORTH: if (y1 > y) { x = x1; y = y1; } break; case SOUTH: if (y1 < y) { x = x1; y = y1; } break; @@ -184,40 +297,23 @@ struct obj *getpos(p, corner) /* find position of point */ case WEST: if (x1 < x) { x = x1; y = y1; } break; } break; - case ARC: - switch (corner) { - case START: - if (p->o_attr & CW_ARC) { - x = p->o_val[2]; y = p->o_val[3]; - } else { - x = x1; y = y1; - } - break; - case END: - if (p->o_attr & CW_ARC) { - x = x1; y = y1; - } else { - x = p->o_val[2]; y = p->o_val[3]; - } - break; - } - break; } - dprintf("getpos returns %g %g\n", x, y); - return(makepos(x, y)); + dprintf("whatpos returns %g %g\n", x, y); + *px = x; + *py = y; } -struct obj *gethere(n) /* make a place for curx,cury */ +obj *gethere(n) /* make a place for curx,cury */ { dprintf("gethere %g %g\n", curx, cury); return(makepos(curx, cury)); } -struct obj *getlast(n, t) /* find n-th previous occurrence of type t */ +obj *getlast(n, t) /* find n-th previous occurrence of type t */ int n, t; { int i, k; - struct obj *p; + obj *p; k = n; for (i = nobj-1; i >= 0; i--) { @@ -237,11 +333,11 @@ struct obj *getlast(n, t) /* find n-th previous occurrence of type t */ return(NULL); } -struct obj *getfirst(n, t) /* find n-th occurrence of type t */ +obj *getfirst(n, t) /* find n-th occurrence of type t */ int n, t; { int i, k; - struct obj *p; + obj *p; k = n; for (i = 0; i < nobj; i++) { @@ -261,8 +357,8 @@ struct obj *getfirst(n, t) /* find n-th occurrence of type t */ return(NULL); } -struct obj *getblock(p, s) /* find variable s in block p */ - struct obj *p; +obj *getblock(p, s) /* find variable s in block p */ + obj *p; char *s; { struct symtab *stp; @@ -271,7 +367,7 @@ struct obj *getblock(p, s) /* find variable s in block p */ yyerror(".%s is not in that block", s); return(NULL); } - for (stp = (struct symtab *) p->o_dotdash; stp != NULL; stp = stp->s_next) + for (stp = p->o_symtab; stp != NULL; stp = stp->s_next) if (strcmp(s, stp->s_name) == 0) { dprintf("getblock found x,y= %g,%g\n", (stp->s_val.o)->o_x, (stp->s_val.o)->o_y); @@ -281,21 +377,36 @@ struct obj *getblock(p, s) /* find variable s in block p */ return(NULL); } -struct obj *fixpos(p, x, y) - struct obj *p; +obj *fixpos(p, x, y) + obj *p; float x, y; { dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y); return makepos(p->o_x + x, p->o_y + y); } -struct obj *makenode(type, n) +obj *addpos(p, q) + obj *p, *q; +{ + dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y); + return makepos(p->o_x+q->o_x, p->o_y+q->o_y); +} + +obj *subpos(p, q) + obj *p, *q; +{ + dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y); + return makepos(p->o_x-q->o_x, p->o_y-q->o_y); +} + +obj *makenode(type, n) int type, n; { - struct obj *p; + obj *p; int i; + extern char *calloc(); - p = (struct obj *) malloc(sizeof(struct obj) + (n-1)*sizeof(float)); + p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(float)); if (p == NULL) { yyerror("out of space in makenode\n"); exit(1); @@ -309,13 +420,9 @@ struct obj *makenode(type, n) p->o_nt1 = ntext1; p->o_nt2 = ntext; ntext1 = ntext; /* ready for next caller */ - p->o_attr = p->o_dotdash = p->o_ddval = 0; - for (i = 0; i < n; i++) - p->o_val[i] = 0; - if (nobj >= MAXOBJ) { - yyerror("objlist overflow\n"); - exit(1); - } + if (nobj >= nobjlist) + objlist = (obj **) grow(objlist, "objlist", + nobjlist += 100, sizeof(obj *)); objlist[nobj++] = p; return(p); } diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/movegen.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/movegen.c index e55cb74f43..aa56d0e4f2 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/movegen.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/movegen.c @@ -1,28 +1,29 @@ #ifndef lint -static char sccsid[] = "@(#)movegen.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)movegen.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include "pic.h" #include "y.tab.h" -struct obj *movegen(type) +obj *movegen(type) { static float prevdx, prevdy; int i, some; float defx, defy, dx, dy; - struct obj *p; - struct obj *ppos; + obj *p; + obj *ppos; static int xtab[] = { 1, 0, -1, 0 }; /* R=0, U=1, L=2, D=3 */ static int ytab[] = { 0, 1, 0, -1 }; + Attr *ap; defx = getfval("movewid"); defy = getfval("moveht"); dx = dy = some = 0; for (i = 0; i < nattr; i++) { - switch (attr[i].a_type) { - case LJUST: case RJUST: case CENTER: case SPREAD: case FILL: case ABOVE: case BELOW: - savetext(attr[i].a_type, attr[i].a_val.p); + ap = &attr[i]; + switch (ap->a_type) { + case TEXTATTR: + savetext(ap->a_sub, ap->a_val.p); break; case SAME: dx = prevdx; @@ -30,40 +31,40 @@ struct obj *movegen(type) some++; break; case LEFT: - dx -= (attr[i].a_val.f==0) ? defx : attr[i].a_val.f; + dx -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f; some++; hvmode = L_DIR; break; case RIGHT: - dx += (attr[i].a_val.f==0) ? defx : attr[i].a_val.f; + dx += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f; some++; hvmode = R_DIR; break; case UP: - dy += (attr[i].a_val.f==0) ? defy : attr[i].a_val.f; + dy += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f; some++; hvmode = U_DIR; break; case DOWN: - dy -= (attr[i].a_val.f==0) ? defy : attr[i].a_val.f; + dy -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f; some++; hvmode = D_DIR; break; case TO: - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; dx = ppos->o_x - curx; dy = ppos->o_y - cury; some++; break; case BY: - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; dx = ppos->o_x; dy = ppos->o_y; some++; break; case FROM: case AT: - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; curx = ppos->o_x; cury = ppos->o_y; break; diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/pic.h b/usr/src/local/ditroff/ditroff.okeeffe/pic/pic.h index 57da3f4617..29a6eeee82 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/pic.h +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/pic.h @@ -1,16 +1,26 @@ -#ifndef lint -static char sccsid[] = "@(#)pic.h 1.1 (CWI) 85/07/19"; -#endif lint - #define dprintf if(dbg)printf +#define DEFAULT 0 + #define HEAD1 1 #define HEAD2 2 #define HEAD12 (HEAD1+HEAD2) #define INVIS 4 #define CW_ARC 8 /* clockwise arc */ +#ifndef PI #define PI 3.141592654 -#define PI2 PI/2 +#endif +#define DOTBIT 16 +#define DASHBIT 32 + +#define CENTER 01 /* text attributes */ +#define LJUST 02 +#define RJUST 04 +#define ABOVE 010 +#define BELOW 020 +#define SPREAD 040 +#define FILL 0100 + #define SCALE 1.0 /* default scale: units/inch */ #define WID 0.75 /* default width for boxes and ellipses */ #define WID2 0.375 @@ -19,16 +29,6 @@ static char sccsid[] = "@(#)pic.h 1.1 (CWI) 85/07/19"; #define HT5 0.1 #define HT10 0.05 -#define MAXOBJ 1200 -#define MAXTEXT 1200 -#define SYMTAB 200 -#define DEV202 1 -#define DEVAPS 2 -#define DEVCAT 3 -#define DEV450 4 -#define DEVVER 5 -#define DEVHAR 6 - /* these have to be like so, so that we can write */ /* things like R & V, etc. */ #define H 0 @@ -44,35 +44,37 @@ static char sccsid[] = "@(#)pic.h 1.1 (CWI) 85/07/19"; #define isdown(n) ((n) == D_DIR) #define isup(n) ((n) == U_DIR) -typedef union { /* the yacc stack type */ - int i; - char *p; - struct obj *o; - float f; -} YYSTYPE; - -extern YYSTYPE yylval, yyval; - -struct attr { /* attribute of an object */ - int a_type; - YYSTYPE a_val; +typedef struct Point { + float x; + float y; }; -struct obj { /* stores various things in variable length */ +typedef struct obj { /* stores various things in variable length */ int o_type; int o_count; /* number of things */ int o_nobj; /* index in objlist */ int o_mode; /* hor or vert */ - float o_x; /* coord of "center" */ + float o_x; /* coord of "center" */ float o_y; - int o_nt1; /* 1st index in text[] for this object */ - int o_nt2; /* 2nd; difference is #text strings */ - int o_attr; /* various attributes of interest */ - int o_dotdash; /* kludge in a dot/dash mode */ + int o_nt1; /* 1st index in text[] for this object */ + int o_nt2; /* 2nd; difference is #text strings */ + int o_attr; /* HEAD, CW, INVIS go here */ + int o_size; /* linesize */ + int o_nhead; /* arrowhead style */ + struct symtab *o_symtab; /* symtab for [...] */ float o_ddval; /* value of dot/dash expression */ float o_val[1]; /* actually this will be > 1 in general */ /* type is not always FLOAT!!!! */ -}; +} obj; + +typedef union { /* the yacc stack type */ + int i; + char *p; + obj *o; + float f; +} YYSTYPE; + +extern YYSTYPE yylval, yyval; struct symtab { char *s_name; @@ -81,40 +83,75 @@ struct symtab { struct symtab *s_next; }; -struct text { - int t_type; +typedef struct { /* attribute of an object */ + int a_type; + int a_sub; + YYSTYPE a_val; +} Attr; + +typedef struct { + int t_type; /* CENTER, LJUST, etc. */ + char t_op; /* optional sign for size changes */ + char t_size; /* size, abs or rel */ char *t_val; -}; +} Text; + +#define String 01 +#define Macro 02 +#define File 04 +#define Char 010 +#define Thru 020 +#define Free 040 + +typedef struct { /* input source */ + int type; /* Macro, String, File */ + char *sp; /* if String or Macro */ +} Src; + +extern Src src[], *srcp; /* input source stack */ + +typedef struct { + FILE *fin; + char *fname; + int lineno; +} Infile; + +extern Infile infile[], *curfile; + +#define MAXARGS 20 +typedef struct { /* argument stack */ + char *argstk[MAXARGS]; /* pointers to args */ + char *argval; /* points to space containing args */ +} Arg; extern int dbg; -extern struct obj *objlist[]; -extern int nobj; -extern struct attr attr[]; -extern int nattr; -extern struct text text[]; +extern obj **objlist; +extern int nobj, nobjlist; +extern Attr *attr; +extern int nattr, nattrlist; +extern Text *text; +extern int ntextlist; extern int ntext; extern int ntext1; extern float curx, cury; extern int hvmode; extern int codegen; -extern char *malloc(), *tostring(); +extern char *malloc(), *realloc(), *tostring(), *grow(); extern float getfval(), getcomp(); extern YYSTYPE getvar(); extern struct symtab *lookup(), *makevar(); +extern char *ifstat(), *delimstr(), *sprintgen(); extern float deltx, delty; extern int lineno; extern int synerr; -extern int crop; -extern int devtype, res, DX, DY; -extern float sxmin, sxmax, symin, symax; extern float xmin, ymin, xmax, ymax; -extern struct obj *leftthing(), *boxgen(), *circgen(), *arcgen(); -extern struct obj *linegen(), *splinegen(), *movegen(), *textgen(); -extern struct obj *troffgen(), *rightthing(), *blockgen(); -extern struct obj *makenode(), *makepos(), *fixpos(), *makebetween(); -extern struct obj *getpos(), *gethere(), *getfirst(), *getlast(), *getblock(); +extern obj *leftthing(), *boxgen(), *circgen(), *arcgen(); +extern obj *linegen(), *splinegen(), *movegen(), *textgen(), *plotgen(); +extern obj *troffgen(), *rightthing(), *blockgen(); +extern obj *makenode(), *makepos(), *fixpos(), *addpos(), *subpos(), *makebetween(); +extern obj *getpos(), *gethere(), *getfirst(), *getlast(), *getblock(); struct pushstack { float p_x; @@ -128,6 +165,9 @@ struct pushstack { }; extern struct pushstack stack[]; extern int nstack; -extern int cw; +extern int cw; -extern float atof(); +extern double errcheck(); +#define Log10(x) errcheck(log10(x), "log") +#define Exp(x) errcheck(exp(x), "exp") +#define Sqrt(x) errcheck(sqrt(x), "sqrt") diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/picl.l b/usr/src/local/ditroff/ditroff.okeeffe/pic/picl.l index 71f46287fe..0eaf73d874 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/picl.l +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/picl.l @@ -1,14 +1,10 @@ -#ifndef lint -static char sccsid[] = "@(#)picl.l 1.1 (CWI) 85/07/19"; -#endif lint - -%Start A str comment def sc br -%e 1300 -%k 100 -%a 1400 -%o 1200 -%p 4000 -%n 600 +%Start A str def sc br thru sh +%e 1700 +%k 120 +%a 1800 +%o 1500 +%p 5000 +%n 700 %{ #undef input @@ -20,13 +16,13 @@ static char sccsid[] = "@(#)picl.l 1.1 (CWI) 85/07/19"; extern float atof(); extern struct symtab symtab[]; -extern char *filename; -extern int synerr; +extern char *filename, *copythru(); #define CADD cbuf[clen++]=yytext[0]; if(clen>=CBUFLEN-1) {yyerror("string too long", cbuf); BEGIN A;} -#define CBUFLEN 150 +#define CBUFLEN 500 char cbuf[CBUFLEN]; -int clen, cflag; +int c, clen, cflag, delim; +int ifsw = 0; /* 1 if if statement in progress */ %} A [a-zA-Z_] @@ -54,14 +50,13 @@ WS [ \t] "}" { BEGIN sc; return(ST); } "]" { BEGIN br; return(ST); } -^".".* { if (yytext[1] == 'P' && (yytext[2] == 'E' || yytext[2] == 'F')) { +^".PS".* { if (curfile == infile) yyerror(".PS found inside .PS/.PE"); } +^"."P[EF].* { if (curfile == infile) { yylval.i = yytext[2]; return(EOF); - } else { - yylval.p = tostring(yytext); - return(TROFF); } } +^".".* { yylval.p = tostring(yytext); return(TROFF); } print return(yylval.i = PRINT); box return(yylval.i = BOX); @@ -73,6 +68,8 @@ WS [ \t] line return(yylval.i = LINE); move return(yylval.i = MOVE); "[]" return(yylval.i = BLOCK); +reset return(RESET); +sprintf return(SPRINTF); same return(SAME); between return(BETWEEN); @@ -82,35 +79,21 @@ WS [ \t] the ; way ; -".e" { yylval.i = EAST; return(CORNER); } -".east" { yylval.i = EAST; return(CORNER); } -".r" { yylval.i = EAST; return(CORNER); } -".right" { yylval.i = EAST; return(CORNER); } -".w" { yylval.i = WEST; return(CORNER); } -".west" { yylval.i = WEST; return(CORNER); } -".l" { yylval.i = WEST; return(CORNER); } -".left" { yylval.i = WEST; return(CORNER); } -".n" { yylval.i = NORTH; return(CORNER); } -".north" { yylval.i = NORTH; return(CORNER); } -".t" { yylval.i = NORTH; return(CORNER); } -".top" { yylval.i = NORTH; return(CORNER); } -".s" { yylval.i = SOUTH; return(CORNER); } -".south" { yylval.i = SOUTH; return(CORNER); } -".b" { yylval.i = SOUTH; return(CORNER); } -".bot" { yylval.i = SOUTH; return(CORNER); } -".bottom" { yylval.i = SOUTH; return(CORNER); } -".c" { yylval.i = CENTER; return(CORNER); } -".center" { yylval.i = CENTER; return(CORNER); } -".start" { yylval.i = START; return(CORNER); } -".end" { yylval.i = END; return(CORNER); } +"."(e|east) { yylval.i = EAST; return(CORNER); } +"."(r|right) { yylval.i = EAST; return(CORNER); } +"."(w|west) { yylval.i = WEST; return(CORNER); } +"."(l|left) { yylval.i = WEST; return(CORNER); } +"."(n|north) { yylval.i = NORTH; return(CORNER); } +"."(t|top) { yylval.i = NORTH; return(CORNER); } +"."(s|south) { yylval.i = SOUTH; return(CORNER); } +"."(b|bot|bottom) { yylval.i = SOUTH; return(CORNER); } +"."(c|center) { yylval.i = CENTER; return(CORNER); } +".start" { yylval.i = START; return(CORNER); } +".end" { yylval.i = END; return(CORNER); } ".ne" { yylval.i = NE; return(CORNER); } -"."upper" "*right { yylval.i = NE; return(CORNER); } ".se" { yylval.i = SE; return(CORNER); } -"."lower" "*right { yylval.i = SE; return(CORNER); } ".nw" { yylval.i = NW; return(CORNER); } -"."upper" "*left { yylval.i = NW; return(CORNER); } ".sw" { yylval.i = SW; return(CORNER); } -"."lower" "*left { yylval.i = SW; return(CORNER); } top" "+of { yylval.i = NORTH; return(CORNER); } north" "+of { yylval.i = NORTH; return(CORNER); } @@ -123,19 +106,11 @@ WS [ \t] center" "+of { yylval.i = CENTER; return(CORNER); } start" "+of { yylval.i = START; return(CORNER); } end" "+of { yylval.i = END; return(CORNER); } -upper" "+right" "+of { yylval.i = NE; return(CORNER); } -upper" "+left" "+of { yylval.i = NW; return(CORNER); } -lower" "+right" "+of { yylval.i = SE; return(CORNER); } -lower" "+left" "+of { yylval.i = SW; return(CORNER); } - -height { yylval.i = HEIGHT; return(ATTR); } -ht { yylval.i = HEIGHT; return(ATTR); } -wid { yylval.i = WIDTH; return(ATTR); } -width { yylval.i = WIDTH; return(ATTR); } -rad { yylval.i = RADIUS; return(ATTR); } -radius { yylval.i = RADIUS; return(ATTR); } -diam { yylval.i = DIAMETER; return(ATTR); } -diameter { yylval.i = DIAMETER; return(ATTR); } + +height|ht { yylval.i = HEIGHT; return(ATTR); } +width|wid { yylval.i = WIDTH; return(ATTR); } +radius|rad { yylval.i = RADIUS; return(ATTR); } +diameter|diam { yylval.i = DIAMETER; return(ATTR); } size { yylval.i = SIZE; return(ATTR); } left { yylval.i = LEFT; return(DIR); } right { yylval.i = RIGHT; return(DIR); } @@ -144,34 +119,28 @@ WS [ \t] cw { yylval.i = CW; return(ATTR); } clockwise { yylval.i = CW; return(ATTR); } ccw { yylval.i = CCW; return(ATTR); } -then { yylval.i = THEN; return(ATTR); } -invis { yylval.i = INVIS; return(ATTR); } -invisible { yylval.i = INVIS; return(ATTR); } -dot return(yylval.i = DOT); -dotted return(yylval.i = DOT); -dash return(yylval.i = DASH); -dashed return(yylval.i = DASH); +invis(ible)? { yylval.i = INVIS; return(ATTR); } +dot(ted)? return(yylval.i = DOT); +dash(ed)? return(yylval.i = DASH); chop return(yylval.i = CHOP); -spread return(yylval.i = SPREAD); -fill return(yylval.i = FILL); -ljust return(yylval.i = LJUST); -rjust return(yylval.i = RJUST); -above return(yylval.i = ABOVE); -below return(yylval.i = BELOW); +spread { yylval.i = SPREAD; return TEXTATTR; } +fill { yylval.i = FILL; return TEXTATTR; } +ljust { yylval.i = LJUST; return TEXTATTR; } +rjust { yylval.i = RJUST; return TEXTATTR; } +above { yylval.i = ABOVE; return TEXTATTR; } +below { yylval.i = BELOW; return TEXTATTR; } +center { yylval.i = CENTER; return TEXTATTR; } "<-" { yylval.i = HEAD1; return(HEAD); } "->" { yylval.i = HEAD2; return(HEAD); } "<->" { yylval.i = HEAD12; return(HEAD); } -".x" return(yylval.i = DOTX); -".y" return(yylval.i = DOTY); -".ht" return(yylval.i = DOTHT); -".height" return(yylval.i = DOTHT); -".wid" return(yylval.i = DOTWID); -".width" return(yylval.i = DOTWID); -".rad" return(yylval.i = DOTRAD); -".radius" return(yylval.i = DOTRAD); +".x" return(yylval.i = DOTX); +".y" return(yylval.i = DOTY); +"."(ht|height) return(yylval.i = DOTHT); +"."(wid|width) return(yylval.i = DOTWID); +"."(rad|radius) return(yylval.i = DOTRAD); from return(yylval.i = FROM); to return(yylval.i = TO); @@ -180,17 +149,81 @@ WS [ \t] with return(yylval.i = WITH); last return(yylval.i = LAST); +log return(LOG); +exp return(EXP); +sin return(SIN); +cos return(COS); +atan2 return(ATAN2); +sqrt return(SQRT); +rand return(RAND); +max return(MAX); +min return(MIN); +int return(INT); + +"==" return(EQ); +">=" return(GE); +"<=" return(LE); +"!=" return(NEQ); +">" return(GT); +"<" return(LT); +"&&" return(ANDAND); +"||" return(OROR); +"!" return(NOT); + Here return(yylval.i = HERE); -define{WS}+ { BEGIN def; } -{A}{B}* { definition(yytext); BEGIN A; } + +for return(FOR); +^Endfor\n { endfor(); } +do { yylval.p = delimstr("loop body"); return(DOSTR); } + +copy|include return(COPY); +(thru|through){WS}+ { BEGIN thru; return(THRU); } +{A}{B}*|. { yylval.p = copythru(yytext); BEGIN A; return(DEFNAME); } +until return(UNTIL); + +if { ifsw = 1; return(IF); } +then { if (!ifsw) { yylval.i = THEN; return(ATTR); } + yylval.p = delimstr("then part"); ifsw = 0; + return(THENSTR); } +else { yylval.p = delimstr("else part"); return(ELSESTR); } + +sh{WS}+ { BEGIN sh; + if ((delim = input()) == '{') delim = '}'; /* no nested {} */ + shell_init(); } +{A}{B}* { struct symtab *p; + if (yytext[0] == delim) { + shell_exec(); + BEGIN A; + } else { + p = lookup(yytext, 0); + if (p != NULL && p->s_type == DEFNAME) { + c = input(); + unput(c); + if (c == '(') + dodef(p); + else + pbstr(p->s_val.p); + } else + shell_text(yytext); + } + } +.|\n { if (yytext[0] == delim) { + shell_exec(); + BEGIN A; + } else + shell_text(yytext); + } + +define{WS}+ { BEGIN def; } +{A}{B}* { definition(yytext); BEGIN A; } +undef(ine)?{WS}+{A}{B}* { undefine(yytext); } first { yylval.i = 1; return(NTH); } {D}+(th|nd|rd|st) { yylval.i = atoi(yytext); return(NTH); } -({D}+("."?){D}*|"."{D}+)i? { yylval.f = atof(yytext); return(NUMBER); } +({D}+("."?){D}*|"."{D}+)((e|E)("+"|-)?{D}+)?i? { + yylval.f = atof(yytext); return(NUMBER); } -{A}{B}* { - int c; - struct symtab *p; +{A}{B}* { struct symtab *p; p = lookup(yytext); if (p != NULL && p->s_type == DEFNAME) { c = input(); @@ -211,18 +244,15 @@ WS [ \t] } \" { BEGIN str; clen=0; } - -# { BEGIN comment; } -\n { BEGIN A; return(ST); } -. ; - -. { yylval.i = yytext[0]; return(yytext[0]); } - -\" { BEGIN A; cbuf[clen]=0; yylval.p = tostring(cbuf); return(TEXT); } +\" { cbuf[clen]=0; yylval.p = tostring(cbuf); BEGIN A; return(TEXT); } \n { yyerror("newline in string"); BEGIN A; return(ST); } "\\\"" { cbuf[clen++]='"'; } "\\"t { cbuf[clen++]='\t'; } "\\\\" { cbuf[clen++]='\\'; } . { CADD; } +#.* ; + +. return(yylval.i = yytext[0]); + %% diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/picy.y b/usr/src/local/ditroff/ditroff.okeeffe/pic/picy.y index d9b69a7fb3..52ed143a81 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/picy.y +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/picy.y @@ -1,48 +1,56 @@ -#ifndef lint -static char sccsid[] = "@(#)picy.y 1.1 (CWI) 85/07/19"; -#endif lint - %{ -#include -#include "pic.h" +#include +#include "pic.h" +#include YYSTYPE y; %} -%token BOX 1 -%token ARROW 2 -%token CIRCLE 3 -%token ARC 4 +%token BOX 1 /* DON'T CHANGE THESE! */ +%token LINE 2 +%token ARROW 3 +%token CIRCLE 4 %token ELLIPSE 5 -%token LINE 6 -%token MOVE 7 -%token TEXT 8 -%token TROFF 9 -%token SPLINE 10 -%token BLOCK 11 +%token ARC 6 +%token SPLINE 7 +%token BLOCK 8 +%token

TEXT 9 +%token TROFF 10 +%token MOVE 11 %token BLOCKEND 12 -%token PRINT %token PLACE -%token ATTR -%token SPREAD FILL LJUST RJUST ABOVE BELOW +%token PRINT RESET THRU UNTIL +%token FOR IF COPY +%token

THENSTR ELSESTR DOSTR DEFNAME PLACENAME VARNAME SPRINTF +%token ATTR TEXTATTR %token LEFT RIGHT UP DOWN FROM TO AT BY WITH HEAD CW CCW THEN %token HEIGHT WIDTH RADIUS DIAMETER LENGTH SIZE -%token PLACENAME VARNAME DEFNAME CORNER HERE LAST NTH SAME BETWEEN AND -%token EAST WEST NORTH SOUTH NE NW SE SW CENTER START END +%token CORNER HERE LAST NTH SAME BETWEEN AND +%token EAST WEST NORTH SOUTH NE NW SE SW START END %token DOTX DOTY DOTHT DOTWID DOTRAD %token NUMBER +%token LOG EXP SIN COS ATAN2 SQRT RAND MIN MAX INT %token DIR %token DOT DASH CHOP %token ST /* statement terminator */ +%right '=' +%left OROR +%left ANDAND +%nonassoc GT LT LE GE EQ NEQ %left '+' '-' %left '*' '/' '%' -%right UMINUS +%right UMINUS NOT + +%type expr if_expr asgn +%type

name text +%type optop exprlist +%type if for copy -%type expr opt_expr +/* this is a lie: picture and position are really the whole union */ %type leftbrace picture piclist position lbracket %type prim place blockname -%type textattr last type - +%type textlist textattr /* not a sensible value */ +%type last type %% @@ -58,18 +66,80 @@ piclist: ; picture: - prim ST { codegen = 1; } + prim ST { codegen = 1; makeiattr(0, 0); } | leftbrace piclist '}' { rightthing($1, '}'); $$ = $2; } - | PLACENAME ':' picture { makevar($1, PLACENAME, $3); $$ = $3; } - | PLACENAME ':' ST picture { makevar($1, PLACENAME, $4); $$ = $4; } - | PLACENAME ':' position ST { makevar($1, PLACENAME, $3); $$ = $3; } - | VARNAME '=' expr ST { makevar($1, VARNAME, $3); checkscale($1); } + | PLACENAME ':' picture { y.o=$3; makevar($1,PLACENAME,y); $$ = $3; } + | PLACENAME ':' ST picture { y.o=$4; makevar($1,PLACENAME,y); $$ = $4; } + | PLACENAME ':' position ST { y.o=$3; makevar($1,PLACENAME,y); $$ = $3; } + | asgn ST { y.f = $1; $$ = y.o; } | DIR { setdir($1); } | PRINT expr ST { printexpr($2); } | PRINT position ST { printpos($2); } + | PRINT text ST { printf("%s\n", $2); free($2); } + | RESET varlist ST { resetvar(); makeiattr(0, 0); } + | copy + | for + | if | ST ; +varlist: + /* empty */ + | VARNAME { makevattr($1); } + | varlist VARNAME { makevattr($2); } + | varlist ',' VARNAME { makevattr($3); } + ; + +asgn: + VARNAME '=' expr { $$=y.f=$3; makevar($1,VARNAME,y); checkscale($1); } + ; + +copy: + COPY copylist { copy(); } + ; +copylist: + copyattr + | copylist copyattr + ; +copyattr: + text { copyfile($1); } + | THRU DEFNAME { copydef($2); } + | UNTIL text { copyuntil($2); } + ; + +for: + FOR name FROM expr TO expr BY optop expr DOSTR + { forloop($2, $4, $6, $8, $9, $10); } + | FOR name FROM expr TO expr DOSTR + { forloop($2, $4, $6, '+', 1.0, $7); } + | FOR name '=' expr TO expr BY optop expr DOSTR + { forloop($2, $4, $6, $8, $9, $10); } + | FOR name '=' expr TO expr DOSTR + { forloop($2, $4, $6, '+', 1.0, $7); } + ; + +if: + IF if_expr THENSTR ELSESTR { ifstat($2, $3, $4); } + | IF if_expr THENSTR { ifstat($2, $3, (char *) 0); } + ; +if_expr: + expr + | text EQ text { $$ = strcmp($1,$3) == 0; free($1); free($3); } + | text NEQ text { $$ = strcmp($1,$3) != 0; free($1); free($3); } + ; + +name: + VARNAME { y.f = 0; makevar($1, VARNAME, y); } + ; +optop: + '+' { $$ = '+'; } + | '-' { $$ = '-'; } + | '*' { $$ = '*'; } + | '/' { $$ = '/'; } + | /* empty */ { $$ = ' '; } + ; + + leftbrace: '{' { $$ = leftthing('{'); } ; @@ -81,9 +151,9 @@ prim: | ARC attrlist { $$ = arcgen($1); } | LINE attrlist { $$ = linegen($1); } | ARROW attrlist { $$ = linegen($1); } - | SPLINE attrlist { $$ = splinegen($1); } + | SPLINE attrlist { $$ = linegen($1); } | MOVE attrlist { $$ = movegen($1); } - | TEXT attrlist { $$ = textgen($1); } + | textlist attrlist { $$ = textgen($1); } | TROFF { $$ = troffgen($1); } | lbracket piclist ']' { $$=rightthing($1,']'); } attrlist { $$ = blockgen($1, $2, $4); } @@ -95,60 +165,66 @@ lbracket: attrlist: attrlist attr - | /* empty */ { makeattr(0, 0); } + | /* empty */ ; attr: - ATTR opt_expr { makeattr($1, $2); } - | DIR opt_expr { makeattr($1, $2); } - | FROM position { makeattr($1, $2); } - | TO position { makeattr($1, $2); } - | AT position { makeattr($1, $2); } - | BY position { makeattr($1, $2); } - | WITH CORNER { makeattr(WITH, $2); } - | WITH '.' PLACENAME { makeattr(PLACE, getblock(getlast(1,BLOCK), $3)); } - | WITH position { makeattr(PLACE, $2); } - | SAME { makeattr(SAME, $1); } - | textattr { makeattr($1, 0); } - | HEAD { makeattr(HEAD, $1); } - | DOT opt_expr { makeattr(DOT, $2); } - | DASH opt_expr { makeattr(DASH, $2); } - | CHOP opt_expr { makeattr(CHOP, $2); } + ATTR expr { makefattr($1, !DEFAULT, $2); } + | ATTR { makefattr($1, DEFAULT, 0.0); } + | expr { makefattr(curdir(), !DEFAULT, $1); } + | DIR expr { makefattr($1, !DEFAULT, $2); } + | DIR { makefattr($1, DEFAULT, 0.0); } + | FROM position { makeoattr($1, $2); } + | TO position { makeoattr($1, $2); } + | AT position { makeoattr($1, $2); } + | BY position { makeoattr($1, $2); } + | WITH CORNER { makeiattr(WITH, $2); } + | WITH '.' PLACENAME { makeoattr(PLACE, getblock(getlast(1,BLOCK), $3)); } + | WITH '.' PLACENAME CORNER + { makeoattr(PLACE, getpos(getblock(getlast(1,BLOCK), $3), $4)); } + | WITH position { makeoattr(PLACE, $2); } + | SAME { makeiattr(SAME, $1); } + | TEXTATTR { maketattr($1, 0); } + | HEAD { makeiattr(HEAD, $1); } + | DOT expr { makefattr(DOT, !DEFAULT, $2); } + | DOT { makefattr(DOT, DEFAULT, 0.0); } + | DASH expr { makefattr(DASH, !DEFAULT, $2); } + | DASH { makefattr(DASH, DEFAULT, 0.0); } + | CHOP expr { makefattr(CHOP, !DEFAULT, $2); } + | CHOP { makefattr(CHOP, DEFAULT, 0.0); } | textlist ; -opt_expr: - expr - | /* empty */ { $$ = 0; } - ; - textlist: - TEXT { makeattr(CENTER, $1); } - | TEXT textattr { makeattr($2, $1); } - | textlist TEXT { makeattr(CENTER, $2); } - | textlist TEXT textattr { makeattr($3, $2); } + textattr + | textlist textattr ; - textattr: - LJUST - | RJUST - | SPREAD - | FILL - | CENTER - | ABOVE - | BELOW + text { maketattr(CENTER, $1); } + | text TEXTATTR { maketattr($2, $1); } + | textattr TEXTATTR { addtattr($2); } + ; +text: + TEXT + | SPRINTF '(' text ')' { $$ = sprintgen($3); } + | SPRINTF '(' text ',' exprlist ')' { $$ = sprintgen($3); } + ; + +exprlist: + expr { exprsave($1); $$ = 0; } + | exprlist ',' expr { exprsave($3); } ; position: /* absolute, not relative */ place - | expr ',' expr { $$ = makepos($1, $3); } - | position '+' expr ',' expr { $$ = fixpos($1, $3, $5); } - | position '-' expr ',' expr { $$ = fixpos($1, -$3, -$5); } - | '(' expr ',' expr ')' { $$ = makepos($2, $4); } + | '(' position ')' { $$ = $2; } + | expr ',' expr { $$ = makepos($1, $3); } + | position '+' expr ',' expr { $$ = fixpos($1, $3, $5); } + | position '-' expr ',' expr { $$ = fixpos($1, -$3, -$5); } | position '+' '(' expr ',' expr ')' { $$ = fixpos($1, $4, $6); } | position '-' '(' expr ',' expr ')' { $$ = fixpos($1, -$4, -$6); } | '(' place ',' place ')' { $$ = makepos(getcomp($2,DOTX), getcomp($4,DOTY)); } - | expr '<' position ',' position '>' { $$ = makebetween($1, $3, $5); } + | expr LT position ',' position GT { $$ = makebetween($1, $3, $5); } | expr BETWEEN position AND position { $$ = makebetween($1, $3, $5); } ; @@ -192,18 +268,42 @@ type: ; expr: - expr '+' expr { $$ = $1 + $3; } + NUMBER + | VARNAME { $$ = getfval($1); } + | asgn + | expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '*' expr { $$ = $1 * $3; } - | expr '/' expr { $$ = $1 / $3; } - | expr '%' expr { $$ = (long)$1 % (long)$3; } + | expr '/' expr { if ($3 == 0.0) { + yyerror("division by 0"); $3 = 1; } + $$ = $1 / $3; } + | expr '%' expr { if ((long)$3 == 0) { + yyerror("mod does division by 0"); $3 = 1; } + $$ = (long)$1 % (long)$3; } | '-' expr %prec UMINUS { $$ = -$2; } | '(' expr ')' { $$ = $2; } - | VARNAME { $$ = getfval($1); } - | NUMBER | place DOTX { $$ = getcomp($1, $2); } | place DOTY { $$ = getcomp($1, $2); } | place DOTHT { $$ = getcomp($1, $2); } | place DOTWID { $$ = getcomp($1, $2); } | place DOTRAD { $$ = getcomp($1, $2); } + | expr GT expr { $$ = $1 > $3; } + | expr LT expr { $$ = $1 < $3; } + | expr LE expr { $$ = $1 <= $3; } + | expr GE expr { $$ = $1 >= $3; } + | expr EQ expr { $$ = $1 == $3; } + | expr NEQ expr { $$ = $1 != $3; } + | expr ANDAND expr { $$ = $1 && $3; } + | expr OROR expr { $$ = $1 || $3; } + | NOT expr { $$ = !($2); } + | LOG '(' expr ')' { $$ = Log10($3); } + | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); } + | SIN '(' expr ')' { $$ = sin($3); } + | COS '(' expr ')' { $$ = cos($3); } + | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); } + | SQRT '(' expr ')' { $$ = Sqrt($3); } + | RAND '(' ')' { $$ = (float)rand() / 32767.0; /* might be 2^31-1 */ } + | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; } + | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; } + | INT '(' expr ')' { $$ = (long) $3; } ; diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/pltroff.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/pltroff.c index f445d5995f..196e7ead60 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/pltroff.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/pltroff.c @@ -1,62 +1,17 @@ #ifndef lint -static char sccsid[] = "@(#)pltroff.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)pltroff.c 2.1 (CWI) 85/07/23"; #endif lint - -/* - * This version has code generators to drive the old-style troff - * that produces output for the Graphic Systems C/A/T. - * Very few people actually have a C/A/T; they instead typically - * use some other typesetter that simulates it. This is slow and - * rather silly, but compatibility with the past is important. - * Or so they say. Anyway ... - - * The code generator can be turned on to old-style troff by setting - * the constant OLDTROFF with a #define statement; this will also - * have the effect of setting the default typesetter to the C/A/T - * in a consistent manner. - */ - #include -#include #include +#include "pic.h" extern int dbg; -/* this is the place to define OLDTROFF if you're going to */ -#ifdef OLDTROFF -# define MAXY 8192 -# define MAXX 8192 -# define OLDSTYLE 1 -#else -# define MAXY 32768 -# define MAXX 32768 -# define OLDSTYLE 0 -#endif - #define abs(n) (n >= 0 ? n : -(n)) #define max(x,y) ((x)>(y) ? (x) : (y)) -#define PI 3.141592654 -#define PI2 PI/2 - -extern int res; -extern int DX; /* step size in x */ -extern int DY; /* step size in y */ - -#define DEV202 1 -#define DEVAPS 2 -#define DEVCAT 3 -#define DEV450 4 -extern int devtype; -int minline = 245; /* draw lines shorter than this with dots on 202 */ - /* ought to be point-size dependent, but what's that? */ - /* this is big enough to handle 202 up to 36 points */ -int drawdot = '.'; /* character to use when drawing */ - -int useDline = 0; /* if set, produce \D for all lines */ -extern float hshift; /* how much to move left by for text */ -extern float vshift; /* how much down */ - -/* scaling stuff, specific to typesetter */ -/* defined by s command as X0,Y0 to X1,Y1 */ + +char *textshift = "\\v'.2m'"; /* move text this far down */ + +/* scaling stuff defined by s command as X0,Y0 to X1,Y1 */ /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */ /* default output is 6x6 inches */ @@ -64,22 +19,23 @@ extern float vshift; /* how much down */ float xscale; float yscale; -int hpos = 0; /* current horizontal position in output coordinate system */ -int vpos = 0; /* current vertical position; 0 is top of page */ +float hpos = 0; /* current horizontal position in output coordinate system */ +float vpos = 0; /* current vertical position; 0 is top of page */ -int htrue = 0; /* where we really are */ -int vtrue = 0; +float htrue = 0; /* where we really are */ +float vtrue = 0; float X0, Y0; /* left bottom of input */ float X1, Y1; /* right top of input */ -int hmax; /* right end of output */ -int vmax; /* top of output (down is positive) */ +float hmax; /* right end of output */ +float vmax; /* top of output (down is positive) */ extern float deltx; extern float delty; -extern float xmin, ymin, xmax, ymax, sxmin, symin, sxmax, symax; -extern int crop; +extern float xmin, ymin, xmax, ymax; + +float xconv(), yconv(), xsc(), ysc(); openpl(s) /* initialize device */ char *s; /* residue of .PS invocation line */ @@ -87,49 +43,70 @@ openpl(s) /* initialize device */ float maxdelt; hpos = vpos = 0; - hmax = vmax = 6 * res; /* default = 6 x 6 */ - maxdelt = max(deltx, delty); - if (maxdelt > 8) { /* 8 inches */ + if (deltx > 8.5 || delty > 11) { /* 8.5x11 inches max */ fprintf(stderr, "pic: %g X %g picture shrunk to", deltx, delty); - deltx *= 8/maxdelt; - delty *= 8/maxdelt; + maxdelt = max(deltx, delty); + deltx *= 7/maxdelt; + delty *= 7/maxdelt; fprintf(stderr, " %g X %g\n", deltx, delty); } - if (deltx > 0 && delty > 0) { /* have to change default size */ - hmax = res * deltx; - vmax = res * delty; - } - if (crop) { - if (xmax == xmin) - space(xmin, ymin, xmin + ymax-ymin, ymax); - else - space(xmin, ymin, xmax, ymin + xmax-xmin); /* assumes 1:1 aspect ratio */ - } - else - space(sxmin, symin, sxmax, symax); - printf("... %g %g %g %g %g %g %g %g\n", - xmin, ymin, xmax, ymax, sxmin, symin, sxmax, symax); - printf("... %du %du %du %du %du %du %du %du\n", - xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax), - xconv(sxmin), yconv(symin), xconv(sxmax), yconv(symax)); - printf(".PS %d %d %s", yconv(ymin), xconv(xmax), s); + space(xmin, ymin, xmax, ymax); + printf("... %g %g %g %g\n", xmin, ymin, xmax, ymax); + printf("... %.3fi %.3fi %.3fi %.3fi\n", + xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax)); + printf(".nr 00 \\n(.u\n"); + printf(".nf\n"); + printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s); /* assumes \n comes as part of s */ - if (xconv(xmax) >= MAXX || yconv(ymax) >= MAXY) { /* internal troff limit: 13 bits for motion */ - fprintf(stderr, "picture too high or wide"); - exit(1); - } - printf(".br\n"); +} + +space(x0, y0, x1, y1) /* set limits of page */ + float x0, y0, x1, y1; +{ + X0 = x0; + Y0 = y0; + X1 = x1; + Y1 = y1; + xscale = deltx == 0.0 ? 1.0 : deltx / (X1-X0); + yscale = delty == 0.0 ? 1.0 : delty / (Y1-Y0); +} + +float xconv(x) /* convert x from external to internal form */ + float x; +{ + return (x-X0) * xscale; +} + +float xsc(x) /* convert x from external to internal form, scaling only */ + float x; +{ + + return (x) * xscale; +} + +float yconv(y) /* convert y from external to internal form */ + float y; +{ + return (Y1-y) * yscale; +} + +float ysc(y) /* convert y from external to internal form, scaling only */ + float y; +{ + return (y) * yscale; } closepl(type) /* clean up after finished */ + int type; { - movehv(0, 0); /* get back to where we started */ + movehv(0.0, 0.0); /* get back to where we started */ if (type == 'F') printf(".PF\n"); else { - printf(".sp 1+%du\n", yconv(ymin)); + printf(".sp 1+%.3fi\n", yconv(ymin)); printf(".PE\n"); } + printf(".if \\n(00 .fi\n"); } move(x, y) /* go to position x, y in external coords */ @@ -140,30 +117,32 @@ move(x, y) /* go to position x, y in external coords */ } movehv(h, v) /* go to internal position h, v */ - int h, v; + float h, v; { hgoto(h); vgoto(v); } hmot(n) /* generate n units of horizontal motion */ - int n; + float n; { hpos += n; } vmot(n) /* generate n units of vertical motion */ - int n; + float n; { vpos += n; } hgoto(n) + float n; { hpos = n; } vgoto(n) + float n; { vpos = n; } @@ -171,11 +150,11 @@ vgoto(n) hvflush() /* get to proper point for output */ { if (hpos != htrue) { - printf("\\h'%du'", hpos - htrue); + printf("\\h'%.3fi'", hpos - htrue); htrue = hpos; } if (vpos != vtrue) { - printf("\\v'%du'", vpos - vtrue); + printf("\\v'%.3fi'", vpos - vtrue); vtrue = vpos; } } @@ -200,11 +179,11 @@ label(s, t, nh) /* text s of type t nh half-lines up */ char *p; hvflush(); - printf("\\h'-%.1fm'\\v'%.1fm'", hshift, vshift); /* shift down and left */ - /* .3 .3 is best for PO in circuit diagrams */ - if (t == 'A') + dprintf("label: %s %o %d\n", s, t, nh); + printf("%s", textshift); /* shift down and left */ + if (t & ABOVE) nh++; - else if (t == 'B') + else if (t & BELOW) nh--; if (nh) printf("\\v'%du*\\n(.vu/2u'", -nh); @@ -215,27 +194,20 @@ label(s, t, nh) /* text s of type t nh half-lines up */ q = 1; break; } - switch (t) { - case 'L': - default: + t &= ~(ABOVE|BELOW); + if (t & LJUST) { printf("%s", s); - break; - case 'C': - case 'A': - case 'B': - if (q) - printf("\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts%s\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts", s, s, s); - else - printf("\\h'-\\w'%s'u/2u'%s\\h'-\\w'%s'u/2u'", s, s, s); - break; - case 'R': + } else if (t & RJUST) { if (q) printf("\\h\\(ts-\\w\\(ts%s\\(tsu\\(ts%s", s, s); else printf("\\h'-\\w'%s'u'%s", s, s); - break; + } else { /* CENTER */ + if (q) + printf("\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts%s\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts", s, s, s); + else + printf("\\h'-\\w'%s'u/2u'%s\\h'-\\w'%s'u/2u'", s, s, s); } - /* don't need these if flyback called immediately */ printf("\n"); flyback(); } @@ -247,25 +219,27 @@ line(x0, y0, x1, y1) /* draw line from x0,y0 to x1,y1 */ cont(x1, y1); } -arrow(x0, y0, x1, y1, w, h) /* draw arrow (without line), head wid w & len h */ - float x0, y0, x1, y1, w, h; +arrow(x0, y0, x1, y1, w, h, ang, nhead) /* draw arrow (without shaft) */ + float x0, y0, x1, y1, w, h, ang; /* head wid w, len h, rotated ang */ + int nhead; /* and drawn with nhead lines */ { - double alpha, rot, hyp; + double alpha, rot, drot, hyp; float dx, dy; + int i; - rot = atan2( w / 2, h ); + rot = atan2(w / 2, h); hyp = sqrt(w/2 * w/2 + h * h); - alpha = atan2(y1-y0, x1-x0); - if (dbg) - printf("rot=%f, hyp=%f, alpha=%f\n", rot, hyp, alpha); - dx = hyp * cos(alpha + PI + rot); - dy = hyp * sin(alpha + PI + rot); - if (dbg) printf("dx,dy = %g,%g\n", dx, dy); - line(x1+dx, y1+dy, x1, y1); - dx = hyp * cos(alpha + PI - rot); - dy = hyp * sin(alpha + PI - rot); - if (dbg) printf("dx,dy = %g,%g\n", dx, dy); - line(x1+dx, y1+dy, x1, y1); + alpha = atan2(y1-y0, x1-x0) + ang; + if (nhead < 2) + nhead = 2; + dprintf("rot=%g, hyp=%g, alpha=%g\n", rot, hyp, alpha); + for (i = nhead-1; i >= 0; i--) { + drot = 2 * rot / (float) (nhead-1) * (float) i; + dx = hyp * cos(alpha + PI - rot + drot); + dy = hyp * sin(alpha + PI - rot + drot); + dprintf("dx,dy = %g,%g\n", dx, dy); + line(x1+dx, y1+dy, x1, y1); + } } box(x0, y0, x1, y1) @@ -281,29 +255,15 @@ box(x0, y0, x1, y1) cont(x, y) /* continue line from here to x,y */ float x, y; { - int h1, v1; - int dh, dv; + float h1, v1; + float dh, dv; h1 = xconv(x); v1 = yconv(y); dh = h1 - hpos; dv = v1 - vpos; - downsize(); hvflush(); - if (!useDline && dv == 0 && abs(dh) > minline) /* horizontal */ - printf("\\l'%du'\n", dh); - else if (!useDline && dh == 0 && abs(dv) > minline) { /* vertical */ - if (devtype == DEV202) - printf("\\L'%du\\(vr'\n", dv); - else - printf("\\v'-.25m'\\L'%du\\(br'\\v'.25m'\n", dv); /* add -.25m correction if use \(br */ - } else { - if (OLDSTYLE) - drawline(dh, dv); - else - printf("\\D'l%du %du'\n", dh, dv); - } - upsize(); + printf("\\D'l%.3fi %.3fi'\n", dh, dv); flyback(); /* expensive */ hpos = h1; vpos = v1; @@ -312,667 +272,65 @@ cont(x, y) /* continue line from here to x,y */ circle(x, y, r) float x, y, r; { - int d; - - downsize(); - d = xsc(2 * r); move(x-r, y); hvflush(); - if (OLDSTYLE) - drawcircle(d); - else - printf("\\D'c%du'\n", d); - upsize(); + printf("\\D'c%.3fi'\n", xsc(2 * r)); flyback(); } spline(x, y, n, p) float x, y, *p; - float n; + float n; /* sic */ { - int i, j, dx, dy; - char temp[1000]; + int i; + float dx, dy; + float xerr, yerr; - downsize(); move(x, y); hvflush(); - if (OLDSTYLE) { - temp[0] = 0; - for (i = 0; i < 2 * n; i += 2) { - dx = xsc(p[i]); - dy = ysc(p[i+1]); - sprintf(&temp[strlen(temp)], " %d %d", dx, dy); - } - drawspline(temp); - } - else { - printf("\\D'~"); - for (i = 0; i < 2 * n; i += 2) { - dx = xsc(p[i]); - dy = ysc(p[i+1]); - printf(" %du %du", dx, dy); - } - printf("'\n"); + printf("\\D'~"); + xerr = yerr = 0.0; + for (i = 0; i < 2 * n; i += 2) { + dx = xsc(xerr += p[i]); + xerr -= dx/xscale; + dy = ysc(yerr += p[i+1]); + yerr -= dy/yscale; + printf(" %.3fi %.3fi", dx, -dy); /* WATCH SIGN */ } - upsize(); + printf("'\n"); flyback(); } ellipse(x, y, r1, r2) float x, y, r1, r2; { - int ir1, ir2; + float ir1, ir2; - downsize(); move(x-r1, y); hvflush(); ir1 = xsc(r1); ir2 = ysc(r2); - if (OLDSTYLE) - drawellipse(2 * ir1, 2 * abs(ir2)); - else - printf("\\D'e%du %du'\n", 2 * ir1, 2 * abs(ir2)); - upsize(); + printf("\\D'e%.3fi %.3fi'\n", 2 * ir1, 2 * abs(ir2)); flyback(); } -arc(x, y, x0, y0, x1, y1, r) /* draw arc with center x,y */ - float x, y, x0, y0, x1, y1, r; +arc(x, y, x0, y0, x1, y1) /* draw arc with center x,y */ + float x, y, x0, y0, x1, y1; { - downsize(); move(x0, y0); hvflush(); - if (OLDSTYLE) { - drawarc(xsc(x1-x0), ysc(y1-y0), xsc(r)); - } else { - printf("\\D'a%du %du %du %du'\n", - xsc(x-x0), ysc(y-y0), xsc(x1-x), ysc(y1-y)); - } - upsize(); + printf("\\D'a%.3fi %.3fi %.3fi %.3fi'\n", + xsc(x-x0), -ysc(y-y0), xsc(x1-x), -ysc(y1-y)); /* WATCH SIGNS */ flyback(); } -erase() /* get to bottom of frame */ -{ - return; /* for now, ignore them */ -} - -point(x, y) /* put point at x,y */ - float x, y; -{ - static char *temp = "."; - - move(x, y); - label(temp, 'L'); -} - -space(x0, y0, x1, y1) /* set limits of page */ - float x0, y0, x1, y1; -{ - if (x0 == x1) - x1 = x0 + 1; - if (y0 == y1) - y1 = y0 - 1; /* kludge */ - X0 = x0; - Y0 = y0; - X1 = x1; - Y1 = y1; - xscale = hmax / (X1-X0); - yscale = vmax / (Y0-Y1); -} - -xconv(x) /* convert x from external to internal form */ - float x; -{ - int v; - - v = (x-X0) * xscale + 0.5; - if (OLDSTYLE) { - v = (v + DX - 1) / DX; - v *= DX; - } - return v; -} - -xsc(x) /* convert x from external to internal form, scaling only */ - float x; -{ - int v; - - v = (x) * xscale + 0.5; - if (OLDSTYLE) { - v = (v + DX - 1) / DX; - v *= DX; - } - return v; -} - -yconv(y) /* convert y from external to internal form */ - float y; -{ - int v; - - y += Y1 - ymax; - v = (y-Y1) * yscale + 0.5; - if (OLDSTYLE) { - v = (v + DY - 1) / DY; - v *= DY; - } - return v; -} - -ysc(y) /* convert y from external to internal form, scaling only */ - float y; -{ - int v; - - v = (y) * yscale + 0.5; - if (OLDSTYLE) { - v = (v + DY - 1) / DY; - v *= DY; - } - return v; -} - -linemod(s) - char *s; -{ -} - dot() { hvflush(); /* what character to draw here depends on what's available. */ /* on the 202, l. is good but small. */ - /* on other typesetters, use a period and hope */ - if (OLDSTYLE) - printf("\\&.\n"); - else if (devtype == DEV202) - printf("\\z\\(l.\\(l.\\z\\(l.\\(l.\n"); - else - printf("\\&.\n"); - flyback(); -} - -#ifndef OLDTROFF - - /* satisfy the loader... */ - -drawline(){;} -drawcircle(){;} -drawspline(){;} -drawellipse(){;} -drawarc(){;} -upsize(){;} -downsize(){;} - -#endif - -#ifdef OLDTROFF - - /* these are for real */ - -int drawsize = 2; /* shrink point size by this factor */ - -#define sgn(n) ((n > 0) ? 1 : ((n < 0) ? -1 : 0)) -#define arcmove(x,y) { hgoto(x); vmot(-vpos-(y)); } - -put1(c) /* output one character, usually a dot */ -{ - static int nput = 0; - - if (nput++ > 100) { /* crude approx: troff input buffer ~ 400 */ - nput = 0; - printf("\n"); /* someday this will give a spurious break */ - flyback(); - printf("\\\&"); - } - hvflush(); /* crude! */ - printf("\\z%c", c); -} + /* in general, use a smaller, shifted period and hope */ -downsize() /* set size lower to make it lighter */ -{ - if (drawsize != 1) { - printf(".nr .. \\n(.s/%d\n", drawsize); - printf(".ps \\n(..\n"); - } -} - -upsize() /* undo downsize */ -{ - printf(".ps\n"); /* God help anyone who fiddles .ps */ -} - -drawline(dx, dy) /* draw line from here to dx, dy */ -int dx, dy; -{ - int xd, yd; - float val, slope; - int i, numdots; - int dirmot, perp; - int motincr, perpincr; - int ohpos, ovpos, osize; - float incrway; - - ohpos = hpos; - ovpos = vpos; - xd = dx / DX; - yd = dy / DX; - printf("\\\&"); - put1(drawdot); - if (xd == 0) { - numdots = abs (yd); - motincr = DX * sgn (yd); - for (i = 0; i < numdots; i++) { - vmot(motincr); - put1(drawdot); - } - vgoto(ovpos + dy); - printf("\n"); - return; - } - if (yd == 0) { - numdots = abs (xd); - motincr = DX * sgn (xd); - for (i = 0; i < numdots; i++) { - hmot(motincr); - put1(drawdot); - } - hgoto(ohpos + dx); - printf("\n"); - return; - } - if (abs (xd) > abs (yd)) { - val = slope = (float) xd/yd; - numdots = abs (xd); - dirmot = 'h'; - perp = 'v'; - motincr = DX * sgn (xd); - perpincr = DX * sgn (yd); - } - else { - val = slope = (float) yd/xd; - numdots = abs (yd); - dirmot = 'v'; - perp = 'h'; - motincr = DX * sgn (yd); - perpincr = DX * sgn (xd); - } - incrway = sgn ((int) slope); - for (i = 0; i < numdots; i++) { - val -= incrway; - if (dirmot == 'h') - hmot(motincr); - else - vmot(motincr); - if (val * slope < 0) { - if (perp == 'h') - hmot(perpincr); - else - vmot(perpincr); - val += slope; - } - put1(drawdot); - } - hgoto(ohpos + dx); - vgoto(ovpos + dy); - printf("\n"); -} - -drawspline(s) /* draw spline curve */ - char *s; -{ - int x[50], y[50], xp, yp, pxp, pyp; - float t1, t2, t3, w; - int i, j, steps, N, prevsteps; - register char *p; - - N = 0; - -/* Weird... - N = sscanf(s, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d ", - &x[2], &y[2], &x[3], &y[3], &x[4], &y[4], &x[5], &y[5], &x[6], &y[6], &x[7], &y[7], &x[8], &y[8], &x[9], &y[9], &x[10], &y[10], &x[11], &y[11], &x[12], &y[12], -&x[13], &y[13], &x[14], &y[14], &x[15], &y[15], &x[16], &y[16], &x[17], &y[17], &x[18], &y[18], &x[19], &y[19], &x[20], &y[20], &x[21], &y[21], &x[22], &y[22], &x[23], &y[23], &x[24], &y[24], -&x[25], &y[25], &x[26], &y[26], &x[27], &y[27], &x[28], &y[28], &x[29], &y[29], &x[30], &y[30], &x[31], &y[31], &x[32], &y[32], &x[33], &y[33], &x[34], &y[34], &x[35], &y[35], &x[36], &y[36], -&x[37], &y[37]); -*/ - p = s; - for( i = 2; i <= 37; i++) { - j = sscanf(p, "%d%d", &x[i], &y[i]); - if( j == -1) - break; - while( isspace(*p)) - p++; - while( isdigit(*p) || *p == '-') - p++; - while( isspace(*p)) - p++; - while( isdigit(*p) || *p == '-') - p++; - N += 2; - } - - N = N/2 + 2; - x[0] = x[1] = hpos; - y[0] = y[1] = vpos; - for (i = 1; i < N; i++) { - x[i+1] += x[i]; - y[i+1] += y[i]; - } - x[N] = x[N-1]; - y[N] = y[N-1]; - prevsteps = 0; - pxp = pyp = -9999; - printf("\\\&"); - for (i = 0; i < N-1; i++) { /* interval */ - steps = (dist(x[i],y[i], x[i+1],y[i+1]) + dist(x[i+1],y[i+1], x[i+2],y[i+2])) / 2; - steps /= DX; - for (j = 0; j < steps; j++) { /* points within */ - w = (float) j / steps; - t1 = 0.5 * w * w; - w = w - 0.5; - t2 = 0.75 - w * w; - w = w - 0.5; - t3 = 0.5 * w * w; - xp = t1 * x[i+2] + t2 * x[i+1] + t3 * x[i] + 0.5; - yp = t1 * y[i+2] + t2 * y[i+1] + t3 * y[i] + 0.5; - xp = round(xp, DX); - yp = round(yp, DY); - if (xp != pxp || yp != pyp) { - hgoto(xp); - vgoto(yp); - put1(drawdot); - pxp = xp; - pyp = yp; - } - } - } - printf("\n"); -} - -drawcircle(d) -{ - int xc, yc; - - xc = hpos; - yc = vpos; - printf("\\\&"); - conicarc(hpos + d/2, -vpos, hpos, -vpos, hpos, -vpos, d/2, d/2); - hgoto(xc + d); /* circle goes to right side */ - vgoto(yc); - printf("\n"); -} - -dist(x1, y1, x2, y2) /* integer distance from x1,y1 to x2,y2 */ -{ - float dx, dy; - - dx = x2 - x1; - dy = y2 - y1; - return sqrt(dx*dx + dy*dy) + 0.5; -} - -drawarc(x, y, r) -{ - int x0, y0; - float dx, dy, phi, d, ht, ang; - - if (r == 0) - r = 1; - if (r < 0) - ang = PI / 2; - else - ang = -(PI / 2); - dx = x / 2; - dy = y / 2; - phi = atan2(dy, dx) + ang; - while ((d = (float)r * r - (dx*dx + dy*dy)) < 0.0) - r *= 2; - ht = sqrt(d); - x0 = hpos + dx + ht * cos(phi) + 0.5; - y0 = vpos + dy + ht * sin(phi) + 0.5; - printf("\\\&"); - conicarc(x0, -y0, hpos, -vpos, hpos+x, -vpos-y, r, r); - printf("\n"); -} - -drawellipse(a, b) -{ - int xc, yc; - - xc = hpos; - yc = vpos; - printf("\\\&"); - conicarc(hpos + a/2, -vpos, hpos, -vpos, hpos, -vpos, a/2, b/2); - hgoto(xc + a); - vgoto(yc); - printf("\n"); -} - -#define sqr(x) (long int)(x)*(x) - -conicarc(x, y, x0, y0, x1, y1, a, b) -{ - /* based on Bresenham, CACM, Feb 77, pp 102-3 */ - /* by Chris Van Wyk */ - /* capitalized vars are an internal reference frame */ - long dotcount = 0; - int xs, ys, xt, yt, Xs, Ys, qs, Xt, Yt, qt, - M1x, M1y, M2x, M2y, M3x, M3y, - Q, move, Xc, Yc; - int delta; - float xc, yc; - float radius, slope; - float xstep, ystep; - if (a != b) /* an arc of an ellipse; internally, will still think of circle */ - if (a > b) { - xstep = (float)a / b; - ystep = 1; - radius = b; - } - else - { - xstep = 1; - ystep = (float)b / a; - radius = a; - } - else /* a circular arc; radius is computed from center and first point */ { - xstep = ystep = 1; - radius = sqrt((float)(sqr(x0 - x) + sqr(y0 - y))); - } - - - xc = x0; - yc = y0; - /* now, use start and end point locations to figure out - the angle at which start and end happen; use these - angles with known radius to figure out where start - and end should be */ - slope = atan2((double)(y0 - y), (double)(x0 - x) - ); - if ((slope == 0.0) - && (x0 < x) - ) - slope = 3.14159265; - x0 = x + radius * cos(slope) - + 0.5; - y0 = y + radius * sin(slope) - + 0.5; - slope = atan2((double)(y1 - y), (double)(x1 - x) - ); - if ((slope == 0.0) - && (x1 < x) - ) - slope = 3.14159265; - x1 = x + radius * cos(slope) - + 0.5; - y1 = y + radius * sin(slope) - + 0.5; - /* step 2: translate to zero-centered circle */ - xs = x0 - x; - ys = y0 - y; - xt = x1 - x; - yt = y1 - y; - /* step 3: normalize to first quadrant */ - if (xs < 0) - if (ys < 0) { - Xs = abs(ys); - Ys = abs(xs); - qs = 3; - M1x = 0; - M1y = -1; - M2x = 1; - M2y = -1; - M3x = 1; - M3y = 0; - } - else { - Xs = abs(xs); - Ys = abs(ys); - qs = 2; - M1x = -1; - M1y = 0; - M2x = -1; - M2y = -1; - M3x = 0; - M3y = -1; - } - else if (ys < 0) { - Xs = abs(xs); - Ys = abs(ys); - qs = 0; - M1x = 1; - M1y = 0; - M2x = 1; - M2y = 1; - M3x = 0; - M3y = 1; - } else { - Xs = abs(ys); - Ys = abs(xs); - qs = 1; - M1x = 0; - M1y = 1; - M2x = -1; - M2y = 1; - M3x = -1; - M3y = 0; - } - - - Xc = Xs; - Yc = Ys; - if (xt < 0) - if (yt < 0) { - Xt = abs(yt); - Yt = abs(xt); - qt = 3; - } - else { - Xt = abs(xt); - Yt = abs(yt); - qt = 2; - } - else if (yt < 0) { - Xt = abs(xt); - Yt = abs(yt); - qt = 0; - } else { - Xt = abs(yt); - Yt = abs(xt); - qt = 1; - } - - - /* step 4: calculate number of quadrant crossings */ - if (((4 + qt - qs) - % 4 == 0) - && (Xt <= Xs) - && (Yt >= Ys) - ) - Q = 3; - else - Q = (4 + qt - qs) % 4 - 1; - /* step 5: calculate initial decision difference */ - delta = sqr(Xs + 1) - + sqr(Ys - 1) - -sqr(xs) - -sqr(ys); - /* here begins the work of drawing - we hope it ends here too */ - while ((Q >= 0) - || ((Q > -2) - && ((Xt > Xc) - || (Yt < Yc) - ) - ) - ) { - if (dotcount++ % DX == 0) - putdot(round((int) xc, DX), round((int) yc, DY)); - if (Yc < 0.5) { - /* reinitialize */ - Xs = Xc = 0; - Ys = Yc = sqrt((float)(sqr(xs) + sqr(ys))); - delta = sqr(Xs + 1) + sqr(Ys - 1) - sqr(xs) - sqr(ys); - Q--; - M1x = M3x; - M1y = M3y; - { - int T; - T = M2y; - M2y = M2x; - M2x = -T; - T = M3y; - M3y = M3x; - M3x = -T; - } - } else { - if (delta <= 0) - if (2 * delta + 2 * Yc - 1 <= 0) - move = 1; - else - move = 2; - else if (2 * delta - 2 * Xc - 1 <= 0) - move = 2; - else - move = 3; - switch (move) { - case 1: - Xc++; - delta += 2 * Xc + 1; - xc += M1x * xstep; - yc += M1y * ystep; - break; - case 2: - Xc++; - Yc--; - delta += 2 * Xc - 2 * Yc + 2; - xc += M2x * xstep; - yc += M2y * ystep; - break; - case 3: - Yc--; - delta -= 2 * Yc + 1; - xc += M3x * xstep; - yc += M3y * ystep; - break; - } - } - } - - -} - -putdot(x, y) -{ - arcmove(x, y); - put1(drawdot); -} - -round(x, dx) /* round x relative to dx */ -{ - x = (x + dx - 1) / dx; - return x * dx; + printf("\\&\\f1\\h'-.1m'\\v'.03m'\\s-3.\\s+3\\fP\n"); + flyback(); } -#endif diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/print.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/print.c index d608e20df3..7352e95411 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/print.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/print.c @@ -1,19 +1,16 @@ #ifndef lint -static char sccsid[] = "@(#)print.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)print.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include "pic.h" #include "y.tab.h" -int xxx; print() { - struct obj *p; - int i, j, m; + obj *p; + int i, j, k, m; float x0, y0, x1, y1, ox, oy, dx, dy, ndx, ndy; for (i = 0; i < nobj; i++) { - xxx = i; p = objlist[i]; ox = p->o_x; oy = p->o_y; @@ -36,10 +33,10 @@ print() y1 = oy + y1 / 2; if (p->o_attr & INVIS || p->o_type == BLOCK) ; /* nothing at all */ - else if (p->o_dotdash == 0) - box(x0, y0, x1, y1); + else if (p->o_attr & (DOTBIT|DASHBIT)) + dotbox(x0, y0, x1, y1, p->o_attr, p->o_ddval); else - dotbox(x0, y0, x1, y1, p->o_dotdash, p->o_ddval); + box(x0, y0, x1, y1); if (ishor(m)) move(isright(m) ? x1 : x0, oy); /* right side */ else @@ -47,15 +44,6 @@ print() break; case BLOCKEND: break; - x0 = ox - x1 / 2; - y0 = oy - y1 / 2; - x1 = ox + x1 / 2; - y1 = oy + y1 / 2; - if (ishor(m)) - move(isright(m) ? x1 : x0, oy); /* right side */ - else - move(ox, isdown(m) ? y0 : y1); /* bottom */ - break; case CIRCLE: move(ox, oy); dotext(p); @@ -81,16 +69,15 @@ print() dotext(p); if (p->o_attr & HEAD1) arrow(x1 - (y1 - oy), y1 + (x1 - ox), - x1, y1, p->o_val[4], p->o_val[5]); + x1, y1, p->o_val[4], p->o_val[5], p->o_val[5]/p->o_val[6]/2, p->o_nhead); if (p->o_attr & INVIS) /* probably wrong when it's cw */ move(x1, y1); else - arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3], p->o_val[6] - ,(p->o_attr&CW_ARC)); + arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3]); if (p->o_attr & HEAD2) arrow(p->o_val[2] + p->o_val[3] - oy, p->o_val[3] - (p->o_val[2] - ox), - p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5]); + p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5], -p->o_val[5]/p->o_val[6]/2, p->o_nhead); if (p->o_attr & CW_ARC) move(x1, y1); /* because drawn backwards */ break; @@ -100,45 +87,39 @@ print() move((ox + x1)/2, (oy + y1)/2); /* center */ dotext(p); if (p->o_attr & HEAD1) - arrow(ox + p->o_val[5], oy + p->o_val[6], ox, oy, p->o_val[2], p->o_val[3]); + arrow(ox + p->o_val[5], oy + p->o_val[6], ox, oy, p->o_val[2], p->o_val[3], 0.0, p->o_nhead); if (p->o_attr & INVIS) move(x1, y1); else if (p->o_type == SPLINE) spline(ox, oy, p->o_val[4], &p->o_val[5]); else { - int i, j; dx = ox; dy = oy; - for (i=0, j=5; i < p->o_val[4]; i++, j += 2) { + for (k=0, j=5; k < p->o_val[4]; k++, j += 2) { ndx = dx + p->o_val[j]; ndy = dy + p->o_val[j+1]; - if (p->o_dotdash == 0) - line(dx, dy, ndx, ndy); + if (p->o_attr & (DOTBIT|DASHBIT)) + dotline(dx, dy, ndx, ndy, p->o_attr, p->o_ddval); else - dotline(dx, dy, ndx, ndy, p->o_dotdash, p->o_ddval); + line(dx, dy, ndx, ndy); dx = ndx; dy = ndy; } } if (p->o_attr & HEAD2) { - int i, j; dx = ox; dy = oy; - for (i = 0, j = 5; i < p->o_val[4] - 1; i++, j += 2) { + for (k = 0, j = 5; k < p->o_val[4] - 1; k++, j += 2) { dx += p->o_val[j]; dy += p->o_val[j+1]; } - arrow(dx, dy, x1, y1, p->o_val[2], p->o_val[3]); + arrow(dx, dy, x1, y1, p->o_val[2], p->o_val[3], 0.0, p->o_nhead); } break; case MOVE: - move(ox, oy); - dotext(p); - break; case TEXT: move(ox, oy); - label((char *)p->o_attr, p->o_dotdash, 0); /* string in funny place */ - free((char *)p->o_attr); + dotext(p); break; } } @@ -159,7 +140,7 @@ dotline(x0, y0, x1, y1, ddtype, ddval) /* dotted line */ /* don't save dot/dash value */ dx = x1 - x0; dy = y1 - y0; - if (ddtype == DOT) { + if (ddtype & DOTBIT) { numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5; if (numdots > 0) for (i = 0; i <= numdots; i++) { @@ -167,7 +148,7 @@ dotline(x0, y0, x1, y1, ddtype, ddval) /* dotted line */ move(x0 + (a * dx), y0 + (a * dy)); dot(); } - } else if (ddtype == DASH) { + } else if (ddtype & DASHBIT) { double d, dashsize, spacesize; d = sqrt(dx*dx + dy*dy); if (d <= 2 * prevval) { @@ -202,7 +183,7 @@ dotbox(x0, y0, x1, y1, ddtype, ddval) /* dotted or dashed box */ } dotext(p) /* print text strings of p in proper vertical spacing */ - struct obj *p; + obj *p; { int i, nhalf; diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/symtab.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/symtab.c index e6f737f946..ea76778e23 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/symtab.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/symtab.c @@ -1,7 +1,6 @@ #ifndef lint -static char sccsid[] = "@(#)symtab.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)symtab.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include #include "pic.h" @@ -85,8 +84,34 @@ struct symtab *lookup(s) /* find s in symtab */ freesymtab(p) /* free space used by symtab at p */ struct symtab *p; { - for ( ; p != NULL; p = p->s_next) { + struct symtab *q; + + for ( ; p != NULL; p = q) { + q = p->s_next; free(p->s_name); /* assumes done with tostring */ free(p); } } + +freedef(s) /* free definition for string s */ + char *s; +{ + struct symtab *p, *q, *op; + + for (p = op = q = stack[nstack].p_symtab; p != NULL; p = p->s_next) { + if (strcmp(s, p->s_name) == 0) { /* got it */ + if (p->s_type != DEFNAME) + break; + if (p == op) /* 1st elem */ + stack[nstack].p_symtab = p->s_next; + else + q->s_next = p->s_next; + free(p->s_name); + free(p->s_val.p); + free(p); + return; + } + q = p; + } + yyerror("%s is not defined at this point", s); +} diff --git a/usr/src/local/ditroff/ditroff.okeeffe/pic/textgen.c b/usr/src/local/ditroff/ditroff.okeeffe/pic/textgen.c index 6c27dd1e2e..f84d148d77 100644 --- a/usr/src/local/ditroff/ditroff.okeeffe/pic/textgen.c +++ b/usr/src/local/ditroff/ditroff.okeeffe/pic/textgen.c @@ -1,65 +1,118 @@ #ifndef lint -static char sccsid[] = "@(#)textgen.c 1.1 (CWI) 85/07/19"; +static char sccsid[] = "@(#)textgen.c 2.1 (CWI) 85/07/23"; #endif lint - #include #include "pic.h" #include "y.tab.h" -struct obj *textgen(s) +obj *textgen() { - int i, type; - float dx, dy; - struct obj *p, *ppos; + int i, type, sub, nstr, at, with, hset; + float xwith, ywith, h, w, x0, y0, x1, y1; + obj *p, *ppos; + static float prevh = 0; + static float prevw = 0; + Attr *ap; - type = 'C'; - dx = dy = 0; - for (i = 0; i < nattr; i++) - switch (attr[i].a_type) { - case LEFT: - dx -= attr[i].a_val.f; - break; - case RIGHT: - dx += attr[i].a_val.f; + sub = CENTER; + at = with = nstr = hset = 0; + h = getfval("textht"); + w = getfval("textwid"); + for (i = 0; i < nattr; i++) { + ap = &attr[i]; + switch (ap->a_type) { + case HEIGHT: + h = ap->a_val.f; + hset++; break; - case UP: - dy += attr[i].a_val.f; + case WIDTH: + w = ap->a_val.f; break; - case DOWN: - dy -= attr[i].a_val.f; + case WITH: + with = ap->a_val.i; break; case AT: - ppos = attr[i].a_val.o; + ppos = ap->a_val.o; curx = ppos->o_x; cury = ppos->o_y; + at++; break; - case LJUST: - type = 'L'; - break; - case RJUST: - type = 'R'; - break; - case SPREAD: - type = 'S'; - break; - case FILL: - type = 'F'; - break; - case ABOVE: - type = 'A'; - break; - case BELOW: - type = 'B'; + case TEXTATTR: + sub = ap->a_sub; + if (ap->a_val.p == NULL) /* an isolated modifier */ + text[ntext-1].t_type = sub; + else { + savetext(sub, ap->a_val.p); + nstr++; + } break; } - dprintf("T %c %s\n", type, s); - extreme(curx, cury); - curx += dx; - cury += dy; - extreme(curx, cury); + } + if (hset == 0) /* no explicit ht cmd */ + h *= nstr; + if (with) { + xwith = ywith = 0.0; + switch (with) { + case NORTH: ywith = -h / 2; break; + case SOUTH: ywith = h / 2; break; + case EAST: xwith = -w / 2; break; + case WEST: xwith = w / 2; break; + case NE: xwith = -w / 2; ywith = -h / 2; break; + case SE: xwith = -w / 2; ywith = h / 2; break; + case NW: xwith = w / 2; ywith = -h / 2; break; + case SW: xwith = w / 2; ywith = h / 2; break; + } + curx += xwith; + cury += ywith; + } + if (!at) { + if (isright(hvmode)) + curx += w / 2; + else if (isleft(hvmode)) + curx -= w / 2; + else if (isup(hvmode)) + cury += h / 2; + else + cury -= h / 2; + } + x0 = curx - w / 2; + y0 = cury - h / 2; + x1 = curx + w / 2; + y1 = cury + h / 2; + extreme(x0, y0); + extreme(x1, y1); + dprintf("Text h %g w %g at %g,%g\n", h, w, curx, cury); p = makenode(TEXT, 2); - p->o_val[0] = p->o_val[1] = 0; - p->o_attr = s; /* kludge into funny place to avoid coercion */ - p->o_dotdash = type; + p->o_val[0] = w; + p->o_val[1] = h; + if (isright(hvmode)) + curx = x1; + else if (isleft(hvmode)) + curx = x0; + else if (isup(hvmode)) + cury = y1; + else + cury = y0; + prevh = h; + prevw = w; return(p); } + +obj *troffgen(s) /* save away a string of troff commands */ + YYSTYPE s; +{ + savetext(CENTER, s.p); /* use the existing text mechanism */ + return makenode(TROFF, 0); +} + +savetext(t, s) /* record text elements for current object */ + int t; + char *s; +{ + if (ntext >= ntextlist) + text = (Text *) grow(text, "text", ntextlist += 200, sizeof(Text)); + text[ntext].t_type = t; + text[ntext].t_val = s; + dprintf("saving %d text %s at %d\n", t, s, ntext); + ntext++; +} -- 2.20.1