Annotation of researchv10no/cmd/picasso/linegen.c, revision 1.1.1.1

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:linegen.c   1.0     */
                      9: #include       "picasso.h"
                     10: #include       "y.tab.h"
                     11: 
                     12: static float   *dx = NULL;
                     13: static float   *dy = NULL;
                     14: static int     nxy = 0;
                     15: static int     nxyvec = 0;
                     16: 
                     17: growxy()
                     18: {
                     19:        if (nxy++ >= nxyvec - 1) {
                     20:                dx = (float *)grow((char *)dx,"dx",nxyvec += 256,sizeof(float));
                     21:                dy = (float *)grow((char *)dy,"dy",nxyvec,sizeof(float));
                     22:        }
                     23: }
                     24: 
                     25: obj *linegen(type)
                     26: {
                     27: static double  prevdx  = HT;
                     28: static double  prevdy  = 0;
                     29: static double  prevw   = HT10; /* arrow dimensions */
                     30: static double  prevh   = HT5;
                     31: static double  prevrad = 0;
                     32: static int xtab[] = { 1, 0, -1, 0 };   /* R=0, U=1, L=2, D=3 */
                     33: static int ytab[] = { 0, 1, 0, -1 };
                     34: 
                     35: struct objattr obat;
                     36:        double  theta, defx, defy, nx, ny, x0, y0, x1, y1, chop1, chop2;
                     37:        float   bbox[4];
                     38:        int     i, j, some, head, chop;
                     39:        obj     *p, *ppos;
                     40:        Attr    *ap;
                     41:        struct  symtab  *xlist, *ylist;
                     42: 
                     43:        nx    = curx;
                     44:        ny    = cury;
                     45:        defy  = getfval("lineht");
                     46:        defx  = getfval("linewid");
                     47:        obat.a_ht  = getfval("arrowht");
                     48:        obat.a_wid = getfval("arrowwid");
                     49:        obat.a_rad = getfval("linerad");
                     50:        obat.a_layer = (int)getfval("curlayer");
                     51:        obat.a_flags = EDGED;
                     52:        obat.a_weight = obat.a_lcolor = obat.a_pcolor = obat.a_tcolor = -1;
                     53:        obat.a_dashpat.a = (float *)0;
                     54:        set_text();
                     55:        if (nxyvec == 0)
                     56:                growxy();
                     57:        dx[0] = dy[0] = chop1 = chop2 = 0;
                     58:        nxy = some = head = chop = 0;
                     59:        for (i = 0; i < nattr; i++) {
                     60:                ap = &attr[i];
                     61:                switch (ap->a_type) {
                     62:                default:
                     63:                        miscattrs(ap, &obat);
                     64:                        break;
                     65:                case HEAD:
                     66:                        head += ap->a_val.i;
                     67:                        break;
                     68:                case CHOP:
                     69:                        if (chop++ == 0)
                     70:                                chop1 = chop2 = ap->a_val.f;
                     71:                        else
                     72:                                chop2 = ap->a_val.f;
                     73:                        break;
                     74:                case SAME:
                     75:                        dx[nxy]  = prevdx;
                     76:                        dy[nxy]  = prevdy;
                     77:                        obat.a_rad = prevrad;
                     78:                        obat.a_ht  = prevh;
                     79:                        obat.a_wid = prevw;
                     80:                        some++;
                     81:                        break;
                     82:                case LEFT:
                     83:                        dx[nxy] -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
                     84:                        some++;
                     85:                        hvmode = L_DIR;
                     86:                        break;
                     87:                case RIGHT:
                     88:                        dx[nxy] += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
                     89:                        some++;
                     90:                        hvmode = R_DIR;
                     91:                        break;
                     92:                case UP:
                     93:                        dy[nxy] += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
                     94:                        some++;
                     95:                        hvmode = U_DIR;
                     96:                        break;
                     97:                case DOWN:
                     98:                        dy[nxy] -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
                     99:                        some++;
                    100:                        hvmode = D_DIR;
                    101:                        break;
                    102:                case XLIST:
                    103:                        xlist = findvar(ap->a_val.p, VARNAME);
                    104:                        break;
                    105:                case YLIST:
                    106:                        ylist = findvar(ap->a_val.p, VARNAME);
                    107:                        if (some) {
                    108:                                nx += dx[nxy];
                    109:                                ny += dy[nxy];
                    110:                                growxy();
                    111:                        }
                    112:                        first_xy(xlist, ylist, &x0, &y0);
                    113:                        dx[nxy] = x0 - nx;
                    114:                        dy[nxy] = y0 - ny;
                    115:                        while (next_xy(xlist, ylist, &x0, &y0)) {
                    116:                                nx += dx[nxy];
                    117:                                ny += dy[nxy];
                    118:                                growxy();
                    119:                                dx[nxy] = x0 - nx;
                    120:                                dy[nxy] = y0 - ny;
                    121:                        }
                    122:                        some++;
                    123:                        break;
                    124:                case TO:
                    125:                        if (some) {
                    126:                                nx += dx[nxy];
                    127:                                ny += dy[nxy];
                    128:                                growxy();
                    129:                        }
                    130:                        ppos = ap->a_val.o;
                    131:                        dx[nxy] = Xformx(ppos, 1, ppos->o_x, ppos->o_y) - nx;
                    132:                        dy[nxy] = Xformy(ppos, 0, ppos->o_x, ppos->o_y) - ny;
                    133:                        some++;
                    134:                        break;
                    135:                case BY:
                    136:                        if (some) {
                    137:                                nx += dx[nxy];
                    138:                                ny += dy[nxy];
                    139:                                growxy();
                    140:                        }
                    141:                        ppos = ap->a_val.o;
                    142:                        dx[nxy] = Xformx(ppos, 1, ppos->o_x, ppos->o_y);
                    143:                        dy[nxy] = Xformy(ppos, 0, ppos->o_x, ppos->o_y);
                    144:                        some++;
                    145:                        break;
                    146:                case THEN:      /* turn off any previous accumulation */
                    147:                        if (some) {
                    148:                                nx += dx[nxy];
                    149:                                ny += dy[nxy];
                    150:                                growxy();
                    151:                                dx[nxy] = dy[nxy] = some = 0;
                    152:                        }
                    153:                        break;
                    154:                case FROM:
                    155:                case AT:
                    156:                        ppos = ap->a_val.o;
                    157:                        nx = curx = Xformx(ppos, 1, ppos->o_x, ppos->o_y);
                    158:                        ny = cury = Xformy(ppos, 0, ppos->o_x, ppos->o_y);
                    159:                        break;
                    160:                }
                    161:        }
                    162:        if (some) {
                    163:                nx += dx[nxy];
                    164:                ny += dy[nxy];
                    165:                growxy();
                    166:                defx = dx[nxy-1];
                    167:                defy = dy[nxy-1];
                    168:        } else {
                    169:                defx *= xtab[hvmode];
                    170:                defy *= ytab[hvmode];
                    171:                dx[nxy] = defx;
                    172:                dy[nxy] = defy;
                    173:                growxy();
                    174:                nx += defx;
                    175:                ny += defy;
                    176:        }
                    177:        prevdx  = defx;
                    178:        prevdy  = defy;
                    179:        prevh   = obat.a_ht;
                    180:        prevw   = obat.a_wid;
                    181:        prevrad = obat.a_rad;
                    182:        if (chop) {
                    183:                if (chop1 == -1.0) /* just said "chop", so use default */
                    184:                        chop1 = getfval("circlerad");
                    185:                if (chop2 == -1.0)
                    186:                        chop2 = getfval("circlerad");
                    187:                x0 = dx[0] * dx[0] + dy[0] *dy[0];
                    188:                if (chop1 > sqrt(x0)) {
                    189:                        yyerror("can't chop that much");
                    190:                        chop1 = x0;
                    191:                }
                    192:                theta = atan2(dy[0], dx[0]);
                    193:                x0 = chop1 * cos(theta);
                    194:                y0 = chop1 * sin(theta);
                    195:                curx += x0;
                    196:                cury += y0;
                    197:                dx[0] -= x0;
                    198:                dy[0] -= y0;
                    199:                
                    200:                x1 = dx[nxy-1] * dx[nxy-1] + dy[nxy-1] *dy[nxy-1];
                    201:                if (chop2 > sqrt(x1)) {
                    202:                        yyerror("can't chop that much");
                    203:                        chop2 = x1;
                    204:                }
                    205:                theta = atan2(dy[nxy-1], dx[nxy-1]);
                    206:                x1 = chop2 * cos(theta);
                    207:                y1 = chop2 * sin(theta);
                    208:                nx -= x1;
                    209:                ny -= y1;
                    210:                dx[nxy-1] -= x1;
                    211:                dy[nxy-1] -= y1;
                    212:        }
                    213:        /* input file could specify ...to 3,2 to 3,2 ...
                    214:                                so eliminate repeated pts */
                    215:        for (i = j = 0; i < nxy; i++) {
                    216:            if (dx[i] == 0. && dy[i] == 0.)
                    217:                continue;
                    218:            else if (j != i) {
                    219:                dx[j] = dx[i];
                    220:                dy[j] = dy[i];
                    221:            }
                    222:            j++;
                    223:        }
                    224:        nxy = j;
                    225:        p = makenode(type, N_VAL + 6 + 2 * nxy, obat.a_layer);
                    226:        primattrs(p, &obat);
                    227:        text_bounds(p);
                    228:        prevrad = p->o_val[N_VAL].f = obat.a_rad;
                    229:        p->o_val[N_VAL+3].f = nxy;              /* note: segments, not points */
                    230:        p->o_val[N_VAL+4].f = bbox[0] = bbox[2] = curx;
                    231:        p->o_val[N_VAL+5].f = bbox[1] = bbox[3] = cury;
                    232: 
                    233:        for (i = 0, j = N_VAL+6; i < nxy; i++, j += 2) {
                    234:                        /* restoring absolute coordinates */
                    235:                p->o_val[j].f   = curx += dx[i];
                    236:                p->o_val[j+1].f = cury += dy[i];
                    237:                extreme(curx, cury, bbox);      /* OVERestimate, for splines */
                    238: #if 0
                    239:                if (type == LINE || type == ARROW)
                    240:                        extreme(curx, cury, bbox);
                    241:                else if (type == SPLINE) {
                    242:                        if (i < nxy-1) {
                    243:                                /* to compute approx extreme of spline at p, */
                    244:                                /* compute midway between p-1 and p+1,       */
                    245:                                /* then go 3/4 from there to p               */
                    246:                                double ex, ey, xi, yi, xi1, yi1;
                    247: 
                    248:                                xi  = curx-dx[i];
                    249:                                yi  = cury-dy[i];    /* p-1   */
                    250:                                xi1 = curx+dx[i+1];
                    251:                                yi1 = cury+dy[i+1];  /* p+1   */
                    252:                                ex = (curx+xi1)/2;
                    253:                                ey = (cury+yi1)/2;   /* midpt */
                    254:                                ex += 0.75*(curx-ex);   ey += 0.75*(cury-ey);
                    255:                                extreme(ex, ey, bbox);
                    256:                        }
                    257:                        else extreme(curx, cury, bbox);
                    258:                }
                    259: #endif
                    260:        }
                    261:        if (head || type == ARROW) {
                    262:                if (head == 0)
                    263:                        head = HEAD2;   /* default arrow head */
                    264:                p->o_attr |= head | arrowfill();
                    265:                p->o_val[N_VAL+1].f = obat.a_wid;
                    266:                p->o_val[N_VAL+2].f = obat.a_ht;
                    267:                if (head & HEAD1)
                    268:                        track_head (p->o_val[N_VAL+6].f, p->o_val[N_VAL+7].f,
                    269:                                    p->o_val[N_VAL+4].f, p->o_val[N_VAL+5].f,
                    270:                                        prevw, prevh, bbox);
                    271:                if (head & HEAD2) {
                    272:                        j = N_VAL + 2 + 2 * nxy;
                    273:                        track_head (p->o_val[j+0].f, p->o_val[j+1].f,
                    274:                                    p->o_val[j+2].f, p->o_val[j+3].f,
                    275:                                        prevw, prevh, bbox);
                    276:                }
                    277:        }
                    278:        track_bounds(bbox[0]-p->o_weight/2, bbox[1]-p->o_weight/2,
                    279:                     bbox[2]+p->o_weight/2, bbox[3]+p->o_weight/2);
                    280:        p->o_x = 0.5 * (bbox[0] + bbox[2]);
                    281:        p->o_y = 0.5 * (bbox[1] + bbox[3]);
                    282:        p->o_wid = bbox[2] - bbox[0];
                    283:        p->o_ht  = bbox[3] - bbox[1];
                    284:        return(p);
                    285: }
                    286: 
                    287: arrowfill ()   /* a bit of a kludge for an obsolescent feature; arroprevw */
                    288: {              /* now is taken simply as odd (fill) or even (nofill) and  */
                    289:                /* has no implication of "number of lines drawn" as in pic */
                    290: 
                    291:        return (((int)getfval("arrowfill")) % 2) * HEADFILL;
                    292: }
                    293: 
                    294: /* NOTE: DBK added bbox parameter to track_head 9/30/89.  Only calls to
                    295:    track_head are in linegen() above.  The purpose is to get o_wid and o_ht
                    296:    computed large enough so get_bounds won't lie about arrows.  Note that
                    297:    o_x and o_y may also be affected.  */
                    298: static
                    299: track_head (x0, y0, x1, y1, w, h, bbox)
                    300:        double  x0, y0, x1, y1, w, h;
                    301:        float   bbox[];
                    302: {
                    303:        double  rot, hyp, phi;
                    304: 
                    305:        rot = atan2(w/2, h);
                    306:        hyp = hypot(w/2, h);
                    307:        phi = atan2(y1-y0, x1-x0) + M_PI - rot;
                    308:        x0 = x1 + hyp * cos(phi);       y0 = y1 + hyp * sin(phi);
                    309:        extreme (x0, y0, Gbox);
                    310:        extreme (x0, y0, bbox);
                    311:        phi += 2 * rot;
                    312:        x0 = x1 + hyp * cos(phi);       y0 = y1 + hyp * sin(phi);
                    313:        extreme (x0, y0, Gbox);
                    314:        extreme (x0, y0, bbox);
                    315: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.