Annotation of researchv10no/cmd/bcp/Coord.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1989, 1990 AT&T --- All Rights Reserved.              */
                      2: /* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T.                */
                      3: /* The copyright notice does not imply actual or intended publication. */
                      4: /* AUTHORS:                                            */
                      5: /*     H. S. Baird - ATT-BL MH - first versions        */
                      6: /*     T. J. Thompson - ATT-BL HO - improvements       */
                      7: 
                      8: /* Coord.c - function bodies for basic Coordinate geometry.
                      9:    See Coord.h for associated defines, typedefs, etc.
                     10:    */
                     11: 
                     12: #include <stdio.h>
                     13: #include <math.h>
                     14: #include <string.h>
                     15: #define ATAN_INCL 1
                     16: #include "CPU.h"
                     17: #include "boole.h"
                     18: #include "Units.h"
                     19: #include "Coord.h"
                     20: 
                     21: /* Added by Tim Thompson ... */
                     22: int Readvax = 0;
                     23: 
                     24: VOID
                     25: setreadvax()
                     26: {
                     27:        char *getenv();
                     28:        char *p = getenv("READVAX");
                     29:        /* any non-null value of READVAX will set it */
                     30:        if ( p!=NULL && strlen(p)>0 )
                     31:                Readvax = 1;
                     32: }
                     33: 
                     34: /* ... */
                     35: 
                     36: /* Convert a real value, a units specification, and a resolution
                     37:    into a value in scanner coordinates. */
                     38: int vto_scoor(v,u,r)
                     39:     double v;  /* value in special units */
                     40:     char u;    /* units: one of UNITS (see ric.h) */
                     41:     int r;     /* resolution in pixels/inch */
                     42: {   int c;
                     43:        switch(u) {
                     44:            case 'i':   /* inches */
                     45:                c = (int)(v*r + 0.5);
                     46:                break;
                     47:            case 'c':   /* cm */
                     48:                c = (int)((v*r/2.54) + 0.5);
                     49:                break;
                     50:            case 'p':   /* points */
                     51:                c = (int)((v*INCHES_PER_POINT*r) + 0.5);
                     52:                break;
                     53:            case 'P':   /* picas */
                     54:                c = (int)((v*12.0*INCHES_PER_POINT*r) + 0.5);
                     55:                break;
                     56:            case 's':   /* scanner pixel (Scoor) */
                     57:            case 'u':   /* basic unit */
                     58:                c = (int)(v + 0.5);
                     59:                break;
                     60:            default:
                     61:                c = (int)(v + 0.5);
                     62:                break;
                     63:            };
                     64:        return(c);
                     65:        }
                     66: 
                     67: /* Return pointer to empty Sp from malloc space */
                     68: Sp *alloc_sp()
                     69: {   Sp *spp;
                     70:        if((spp=(Sp *)malloc(sizeof(Sp)))==NULL)
                     71:                abort("alloc_sp: can't");
                     72:        *spp = zero_Sp;
                     73:        return(spp);
                     74:        }
                     75: 
                     76: /* Free Sp from malloc space */
                     77: free_sp(spp)
                     78:     Sp *spp;
                     79: {      free(spp);
                     80:        }
                     81: 
                     82: Sp *ato_sp(s)
                     83:     char *s;
                     84: {   char *d;
                     85:     static Sp p;
                     86:     char *p_x,*p_y;
                     87: #define SP_DELIM "(), "
                     88:        d = strdup(s);
                     89:        p_x = strtok(d,SP_DELIM);
                     90:        p_y = strtok((char *)0,SP_DELIM);
                     91:        if(p_x==NULL||p_y==NULL)
                     92:                {free(d); return(NULL);};
                     93:        p.x = atoi(p_x);
                     94:        p.y = atoi(p_y);
                     95:        free(d);
                     96:        return(&p);
                     97:        }
                     98: 
                     99: char *sp_toa(sp)
                    100:     Sp *sp;
                    101: #define sp_toa_distinct (5)
                    102: {   static char s[sp_toa_distinct][40];
                    103:     static int sp_toa_cur = -1;
                    104:        sp_toa_cur = (sp_toa_cur+1)%sp_toa_distinct;
                    105:        sprintf(s[sp_toa_cur],"(%d,%d)",sp->x,sp->y);
                    106:        return(s[sp_toa_cur]);
                    107:        }
                    108: 
                    109: /* Read a list of Sp's (in ascii) from file *fp, into set *spsp */
                    110: frda_sps(fp,spsp)
                    111:     FILE *fp;
                    112:     Sps *spsp;
                    113: #define MAX_SPS_LINE (80)
                    114: {   Sp *spp,**bb;
                    115:     long seek;
                    116:     char line[MAX_SPS_LINE+1];
                    117:        *spsp = empty_Sps;
                    118:        seek = ftell(fp);
                    119:        /* count all points quickly, in advance */
                    120:        while(!feof(fp)) {
                    121:                line[0] = '\0';
                    122:                fgets(line,MAX_SPS_LINE,fp);
                    123:                if(strlen(line)>0) {
                    124:                        spsp->mny++;
                    125:                        };
                    126:                };
                    127:        if((spsp->pa=(Sp **)malloc((spsp->mny+1)*sizeof(Sp *)))==NULL)
                    128:                abort("frda_sps: can't alloc spsp->pa[%d]",spsp->mny+1);
                    129:        /* next, reread points */
                    130:        fseek(fp,(long)seek,0);
                    131:        bb=spsp->pa;
                    132:        while(!feof(fp)) {
                    133:                line[0] = '\0';
                    134:                fgets(line,MAX_SPS_LINE,fp);
                    135:                if(strlen(line)>0) {
                    136:                        *(spp = alloc_sp()) = *ato_sp(line);
                    137:                        *(bb++) = spp;
                    138:                        };
                    139:                };
                    140:        *bb = NULL;
                    141:        }
                    142: 
                    143: err_sps(p)
                    144:     Sps *p;
                    145: {   int i;
                    146:     Sp **s;
                    147:        fprintf(stderr,"Sps: %d points: ",p->mny);
                    148:        if(p->mny>0) for(s=p->pa; (*s)!=NULL; s++) {
                    149:                fprintf(stderr,"%s ",sp_toa(*s));
                    150:                };
                    151:        fprintf(stderr,"\n");
                    152:        }
                    153: 
                    154: Sp *append_sp_sps(sp,sps)
                    155:    Sp *sp;
                    156:    Sps *sps;
                    157: {      if(sps->mny>0) {
                    158:                if((sps->pa=(Sp **)realloc(sps->pa,(sps->mny+2)*sizeof(Sp *)))==NULL)
                    159:                        abort("append_sp_sps: can't realloc sps->pa[%d]",sps->mny+2);
                    160:                }
                    161:        else {  sps->mny=0;
                    162:                if((sps->pa=(Sp **)malloc((sps->mny+2)*sizeof(Sp *)))==NULL)
                    163:                        abort("append_sp_sps: can't alloc sps->pa[%d]",sps->mny+2);
                    164:                };
                    165:        sps->pa[sps->mny++] = sp;
                    166:        sps->pa[sps->mny] = NULL;
                    167:        }
                    168: 
                    169: /* Return pointer to local static Sps which holds a duplicate of the
                    170:    given Sps (all contents are freshly malloc'ed) */
                    171: Sps *dup_sps(old)
                    172:     Sps *old;
                    173: {   static Sps new;
                    174:     Sp **o,**n;
                    175:        if(old->mny>0) {
                    176:                new.mny = old->mny;
                    177:                if((new.pa=(Sp **)malloc((new.mny+1)*sizeof(Sp *)))==NULL)
                    178:                        abort("dup_sps: can't alloc new.pa[%d]",new.mny+1);
                    179:                for(o=old->pa,n=new.pa; *o!=NULL; o++,n++) {
                    180:                        *(*n = alloc_sp()) = **o;
                    181:                        };
                    182:                *n = NULL;
                    183:                }
                    184:        else new = empty_Sps;
                    185:        return(&new);
                    186:        }
                    187: 
                    188: free_sps(p)
                    189:    Sps *p;
                    190: {      if(p->pa!=NULL) free(p->pa);
                    191:        *p = empty_Sps;
                    192:        }
                    193: 
                    194: Sp *append_sp_spa(sp,spa)
                    195:    Sp *sp;
                    196:    Spa *spa;
                    197: {      if(spa->mny>0) {
                    198:                if((spa->a=(Sp *)realloc(spa->a,(spa->mny+1)*sizeof(Sp)))==NULL)
                    199:                        abort("append_sp_spa: can't alloc spa->a[%d]",spa->mny+1);
                    200:                }
                    201:        else {  spa->mny=0;
                    202:                if((spa->a=(Sp *)malloc((spa->mny+1)*sizeof(Sp)))==NULL)
                    203:                        abort("append_sp_spa: can't alloc spa->a[%d]",spa->mny+1);
                    204:                };
                    205:        spa->a[spa->mny++] = *sp;
                    206:        }
                    207: 
                    208: err_spa(p)
                    209:     Spa *p;
                    210: {   int i;
                    211:     Sp *sp;
                    212:        fprintf(stderr,"Spa: %d points: ",p->mny);
                    213:        for(i=0,sp=p->a;i<p->mny;i++,sp++) {
                    214:                fprintf(stderr,"%s ",sp_toa(sp));
                    215:                };
                    216:        fprintf(stderr,"\n");
                    217:        }
                    218: 
                    219: free_spa(p)
                    220:    Spa *p;
                    221: {      if(p->a!=NULL) free(p->a);
                    222:        *p = empty_Spa;
                    223:        }
                    224: 
                    225: /* Rotate the Scanner point `(x,y') about origin `*orp' by angle `ang',
                    226:    and return pointer to the result.  This is slow, but no matter. */
                    227: Sp *rotate_Sp(ang,orp,x,y)
                    228:     double ang;
                    229:     Sp *orp;
                    230:     int x,y;
                    231: {   static Sp res;
                    232:     Sp of;
                    233:        of.x = x - orp->x;  of.y = y - orp->y;
                    234:        res.x = (short)(((cos(ang)*of.x - sin(ang)*of.y)) + orp->x + 0.5);
                    235:        res.y = (short)(((sin(ang)*of.x + cos(ang)*of.y)) + orp->y + 0.5);
                    236:        return(&res);
                    237:        }
                    238: 
                    239: /* Horizontally shear the Scanner point `(x,y') about origin `*orp' by shear
                    240:    angle `ang', and return pointer to the result.  `Ang' is close to 90 degrees.
                    241:    This is slow, but no matter. */
                    242: Sp *hshear_Sp(ang,orp,x,y)
                    243:     double ang;
                    244:     Sp *orp;
                    245:     int x,y;
                    246: {   static Sp res;
                    247:     Scoor of_y,tr_x;
                    248:        res.x = (short)(orp->x - (y - orp->y)*tan(ang-(90.0*DtoR)) + 0.5);
                    249:        res.y = orp->y;
                    250:        return(&res);
                    251:        }
                    252: 
                    253: /* Return pointer to initialized Edge from malloc space */
                    254: Edge *alloc_edge()
                    255: {   Edge *ep;
                    256:        if((ep=(Edge *)malloc(sizeof(Edge)))==NULL)
                    257:                abort("alloc_edge: can't");
                    258:        *ep = empty_Edge;
                    259:        return(ep);
                    260:        }
                    261: 
                    262: /* Free Edge from malloc space */
                    263: free_edge(ep)
                    264:     Edge *ep;
                    265: {      free(ep);
                    266:        }
                    267: 
                    268: char *edge_toa(ep)
                    269:        Edge *ep;
                    270: {   static char s[40];
                    271:        strcpy(s,sp_toa(&(ep->a)));
                    272:        strcat(s,"-");
                    273:        strcat(s,sp_toa(&(ep->b)));
                    274:        return(s);
                    275:        }
                    276: 
                    277: Edge *ato_edge(s)
                    278:     char *s;
                    279: {   char *d;
                    280:     static Edge e;
                    281:     char *a_x,*a_y,*b_x,*b_y;
                    282: #define EDGE_DELIM "(),- "
                    283:        d = strdup(s);
                    284:        a_x = strtok(d,EDGE_DELIM);
                    285:        a_y = strtok((char *)0,EDGE_DELIM);
                    286:        b_x = strtok((char *)0,EDGE_DELIM);
                    287:        b_y = strtok((char *)0,EDGE_DELIM);
                    288:        if(a_x==NULL||a_y==NULL||b_x==NULL||b_y==NULL)
                    289:                {free(d); return(NULL);};
                    290:        e.a.x = atoi(a_x);
                    291:        e.a.y = atoi(a_y);
                    292:        e.b.x = atoi(b_x);
                    293:        e.b.y = atoi(b_y);
                    294:        free(d);
                    295:        return(&e);
                    296:        }
                    297: 
                    298: /* Return pointer to empty Bbx from malloc space */
                    299: Bbx *alloc_bbx()
                    300: {   Bbx *bxp;
                    301:        if((bxp=(Bbx *)malloc(sizeof(Bbx)))==NULL)
                    302:                abort("alloc_bbx: can't");
                    303:        *bxp = empty_Bbx;
                    304:        return(bxp);
                    305:        }
                    306: 
                    307: /* Free Bbx from malloc space */
                    308: free_bbx(bxp)
                    309:     Bbx *bxp;
                    310: {      free(bxp);
                    311:        }
                    312: 
                    313: char *bbx_toa(bxp)
                    314:        Bbx *bxp;
                    315: {   static char s[40];
                    316:        strcpy(s,sp_toa(&(bxp->a)));
                    317:        strcat(s,sp_toa(&(bxp->b)));
                    318:        return(s);
                    319:        }
                    320: 
                    321: Bbx *ato_bbx(s)
                    322:     char *s;
                    323: {   char *d;
                    324:     static Bbx bx;
                    325:     char *a_x,*a_y,*b_x,*b_y;
                    326: #define BBX_DELIM "(), "
                    327:        d = strdup(s);
                    328:        a_x = strtok(d,BBX_DELIM);
                    329:        a_y = strtok((char *)0,BBX_DELIM);
                    330:        b_x = strtok((char *)0,BBX_DELIM);
                    331:        b_y = strtok((char *)0,BBX_DELIM);
                    332:        if(a_x==NULL||a_y==NULL||b_x==NULL||b_y==NULL)
                    333:                {free(d); return(NULL);};
                    334:        bx.a.x = atoi(a_x);
                    335:        bx.a.y = atoi(a_y);
                    336:        bx.b.x = atoi(b_x);
                    337:        bx.b.y = atoi(b_y);
                    338:        free(d);
                    339:        return(&bx);
                    340:        }
                    341: 
                    342: Bbx *expand_bbx(bxp,X)
                    343:     Bbx *bxp;
                    344:     int X;             /* expansion code */
                    345: {   static Bbx xbx;
                    346:        xbx = *bxp;
                    347:        switch(X) {
                    348:            case -3:
                    349:                xbx.a.x += 2;
                    350:                xbx.a.y += 2;
                    351:                xbx.b.x -= 1;
                    352:                xbx.b.y -= 1;
                    353:                break;
                    354:            case -2:
                    355:                xbx.a.x += 1;
                    356:                xbx.a.y += 1;
                    357:                xbx.b.x -= 1;
                    358:                xbx.b.y -= 1;
                    359:                break;
                    360:            case -1:
                    361:                xbx.a.x += 1;
                    362:                xbx.a.y += 1;
                    363:                break;
                    364:            case 0:
                    365:                break;
                    366:            case 1:
                    367:                xbx.b.x += 1;
                    368:                xbx.b.y += 1;
                    369:                break;
                    370:            case 2:
                    371:                xbx.a.x -= 1;
                    372:                xbx.a.y -= 1;
                    373:                xbx.b.x += 1;
                    374:                xbx.b.y += 1;
                    375:                break;
                    376:            case 3:
                    377:                xbx.a.x -= 1;
                    378:                xbx.a.y -= 1;
                    379:                xbx.b.x += 2;
                    380:                xbx.b.y += 2;
                    381:                break;
                    382:            default:
                    383:                break;
                    384:            };
                    385:        return(&xbx);
                    386:        }
                    387: 
                    388: /* Predicate:  Is most of Bbx 1 inside Bbx 2?  ``Most'' is defined
                    389:    as more than half of the first Bbx's area inside BBx 2.*/
                    390: boolean bbx_inside_most(b1,b2)
                    391:     Bbx *b1,*b2;
                    392: {   struct {           /* overlap between blob box and selection box */
                    393:        Bbx bx;         /* Bbx of intersection */
                    394:        Sp sd;          /* side-lengths of overlap box, >=0 */
                    395:        long area;      /* area is square pixels, >=0 */
                    396:        } ov;
                    397:        if(!bbx_inside_any(b1,b2)) return(F);
                    398:        else if(bbx_inside_all(b1,b2)) return(T);
                    399:        else {  /* compute overlap box */
                    400:                ov.bx.a.x = ((b1)->a.x>(b2)->a.x)? (b1)->a.x: (b2)->a.x;
                    401:                ov.bx.a.y = ((b1)->a.y>(b2)->a.y)? (b1)->a.y: (b2)->a.y;
                    402:                ov.bx.b.x = ((b1)->b.x<(b2)->b.x)? (b1)->b.x: (b2)->b.x;
                    403:                ov.bx.b.y = ((b1)->b.y<(b2)->b.y)? (b1)->b.y: (b2)->b.y;
                    404:                ov.sd.x = bbx_wid(&ov.bx);  if(ov.sd.x<0) ov.sd.x=0;
                    405:                ov.sd.y = bbx_hgt(&ov.bx);  if(ov.sd.y<0) ov.sd.y=0;
                    406:                ov.area = ov.sd.x*ov.sd.y;
                    407:                return( (ov.area>0) && ( 2*ov.area > bbx_area(b1) ) );
                    408:                };
                    409:        }
                    410: 
                    411: Bbx *translate_bbx(bxp,off)
                    412:     Bbx *bxp;
                    413:     Sp off;
                    414: {   static Bbx res;
                    415:        res.a.x = bxp->a.x + off.x;
                    416:        res.a.y = bxp->a.y + off.y;
                    417:        res.b.x = bxp->b.x + off.x;
                    418:        res.b.y = bxp->b.y + off.y;
                    419:        return(&res);
                    420:        }
                    421: 
                    422: /* Free Bbxs (but not the contents) */
                    423: free_bbxs(bxsp)
                    424:     Bbxs *bxsp;
                    425: {   Bbx **b;
                    426:        if(bxsp->mny>0) {
                    427:                if(bxsp->pa!=NULL) free(bxsp->pa);
                    428:                };
                    429:        *bxsp = empty_Bbxs;
                    430:        }
                    431: 
                    432: /* Free Bbxs (and the individually-malloc'ed contents) */
                    433: free_bbxs_etc(bxsp)
                    434:     Bbxs *bxsp;
                    435: {   Bbx **b;
                    436:        if(bxsp->mny>0) {
                    437:                for(b=bxsp->pa; (*b)!=NULL; b++) free(*b);
                    438:                if(bxsp->pa!=NULL) free(bxsp->pa);
                    439:                };
                    440:        *bxsp = empty_Bbxs;
                    441:        }
                    442: 
                    443: /* Return pointer to local static Bbxs which holds a duplicate of the
                    444:    given Bbxs (all contents are freshly malloc'ed) */
                    445: Bbxs *dup_bbxs(old)
                    446:     Bbxs *old;
                    447: {   static Bbxs new;
                    448:     Bbx **o,**n;
                    449:        if(old->mny>0) {
                    450:                new.mny = old->mny;
                    451:                new.alloc = old->alloc;
                    452:                new.incr = old->incr;
                    453:                if((new.pa=(Bbx **)malloc((new.alloc)*sizeof(Bbx *)))==NULL)
                    454:                        abort("dup_bbxs: can't alloc new.pa[%d]",new.alloc);
                    455:                for(o=old->pa,n=new.pa; *o!=NULL; o++,n++) {
                    456:                        *(*n = alloc_bbx()) = **o;
                    457:                        };
                    458:                *n = NULL;
                    459:                }
                    460:        else new = empty_Bbxs;
                    461:        return(&new);
                    462:        }
                    463: 
                    464: Bbx *append_bbx(bxp,bxsp)
                    465:    Bbx *bxp;
                    466:    Bbxs *bxsp;
                    467: {      if(bxsp->mny>0) {
                    468:                if((bxsp->mny+2)>bxsp->alloc) {
                    469:                        bxsp->alloc += bxsp->incr;
                    470:                        if( ( bxsp->pa =
                    471:                              (Bbx **)realloc(bxsp->pa,bxsp->alloc*sizeof(Bbx *)) )
                    472:                            ==NULL )
                    473:                                abort("append_bbx: can't alloc bxsp->pa[%d]",bxsp->alloc);
                    474:                        };
                    475:                }
                    476:        else {  bxsp->mny=0;
                    477:                if(bxsp->pa!=NULL) free(bxsp->pa);
                    478:                bxsp->alloc=0;
                    479:                while((bxsp->mny+2)>bxsp->alloc) bxsp->alloc += bxsp->incr;
                    480:                if((bxsp->pa=(Bbx **)malloc(bxsp->alloc*sizeof(Bbx *)))==NULL)
                    481:                        abort("append_bbx: can't alloc bxsp->a[%d]",bxsp->alloc);
                    482:                };
                    483:        bxsp->pa[bxsp->mny++] = bxp;
                    484:        bxsp->pa[bxsp->mny] = NULL;
                    485:        }
                    486: 
                    487: frda_bbxs(fp,bxsp)
                    488:     FILE *fp;
                    489:     Bbxs *bxsp;
                    490: #define MAX_BBX_LINE (80)
                    491: {   Bbx *bxp,**bb;
                    492:     long seek;
                    493:     char line[MAX_BBX_LINE+1];
                    494:        *bxsp = empty_Bbxs;
                    495:        seek = ftell(fp);
                    496:        /* count all boxes quickly, in advance */
                    497:        while(!feof(fp)) {
                    498:                line[0] = '\0';
                    499:                fgets(line,MAX_BBX_LINE,fp);
                    500:                if(strlen(line)>0) {
                    501:                        bxsp->mny++;
                    502:                        };
                    503:                };
                    504:        if((bxsp->pa=(Bbx **)malloc((bxsp->mny+1)*sizeof(Bbx *)))==NULL)
                    505:                abort("frda_bbxs: can't alloc bxsp->pa[%d]",bxsp->mny+1);
                    506:        bxsp->alloc = bxsp->mny+1;
                    507:        /* next, reread boxes */
                    508:        fseek(fp,(long)seek,0);
                    509:        bb=bxsp->pa;
                    510:        while(!feof(fp)) {
                    511:                line[0] = '\0';
                    512:                fgets(line,MAX_BBX_LINE,fp);
                    513:                if(strlen(line)>0) {
                    514:                        *(bxp = alloc_bbx()) = *ato_bbx(line);
                    515:                        *(bb++) = bxp;
                    516:                        };
                    517:                };
                    518:        *bb = NULL;
                    519:        }
                    520: 
                    521: fwra_bbxs(fp,bxsp)
                    522:     FILE *fp;
                    523:     Bbxs *bxsp;
                    524: {   Bbx **b;
                    525:        if(bxsp->mny>0) for(b=bxsp->pa; *b!=NULL; b++) {
                    526:                fputs(bbx_toa(*b),fp);
                    527:                fputs("\n",fp);
                    528:                };
                    529:        fflush(fp);
                    530:        }

unix.superglobalmegacorp.com

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