|
|
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:print.c 1.0 */ ! 9: ! 10: #include <assert.h> ! 11: #include <ctype.h> ! 12: #include <string.h> ! 13: #include "picasso.h" ! 14: #include "y.tab.h" ! 15: ! 16: extern int eqn_count; ! 17: int flyback; ! 18: int redo_gbox = 0; ! 19: int objcount = 0; ! 20: ! 21: print_buf() ! 22: { ! 23: int n; ! 24: obj *p; ! 25: ! 26: if (++objcount > objbuf) { ! 27: p = objhead->o_next; ! 28: if (p->o_type != BLOCK) ! 29: print_obj(p->o_layer, p); ! 30: else if (p->o_val[N_VAL].o == (obj *)0) ! 31: return; ! 32: else for (n = draftlayer; n <= top_layer; n++) ! 33: print_obj(n,p); ! 34: freenode(p); ! 35: } ! 36: } ! 37: ! 38: extern FILE *pipefp, *eqnfp; ! 39: extern char psfname[]; ! 40: ! 41: print(c) /* show everything (above draft layers) */ ! 42: int c; ! 43: { ! 44: int n; ! 45: ! 46: /* Added 10/15/90--DBK. Is there any reason NOT to do this? */ ! 47: redo_gbox = 1; ! 48: if (pipefp) { ! 49: pclose(pipefp); ! 50: pipefp = NULL; ! 51: if ((eqnfp = fopen(psfname,"r")) == NULL) ! 52: fatal("cannot read eqn output"); ! 53: } ! 54: flyback = (c == 'F'); ! 55: if (c != 'N') ! 56: for (n = draftlayer; n <= top_layer; ++n) ! 57: print_layer(n); ! 58: if (eqnfp) { ! 59: fclose(eqnfp); ! 60: eqnfp = NULL; ! 61: eqn_count = 0; ! 62: unlink(psfname); ! 63: } ! 64: } ! 65: ! 66: print_layer(n) /* show contents of a single layer (maybe a draft layer) */ ! 67: int n; ! 68: { ! 69: obj *p; ! 70: ! 71: for (p = objhead->o_next; p!= objtail; p = p->o_next) ! 72: p = print_obj(n, p); ! 73: } ! 74: ! 75: print_bnd(p, q) /* show everything (non-draft) between given bounds */ ! 76: obj *p, *q; ! 77: { ! 78: int n; ! 79: ! 80: for (n = draftlayer; n <= top_layer; ++n) ! 81: print_layer_bnd(n, p, q); ! 82: } ! 83: ! 84: print_layer_bnd(n, p, q) /* show objects in layer n from p to q */ ! 85: int n; ! 86: obj *p, *q; ! 87: { ! 88: obj *r; ! 89: float x0, y0, x1, y1, bnd[4]; ! 90: ! 91: if (p->o_x < q->o_x) ! 92: { x0 = p->o_x; x1 = q->o_x; } ! 93: else ! 94: { x0 = q->o_x; x1 = p->o_x; } ! 95: if (p->o_y < q->o_y) ! 96: { y0 = p->o_y; y1 = q->o_y; } ! 97: else ! 98: { y0 = q->o_y; y1 = p->o_y; } ! 99: ! 100: for (r = objhead->o_next; r!= objtail; r = r->o_next) ! 101: if (r->o_x >= x0 && r->o_x <= x1 ! 102: && r->o_y >= y0 && r->o_y <= y1) ! 103: r = print_obj(n, r); ! 104: } ! 105: ! 106: obj *print_obj(layer, p) ! 107: int layer; ! 108: obj *p; ! 109: { ! 110: double r, dx, dy, ox, oy, x0, y0, x1, y1; ! 111: obj *q; ! 112: int n; ! 113: ! 114: if (redo_gbox) { ! 115: float bnd[4]; ! 116: Gbox[2] = Gbox[3] = -(Gbox[0] = Gbox[1] = 32767); ! 117: for (q = objhead->o_next; q != objtail; q = q->o_next) { ! 118: get_bounds(q, bnd, 1); ! 119: track_bounds (bnd[0], bnd[1], bnd[2], bnd[3]); ! 120: if (q->o_type == BLOCK) ! 121: q = q->o_val[N_VAL].o; ! 122: } ! 123: redo_gbox = 0; ! 124: } ! 125: openpl(""); ! 126: if (p->o_type != BLOCK && p->o_layer != layer) ! 127: return p; ! 128: if (p->o_type <= TEXT && (p->o_mxx!=1 || p->o_myy!=1 || p->o_mxy!=0 || ! 129: p->o_myx!=0 || p->o_mxt!=0 || p->o_myt!=0)) ! 130: return print_xform(layer,p); ! 131: ! 132: ox = p->o_x; ! 133: oy = p->o_y; ! 134: if (p->o_type < TEXT && (p->o_attr & (FILLED | EDGED))) ! 135: chk_attrs (p); ! 136: switch (p->o_type) { ! 137: ! 138: case TROFF: ! 139: n = p->o_nt1; ! 140: if (text[n].t_type & EQNTXT) ! 141: puteqn(ox, oy, text[n].t_type, atoi(text[n].t_val)); ! 142: else ! 143: troff(text[n].t_val); ! 144: return p; ! 145: case BLOCK: ! 146: for (q = p->o_next; q != p->o_val[N_VAL].o; q = q->o_next) ! 147: if (q->o_type <= TEXT || q->o_nt2 > q->o_nt1) ! 148: q = print_obj(layer,q); ! 149: p = q; ! 150: break; ! 151: case PSFILE: ! 152: puteps(p); ! 153: /* CAREFUL!! THIS FLOWS THROUGH INTO BOX!! */ ! 154: case BOX: ! 155: if (p->o_attr & (FILLED|EDGED)) { ! 156: x0 = ox - p->o_wid/2; x1 = ox + p->o_wid/2; ! 157: y0 = oy - p->o_ht/2; y1 = oy + p->o_ht/2; ! 158: r = p->o_val[N_VAL].f; ! 159: box(x0, y0, x1, y1, r); ! 160: } ! 161: break; ! 162: case CIRCLE: ! 163: case ELLIPSE: ! 164: if (p->o_attr & (FILLED|EDGED)) ! 165: ellipse(ox,oy,p->o_wid/2,0.,0.,p->o_ht/2,0.,2*M_PI,0); ! 166: break; ! 167: case SECTOR: ! 168: case ARC: ! 169: if (p->o_attr & (FILLED|EDGED)) { ! 170: register double ang1, ang2; ! 171: ! 172: if (p->o_attr & HEAD12) { ! 173: print_xform(layer, p); ! 174: break; ! 175: } ! 176: r = p->o_val[N_VAL+0].f; ! 177: x0 = p->o_val[N_VAL+2].f; /* starting point */ ! 178: y0 = p->o_val[N_VAL+3].f; ! 179: x1 = p->o_val[N_VAL+4].f; /* ending point */ ! 180: y1 = p->o_val[N_VAL+5].f; ! 181: ang1 = atan2(y0-oy, x0-ox); ! 182: ang2 = atan2(y1-oy, x1-ox); ! 183: ellipse(ox, oy, r, 0., 0., r, ang1, ang2, p->o_type); ! 184: } ! 185: break; ! 186: case LINE: ! 187: case ARROW: ! 188: case SPLINE: ! 189: if (p->o_attr & (FILLED|EDGED)) { ! 190: int c, nxy; ! 191: ! 192: if (p->o_attr & HEAD12) { ! 193: print_xform(layer, p); ! 194: break; ! 195: } ! 196: r = p->o_val[N_VAL+0].f; ! 197: nxy = p->o_val[N_VAL+3].f; /* segment count */ ! 198: x0 = p->o_val[N_VAL+4].f; /* first point */ ! 199: y0 = p->o_val[N_VAL+5].f; ! 200: x1 = p->o_val[N_VAL+4+2*nxy].f; /* last point */ ! 201: y1 = p->o_val[N_VAL+5+2*nxy].f; ! 202: c = (x0 == x1 && y0 == y1); /* flags closure */ ! 203: if (nxy == 1) ! 204: line(x0, y0, x1, y1); ! 205: else if (p->o_type == SPLINE) ! 206: spline(nxy, c, &p->o_val[N_VAL+4]); ! 207: else ! 208: pline (nxy, c, &p->o_val[N_VAL+4], r); ! 209: } ! 210: break; ! 211: } ! 212: if (p->o_nt1 < p->o_nt2) ! 213: objtext(ox, oy, p); ! 214: return p; ! 215: } ! 216: ! 217: obj *print_xform (layer,p) ! 218: int layer; ! 219: obj *p; ! 220: { ! 221: double r, ox, oy, dx, dy, x0, y0, x1, y1, M[4]; ! 222: double b, tx0, ty0, tx1, ty1; ! 223: valtype *X; ! 224: obj *q; ! 225: int n; ! 226: ! 227: if (p->o_type == BLOCK) { ! 228: for (q = p->o_next; q != p->o_val[N_VAL].o; q = q->o_next) ! 229: if (q->o_type <= TEXT || q->o_nt2 > q->o_nt1) ! 230: q = print_xform(layer,q); ! 231: p = q; ! 232: } ! 233: if (p->o_layer != layer && p->o_type != BLOCK) ! 234: return p; ! 235: #if 0 ! 236: if (p->o_type == TEXT) { ! 237: ox = Xformx(p->o_parent, 1, p->o_x, p->o_y); ! 238: oy = Xformy(p->o_parent, 0, p->o_x, p->o_y); ! 239: } ! 240: else { ! 241: #endif ! 242: ox = Xformx(p, 1, p->o_x, p->o_y); ! 243: oy = Xformy(p, 0, p->o_x, p->o_y); ! 244: #if 0 ! 245: } ! 246: #endif ! 247: X = (valtype *)0; ! 248: if (p->o_type < TEXT && (p->o_attr & (FILLED | EDGED))) ! 249: chk_attrs (p); ! 250: ! 251: switch (p->o_type) { ! 252: ! 253: case TROFF: ! 254: n = p->o_nt1; ! 255: if (text[n].t_type & EQNTXT) ! 256: puteqn(ox, oy, text[n].t_type, atoi(text[n].t_val)); ! 257: else ! 258: troff(text[n].t_val); ! 259: return p; ! 260: case PSFILE: ! 261: puteps(p); ! 262: /* CAREFUL!! THIS FLOWS THROUGH INTO BOX!! */ ! 263: case BOX: ! 264: if (p->o_attr & (FILLED|EDGED)) { ! 265: if ((X = (valtype *)malloc(10*sizeof(valtype))) == NULL) ! 266: yyerror("out of room in print_xform"); ! 267: r = p->o_val[N_VAL].f; ! 268: X[6].f = X[0].f = -(X[2].f = X[4].f = p->o_wid/2); ! 269: X[1].f = X[3].f = -(X[5].f = X[7].f = p->o_ht/2); ! 270: for (n = 0; n < 8; n += 2) { ! 271: x1 = ox + Linx(p, 0, X[n].f, X[n+1].f); ! 272: X[n+1].f = oy + Liny(p, 0, X[n].f, X[n+1].f); ! 273: X[n].f = x1; ! 274: } ! 275: X[n] = X[0]; X[++n] = X[1]; ! 276: x1 = Linx(p, 0, r, 0.); ! 277: r = Liny(p, 0, r, 0.); ! 278: r = sqrt(x1 * x1 + r * r); ! 279: pline(4, 1, X, r); ! 280: } ! 281: break; ! 282: case CIRCLE: ! 283: case ELLIPSE: ! 284: if (p->o_attr & (FILLED|EDGED)) { ! 285: get_matrix(&x0, &y0, &x1, &y1); ! 286: x0 *= p->o_wid/2; ! 287: y0 *= p->o_wid/2; ! 288: x1 *= p->o_ht/2; ! 289: y1 *= p->o_ht/2; ! 290: ellipse(ox, oy, x0, y0, x1, y1, 0., 2*M_PI, 0); ! 291: } ! 292: break; ! 293: case SECTOR: ! 294: case ARC: ! 295: if (p->o_attr & (FILLED|EDGED)) { ! 296: register double ang1, ang2; ! 297: double xa, ya; ! 298: double dx0, dy0, dx1, dy1; ! 299: ! 300: r = p->o_val[N_VAL+0].f; ! 301: x0 = p->o_val[N_VAL+2].f; /* starting point */ ! 302: y0 = p->o_val[N_VAL+3].f; ! 303: x1 = p->o_val[N_VAL+4].f; /* ending point */ ! 304: y1 = p->o_val[N_VAL+5].f; ! 305: get_matrix(M, M+1, M+2, M+3); ! 306: /* ! 307: * If there are arrowheads and non-zero line thickness, we ! 308: * should adjust the end points so as to get nice arrowheads. ! 309: */ ! 310: if (p->o_attr & HEAD12) { ! 311: dx0 = Xformx(p, 1, x0, y0); /* Remember */ ! 312: dy0 = Xformy(p, 0, x0, y0); /* directions for */ ! 313: dx1 = Xformx(p, 0, x1, y1); /* arrowheads */ ! 314: dy1 = Xformy(p, 0, x1, y1); ! 315: /* in here we need to change the points used to compute ! 316: the angles. */ ! 317: dx = p->o_val[N_VAL+8].f; ! 318: dy = p->o_val[N_VAL+9].f; ! 319: if (p->o_weight > 0.) { ! 320: double linex, liney, a; ! 321: ! 322: b = p->o_weight / 2 / p->o_val[N_VAL+8].f; ! 323: b *= sqrt(dx*dx + 4*dy*dy); ! 324: if (p->o_attr & HEAD2) { ! 325: linex = - (y1 - p->o_y); ! 326: liney = (x1 - p->o_x); ! 327: a = b / sqrt(linex*linex + liney*liney); ! 328: x1 -= a * linex; ! 329: y1 -= a * liney; ! 330: } ! 331: if (p->o_attr & HEAD1) { ! 332: linex = (y0 - p->o_y); ! 333: liney = - (x0 - p->o_x); ! 334: a = b / sqrt(linex*linex + liney*liney); ! 335: x0 -= a * linex; ! 336: y0 -= a * liney; ! 337: } ! 338: } ! 339: } ! 340: tx0 = Xformx(p, 1, x0, y0); /* transformed starting point */ ! 341: ty0 = Xformy(p, 0, x0, y0); ! 342: tx1 = Xformx(p, 0, x1, y1); /* transformed ending point */ ! 343: ty1 = Xformy(p, 0, x1, y1); ! 344: ang1 = atan2(ty0 - oy, tx0 - ox); ! 345: ang2 = atan2(ty1 - oy, tx1 - ox); ! 346: ! 347: dx = M[0] * M[3] - M[1] * M[2]; ! 348: if (dx < 0) { /* reflection */ ! 349: xa = ang1; ! 350: ang1 = ang2; ! 351: ang2 = xa; ! 352: M[0] = -M[0]; ! 353: M[2] = -M[2]; ! 354: } ! 355: ellipse(ox, oy, r*M[0], r*M[1], r*M[2], r*M[3], ! 356: ang1, ang2, p->o_type); ! 357: ! 358: if (p->o_attr & (HEAD1 | HEAD2)) { ! 359: ang1 = 0; ! 360: if (dx < 0) { ! 361: ang1 = M_PI; ! 362: dx = -dx; ! 363: } ! 364: dy = dx = sqrt(dx); ! 365: dx *= p->o_val[N_VAL+8].f; ! 366: dy *= p->o_val[N_VAL+9].f; ! 367: if (p->o_attr & HEAD1) ! 368: arrow(tx0-(dy0-oy), ty0+(dx0-ox), tx0, ty0, ! 369: dx, dy, dy/r/2 + ang1, p->o_attr); ! 370: if (p->o_attr & HEAD2) ! 371: arrow(tx1+(dy1-oy), ty1-(dx1-ox), tx1, ty1, ! 372: dx, dy, -dy/r/2 + ang1, p->o_attr); ! 373: } ! 374: } ! 375: break; ! 376: case LINE: ! 377: case ARROW: ! 378: case SPLINE: ! 379: if (p->o_attr & (FILLED|EDGED)) { ! 380: int c, i, nxy; ! 381: ! 382: r = p->o_val[N_VAL+0].f; ! 383: x1 = Linx(p, 0, r, 0.); ! 384: r = Liny(p, 0, r, 0.); ! 385: r = sqrt(x1 * x1 + r * r); ! 386: nxy = p->o_val[N_VAL+3].f; /* segment count */ ! 387: X = (valtype *)malloc((2*nxy+2)*sizeof(valtype)); ! 388: if (X == NULL) ! 389: yyerror("out of room in print_xform"); ! 390: for (i = 0, n = N_VAL+4; i <= 2 * nxy; ) { ! 391: register double xx = p->o_val[n++].f, ! 392: yy = p->o_val[n++].f; ! 393: X[i++].f = Xformx(p, 0, xx, yy); ! 394: X[i++].f = Xformy(p, 0, xx, yy); ! 395: } ! 396: x0 = X[0].f; ! 397: y0 = X[1].f; ! 398: x1 = X[i-2].f; ! 399: y1 = X[i-1].f; ! 400: tx0 = ty0 = tx1 = ty1 = 0.; ! 401: n = 2 * nxy - 2; ! 402: if (p->o_attr & HEAD12) { ! 403: get_matrix(M, M+1, M+2, M+3); ! 404: /* DBK: I added the fabs to eliminate sqrt errors ! 405: * and make it same as xprint.c. 9/20/90 */ ! 406: dy = dx = sqrt(fabs(M[0]*M[3] - M[1]*M[2])); ! 407: dx *= p->o_val[N_VAL+1].f; ! 408: dy *= p->o_val[N_VAL+2].f; ! 409: if (p->o_weight > 0.) { ! 410: double linex, liney, a; ! 411: ! 412: b = p->o_weight / 2 / p->o_val[N_VAL+1].f; ! 413: b *= sqrt(dx*dx + 4*dy*dy); ! 414: if (p->o_attr & HEAD2) { ! 415: linex = x1 - X[n].f; ! 416: liney = y1 - X[n+1].f; ! 417: a = b / sqrt(linex*linex + liney*liney); ! 418: tx1 = -a * linex; ! 419: ty1 = -a * liney; ! 420: x1 = X[n+2].f += tx1; ! 421: y1 = X[n+3].f += ty1; ! 422: } ! 423: if (p->o_attr & HEAD1) { ! 424: linex = x0 - X[2].f; ! 425: liney = y0 - X[3].f; ! 426: a = b / sqrt(linex*linex + liney*liney); ! 427: tx0 = -a * linex; ! 428: ty0 = -a * liney; ! 429: x0 = X[0].f += tx0; ! 430: y0 = X[1].f += ty0; ! 431: } ! 432: } ! 433: } ! 434: /* The first two args are just to give a direction to ! 435: * the second two. To make sure that the direction ! 436: * isn't reversed, adjust the first two by the same ! 437: * amount as we adjusted x1 and y1 above. ! 438: */ ! 439: c = (x0 == x1 && y0 == y1); /* flags closure */ ! 440: if (nxy == 1) ! 441: line(X[0].f, X[1].f, X[2].f, X[3].f); ! 442: else if (p->o_type == SPLINE) ! 443: spline(nxy, c, X); ! 444: else ! 445: pline (nxy, c, X, r); ! 446: if (p->o_attr & HEAD2) { ! 447: tx1 += X[n].f; ! 448: ty1 += X[n+1].f; ! 449: arrow(tx1, ty1, x1, y1, dx, dy, 0.0, p->o_attr); ! 450: } ! 451: if (p->o_attr & HEAD1) { ! 452: tx0 += X[2].f; ! 453: ty0 += X[3].f; ! 454: arrow(tx0, ty0, x0, y0, dx, dy, 0.0, p->o_attr); ! 455: } ! 456: } ! 457: break; ! 458: case TEXT: ! 459: tmp_xform(p); ! 460: #if 0 ! 461: dotext(ox, oy, p); ! 462: #else ! 463: dotext(p->o_x, p->o_y, p); ! 464: #endif ! 465: undo_tmpx(); ! 466: return p; ! 467: } ! 468: if (X) ! 469: free(X); ! 470: if (p->o_nt1 < p->o_nt2) ! 471: objtext(ox, oy, p); ! 472: return p; ! 473: } ! 474: ! 475: objtext(x, y, p) ! 476: double x, y; ! 477: obj *p; ! 478: { ! 479: double *bnd; ! 480: int i, t; ! 481: ! 482: t = text[p->o_nt1].t_type; ! 483: for (i = p->o_nt1; i < p->o_nt2; i++) ! 484: if (text[i].t_type != t) ! 485: break; ! 486: if (i >= p->o_nt2 && p->o_type != TEXT) { /* all strings same type */ ! 487: bnd = text_bounds(p); ! 488: if (t & RJUST) ! 489: x += (bnd[2] - bnd[0]) / 2; ! 490: if (t & LJUST) ! 491: x -= (bnd[2] - bnd[0]) / 2; ! 492: } ! 493: dotext(x, y, p); ! 494: } ! 495: ! 496: dotext(x, y, p) /* print text strings of p in proper vertical spacing */ ! 497: double x, y; ! 498: obj *p; ! 499: { ! 500: double h, v, w, dely; ! 501: int i, j, n, t; ! 502: ! 503: i = p->o_nt1; ! 504: j = text[i].t_line; /* sequence # of first line */ ! 505: n = text[p->o_nt2-1].t_line - j; /* total number of lines (-1) */ ! 506: v = abs(text[i].t_size) / (2 * pgscale); ! 507: dely = abs(text[i].t_space) / (2 * pgscale); ! 508: v = n * dely - v/2; ! 509: new_color(p->o_text); ! 510: for (h = w = 0; i < p->o_nt2; ++j, v -= 2*dely, h = w = 0) { ! 511: t = text[i].t_type; ! 512: if (t & ABOVE) ! 513: v += dely; ! 514: else if (t & BELOW) ! 515: v -= dely; ! 516: for (n = i; text[n].t_line == j; n++) ! 517: w += text[n].t_width*72/pgscale; ! 518: if (t & RJUST) ! 519: h = w; ! 520: else if (t & CENTER) ! 521: h = w/2; ! 522: newlabel(t, text[i].t_val, abs(text[i].t_font), x-h, y+v, ! 523: text[i].t_size / pgscale, ! 524: text[i].t_width * 72 / pgscale); ! 525: while (++i < n) ! 526: addlabel(text[i].t_type, text[i].t_val, ! 527: text[i].t_font, text[i].t_size / pgscale, ! 528: text[i].t_width * 72 / pgscale); ! 529: } ! 530: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.