|
|
1.1 ! root 1: /* Copyright (c) 1988 AT&T */ ! 2: /* All Rights Reserved */ ! 3: ! 4: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */ ! 5: /* The copyright notice above does not evidence any */ ! 6: /* actual or intended publication of such source code. */ ! 7: ! 8: /* @(#)picasso:plps.c 1.0 */ ! 9: ! 10: #include <string.h> ! 11: #include <ctype.h> ! 12: #include "font.h" ! 13: #include "picasso.h" ! 14: #include "y.tab.h" ! 15: ! 16: #define max(x,y) ((x)>(y) ? (x) : (y)) ! 17: #define min(x,y) ((x)<(y) ? (x) : (y)) ! 18: ! 19: #define PROLOGUE "picasso.ps" ! 20: #define FONTDEFS "fonts.ps" ! 21: ! 22: extern char *gwblib; /* defined by installer, or set by -I flag */ ! 23: extern int margin; ! 24: extern float magnification; ! 25: extern float *miters; ! 26: extern FILE *textfp; ! 27: extern int batch; ! 28: extern int pic_compat; ! 29: ! 30: FILE *outfp = stdout; ! 31: int pages = 0; ! 32: int pictures = 0; ! 33: int started = 0; ! 34: int bboxllx = 32767; ! 35: int bboxlly = 32767; ! 36: int bboxurx = -32767; ! 37: int bboxury = -32767; ! 38: int psfont = -1; ! 39: double pssize = 0; ! 40: int last_cap = -1; ! 41: int last_join = -1; ! 42: float last_miter = -1; ! 43: float last_weight = -1; ! 44: float last_color = -1; ! 45: float *last_dash = NULL; ! 46: ! 47: static int extra_chars = 0; ! 48: ! 49: resetps() /* these must be reset for each page of a multipage file */ ! 50: { /* (so that -mpictures inclusions will work correctly.) */ ! 51: ! 52: psfont = last_miter = last_cap = last_join = -1; ! 53: last_weight = last_color = -1; ! 54: last_dash = NULL; ! 55: pssize = 0; ! 56: } ! 57: ! 58: static char *nopro = "can't read prologue file "; ! 59: ! 60: findfile(path, name) ! 61: char *path, *name; ! 62: { ! 63: char *msgbuf; ! 64: ! 65: if (access(strcat(strcat(strcpy(path,gwblib),"/"),name),4) != 0) { ! 66: if (batch) ! 67: fprintf(stderr, "%s%s\n", nopro, path); ! 68: else { ! 69: msgbuf = (char *) malloc(strlen(path)+strlen(nopro)+2); ! 70: if (msgbuf != NULL) { ! 71: sprintf(msgbuf, "%s%s", nopro, path); ! 72: writemessage(msgbuf, 15, 1); ! 73: free(msgbuf); ! 74: } ! 75: } ! 76: } ! 77: } ! 78: ! 79: beginpl() ! 80: { ! 81: char filename[100]; ! 82: ! 83: fputs("%!PS-Adobe-2.0\n", outfp); ! 84: fputs("%%Creator: picasso\n", outfp); ! 85: fputs("%%BoundingBox: (atend)\n", outfp); ! 86: fputs("%%Pages: (atend)\n", outfp); ! 87: fputs("%%EndComments\n", outfp); ! 88: if (!pass_thru) { ! 89: findfile(filename, FONTDEFS); ! 90: catfile(filename); ! 91: } ! 92: findfile(filename, PROLOGUE); ! 93: catfile(filename); ! 94: fputs("%%EndProlog\n", outfp); ! 95: fputs("%%BeginSetup\n", outfp); ! 96: if (magnification != 1.0) ! 97: fprintf(outfp, "/magnification %f def\n", magnification); ! 98: fputs("%%EndSetup\n", outfp); ! 99: pages = 0; ! 100: bboxllx = 32767; ! 101: bboxlly = 32767; ! 102: bboxurx = -32767; ! 103: bboxury = -32767; ! 104: started = 1; ! 105: } ! 106: ! 107: endpl() ! 108: { ! 109: if (started) { ! 110: fputs("%%Trailer\n", outfp); ! 111: fprintf(outfp, "%%%%BoundingBox: %d %d %d %d\n", ! 112: (int)(bboxllx*magnification), (int)(bboxlly*magnification), ! 113: (int)(bboxurx*magnification), (int)(bboxury*magnification)); ! 114: fprintf(outfp, "%%%%Pages: %d\n", pages); ! 115: } ! 116: } ! 117: ! 118: int open_done = 0; ! 119: double tx, ty, pgscale = 72; ! 120: static double px, py, sx, sy; ! 121: static int pbnd[4]; ! 122: ! 123: openpl(s) /* initialize page */ ! 124: char *s; ! 125: { ! 126: extern FILE *tmpfile(); ! 127: extern double pght, pgwid; ! 128: double deltx, delty, r; ! 129: ! 130: if (open_done) ! 131: return; ! 132: pgscale = 72; /* reset for every picture */ ! 133: while (isspace(*s)) ! 134: s++; ! 135: if (*s == '\0') { ! 136: px = pgwid; ! 137: py = pght; ! 138: } ! 139: else { ! 140: px = py = 0; ! 141: sscanf(s, "%lf %lf", &py, &px); ! 142: if (pic_compat) { ! 143: r = px; ! 144: px = py; ! 145: py = r; ! 146: } ! 147: if (px <= 0) px = pgwid; ! 148: if (py <= 0) py = pght; ! 149: } ! 150: if (pass_thru) { ! 151: if ((outfp = tmpfile()) == NULL) ! 152: fatal("can't open internal temporary file"); ! 153: started = 0; ! 154: } ! 155: if (!started) ! 156: beginpl(); ! 157: if (nosqueeze) { ! 158: sx = sy = 72; ! 159: tx = ty = 0; ! 160: } ! 161: else { ! 162: deltx = (Gbox[2]-Gbox[0]); ! 163: delty = (Gbox[3]-Gbox[1]); ! 164: if (cur_xform[0].f != 1) { /* implicit scaling */ ! 165: deltx *= cur_xform[0].f; ! 166: delty *= cur_xform[0].f; ! 167: } ! 168: r = max(deltx/px, delty/py); ! 169: if (r <= 1) ! 170: r = 1; ! 171: else if (verbose || px == pgwid && py == pght) { ! 172: fprintf(stderr, "%s: %g X %g picture shrunk to", ! 173: cmdname, deltx, delty); ! 174: deltx /= r; ! 175: delty /= r; ! 176: fprintf(stderr, " %g X %g\n", deltx, delty); ! 177: } ! 178: /* NOTE: Setting pgscale affects the subsequent ouput of text, so ! 179: that text will come out the same size regardless of the scaling ! 180: of the rest of the drawing. This is only appropriate when we ! 181: are in pic emulation mode, since pic couldn't scale text.--DBK */ ! 182: if (pic_compat) ! 183: pgscale = 72/r; ! 184: sx = sy = 72/r; ! 185: tx = -(Gbox[0]+Gbox[2])/2; ! 186: ty = -(Gbox[1]+Gbox[3])/2; ! 187: } ! 188: pages++; ! 189: fprintf(outfp, "%%%%Page: ? %d\n", pages); ! 190: fprintf(outfp, "%%%%PageBoundingBox: (atend)\n"); ! 191: fputs("%%BeginPageSetup\n", outfp); ! 192: fprintf(outfp, "%.5g %.5g %.5g %.5g PIC\n", tx, ty, sx, sy); ! 193: fputs("%%EndPageSetup\n", outfp); ! 194: setattrdefaults (); ! 195: open_done = 1; ! 196: } ! 197: ! 198: closepl(s) /* clean up after finished with one picture */ ! 199: char *s; /* residue of .PS invocation line */ ! 200: { ! 201: extern long ftell(); ! 202: extern int flyback; ! 203: long filesize; ! 204: ! 205: if (open_done) { ! 206: fputs("showpage\n", outfp); ! 207: if (nosqueeze) { ! 208: pbnd[0] = Gbox[0]*72 + px * 72 / 2; ! 209: pbnd[3] = (11+Gbox[3])*72 - py * 72 / 2; ! 210: } ! 211: else { ! 212: pbnd[0] = pgwid * 72 / 2 + (Gbox[0] - Gbox[2]) * sx / 2; ! 213: pbnd[3] = pght * 72 / 2 + (Gbox[3] - Gbox[1]) * sy / 2; ! 214: } ! 215: pbnd[1] = pbnd[3] - (Gbox[3] - Gbox[1]) * sy; ! 216: pbnd[2] = pbnd[0] + (Gbox[2] - Gbox[0]) * sx; ! 217: pbnd[0] -= margin; pbnd[1] -= margin; ! 218: pbnd[2] += margin; pbnd[3] += margin; ! 219: if (pbnd[0] < 0) pbnd[0] = margin; ! 220: if (pbnd[1] < 0) pbnd[1] = margin; ! 221: if (pbnd[2] > pgwid * 72) pbnd[2] = pgwid * 72 - margin; ! 222: if (pbnd[3] > pght * 72) pbnd[3] = pght * 72 - margin; ! 223: fprintf(outfp, "%%%%PageBoundingBox: %d %d %d %d\n", ! 224: (int)(pbnd[0]*magnification), (int)(pbnd[1]*magnification), ! 225: (int)(pbnd[2]*magnification), (int)(pbnd[3]*magnification)); ! 226: if (bboxllx > pbnd[0]) bboxllx = pbnd[0]; ! 227: if (bboxlly > pbnd[1]) bboxlly = pbnd[1]; ! 228: if (bboxurx < pbnd[2]) bboxurx = pbnd[2]; ! 229: if (bboxury < pbnd[3]) bboxury = pbnd[3]; ! 230: if (pass_thru) { ! 231: endpl(); ! 232: fflush(outfp); ! 233: filesize = ftell(outfp) - extra_chars; ! 234: rewind(outfp); ! 235: pictures++; ! 236: printf("\\!x X InlinePicture picture%d %ld\n", ! 237: pictures, filesize); ! 238: transparent(outfp); ! 239: fclose(outfp); ! 240: fprintf(textfp, ".BP picture%d ", pictures); ! 241: while (isspace(*s)) ! 242: s++; ! 243: if (*s != '\0') ! 244: if (pic_compat) { /* interchange x and y */ ! 245: double x, y; ! 246: int i; ! 247: char r[120]; ! 248: ! 249: i = sscanf(s, "%lf %lf %[^\n]", ! 250: &x, &y, r); ! 251: if (i <= 0) ! 252: x = (bboxurx - bboxllx)/72.0; ! 253: if (i == 1) ! 254: y = x * (bboxury - bboxlly) / ! 255: (bboxurx - bboxllx); ! 256: if (i < 3) ! 257: strcpy(r, "c"); ! 258: fprintf(textfp, "%g %g %s\n", y, x, r); ! 259: } ! 260: else ! 261: fputs(s, textfp); ! 262: else ! 263: fprintf(textfp, "%g %g%s\n", ! 264: (bboxury - bboxlly)/72.0, ! 265: (bboxurx - bboxllx)/72.0, ! 266: pic_compat ? " c" : ""); ! 267: if (!flyback) ! 268: fputs(".EP\n", textfp); ! 269: } ! 270: extra_chars = 0; ! 271: open_done = 0; ! 272: resetps(); ! 273: } ! 274: } ! 275: ! 276: /* If not specified with the object, any geometrical primitve is stroked */ ! 277: /* in the default linecolor (and at default lineweight) and is not filled. */ ! 278: /* The most recent settings of color and weight are preserved and used to */ ! 279: /* compare with values requested for this object. */ ! 280: ! 281: check_psxform() ! 282: { ! 283: if (cur_xform[0].f != 1 || cur_xform[1].f != 0 || cur_xform[2].f != 0 ! 284: || cur_xform[3].f != 1 || cur_xform[4].f != 0 || cur_xform[5].f != 0) { ! 285: ! 286: fprintf (outfp, "[%.5g %.5g %.5g %.5g %.5g %.5g] concat\n", ! 287: cur_xform[0].f, cur_xform[1].f, cur_xform[2].f, ! 288: cur_xform[3].f, cur_xform[4].f, cur_xform[5].f); ! 289: ! 290: cur_xform[0].f = cur_xform[3].f = 1; ! 291: cur_xform[1].f = cur_xform[2].f = ! 292: cur_xform[4].f = cur_xform[5].f = 0; ! 293: } ! 294: } ! 295: ! 296: short have_temp = 0; ! 297: extern double T[]; ! 298: ! 299: tmp_xform (p) /* used only for text */ ! 300: obj *p; ! 301: { ! 302: #if 0 ! 303: if (p->o_mxx != 1 || p->o_myx != 0 || p->o_mxy != 0 || p->o_myy != 1 ! 304: || p->o_mxt != 0 || p->o_myt != 0) { ! 305: have_temp = 1; ! 306: fprintf (outfp, "\ngs [%.5g %.5g %.5g %.5g %.5g %.5g] concat\n", ! 307: p->o_mxx, p->o_myx, p->o_mxy, p->o_myy, ! 308: p->o_mxt, p->o_myt); ! 309: } ! 310: #else ! 311: compose(p); ! 312: if (T[0] != 1 || T[1] != 0 || T[2] != 0 || ! 313: T[3] != 1 || T[4] != 0 || T[5] != 0) { ! 314: have_temp = 1; ! 315: fprintf (outfp, "\ngs [%.5g %.5g %.5g %.5g %.5g %.5g] concat\n", ! 316: T[0], T[1], T[2], T[3], T[4], T[5]); ! 317: } ! 318: #endif ! 319: } ! 320: ! 321: undo_tmpx () ! 322: { ! 323: if (have_temp) { ! 324: fputs("gr\n", outfp); ! 325: } ! 326: have_temp = 0; ! 327: } ! 328: ! 329: new_weight (val) ! 330: float val; ! 331: { ! 332: if (val < 0.) ! 333: yyerror ("bad value for lineweight"); ! 334: else if (val != last_weight) ! 335: fprintf (outfp, " %.5g w\n", last_weight = val); ! 336: } ! 337: ! 338: new_color (val) ! 339: float val; ! 340: { ! 341: if (val != last_color) { ! 342: if (val <= 1.0) ! 343: fprintf (outfp, " %.5g g\n", val); ! 344: else { ! 345: register int n = val; ! 346: ! 347: fprintf (outfp, " %.5g %.5g %.5g rgb\n", ! 348: rgbtable[n].r, rgbtable[n].g, rgbtable[n].b); ! 349: } ! 350: if (!have_temp) ! 351: last_color = val; ! 352: } ! 353: } ! 354: ! 355: int attr_flags; ! 356: float fill_color; ! 357: float line_color; ! 358: float line_weight; ! 359: float *line_dash; ! 360: ! 361: setattrdefaults () ! 362: { ! 363: float x; ! 364: ! 365: if ((x = getfval("flatness")) > 0) ! 366: fprintf(outfp,"%.5g setflat\n", x); ! 367: attr_flags = EDGED; ! 368: new_weight(getfval("lineweight")); ! 369: new_color (getfval("linecolor")); ! 370: new_style(); ! 371: } ! 372: ! 373: float solid = 0; ! 374: ! 375: new_style() /* corners, ends, dash pattern */ ! 376: { ! 377: int i, n; ! 378: ! 379: if ((n = attr_flags & (3*LINECAP)) > 0) { ! 380: n /= LINECAP; ! 381: if (--n != last_cap) ! 382: fprintf(outfp,"%d setlinecap\n",last_cap = n); ! 383: } ! 384: if ((n = attr_flags & (3*JOIN)) > 0) { ! 385: n /= JOIN; ! 386: if (--n != last_join) ! 387: fprintf(outfp,"%d setlinecap\n",last_join = n); ! 388: if (n == 0 && (i = attr_flags/MITER) > 0) ! 389: if (miters[i] != last_miter) ! 390: fprintf(outfp,"%.5g setmiterlimit\n", ! 391: last_miter = miters[i]); ! 392: } ! 393: if (attr_flags & DOTDASH) { ! 394: n = *line_dash; ! 395: for (i = 0; i <= n; i++) ! 396: if (line_dash[i] != last_dash[i]) ! 397: break; ! 398: if (i < n+1) { ! 399: fprintf(outfp," [%.5g",line_dash[1]); ! 400: for (i = 2; i <= n; i++) { ! 401: fprintf(outfp, " %.5g", line_dash[i]); ! 402: } ! 403: fprintf(outfp, "] 0 d\n"); ! 404: last_dash = line_dash; ! 405: } ! 406: } ! 407: else { ! 408: if (last_dash != &solid) ! 409: fprintf(outfp, " [] 0 d\n"); ! 410: last_dash = &solid; ! 411: } ! 412: } ! 413: ! 414: chk_attrs (p) ! 415: obj *p; ! 416: { ! 417: line_weight = p->o_weight; ! 418: /* It seems as though this should scale with the associated ! 419: * object. I have made it so, 9/20/90. DBK ! 420: */ ! 421: compose(p); ! 422: line_weight *= sqrt(fabs(T[0] * T[3] - T[1] * T[2])); ! 423: attr_flags = p->o_attr; ! 424: line_color = p->o_color; ! 425: fill_color = p->o_fill; ! 426: line_dash = p->o_ddpat.a; ! 427: } ! 428: ! 429: fill_or_stroke () /* If fill/edge colors differ, need save/restore */ ! 430: { /* In any case, filled paths must be closed, so */ ! 431: /* a possibly redundant (but harmless) closepath */ ! 432: /* is issued whenever a fillpath is to be done. */ ! 433: switch (attr_flags & (EDGED | FILLED)) { ! 434: ! 435: case EDGED: new_color (line_color); /* simple stroke */ ! 436: new_weight(line_weight); ! 437: new_style(); ! 438: fprintf(outfp, " s\n"); ! 439: break; ! 440: case FILLED: new_color(fill_color); /* simple fill */ ! 441: fprintf(outfp, " c f\n"); ! 442: break; ! 443: default: new_color (line_color); ! 444: new_weight(line_weight); ! 445: new_style(); ! 446: if (fill_color <= 1.0) ! 447: fprintf(outfp, " c gs %.5g g f gr s\n", ! 448: fill_color); ! 449: else { ! 450: register int n = fill_color; ! 451: ! 452: fprintf(outfp," gs %.5g %.5g %.5g rgb f gr s\n", ! 453: rgbtable[n].r, ! 454: rgbtable[n].g, ! 455: rgbtable[n].b); ! 456: } ! 457: break; ! 458: } ! 459: } ! 460: ! 461: line(x0, y0, x1, y1) /* draw line from x0,y0 to x1,y1 */ ! 462: double x0, y0, x1, y1; ! 463: { ! 464: fprintf(outfp, "%.5g %.5g 1 %.5g %.5g L", x1, y1, x0, y0); ! 465: fill_or_stroke (); ! 466: } ! 467: ! 468: box(x0, y0, x1, y1, r) ! 469: double x0, y0, x1, y1, r; ! 470: { ! 471: if (r < MINRAD) ! 472: fprintf(outfp, "%.5g %.5g %.5g %.5g Q", x0,y0, x1,y1); ! 473: else ! 474: fprintf(outfp, "%.5g %.5g %.5g %.5g %.5g rQ", x0,y0, x1,y1, r); ! 475: fill_or_stroke (); ! 476: } ! 477: ! 478: arrow(x0, y0, x1, y1, w, h, ang, attr) /* draw arrowhead (w/o shaft) */ ! 479: double x0, y0, x1, y1, w, h, ang; /* wid w, len h, rotated ang */ ! 480: int attr; /* and drawn filled or open. */ ! 481: { ! 482: double alpha, rot, hyp; ! 483: float dx0, dy0, dx1, dy1; ! 484: ! 485: rot = atan2(w/2, h); ! 486: hyp = hypot(w/2, h); ! 487: alpha = atan2(y1-y0, x1-x0) + ang; ! 488: dx0 = hyp * cos(alpha + M_PI - rot); ! 489: dy0 = hyp * sin(alpha + M_PI - rot); ! 490: dx1 = hyp * cos(alpha + M_PI + rot); ! 491: dy1 = hyp * sin(alpha + M_PI + rot); ! 492: new_weight (line_weight); ! 493: fprintf(outfp, "%.5g %.5g %.5g %.5g 2 %.5g %.5g L ", ! 494: x1+dx1, y1+dy1, x1, y1, x1+dx0, y1+dy0); ! 495: if (attr & HEADFILL) ! 496: fprintf(outfp, "c gs s gr f\n"); ! 497: else ! 498: fprintf(outfp, "s\n"); ! 499: } ! 500: ! 501: spline(n, close, p) ! 502: int n, close; ! 503: valtype *p; ! 504: { ! 505: int i; ! 506: ! 507: for (i = 2*n; i > 2; i -= 2) ! 508: fprintf(outfp,"%.5g %.5g%c",p[i].f,p[i+1].f,i%10==9 ?'\n':' '); ! 509: fprintf(outfp, "%d %.5g %.5g %.5g %.5g Sp %c", ! 510: n-1, p[2].f,p[3].f,p[0].f,p[1].f, close? 'c' : ' '); ! 511: fill_or_stroke (); ! 512: } ! 513: ! 514: pline(n, close, p, r) ! 515: int n; ! 516: valtype *p; ! 517: double r; /* "corner" radius */ ! 518: { ! 519: int i; ! 520: float x, y; ! 521: ! 522: if (close && r > MINRAD) { ! 523: fprintf(outfp, "%.5g %.5g\n", ! 524: x=(p[0].f+p[2].f)/2, y=(p[1].f+p[3].f)/2); ! 525: for (i = 2*n; i > 0; i -= 2) ! 526: fprintf(outfp, "%.5g %.5g%c", ! 527: p[i].f, p[i+1].f, i%8==7 ?'\n':' '); ! 528: fprintf(outfp, "%.5g %d %.5g %.5g rL", r, n+1, x, y); ! 529: } ! 530: else { ! 531: n -= close; ! 532: for (i = 2*n; i > 0; i -= 2) ! 533: fprintf(outfp, "%.5g %.5g%c", ! 534: p[i].f, p[i+1].f, i%8==7 ?'\n':' '); ! 535: if (r > MINRAD) ! 536: fprintf(outfp, "%.5g %d %.5g %.5g rL", ! 537: r, n, p[0].f, p[1].f); ! 538: else ! 539: fprintf(outfp, "%d %.5g %.5g L", n, p[0].f, p[1].f); ! 540: if (close) ! 541: fprintf(outfp, " c"); ! 542: } ! 543: fill_or_stroke (); ! 544: } ! 545: ! 546: ellipse(xc, yc, x0, y0, x1, y1, ang1, ang2, type) /* general elliptical */ ! 547: double xc, yc, x0, y0, x1, y1, ang1, ang2; /* arc/sector routine */ ! 548: int type; ! 549: { ! 550: double c, s, phi, r1, r2; ! 551: int iang1, iang2; ! 552: ! 553: iang1 = (int)(180 * (ang1 * M_1_PI) + 0.5); ! 554: iang2 = (int)(180 * (ang2 * M_1_PI) + 0.5); ! 555: ! 556: /* This finds the angle at which the ellipse is inclined to the axes; the */ ! 557: /* most common case will have phi==0 or pi/2, and it seems worthwhile to */ ! 558: /* check for that case without doing all the trigonometric stuff below. */ ! 559: ! 560: if (y0 == 0 && x1 == 0 || x0 == 0 && y1 == 0) { ! 561: phi = 0; ! 562: r1 = fabs(x0); ! 563: r2 = fabs(y1); ! 564: } ! 565: else { ! 566: phi = atan2(x0*x0 + y0*y0 - x1*x1 - y1*y1, 2*(x0*x1 + y0*y1))/2; ! 567: c = cos(phi); ! 568: s = sin(phi); ! 569: r1 = hypot(c*x0 + s*x1, c*y0 + s*y1); ! 570: r2 = hypot(c*x1 - s*x0, c*y1 - s*y0); ! 571: } ! 572: if (fabs(r1-r2) < MINRAD) ! 573: fprintf(outfp, "n %.5g %.5g %.5g %d %d arc", ! 574: xc, yc, (r1+r2)/2, iang1, iang2); ! 575: else { ! 576: /* note: if phi != 0, non-postScript displays need to call a */ ! 577: /* special elliptical arc generation routine here: */ ! 578: /* */ ! 579: /* gen_ellipse(xc,yc,x0,y0,x1,y1,ang1,ang2) */ ! 580: ! 581: fprintf(outfp,"0 0 1 %d %d [%.5g %.5g %.5g %.5g %.5g %.5g] E", ! 582: iang1, iang2, x0, y0, x1, y1, xc, yc); ! 583: } ! 584: if (type == SECTOR) ! 585: fprintf(outfp, " %.5g %.5g l c", xc, yc); ! 586: fill_or_stroke(); ! 587: } ! 588: ! 589: extra_bs() ! 590: { ! 591: fputc('\\', outfp); ! 592: extra_chars++; ! 593: } ! 594: ! 595: octal_char(c) ! 596: char c; ! 597: { ! 598: if (pass_thru) ! 599: extra_bs(); ! 600: fprintf(outfp,"\\%o", c); ! 601: } ! 602: ! 603: char escapes[] = "()\\"; /* chars needing to be escaped in PostScript */ ! 604: ! 605: escstr(s) ! 606: char *s; ! 607: { ! 608: char *ptr; ! 609: ! 610: fputc('(', outfp); ! 611: while ((ptr = strpbrk(s,escapes)) != NULL) { ! 612: while (s < ptr) ! 613: if (*s >= ' ' && *s <= '~') ! 614: fputc(*s++, outfp); ! 615: else ! 616: octal_char(*s++); ! 617: if (pass_thru) { /* troff changes \\ to \ */ ! 618: extra_bs(); ! 619: if (*s == '\\') /* for a total of 3 extras! */ ! 620: extra_bs(); ! 621: } ! 622: fputc('\\', outfp); ! 623: fputc(*s++, outfp); ! 624: } ! 625: while (*s) ! 626: if (*s >= ' ' && *s <= '~') ! 627: fputc(*s++, outfp); ! 628: else ! 629: octal_char(*s++); ! 630: fputc(')', outfp); ! 631: } ! 632: ! 633: spacecount(s) ! 634: char *s; ! 635: { ! 636: int count = 0; ! 637: ! 638: while (*s) ! 639: if (*s++ == ' ') count++; ! 640: ! 641: return(count); ! 642: } ! 643: ! 644: double lastx, lasty; ! 645: ! 646: newlabel(type, str, font, x, y, size, w) ! 647: char *str; ! 648: int type, font; ! 649: double x, y, size, w; ! 650: { ! 651: if (type & EQNTXT) ! 652: puteqn(x, y, type, atoi(str)); ! 653: else { ! 654: resetfont(font, size); ! 655: escstr(str); ! 656: fprintf(outfp," %d %.5g %.5g %.5g T\n",spacecount(str),w,x,y); ! 657: } ! 658: lastx = x+w; ! 659: lasty = y; ! 660: } ! 661: ! 662: addlabel(type, str, font, size, w) ! 663: char *str; ! 664: int type, font; ! 665: double size, w; ! 666: { ! 667: if (type & EQNTXT) ! 668: puteqn(lastx, lasty, type, atoi(str)); ! 669: else { ! 670: resetfont(font, size); ! 671: escstr(str); ! 672: fprintf(outfp, " %d %.5g AT\n", spacecount(str), w); ! 673: } ! 674: lastx += w; ! 675: } ! 676: ! 677: resetfont (font, size) ! 678: int font; ! 679: double size; ! 680: { ! 681: if (font < 0) font = -font; ! 682: if (size < 0) size = -size; ! 683: if (font != psfont || size != pssize) { ! 684: fprintf(outfp, "%s findfont %.5g scalefont setfont\n", ! 685: mount[font]->name, size); ! 686: if (!have_temp) { ! 687: psfont = font; pssize = size; ! 688: } ! 689: } ! 690: } ! 691: ! 692: int ! 693: catfile(s) ! 694: char *s; ! 695: { ! 696: FILE *fp, *fopen(); ! 697: char buf[BUFSIZ]; ! 698: int count; ! 699: ! 700: if ((fp = fopen(s, "r")) == NULL) return(0); ! 701: while ((count = fread(buf, sizeof(*buf), BUFSIZ, fp)) > 0) ! 702: fwrite(buf, sizeof(*buf), count, outfp); ! 703: fclose(fp); ! 704: return(1); ! 705: } ! 706: ! 707: int ! 708: transparent(fp) ! 709: FILE *fp; ! 710: { ! 711: char buf[BUFSIZ]; ! 712: ! 713: while (fgets(buf, BUFSIZ, fp) != NULL) { ! 714: putchar('\\'); putchar('!'); ! 715: fputs(buf, stdout); ! 716: } ! 717: } ! 718: /* ! 719: * include an encapsulated postscript file. Apply any scaling and ! 720: * transformation specified by p. ! 721: */ ! 722: puteps(o) ! 723: obj *o; ! 724: { ! 725: FILE *fp; ! 726: ! 727: if ((fp = fopen(o->o_val[N_VAL-1].p, "r")) == NULL) { ! 728: yyerror("can't open EPS file %s", o->o_val[N_VAL-1].p); ! 729: return; ! 730: } ! 731: pic_include(fp, outfp, 1, o); ! 732: fclose(fp); ! 733: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.