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

1.1       root        1: #include <stdio.h>
                      2: #include <math.h>
                      3: #include "pic.h"
                      4: #include "y.tab.h"
                      5: 
                      6: obj *linegen(int type)
                      7: {
                      8:        static double prevdx = HT;
                      9:        static double prevdy = 0;
                     10:        static double prevw = HT10;
                     11:        static double prevh = HT5;
                     12:        int i, j, some, head, ddtype, invis, chop, battr, with;
                     13:        double ddval, chop1, chop2, x0, y0, x1, y1;
                     14:        double fillval = 0;
                     15:        double theta;
                     16:        double defx, defy, xwith, ywith;
                     17:        obj *p, *ppos;
                     18:        static int xtab[] = { 1, 0, -1, 0 };    /* R=0, U=1, L=2, D=3 */
                     19:        static int ytab[] = { 0, 1, 0, -1 };
                     20:        double dx[500], dy[500];
                     21:        int ndxy;
                     22:        double nx, ny;
                     23:        Attr *ap, *chop_ap[4];
                     24: 
                     25:        nx = curx;
                     26:        ny = cury;
                     27:        defx = getfval("linewid");
                     28:        defy = getfval("lineht");
                     29:        prevh = getfval("arrowht");
                     30:        prevw = getfval("arrowwid");
                     31:        dx[0] = dy[0] = ndxy = some = head = invis = battr = with = 0;
                     32:        chop = chop1 = chop2 = 0;
                     33:        ddtype = ddval = xwith = ywith = 0;
                     34:        for (i = 0; i < nattr; i++) {
                     35:                ap = &attr[i];
                     36:                switch (ap->a_type) {
                     37:                case TEXTATTR:
                     38:                        savetext(ap->a_sub, ap->a_val.p);
                     39:                        break;
                     40:                case HEAD:
                     41:                        head += ap->a_val.i;
                     42:                        break;
                     43:                case INVIS:
                     44:                        invis = INVIS;
                     45:                        break;
                     46:                case NOEDGE:
                     47:                        battr |= NOEDGEBIT;
                     48:                        break;
                     49:                case DOT:
                     50:                case DASH:
                     51:                        ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT;
                     52:                        if (ap->a_sub == DEFAULT)
                     53:                                ddval = getfval("dashwid");
                     54:                        else
                     55:                                ddval = ap->a_val.f;
                     56:                        break;
                     57:                case SAME:
                     58:                        dx[ndxy] = prevdx;
                     59:                        dy[ndxy] = prevdy;
                     60:                        some++;
                     61:                        break;
                     62:                case LEFT:
                     63:                        dx[ndxy] -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
                     64:                        some++;
                     65:                        hvmode = L_DIR;
                     66:                        break;
                     67:                case RIGHT:
                     68:                        dx[ndxy] += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
                     69:                        some++;
                     70:                        hvmode = R_DIR;
                     71:                        break;
                     72:                case UP:
                     73:                        dy[ndxy] += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
                     74:                        some++;
                     75:                        hvmode = U_DIR;
                     76:                        break;
                     77:                case DOWN:
                     78:                        dy[ndxy] -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
                     79:                        some++;
                     80:                        hvmode = D_DIR;
                     81:                        break;
                     82:                case HEIGHT:    /* length of arrowhead */
                     83:                        prevh = ap->a_val.f;
                     84:                        break;
                     85:                case WIDTH:     /* width of arrowhead */
                     86:                        prevw = ap->a_val.f;
                     87:                        break;
                     88:                case TO:
                     89:                        if (some) {
                     90:                                nx += dx[ndxy];
                     91:                                ny += dy[ndxy];
                     92:                                ndxy++;
                     93:                                dx[ndxy] = dy[ndxy] = some = 0;
                     94:                        }
                     95:                        ppos = attr[i].a_val.o;
                     96:                        dx[ndxy] = ppos->o_x - nx;
                     97:                        dy[ndxy] = ppos->o_y - ny;
                     98:                        some++;
                     99:                        break;
                    100:                case BY:
                    101:                        if (some) {
                    102:                                nx += dx[ndxy];
                    103:                                ny += dy[ndxy];
                    104:                                ndxy++;
                    105:                                dx[ndxy] = dy[ndxy] = some = 0;
                    106:                        }
                    107:                        ppos = ap->a_val.o;
                    108:                        dx[ndxy] = ppos->o_x;
                    109:                        dy[ndxy] = ppos->o_y;
                    110:                        some++;
                    111:                        break;
                    112:                case THEN:      /* turn off any previous accumulation */
                    113:                        if (some) {
                    114:                                nx += dx[ndxy];
                    115:                                ny += dy[ndxy];
                    116:                                ndxy++;
                    117:                                dx[ndxy] = dy[ndxy] = some = 0;
                    118:                        }
                    119:                        break;
                    120:                case FROM:
                    121:                case AT:
                    122:                        ppos = ap->a_val.o;
                    123:                        nx = curx = ppos->o_x;
                    124:                        ny = cury = ppos->o_y;
                    125:                        break;
                    126:                case WITH:
                    127:                        with = ap->a_val.i;
                    128:                        break;
                    129:                case CHOP:
                    130:                        if (ap->a_sub != PLACENAME) {
                    131:                                if( chop == 0)
                    132:                                        chop1 = chop2 = ap->a_val.f;
                    133:                                else
                    134:                                        chop2 = ap->a_val.f;
                    135:                        }
                    136:                        chop_ap[chop++] = ap;
                    137:                        break;
                    138:                case FILL:
                    139:                        battr |= FILLBIT;
                    140:                        if (ap->a_sub == DEFAULT)
                    141:                                fillval = getfval("fillval");
                    142:                        else
                    143:                                fillval = ap->a_val.f;
                    144:                        break;
                    145:                }
                    146:        }
                    147:        if (with) {     /* this doesn't work at all */
                    148:                switch (with) {
                    149:                case CENTER:
                    150:                        xwith = (dx[1] - dx[0]) / 2; ywith = (dy[1] - dy[0]) / 2; break;
                    151:                }
                    152:                for (i = 0; i < ndxy; i++) {
                    153:                        dx[i] -= xwith;
                    154:                        dy[i] -= ywith;
                    155:                }
                    156:                curx += xwith;
                    157:                cury += ywith;
                    158:        }
                    159:        if (some) {
                    160:                nx += dx[ndxy];
                    161:                ny += dy[ndxy];
                    162:                ndxy++;
                    163:                defx = dx[ndxy-1];
                    164:                defy = dy[ndxy-1];
                    165:        } else {
                    166:                defx *= xtab[hvmode];
                    167:                defy *= ytab[hvmode];
                    168:                dx[ndxy] = defx;
                    169:                dy[ndxy] = defy;
                    170:                ndxy++;
                    171:                nx += defx;
                    172:                ny += defy;
                    173:        }
                    174:        prevdx = defx;
                    175:        prevdy = defy;
                    176:        if (chop) {
                    177:                if (chop == 1 && chop1 == 0)    /* just said "chop", so use default */
                    178:                        chop1 = chop2 = getfval("circlerad");
                    179:                theta = atan2(dy[0], dx[0]);
                    180:                x0 = chop1 * cos(theta);
                    181:                y0 = chop1 * sin(theta);
                    182:                curx += x0;
                    183:                cury += y0;
                    184:                dx[0] -= x0;
                    185:                dy[0] -= y0;
                    186: 
                    187:                theta = atan2(dy[ndxy-1], dx[ndxy-1]);
                    188:                x1 = chop2 * cos(theta);
                    189:                y1 = chop2 * sin(theta);
                    190:                nx -= x1;
                    191:                ny -= y1;
                    192:                dx[ndxy-1] -= x1;
                    193:                dy[ndxy-1] -= y1;
                    194:                dprintf("chopping %g %g %g %g; cur=%g,%g end=%g,%g\n",
                    195:                        x0, y0, x1, y1, curx, cury, nx, ny);
                    196:        }
                    197:        p = makenode(type, 5 + 2 * ndxy);
                    198:        curx = p->o_val[0] = nx;
                    199:        cury = p->o_val[1] = ny;
                    200:        if (head || type == ARROW) {
                    201:                p->o_nhead = getfval("arrowhead");
                    202:                p->o_val[2] = prevw;
                    203:                p->o_val[3] = prevh;
                    204:                if (head == 0)
                    205:                        head = HEAD2;   /* default arrow head */
                    206:        }
                    207:        p->o_attr = head | invis | ddtype | battr;
                    208:        p->o_fillval = fillval;
                    209:        p->o_val[4] = ndxy;
                    210:        nx = p->o_x;
                    211:        ny = p->o_y;
                    212:        for (i = 0, j = 5; i < ndxy; i++, j += 2) {
                    213:                p->o_val[j] = dx[i];
                    214:                p->o_val[j+1] = dy[i];
                    215:                if (type == LINE || type == ARROW)
                    216:                        extreme(nx += dx[i], ny += dy[i]);
                    217:                else if (type == SPLINE && i < ndxy-1) {
                    218:                        /* to compute approx extreme of spline at p,
                    219:                        /* compute midway between p-1 and p+1,
                    220:                        /* then go 3/4 from there to p */
                    221:                        double ex, ey, xi, yi, xi1, yi1;
                    222:                        xi = nx + dx[i]; yi = ny + dy[i];       /* p */
                    223:                        xi1 = xi + dx[i+1]; yi1 = yi + dy[i+1]; /* p+1 */
                    224:                        ex = (nx+xi1)/2; ey = (ny+yi1)/2;       /* midway */
                    225:                        ex += 0.75*(xi-ex); ey += 0.75*(yi-ey);
                    226:                        extreme(ex, ey);
                    227:                        nx = xi; ny = yi;
                    228:                }
                    229:                        
                    230:        }
                    231:        p->o_ddval = ddval;
                    232:        if (dbg) {
                    233:                printf("S or L from %g %g to %g %g with %d elements:\n", p->o_x, p->o_y, curx, cury, ndxy);
                    234:                for (i = 0, j = 5; i < ndxy; i++, j += 2)
                    235:                        printf("%g %g\n", p->o_val[j], p->o_val[j+1]);
                    236:        }
                    237:        extreme(p->o_x, p->o_y);
                    238:        extreme(curx, cury);
                    239:        return(p);
                    240: }

unix.superglobalmegacorp.com

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