|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <math.h> ! 3: #include "pic.h" ! 4: extern int dbg; ! 5: ! 6: #define abs(n) (n >= 0 ? n : -(n)) ! 7: #define max(x,y) ((x)>(y) ? (x) : (y)) ! 8: ! 9: char *textshift = "\\v'.2m'"; /* move text this far down */ ! 10: ! 11: /* scaling stuff defined by s command as X0,Y0 to X1,Y1 */ ! 12: /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */ ! 13: /* default output is 6x6 inches */ ! 14: ! 15: ! 16: float xscale; ! 17: float yscale; ! 18: ! 19: float hpos = 0; /* current horizontal position in output coordinate system */ ! 20: float vpos = 0; /* current vertical position; 0 is top of page */ ! 21: ! 22: float htrue = 0; /* where we really are */ ! 23: float vtrue = 0; ! 24: ! 25: float X0, Y0; /* left bottom of input */ ! 26: float X1, Y1; /* right top of input */ ! 27: ! 28: float hmax; /* right end of output */ ! 29: float vmax; /* top of output (down is positive) */ ! 30: ! 31: extern float deltx; ! 32: extern float delty; ! 33: extern float xmin, ymin, xmax, ymax; ! 34: ! 35: double xconv(), yconv(), xsc(), ysc(); ! 36: ! 37: openpl(s) /* initialize device */ ! 38: char *s; /* residue of .PS invocation line */ ! 39: { ! 40: float maxdelt; ! 41: ! 42: hpos = vpos = 0; ! 43: if (deltx > getfval("maxpswid") || delty > getfval("maxpsht")) { /* 8.5x11 inches max */ ! 44: fprintf(stderr, "pic: %g X %g picture shrunk to", deltx, delty); ! 45: maxdelt = max(deltx, delty); ! 46: deltx *= 7/maxdelt; /* screwed up anyway; */ ! 47: delty *= 7/maxdelt; /* make it 7x7 so someone can see it */ ! 48: fprintf(stderr, " %g X %g\n", deltx, delty); ! 49: } ! 50: space(xmin, ymin, xmax, ymax); ! 51: printf("... %g %g %g %g\n", xmin, ymin, xmax, ymax); ! 52: printf("... %.3fi %.3fi %.3fi %.3fi\n", ! 53: xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax)); ! 54: printf(".nr 00 \\n(.u\n"); ! 55: printf(".nf\n"); ! 56: printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s); ! 57: /* assumes \n comes as part of s */ ! 58: } ! 59: ! 60: space(x0, y0, x1, y1) /* set limits of page */ ! 61: double x0, y0, x1, y1; ! 62: { ! 63: X0 = x0; ! 64: Y0 = y0; ! 65: X1 = x1; ! 66: Y1 = y1; ! 67: xscale = deltx == 0.0 ? 1.0 : deltx / (X1-X0); ! 68: yscale = delty == 0.0 ? 1.0 : delty / (Y1-Y0); ! 69: } ! 70: ! 71: double xconv(x) /* convert x from external to internal form */ ! 72: double x; ! 73: { ! 74: return (x-X0) * xscale; ! 75: } ! 76: ! 77: double xsc(x) /* convert x from external to internal form, scaling only */ ! 78: double x; ! 79: { ! 80: ! 81: return (x) * xscale; ! 82: } ! 83: ! 84: double yconv(y) /* convert y from external to internal form */ ! 85: double y; ! 86: { ! 87: return (Y1-y) * yscale; ! 88: } ! 89: ! 90: double ysc(y) /* convert y from external to internal form, scaling only */ ! 91: double y; ! 92: { ! 93: return (y) * yscale; ! 94: } ! 95: ! 96: closepl(type) /* clean up after finished */ ! 97: int type; ! 98: { ! 99: movehv(0.0, 0.0); /* get back to where we started */ ! 100: if (type == 'F') ! 101: printf(".PF\n"); ! 102: else { ! 103: printf(".sp 1+%.3fi\n", yconv(ymin)); ! 104: printf(".PE\n"); ! 105: } ! 106: printf(".if \\n(00 .fi\n"); ! 107: } ! 108: ! 109: move(x, y) /* go to position x, y in external coords */ ! 110: double x, y; ! 111: { ! 112: hgoto(xconv(x)); ! 113: vgoto(yconv(y)); ! 114: } ! 115: ! 116: movehv(h, v) /* go to internal position h, v */ ! 117: double h, v; ! 118: { ! 119: hgoto(h); ! 120: vgoto(v); ! 121: } ! 122: ! 123: hmot(n) /* generate n units of horizontal motion */ ! 124: double n; ! 125: { ! 126: hpos += n; ! 127: } ! 128: ! 129: vmot(n) /* generate n units of vertical motion */ ! 130: double n; ! 131: { ! 132: vpos += n; ! 133: } ! 134: ! 135: hgoto(n) ! 136: double n; ! 137: { ! 138: hpos = n; ! 139: } ! 140: ! 141: vgoto(n) ! 142: double n; ! 143: { ! 144: vpos = n; ! 145: } ! 146: ! 147: hvflush() /* get to proper point for output */ ! 148: { ! 149: if (hpos != htrue) { ! 150: printf("\\h'%.3fi'", hpos - htrue); ! 151: htrue = hpos; ! 152: } ! 153: if (vpos != vtrue) { ! 154: printf("\\v'%.3fi'", vpos - vtrue); ! 155: vtrue = vpos; ! 156: } ! 157: } ! 158: ! 159: flyback() /* return to upper left corner (entry point) */ ! 160: { ! 161: printf(".sp -1\n"); ! 162: htrue = vtrue = 0; ! 163: } ! 164: ! 165: troff(s) /* output troff right here */ ! 166: char *s; ! 167: { ! 168: printf("%s\n", s); ! 169: } ! 170: ! 171: label(s, t, nh) /* text s of type t nh half-lines up */ ! 172: char *s; ! 173: int t, nh; ! 174: { ! 175: int q; ! 176: char *p; ! 177: ! 178: hvflush(); ! 179: dprintf("label: %s %o %d\n", s, t, nh); ! 180: printf("%s", textshift); /* shift down and left */ ! 181: if (t & ABOVE) ! 182: nh++; ! 183: else if (t & BELOW) ! 184: nh--; ! 185: if (nh) ! 186: printf("\\v'%du*\\n(.vu/2u'", -nh); ! 187: /* just in case the text contains a quote: */ ! 188: q = 0; ! 189: for (p = s; *p; p++) ! 190: if (*p == '\'') { ! 191: q = 1; ! 192: break; ! 193: } ! 194: t &= ~(ABOVE|BELOW); ! 195: if (t & LJUST) { ! 196: printf("%s", s); ! 197: } else if (t & RJUST) { ! 198: if (q) ! 199: printf("\\h\\(ts-\\w\\(ts%s\\(tsu\\(ts%s", s, s); ! 200: else ! 201: printf("\\h'-\\w'%s'u'%s", s, s); ! 202: } else { /* CENTER */ ! 203: if (q) ! 204: printf("\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts%s", s, s); ! 205: else ! 206: printf("\\h'-\\w'%s'u/2u'%s", s, s); ! 207: } ! 208: printf("\n"); ! 209: flyback(); ! 210: } ! 211: ! 212: line(x0, y0, x1, y1) /* draw line from x0,y0 to x1,y1 */ ! 213: double x0, y0, x1, y1; ! 214: { ! 215: move(x0, y0); ! 216: cont(x1, y1); ! 217: } ! 218: ! 219: arrow(x0, y0, x1, y1, w, h, ang, nhead) /* draw arrow (without shaft) */ ! 220: double x0, y0, x1, y1, w, h, ang; /* head wid w, len h, rotated ang */ ! 221: int nhead; /* and drawn with nhead lines */ ! 222: { ! 223: double alpha, rot, drot, hyp; ! 224: float dx, dy; ! 225: int i; ! 226: ! 227: rot = atan2(w / 2, h); ! 228: hyp = sqrt(w/2 * w/2 + h * h); ! 229: alpha = atan2(y1-y0, x1-x0) + ang; ! 230: if (nhead < 2) ! 231: nhead = 2; ! 232: dprintf("rot=%g, hyp=%g, alpha=%g\n", rot, hyp, alpha); ! 233: for (i = nhead-1; i >= 0; i--) { ! 234: drot = 2 * rot / (double) (nhead-1) * (double) i; ! 235: dx = hyp * cos(alpha + PI - rot + drot); ! 236: dy = hyp * sin(alpha + PI - rot + drot); ! 237: dprintf("dx,dy = %g,%g\n", dx, dy); ! 238: line(x1+dx, y1+dy, x1, y1); ! 239: } ! 240: } ! 241: ! 242: box(x0, y0, x1, y1) ! 243: double x0, y0, x1, y1; ! 244: { ! 245: move(x0, y0); ! 246: cont(x0, y1); ! 247: cont(x1, y1); ! 248: cont(x1, y0); ! 249: cont(x0, y0); ! 250: } ! 251: ! 252: cont(x, y) /* continue line from here to x,y */ ! 253: double x, y; ! 254: { ! 255: float h1, v1; ! 256: float dh, dv; ! 257: ! 258: h1 = xconv(x); ! 259: v1 = yconv(y); ! 260: dh = h1 - hpos; ! 261: dv = v1 - vpos; ! 262: hvflush(); ! 263: printf("\\D'l%.3fi %.3fi'\n", dh, dv); ! 264: flyback(); /* expensive */ ! 265: hpos = h1; ! 266: vpos = v1; ! 267: } ! 268: ! 269: circle(x, y, r) ! 270: double x, y, r; ! 271: { ! 272: move(x-r, y); ! 273: hvflush(); ! 274: printf("\\D'c%.3fi'\n", xsc(2 * r)); ! 275: flyback(); ! 276: } ! 277: ! 278: spline(x, y, n, p, dashed, ddval) ! 279: double x, y; ! 280: float *p; ! 281: double n; /* sic */ ! 282: int dashed; ! 283: double ddval; ! 284: { ! 285: int i; ! 286: float dx, dy; ! 287: float xerr, yerr; ! 288: ! 289: if (dashed && ddval) ! 290: printf(".nr 99 %.3fi\n", ddval); ! 291: move(x, y); ! 292: hvflush(); ! 293: xerr = yerr = 0.0; ! 294: if (dashed) { ! 295: if (ddval) ! 296: printf("\\X'Pd \\n(99'\\D'q 0 0"); ! 297: else ! 298: printf("\\X'Pd'\\D'q 0 0"); ! 299: } else ! 300: printf("\\D'~"); ! 301: for (i = 0; i < 2 * n; i += 2) { ! 302: dx = xsc(xerr += p[i]); ! 303: xerr -= dx/xscale; ! 304: dy = ysc(yerr += p[i+1]); ! 305: yerr -= dy/yscale; ! 306: printf(" %.3fi %.3fi", dx, -dy); /* WATCH SIGN */ ! 307: } ! 308: if (dashed) ! 309: printf(" 0 0'\\X'Ps'\n"); ! 310: else ! 311: printf("'\n"); ! 312: flyback(); ! 313: } ! 314: ! 315: ellipse(x, y, r1, r2) ! 316: double x, y, r1, r2; ! 317: { ! 318: float ir1, ir2; ! 319: ! 320: move(x-r1, y); ! 321: hvflush(); ! 322: ir1 = xsc(r1); ! 323: ir2 = ysc(r2); ! 324: printf("\\D'e%.3fi %.3fi'\n", 2 * ir1, 2 * abs(ir2)); ! 325: flyback(); ! 326: } ! 327: ! 328: arc(x, y, x0, y0, x1, y1) /* draw arc with center x,y */ ! 329: double x, y, x0, y0, x1, y1; ! 330: { ! 331: ! 332: move(x0, y0); ! 333: hvflush(); ! 334: printf("\\D'a%.3fi %.3fi %.3fi %.3fi'\n", ! 335: xsc(x-x0), -ysc(y-y0), xsc(x1-x), -ysc(y1-y)); /* WATCH SIGNS */ ! 336: flyback(); ! 337: } ! 338: ! 339: dot() { ! 340: hvflush(); ! 341: /* what character to draw here depends on what's available. */ ! 342: /* on the 202, l. is good but small. */ ! 343: /* in general, use a smaller, shifted period and hope */ ! 344: ! 345: printf("\\&\\f1\\h'-.1m'\\v'.03m'\\s-3.\\s+3\\fP\n"); ! 346: flyback(); ! 347: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.