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