Annotation of researchv10no/cmd/picasso/linegen.c, revision 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.