Annotation of researchv10dc/cmd/picasso/misc.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:misc.c      1.0     */
        !             9: #include       "picasso.h"
        !            10: #include       "y.tab.h"
        !            11: 
        !            12: extern int     pic_compat;
        !            13: extern int     batch;
        !            14: 
        !            15: double getcomp(p, t)   /* return component of a position; these must now be */
        !            16:        obj *p;         /* transformed as there is no later chance to do so. */
        !            17:        int t;
        !            18: {
        !            19:        float   bnd[4];
        !            20: 
        !            21:        switch (t) {
        !            22:        case DOTX:      return Xformx(p, 1, p->o_x, p->o_y);
        !            23:        case DOTY:      return Xformy(p, 1, p->o_x, p->o_y);
        !            24:        case DOTRAD:
        !            25:                switch (p->o_type) {
        !            26:                case SECTOR:
        !            27:                case ARC:
        !            28:                case BOX:
        !            29:                case ARROW:
        !            30:                case LINE:      return p->o_val[N_VAL].f;
        !            31:                case CIRCLE:
        !            32:                case ELLIPSE:   break;  /* fall through to DOTWID case */
        !            33:                }
        !            34:        case DOTHT:
        !            35:        case DOTWID:    if (p->o_type <= TEXT) {
        !            36:                                get_bounds(p, bnd, 1);
        !            37:                                if (t == DOTHT)
        !            38:                                        return (bnd[3] - bnd[1]);
        !            39:                                else
        !            40:                                        return (bnd[2] - bnd[0]);
        !            41:                        }
        !            42:        }
        !            43:        yyerror("can't happen getcomp");
        !            44: }
        !            45: 
        !            46: exprsave(f)
        !            47:        double f;
        !            48: {
        !            49:        if (nexpr >= nexprlist)
        !            50:                exprlist = (float *) grow((char *)exprlist, "exprlist",
        !            51:                                        nexprlist += 256, sizeof(float));
        !            52:        exprlist[nexpr] = f;
        !            53:        return ++nexpr;
        !            54: }
        !            55: 
        !            56: char *sprintgen(fmt)
        !            57:        char *fmt;
        !            58: {
        !            59:        char buf[1000];
        !            60: 
        !            61:        sprintf (buf, fmt,  exprlist[0], exprlist[1], exprlist[2],
        !            62:                                         exprlist[3], exprlist[4]);
        !            63:        nexpr = 0;
        !            64:        free(fmt);
        !            65:        return tostring(buf);
        !            66: }
        !            67: 
        !            68: printexpr(f)   /* print expression for debugging */
        !            69:        double f;
        !            70: {
        !            71:        fprintf(stderr, "%g\n", f);
        !            72: }
        !            73: 
        !            74: printpos(p)    /* print position for debugging */
        !            75:        obj *p;
        !            76: {
        !            77:        double  x, y;
        !            78: 
        !            79:        x = Xformx(p, 1, p->o_x, p->o_y);
        !            80:        y = Xformy(p, 0, p->o_x, p->o_y);
        !            81:        fprintf(stderr, "%g, %g\n", x, y);
        !            82: }
        !            83: 
        !            84: char *tostring(s)
        !            85:        register char *s;
        !            86: {
        !            87:        register char *p;
        !            88: 
        !            89:        p = malloc(strlen(s)+1);
        !            90:        if (p == NULL) {
        !            91:                yyerror("out of space in tostring on %s", s);
        !            92:                exit(1);
        !            93:        }
        !            94:        strcpy(p, s);
        !            95:        return(p);
        !            96: }
        !            97: 
        !            98: obj *makepos(x, y, corner, q)  /* make a position cell */
        !            99:        double  x, y;
        !           100:        int     corner;
        !           101:        obj     *q;
        !           102: {
        !           103:        obj *p;
        !           104: 
        !           105:        p = makenode(PLACE, 1, 0);
        !           106:        if (q)
        !           107:                p->o_parent = q;
        !           108:        p->o_x = x;
        !           109:        p->o_y = y;
        !           110:        p->o_val[0].f = corner;
        !           111:        return(p);
        !           112: }
        !           113: 
        !           114: obj *makebetween(f, p1, p2)    /* make position between p1 and p2   */
        !           115:        double  f;              /* again, transforms must be applied */
        !           116:        obj     *p1, *p2;
        !           117: {
        !           118:        obj     *p;
        !           119:        double  x1, y1, x2, y2;
        !           120: 
        !           121:        p = makenode(PLACE, 3, 0);
        !           122:        x1 = Xformx(p1, 1, p1->o_x, p1->o_y);
        !           123:        y1 = Xformy(p1, 0, p1->o_x, p1->o_y);
        !           124:        x2 = Xformx(p2, 1, p2->o_x, p2->o_y);
        !           125:        y2 = Xformy(p2, 0, p2->o_x, p2->o_y);
        !           126:        p->o_x = x1 + f * (x2 - x1);
        !           127:        p->o_y = y1 + f * (y2 - y1);
        !           128:        p->o_val[0].f = f;
        !           129:        p->o_val[1].o = p1;
        !           130:        p->o_val[2].o = p2;
        !           131:        return(p);
        !           132: }
        !           133: 
        !           134: int    xdelta[8] = {1,1,1,0,-1,-1,-1,0},
        !           135:        ydelta[8] = {-1,0,1,1,1,0,-1,-1};
        !           136: 
        !           137: obj *getnth(p, nth)    /* find nth point of an object */
        !           138:        obj     *p;
        !           139:        int     nth;
        !           140: {
        !           141:        float   x, y;
        !           142:        int     n = nth;
        !           143: 
        !           144:        switch (p->o_type) {
        !           145:        default:        if (n != 1)
        !           146:                                yyerror("object has only 1 point defined");
        !           147:                        return p;
        !           148:        case ARC:       if (n > 2) {
        !           149:                                yyerror("arcs have only 2 points defined");
        !           150:                                return p;
        !           151:                        }
        !           152:                        /* else fall through to SECTOR case */
        !           153:        case SECTOR:    if ((n %= 3) == 0)
        !           154:                                return p;
        !           155:                        else if (n == 1) {
        !           156:                                x = p->o_val[N_VAL+2].f;
        !           157:                                y = p->o_val[N_VAL+3].f;
        !           158:                        }
        !           159:                        else {
        !           160:                                x = p->o_val[N_VAL+4].f;
        !           161:                                y = p->o_val[N_VAL+5].f;
        !           162:                        }
        !           163:                        break;
        !           164:        case BLOCK:     while (n--) {
        !           165:                                p = p->o_next;
        !           166:                                if (p->o_type <= TEXT)
        !           167:                                        continue;
        !           168:                                else if (p->o_type == BLOCKEND) {
        !           169:                                        yyerror("[] has less than %d objects",
        !           170:                                                        nth);
        !           171:                                        p = p->o_parent;
        !           172:                                }
        !           173:                        }
        !           174:                        return p;       
        !           175:        case BOX:       n %= 8;
        !           176:                        x = p->o_x + xdelta[n] * p->o_wid / 2;
        !           177:                        y = p->o_y + ydelta[n] * p->o_ht  / 2;
        !           178:                        break;
        !           179:        case ARROW:
        !           180:        case LINE:
        !           181:        case SPLINE:    if (--n > p->o_val[N_VAL+3].f) {
        !           182:                                yyerror("line has less than %d points", nth);
        !           183:                                return p;
        !           184:                        }
        !           185:                        x = p->o_val[N_VAL + 4 + 2 * n].f;
        !           186:                        y = p->o_val[N_VAL + 5 + 2 * n].f;
        !           187:                        break;
        !           188:        case CIRCLE:
        !           189:        case ELLIPSE:   n %= 8;
        !           190:                        x = xdelta[n] * p->o_wid / 2;
        !           191:                        y = ydelta[n] * p->o_ht  / 2;
        !           192:                        if (n % 2 == 0) {
        !           193:                                x *= M_SQRT1_2;
        !           194:                                y *= M_SQRT1_2;
        !           195:                        }
        !           196:                        x += p->o_x;
        !           197:                        y += p->o_y;
        !           198:                        break;
        !           199:        }
        !           200:        /*  DBK--Here also there is a question of whether x and y should
        !           201:            be transformed */
        !           202:        return makepos(x, y, nth, p);
        !           203: }
        !           204: 
        !           205: obj *getpos(p, corner) /* find position of point */
        !           206:        obj     *p;
        !           207:        int     corner;
        !           208: {
        !           209:        float   x, y;
        !           210: 
        !           211:        if (pic_compat && (p->o_type == CIRCLE || p->o_type == ELLIPSE) &&
        !           212:                (corner == NE || corner == NW || corner == SW || corner == SE))
        !           213:                        return getnth(p, corner == NE ? 2 : corner == NW ? 4 :
        !           214:                                                        corner == SW ? 6 : 8);
        !           215:        if (corner == -1 )
        !           216:                if (pic_compat && (p->o_type == LINE || p->o_type == ARROW ||
        !           217:                                                        p->o_type == SPLINE))
        !           218:                        corner = START;
        !           219:                else
        !           220:                        return p;
        !           221:        whatpos(p, corner, &x, &y);
        !           222:        return makepos(x,y,corner,(corner < EAST || corner > SW)? p: (obj *)0);
        !           223: }
        !           224: 
        !           225: whatpos(p, corner, px, py)     /* what is the position (no side effect) */
        !           226:        obj     *p;
        !           227:        int     corner;
        !           228:        float   *px, *py;
        !           229: {
        !           230:        float   x, y, bnd[4];
        !           231: 
        !           232:        if (corner >= EAST && corner <= SW) {
        !           233:                get_bounds(p, bnd, 1);
        !           234:                switch (corner) {
        !           235:        case NE:        x = bnd[2];             y = bnd[3];     break;
        !           236:        case SW:        x = bnd[0];             y = bnd[1];     break;
        !           237:        case SE:        x = bnd[2];             y = bnd[1];     break;
        !           238:        case NW:        x = bnd[0];             y = bnd[3];     break;
        !           239:        case NORTH:     x = (bnd[0]+bnd[2])/2;  y = bnd[3];     break;
        !           240:        case SOUTH:     x = (bnd[0]+bnd[2])/2;  y = bnd[1];     break;
        !           241:        case EAST:      x = bnd[2];     y = (bnd[1]+bnd[3])/2;  break;
        !           242:        case WEST:      x = bnd[0];     y = (bnd[1]+bnd[3])/2;  break;
        !           243:                }
        !           244:        }
        !           245:        else {  /* DBK--note that get_bounds returns the transformed position,
        !           246:                   but the following calculations do not!! */
        !           247:                x = p->o_x;
        !           248:                y = p->o_y;
        !           249: 
        !           250: /* futz around for special cases: */
        !           251: 
        !           252:                switch (p->o_type) {
        !           253:        case BLOCK:     if (corner == START)
        !           254:                                whatpos(p->o_next, START, &x, &y);
        !           255:                        else if (corner == END)
        !           256:                                whatpos(p->o_val[N_VAL+1].o->o_prev,END,&x,&y);
        !           257:                        break;
        !           258:        case ARC:       if (corner == START) {
        !           259:                                x = p->o_val[N_VAL+2].f;
        !           260:                                y = p->o_val[N_VAL+3].f;
        !           261:                        }
        !           262:                        else if (corner == END) {
        !           263:                                x = p->o_val[N_VAL+4].f;
        !           264:                                y = p->o_val[N_VAL+5].f;
        !           265:                        }
        !           266:                        break;
        !           267:        case LINE:
        !           268:        case SPLINE:
        !           269:        case ARROW:     switch (corner) {
        !           270:                                int     n;
        !           271:                case START:     x = p->o_val[N_VAL+4].f;
        !           272:                                y = p->o_val[N_VAL+5].f;
        !           273:                                break;
        !           274:                case END:       n = N_VAL + 4 + 2*p->o_val[N_VAL+3].f;
        !           275:                                x = p->o_val[n].f;
        !           276:                                y = p->o_val[n+1].f;
        !           277:                                break;
        !           278:                        }
        !           279:                        break;
        !           280:                }
        !           281:        }
        !           282:        *px = x;
        !           283:        *py = y;
        !           284:        return 1;
        !           285: }
        !           286: 
        !           287: obj *gethere() /* make a place for curx,cury */
        !           288: {
        !           289:        return(makepos(curx, cury, 0, (obj *)0));
        !           290: }
        !           291: 
        !           292: obj *getlast(n, t)     /* find n-th previous occurrence of type t */
        !           293:        int n, t;
        !           294: {
        !           295:        int k;
        !           296:        obj *p;
        !           297: 
        !           298:        k = n;
        !           299:        if (t == TEXTOBJ)       /* for purely syntactical reasons */
        !           300:                t = TEXT;
        !           301:        for (p = objtail->o_prev; p != objhead; p = p->o_prev) {
        !           302:                if (p->o_type == BLOCKEND) {
        !           303:                        p = p->o_parent;
        !           304:                        if (t != BLOCK && t != OBJECT)
        !           305:                                continue;
        !           306:                }
        !           307:                if (t == OBJECT && p->o_type > TEXT)
        !           308:                        continue;
        !           309:                if (t != OBJECT && p->o_type != t)
        !           310:                        continue;
        !           311:                if (--k > 0)
        !           312:                        continue;       /* not there yet */
        !           313:                return(p);
        !           314:        }
        !           315:        yyerror("there is no %dth last", n);
        !           316:        return(NULL);
        !           317: }
        !           318: 
        !           319: obj *getfirst(n, t)    /* find n-th occurrence of type t */
        !           320:        int n, t;
        !           321: {
        !           322:        int k;
        !           323:        obj *p;
        !           324: 
        !           325:        k = n;
        !           326:        if (t == TEXTOBJ)
        !           327:                t = TEXT;
        !           328:        for (p = objhead->o_next; p != objtail; p = p->o_next) {
        !           329:                if (p->o_type == BLOCK
        !           330:                && t != BLOCK && t != OBJECT) {         /* skip block,  */
        !           331:                        if (p->o_val[N_VAL].o != NULL)  /* unless it's  */
        !           332:                                p = p->o_val[N_VAL].o;  /* still active */
        !           333:                        continue;
        !           334:                }
        !           335:                if (t == OBJECT && p->o_type > TEXT)
        !           336:                        continue;
        !           337:                if (t != OBJECT && p->o_type != t)
        !           338:                        continue;
        !           339:                if (--k > 0)
        !           340:                        continue;       /* not there yet */
        !           341:                return(p);
        !           342:        }
        !           343:        yyerror("there is no %dth", n);
        !           344:        return(NULL);
        !           345: }
        !           346: 
        !           347: double getblkvar(p, s) /* find variable s2 in block p */
        !           348:        obj *p;
        !           349:        char *s;
        !           350: {
        !           351:        YYSTYPE y, getblk();
        !           352: 
        !           353:        y = getblk(p, s);
        !           354:        free(s);
        !           355:        return y.f;
        !           356: }
        !           357: 
        !           358: obj *getblock(p, s)    /* find variable s in block p */
        !           359:        obj *p;
        !           360:        char *s;
        !           361: {
        !           362:        YYSTYPE y, getblk();
        !           363: 
        !           364:        y = getblk(p, s);
        !           365:        free(s);
        !           366:        return y.o;
        !           367: }
        !           368: 
        !           369: YYSTYPE getblk(p, s)   /* find union type for s in p */
        !           370:        obj *p;
        !           371:        char *s;
        !           372: {
        !           373:        static YYSTYPE bug;
        !           374:        struct symtab *stp;
        !           375: 
        !           376:        if (p->o_type != BLOCK) {
        !           377:                yyerror(".%s is not in that block", s);
        !           378:                return(bug);
        !           379:        }
        !           380:        for (stp = p->o_val[N_VAL+1].s; stp != NULL; stp = stp->s_next)
        !           381:                if (strcmp(s, stp->s_name) == 0)
        !           382:                        return(stp->s_val);
        !           383:        yyerror("there is no .%s in that []", s);
        !           384:        return(bug);
        !           385: }
        !           386: 
        !           387: obj *fixpos(p, x, y)   /* this, addpos & subpos SHOULD be altered to give   */
        !           388:        obj *p;         /* o_x,o_y as offset from position of p, with p as   */
        !           389:        double x, y;    /* o_parent, but I haven't yet worked out the xform. */
        !           390: {
        !           391: #if 1
        !           392: /* DBK: 3/21/90 -- comment out the following if clause.  It has the effect
        !           393:    of changing A in the expression A + x,y !!!
        !           394:        if (p->o_type == PLACE) {
        !           395:                p->o_x += x;
        !           396:                p->o_y += y;
        !           397:                return p;
        !           398:        }
        !           399:    end of commented out code *************/
        !           400:        x += Xformx(p, 1, p->o_x, p->o_y);
        !           401:        y += Xformy(p, 0, p->o_x, p->o_y);
        !           402: #else
        !           403:        if (p->o_type == PLACE) {
        !           404:                x += p->o_x;
        !           405:                y += p->o_y;
        !           406:        }
        !           407:        else {
        !           408:                x += Xformx(p, 1, p->o_x, p->o_y);
        !           409:                y += Xformy(p, 0, p->o_x, p->o_y);
        !           410:        }
        !           411: #endif
        !           412:        return makepos(x, y, 0, (obj *)0);
        !           413: }
        !           414: 
        !           415: obj *addpos(p, q)
        !           416:        obj *p, *q;
        !           417: {
        !           418:        double  x, y;
        !           419: 
        !           420:        x = Xformx(q, 1, q->o_x, q->o_y);
        !           421:        y = Xformy(q, 0, q->o_x, q->o_y);
        !           422: /* DBK:  see above
        !           423:        if (p->o_type == PLACE) {
        !           424:                p->o_x += x;
        !           425:                p->o_y += y;
        !           426:                return p;
        !           427:        }
        !           428:  */
        !           429:        x += Xformx(p, 1, p->o_x, p->o_y);
        !           430:        y += Xformy(p, 0, p->o_x, p->o_y);
        !           431:        return makepos(x, y, 0, (obj *)0);
        !           432: }
        !           433: 
        !           434: obj *subpos(p, q)
        !           435:        obj *p, *q;
        !           436: {
        !           437:        double  x, y;
        !           438: 
        !           439:        x = Xformx(q, 1, q->o_x, q->o_y);
        !           440:        y = Xformy(q, 0, q->o_x, q->o_y);
        !           441: /* DBK:  see above
        !           442:        if (p->o_type == PLACE) {
        !           443:                p->o_x -= x;
        !           444:                p->o_y -= y;
        !           445:                return p;
        !           446:        }
        !           447:  */
        !           448:        x -= Xformx(p, 1, p->o_x, p->o_y);
        !           449:        y -= Xformy(p, 0, p->o_x, p->o_y);
        !           450:        return makepos(x, y, 0, (obj *)0);
        !           451: }
        !           452: 
        !           453: obj *makenode(type, n, layer)
        !           454:        int     type, n, layer;
        !           455: {
        !           456:        obj     *p;
        !           457: 
        !           458:        if (objbuf && batch)
        !           459:                print_buf();
        !           460:        p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(YYSTYPE));
        !           461:        if (p == NULL) {
        !           462:                yyerror("out of space in makenode");
        !           463:                exit(1);
        !           464:        }
        !           465:        if (n > 65535)
        !           466:                yyerror("making excessively large object");
        !           467:        p->o_next = objtail;
        !           468:        p->o_prev = objtail->o_prev;
        !           469:        p->o_prev->o_next = objtail->o_prev = p;        
        !           470:        p->o_parent = cur_block;
        !           471:        p->o_x = curx;
        !           472:        p->o_y = cury;
        !           473:        p->o_nt1 = ntext1;
        !           474:        p->o_nt2 = ntext;
        !           475:        p->o_text = -1;
        !           476: #if 1
        !           477:        /* force all strings in object to have same justification */
        !           478:        {
        !           479:        int     jflags, lastf;
        !           480:        jflags = RJUST|LJUST|CENTER|ABOVE|BELOW;
        !           481:        lastf = text[ntext-1].t_type & jflags;
        !           482:        for ( ; ntext1 < ntext; ntext1++)
        !           483:                text[ntext1].t_type = text[ntext1].t_type & ~ jflags | lastf;
        !           484:        }
        !           485: #endif
        !           486:        ntext1 = ntext; /* ready for next caller */
        !           487:        if (layer < -128)
        !           488:                layer = -128;
        !           489:        else if (layer > 127)
        !           490:                layer = 127;
        !           491:        if ((p->o_layer = layer) > 0 && layer > top_layer)
        !           492:                top_layer = layer;
        !           493:        if ((p->o_type = type) <= TEXT) {
        !           494:                p->o_mxx = p->o_myy = 1.0;      /* initialize xform matrix */
        !           495:                p->o_size = n;                  /* keep count, for copies  */
        !           496:        }
        !           497:        return(p);
        !           498: }
        !           499: 
        !           500: freenode (p)           /* free space occupied by object p */
        !           501:        obj     *p;
        !           502: {
        !           503:        obj     *q, *q1;
        !           504: 
        !           505:        if (p->o_type == BLOCK) {                       /* I think there's */
        !           506:                freesymtab(p->o_val[N_VAL+1].s);        /* a bug here, for */
        !           507:                q = p->o_val[N_VAL].o;                  /* nested blocks.  */
        !           508:                p->o_prev->o_next = q->o_next;
        !           509:                q->o_next->o_prev = p->o_prev;
        !           510:                q->o_next = (obj *)NULL;
        !           511:                for (q = p->o_next; q != NULL; ) {
        !           512:                        if (q->o_type == BLOCK)
        !           513:                                freesymtab(q->o_val[N_VAL+1].s);
        !           514:                        q1 = q;
        !           515:                        q = q->o_next;
        !           516:                        free(q1); 
        !           517:                }
        !           518:        }
        !           519:        else {
        !           520:                p->o_prev->o_next = p->o_next;
        !           521:                p->o_next->o_prev = p->o_prev;
        !           522:        }
        !           523:        free (p);
        !           524:        if (!objbuf) redo_gbox = 1;     /* page boundaries are now suspect */
        !           525: }
        !           526: 
        !           527: extreme(x, y, bbox)    /* record max and min x and y values */
        !           528:        double  x, y;
        !           529:        float   *bbox;
        !           530: {
        !           531:        if ((float)x < bbox[0]) bbox[0] = x;
        !           532:        if ((float)y < bbox[1]) bbox[1] = y;
        !           533:        if ((float)x > bbox[2]) bbox[2] = x;
        !           534:        if ((float)y > bbox[3]) bbox[3] = y;
        !           535: }
        !           536: 
        !           537: track_bounds(x0, y0, x1, y1)   /* insert a bounding box into the global box */
        !           538:        double  x0, y0, x1, y1;
        !           539: {
        !           540:        if (x0 < Gbox[0])       Gbox[0] = x0;
        !           541:        if (y0 < Gbox[1])       Gbox[1] = y0;
        !           542:        if (x1 > Gbox[2])       Gbox[2] = x1;
        !           543:        if (y1 > Gbox[3])       Gbox[3] = y1;
        !           544: }
        !           545: 
        !           546: get_bounds(p, bbox, flag) /* reconstruct bounding box from center/basis/xform */
        !           547:        obj     *p;
        !           548:        float   *bbox;
        !           549:        int     flag;
        !           550: {
        !           551: static obj     *lastp = (obj *)0;
        !           552: static double  x0, y0, x1, y1;
        !           553:        double  w, h, wm, hm, x, y;
        !           554:        double  owid, oht;
        !           555: 
        !           556:        if (flag && p == lastp)
        !           557:                goto done;
        !           558:        x = Xformx(p, 1, p->o_x, p->o_y);
        !           559:        y = Xformy(p, 0, p->o_x, p->o_y);
        !           560:        if (p->o_type > TEXT) {
        !           561:                x0 = x1 = x;
        !           562:                y0 = y1 = y;
        !           563:        }
        !           564:        else {
        !           565:                if (p->o_type == TEXT) {
        !           566:                        x += Linx(p,0,p->o_val[N_VAL-2].f,p->o_val[N_VAL-1].f);
        !           567:                        y += Liny(p,0,p->o_val[N_VAL-2].f,p->o_val[N_VAL-1].f);
        !           568:                }
        !           569:                else if (p->o_type == ARC || p->o_type == SECTOR) {
        !           570:                        x -= Linx(p,0,p->o_val[N_VAL+6].f,p->o_val[N_VAL+7].f);
        !           571:                        y -= Liny(p,0,p->o_val[N_VAL+6].f,p->o_val[N_VAL+7].f);
        !           572:                }
        !           573:                owid = p->o_wid + p->o_weight;
        !           574:                oht =  p->o_ht + p->o_weight;
        !           575:                if (     ( p->o_type == ARROW || p->o_type == LINE
        !           576:                        || p->o_type == SPLINE || p->o_type == ARC)
        !           577:                                                && (p->o_attr & HEAD12)) {
        !           578:                    w = p->o_val[N_VAL+(p->o_type == ARC ? 8 : 1)].f;
        !           579:                    owid += w;          /* account for width of arrowheads */
        !           580:                    oht  += w;
        !           581:                }
        !           582:                w = Linx(p, 0, owid, oht) / 2;  /* transform main diagonal */
        !           583:                h = Liny(p, 0, owid, oht) / 2;
        !           584:                wm = Linx(p, 0, -owid, oht) / 2; /* transform other diagonal */
        !           585:                hm = Liny(p, 0, -owid, oht) / 2;
        !           586:                if (w < 0)      w = -w;
        !           587:                if (h < 0)      h = -h;
        !           588:                if (wm < 0)     wm = -wm;
        !           589:                if (hm < 0)     hm = -hm;
        !           590:                if (w < wm)     w = wm;
        !           591:                if (h < hm)     h = hm;
        !           592:                x0 = x - w;
        !           593:                x1 = x + w;
        !           594:                y0 = y - h;
        !           595:                y1 = y + h;
        !           596:        }
        !           597:        lastp = p;
        !           598: done:  bbox[0] = x0;   bbox[1] = y0;   bbox[2] = x1; bbox[3] = y1;
        !           599: }

unix.superglobalmegacorp.com

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