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

1.1       root        1: /*     Copyright (c) 1988 AT&T */
                      2: /*       All Rights Reserved   */
                      3: 
                      4: /*     THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T     */
                      5: /*     The copyright notice above does not evidence any        */
                      6: /*     actual or intended publication of such source code.     */
                      7: 
                      8: /*     @(#)picasso:plps.c      1.0     */
                      9: 
                     10: #include <string.h>
                     11: #include <ctype.h>
                     12: #include "font.h"
                     13: #include "picasso.h"
                     14: #include "y.tab.h"
                     15: 
                     16: #define        max(x,y)        ((x)>(y) ? (x) : (y))
                     17: #define        min(x,y)        ((x)<(y) ? (x) : (y))
                     18: 
                     19: #define PROLOGUE       "picasso.ps"
                     20: #define        FONTDEFS        "fonts.ps"
                     21: 
                     22: extern char    *gwblib;        /* defined by installer, or set by -I flag */
                     23: extern int     margin;
                     24: extern float   magnification;
                     25: extern float   *miters;
                     26: extern FILE    *textfp;
                     27: extern  int    batch;
                     28: extern int     pic_compat;
                     29: 
                     30: FILE   *outfp   = stdout;
                     31: int    pages    = 0;
                     32: int    pictures = 0;
                     33: int    started  = 0;
                     34: int    bboxllx  = 32767;
                     35: int    bboxlly  = 32767;
                     36: int    bboxurx  = -32767;
                     37: int    bboxury  = -32767;
                     38: int    psfont   = -1;
                     39: double pssize   =  0;
                     40: int    last_cap    = -1;
                     41: int    last_join   = -1;
                     42: float  last_miter  = -1;
                     43: float  last_weight = -1;
                     44: float  last_color  = -1;
                     45: float  *last_dash  = NULL;
                     46: 
                     47: static int     extra_chars = 0;
                     48: 
                     49: resetps()      /* these must be reset for each page of a multipage file */
                     50: {              /* (so that -mpictures inclusions will work correctly.)  */
                     51: 
                     52:        psfont = last_miter = last_cap = last_join = -1;
                     53:        last_weight = last_color = -1;
                     54:        last_dash = NULL;
                     55:        pssize  = 0;
                     56: }
                     57: 
                     58: static char *nopro = "can't read prologue file ";
                     59: 
                     60: findfile(path, name)
                     61:        char    *path, *name;
                     62: {
                     63:        char    *msgbuf;
                     64: 
                     65:        if (access(strcat(strcat(strcpy(path,gwblib),"/"),name),4) != 0) {
                     66:                if (batch)
                     67:                        fprintf(stderr, "%s%s\n", nopro, path);
                     68:                else {
                     69:                        msgbuf = (char *) malloc(strlen(path)+strlen(nopro)+2);
                     70:                        if (msgbuf != NULL) {
                     71:                                sprintf(msgbuf, "%s%s", nopro, path);
                     72:                                writemessage(msgbuf, 15, 1);
                     73:                                free(msgbuf);
                     74:                        }
                     75:                }
                     76:        }
                     77: }
                     78: 
                     79: beginpl()
                     80: {
                     81:        char    filename[100];
                     82: 
                     83:        fputs("%!PS-Adobe-2.0\n", outfp);
                     84:        fputs("%%Creator: picasso\n", outfp);
                     85:        fputs("%%BoundingBox: (atend)\n", outfp);
                     86:        fputs("%%Pages: (atend)\n", outfp);
                     87:        fputs("%%EndComments\n", outfp);
                     88:        if (!pass_thru) {
                     89:                findfile(filename, FONTDEFS);
                     90:                catfile(filename);
                     91:        }
                     92:        findfile(filename, PROLOGUE);
                     93:        catfile(filename);
                     94:        fputs("%%EndProlog\n", outfp);
                     95:        fputs("%%BeginSetup\n", outfp);
                     96:        if (magnification != 1.0)
                     97:                fprintf(outfp, "/magnification %f def\n", magnification);
                     98:        fputs("%%EndSetup\n", outfp);
                     99:        pages = 0;
                    100:        bboxllx = 32767;
                    101:        bboxlly = 32767;
                    102:        bboxurx = -32767;
                    103:        bboxury = -32767;
                    104:        started = 1;
                    105: }
                    106: 
                    107: endpl()
                    108: {
                    109:        if (started) {
                    110:                fputs("%%Trailer\n", outfp);
                    111:                fprintf(outfp, "%%%%BoundingBox: %d %d %d %d\n",
                    112:                    (int)(bboxllx*magnification), (int)(bboxlly*magnification),
                    113:                    (int)(bboxurx*magnification), (int)(bboxury*magnification));
                    114:                fprintf(outfp, "%%%%Pages: %d\n", pages);
                    115:        }
                    116: }
                    117: 
                    118: int    open_done = 0;
                    119: double tx, ty, pgscale = 72;
                    120: static double  px, py, sx, sy;
                    121: static int     pbnd[4];
                    122: 
                    123: openpl(s)              /* initialize page */
                    124:        char    *s;
                    125: {
                    126: extern FILE *tmpfile();
                    127: extern double  pght, pgwid;
                    128:        double  deltx, delty, r;
                    129: 
                    130:        if (open_done)
                    131:                return;
                    132:        pgscale = 72;           /* reset for every picture */
                    133:        while (isspace(*s))
                    134:                s++;
                    135:        if (*s == '\0') {
                    136:                px = pgwid;
                    137:                py = pght;
                    138:        }
                    139:        else {
                    140:                px = py = 0;
                    141:                sscanf(s, "%lf %lf", &py, &px);
                    142:                if (pic_compat) {
                    143:                        r = px;
                    144:                        px = py;
                    145:                        py = r;
                    146:                }
                    147:                if (px <= 0)    px = pgwid;
                    148:                if (py <= 0)    py = pght;
                    149:        }
                    150:        if (pass_thru) {
                    151:                if ((outfp = tmpfile()) == NULL)
                    152:                        fatal("can't open internal temporary file");
                    153:                started = 0;
                    154:        }
                    155:        if (!started)
                    156:                beginpl();
                    157:        if (nosqueeze) {
                    158:                sx = sy = 72;
                    159:                tx = ty = 0;
                    160:        }
                    161:        else {
                    162:                deltx = (Gbox[2]-Gbox[0]);
                    163:                delty = (Gbox[3]-Gbox[1]);
                    164:                if (cur_xform[0].f != 1) {      /* implicit scaling */
                    165:                        deltx *= cur_xform[0].f;
                    166:                        delty *= cur_xform[0].f;
                    167:                }
                    168:                r = max(deltx/px, delty/py);
                    169:                if (r <= 1)
                    170:                        r = 1;
                    171:                else if (verbose || px == pgwid && py == pght) {
                    172:                        fprintf(stderr, "%s: %g X %g picture shrunk to",
                    173:                                        cmdname, deltx, delty);
                    174:                        deltx /= r;
                    175:                        delty /= r;
                    176:                        fprintf(stderr, " %g X %g\n", deltx, delty);
                    177:                }
                    178: /*     NOTE: Setting pgscale affects the subsequent ouput of text, so
                    179:        that text will come out the same size regardless of the scaling
                    180:        of the rest of the drawing.  This is only appropriate when we
                    181:        are in pic emulation mode, since pic couldn't scale text.--DBK */
                    182:                if (pic_compat)
                    183:                        pgscale = 72/r;
                    184:                sx = sy = 72/r;
                    185:                tx = -(Gbox[0]+Gbox[2])/2;
                    186:                ty = -(Gbox[1]+Gbox[3])/2;
                    187:        }
                    188:        pages++;
                    189:        fprintf(outfp, "%%%%Page: ? %d\n", pages);
                    190:        fprintf(outfp, "%%%%PageBoundingBox: (atend)\n");
                    191:        fputs("%%BeginPageSetup\n", outfp);
                    192:        fprintf(outfp, "%.5g %.5g %.5g %.5g PIC\n", tx, ty, sx, sy);
                    193:        fputs("%%EndPageSetup\n", outfp);
                    194:        setattrdefaults ();
                    195:        open_done = 1;
                    196: }
                    197: 
                    198: closepl(s)             /* clean up after finished with one picture */
                    199:        char    *s;     /* residue of .PS invocation line */
                    200: {
                    201: extern long    ftell();
                    202: extern int     flyback;
                    203:        long    filesize;
                    204: 
                    205:        if (open_done) {
                    206:                fputs("showpage\n", outfp);
                    207:                if (nosqueeze) {
                    208:                        pbnd[0] = Gbox[0]*72 + px * 72 / 2;
                    209:                        pbnd[3] = (11+Gbox[3])*72 - py  * 72 / 2;
                    210:                }
                    211:                else {
                    212:                        pbnd[0] = pgwid * 72 / 2 + (Gbox[0] - Gbox[2]) * sx / 2;
                    213:                        pbnd[3] = pght  * 72 / 2 + (Gbox[3] - Gbox[1]) * sy / 2;
                    214:                }
                    215:                pbnd[1] = pbnd[3] - (Gbox[3] - Gbox[1]) * sy;
                    216:                pbnd[2] = pbnd[0] + (Gbox[2] - Gbox[0]) * sx;
                    217:                pbnd[0] -= margin;              pbnd[1] -= margin;
                    218:                pbnd[2] += margin;              pbnd[3] += margin;
                    219:                if (pbnd[0] < 0)                pbnd[0] = margin;
                    220:                if (pbnd[1] < 0)                pbnd[1] = margin;
                    221:                if (pbnd[2] > pgwid * 72)       pbnd[2] = pgwid * 72 - margin;
                    222:                if (pbnd[3] > pght  * 72)       pbnd[3] = pght * 72  - margin;
                    223:                fprintf(outfp, "%%%%PageBoundingBox: %d %d %d %d\n",
                    224:                    (int)(pbnd[0]*magnification), (int)(pbnd[1]*magnification),
                    225:                    (int)(pbnd[2]*magnification), (int)(pbnd[3]*magnification));
                    226:                if (bboxllx > pbnd[0])  bboxllx = pbnd[0];
                    227:                if (bboxlly > pbnd[1])  bboxlly = pbnd[1];
                    228:                if (bboxurx < pbnd[2])  bboxurx = pbnd[2];
                    229:                if (bboxury < pbnd[3])  bboxury = pbnd[3];
                    230:                if (pass_thru) {
                    231:                        endpl();
                    232:                        fflush(outfp);
                    233:                        filesize = ftell(outfp) - extra_chars;
                    234:                        rewind(outfp);
                    235:                        pictures++;
                    236:                        printf("\\!x X InlinePicture picture%d %ld\n",
                    237:                                pictures, filesize);
                    238:                        transparent(outfp);
                    239:                        fclose(outfp);
                    240:                        fprintf(textfp, ".BP picture%d ", pictures);
                    241:                        while (isspace(*s))
                    242:                                s++;
                    243:                        if (*s != '\0')
                    244:                                if (pic_compat) {   /* interchange x and y */
                    245:                                        double  x, y;
                    246:                                        int     i;
                    247:                                        char    r[120];
                    248: 
                    249:                                        i = sscanf(s, "%lf %lf %[^\n]",
                    250:                                                                &x, &y, r);
                    251:                                        if (i <= 0)
                    252:                                                x = (bboxurx - bboxllx)/72.0;
                    253:                                        if (i == 1)
                    254:                                                y = x * (bboxury - bboxlly) /
                    255:                                                        (bboxurx - bboxllx);
                    256:                                        if (i < 3)
                    257:                                                strcpy(r, "c");
                    258:                                        fprintf(textfp, "%g %g %s\n", y, x, r);
                    259:                                }
                    260:                                else
                    261:                                        fputs(s, textfp);
                    262:                        else
                    263:                                fprintf(textfp, "%g %g%s\n",
                    264:                                                (bboxury - bboxlly)/72.0,
                    265:                                                (bboxurx - bboxllx)/72.0,
                    266:                                                pic_compat ? " c" : "");
                    267:                        if (!flyback)
                    268:                                fputs(".EP\n", textfp);
                    269:                }
                    270:                extra_chars = 0;
                    271:                open_done = 0;
                    272:                resetps();
                    273:        }
                    274: }
                    275: 
                    276: /* If not specified with the object, any geometrical primitve is stroked   */
                    277: /* in the default linecolor (and at default lineweight) and is not filled. */
                    278: /* The most recent settings of color and weight are preserved and used to  */
                    279: /* compare with values requested for this object.                         */
                    280: 
                    281: check_psxform()
                    282: {
                    283:        if (cur_xform[0].f != 1 || cur_xform[1].f != 0 || cur_xform[2].f != 0
                    284:        ||  cur_xform[3].f != 1 || cur_xform[4].f != 0 || cur_xform[5].f != 0) {
                    285: 
                    286:                fprintf (outfp, "[%.5g %.5g %.5g %.5g %.5g %.5g] concat\n",
                    287:                        cur_xform[0].f, cur_xform[1].f, cur_xform[2].f,
                    288:                        cur_xform[3].f, cur_xform[4].f, cur_xform[5].f);
                    289: 
                    290:                cur_xform[0].f = cur_xform[3].f = 1;
                    291:                cur_xform[1].f = cur_xform[2].f =
                    292:                cur_xform[4].f = cur_xform[5].f = 0;
                    293:        }
                    294: }
                    295: 
                    296: short  have_temp = 0;
                    297: extern double  T[];
                    298: 
                    299: tmp_xform (p)          /* used only for text */
                    300:        obj     *p;
                    301: {
                    302: #if 0
                    303:        if (p->o_mxx != 1 || p->o_myx != 0 || p->o_mxy != 0 || p->o_myy != 1
                    304:        ||  p->o_mxt != 0 || p->o_myt != 0) {
                    305:                have_temp = 1;
                    306:                fprintf (outfp, "\ngs [%.5g %.5g %.5g %.5g %.5g %.5g] concat\n",
                    307:                                        p->o_mxx, p->o_myx, p->o_mxy, p->o_myy,
                    308:                                        p->o_mxt, p->o_myt);
                    309:        }
                    310: #else
                    311:        compose(p);
                    312:        if (T[0] != 1 || T[1] != 0 || T[2] != 0 ||
                    313:            T[3] != 1 || T[4] != 0 || T[5] != 0) {
                    314:                have_temp = 1;
                    315:                fprintf (outfp, "\ngs [%.5g %.5g %.5g %.5g %.5g %.5g] concat\n",
                    316:                        T[0], T[1], T[2], T[3], T[4], T[5]);
                    317:        }
                    318: #endif
                    319: }
                    320: 
                    321: undo_tmpx ()
                    322: {
                    323:        if (have_temp) {
                    324:                fputs("gr\n", outfp);
                    325:        }
                    326:        have_temp = 0;
                    327: }
                    328: 
                    329: new_weight (val)
                    330:        float   val;
                    331: {
                    332:        if (val < 0.)
                    333:                yyerror ("bad value for lineweight");
                    334:        else if (val != last_weight)
                    335:                fprintf (outfp, " %.5g w\n", last_weight = val);
                    336: }
                    337: 
                    338: new_color (val)
                    339:        float   val;
                    340: {
                    341:        if (val != last_color) {
                    342:                if (val <= 1.0)
                    343:                        fprintf (outfp, " %.5g g\n", val);
                    344:                else {
                    345:                        register int    n = val;
                    346: 
                    347:                        fprintf (outfp, " %.5g %.5g %.5g rgb\n",
                    348:                                rgbtable[n].r, rgbtable[n].g, rgbtable[n].b);
                    349:                }
                    350:                if (!have_temp)
                    351:                        last_color = val;
                    352:        }
                    353: }
                    354: 
                    355: int    attr_flags;
                    356: float  fill_color;
                    357: float  line_color;
                    358: float  line_weight;
                    359: float  *line_dash;
                    360: 
                    361: setattrdefaults ()
                    362: {
                    363:        float   x;
                    364: 
                    365:        if ((x = getfval("flatness")) > 0)
                    366:                fprintf(outfp,"%.5g setflat\n", x);
                    367:        attr_flags = EDGED;
                    368:        new_weight(getfval("lineweight"));
                    369:        new_color (getfval("linecolor"));
                    370:        new_style();
                    371: }
                    372: 
                    373: float  solid = 0;
                    374: 
                    375: new_style()    /* corners, ends, dash pattern */
                    376: {
                    377:        int     i, n;
                    378: 
                    379:        if ((n = attr_flags & (3*LINECAP)) > 0) {
                    380:                n /= LINECAP;
                    381:                if (--n != last_cap)
                    382:                        fprintf(outfp,"%d setlinecap\n",last_cap = n);
                    383:        }
                    384:        if ((n = attr_flags & (3*JOIN)) > 0) {
                    385:                n /= JOIN;
                    386:                if (--n != last_join)
                    387:                        fprintf(outfp,"%d setlinecap\n",last_join = n);
                    388:                if (n == 0 && (i = attr_flags/MITER) > 0)
                    389:                        if (miters[i] != last_miter)
                    390:                                fprintf(outfp,"%.5g setmiterlimit\n",
                    391:                                                last_miter = miters[i]);
                    392:        }
                    393:        if (attr_flags & DOTDASH) {
                    394:                n = *line_dash;
                    395:                for (i = 0; i <= n; i++)
                    396:                        if (line_dash[i] != last_dash[i])
                    397:                                break;
                    398:                if (i < n+1) {
                    399:                        fprintf(outfp," [%.5g",line_dash[1]);
                    400:                        for (i = 2; i <= n; i++) {
                    401:                                fprintf(outfp, " %.5g", line_dash[i]);
                    402:                        }
                    403:                        fprintf(outfp, "] 0 d\n");
                    404:                        last_dash = line_dash;
                    405:                }
                    406:        }
                    407:        else {
                    408:                if (last_dash != &solid)
                    409:                        fprintf(outfp, " [] 0 d\n");
                    410:                last_dash = &solid;
                    411:        }
                    412: }
                    413: 
                    414: chk_attrs (p)
                    415:        obj     *p;
                    416: {
                    417:        line_weight = p->o_weight;
                    418:        /*      It seems as though this should scale with the associated
                    419:         *      object.  I have made it so, 9/20/90.  DBK
                    420:         */
                    421:        compose(p);
                    422:        line_weight *= sqrt(fabs(T[0] * T[3] - T[1] * T[2]));
                    423:        attr_flags  = p->o_attr;
                    424:        line_color  = p->o_color;
                    425:        fill_color  = p->o_fill;
                    426:        line_dash   = p->o_ddpat.a;
                    427: }
                    428: 
                    429: fill_or_stroke ()      /* If fill/edge colors differ, need save/restore */
                    430: {                      /* In any case, filled paths must be closed, so  */
                    431:                        /* a possibly redundant (but harmless) closepath */
                    432:                        /* is issued whenever a fillpath is to be done.  */
                    433:        switch (attr_flags & (EDGED | FILLED)) {
                    434: 
                    435:        case EDGED:     new_color (line_color);         /* simple stroke */
                    436:                        new_weight(line_weight);
                    437:                        new_style();
                    438:                        fprintf(outfp, " s\n");
                    439:                        break;
                    440:        case FILLED:    new_color(fill_color);          /* simple fill  */
                    441:                        fprintf(outfp, " c f\n");
                    442:                        break;
                    443:        default:        new_color (line_color);
                    444:                        new_weight(line_weight);
                    445:                        new_style();
                    446:                        if (fill_color <= 1.0)
                    447:                                fprintf(outfp, " c gs %.5g g f gr s\n",
                    448:                                                        fill_color);
                    449:                        else {
                    450:                                register int    n = fill_color;
                    451: 
                    452:                                fprintf(outfp," gs %.5g %.5g %.5g rgb f gr s\n",
                    453:                                                rgbtable[n].r,
                    454:                                                rgbtable[n].g,
                    455:                                                rgbtable[n].b);
                    456:                        }
                    457:                        break;
                    458:        }
                    459: }
                    460: 
                    461: line(x0, y0, x1, y1)   /* draw line from x0,y0 to x1,y1 */
                    462:        double x0, y0, x1, y1;
                    463: {
                    464:        fprintf(outfp, "%.5g %.5g 1 %.5g %.5g L", x1, y1, x0, y0);
                    465:        fill_or_stroke ();
                    466: }
                    467: 
                    468: box(x0, y0, x1, y1, r)
                    469:        double x0, y0, x1, y1, r;
                    470: {
                    471:        if (r < MINRAD)
                    472:                fprintf(outfp, "%.5g %.5g %.5g %.5g Q", x0,y0, x1,y1);
                    473:        else
                    474:                fprintf(outfp, "%.5g %.5g %.5g %.5g %.5g rQ", x0,y0, x1,y1, r);
                    475:        fill_or_stroke ();
                    476: }
                    477: 
                    478: arrow(x0, y0, x1, y1, w, h, ang, attr)                 /* draw arrowhead (w/o shaft) */
                    479:        double x0, y0, x1, y1, w, h, ang;       /* wid w, len h, rotated ang  */
                    480:        int attr;                               /* and drawn filled or open.  */
                    481: {
                    482:        double alpha, rot, hyp;
                    483:        float dx0, dy0, dx1, dy1;
                    484: 
                    485:        rot = atan2(w/2, h);
                    486:        hyp = hypot(w/2, h);
                    487:        alpha = atan2(y1-y0, x1-x0) + ang;
                    488:        dx0 = hyp * cos(alpha + M_PI - rot);
                    489:        dy0 = hyp * sin(alpha + M_PI - rot);
                    490:        dx1 = hyp * cos(alpha + M_PI + rot);
                    491:        dy1 = hyp * sin(alpha + M_PI + rot);
                    492:        new_weight (line_weight);
                    493:        fprintf(outfp, "%.5g %.5g %.5g %.5g 2 %.5g %.5g L ",
                    494:                        x1+dx1, y1+dy1, x1, y1, x1+dx0, y1+dy0);
                    495:        if (attr & HEADFILL)
                    496:                fprintf(outfp, "c gs s gr f\n");
                    497:        else
                    498:                fprintf(outfp, "s\n");
                    499: }
                    500: 
                    501: spline(n, close, p)
                    502:        int     n, close;
                    503:        valtype *p;
                    504: {
                    505:        int i;
                    506: 
                    507:        for (i = 2*n; i > 2; i -= 2)
                    508:                fprintf(outfp,"%.5g %.5g%c",p[i].f,p[i+1].f,i%10==9 ?'\n':' ');
                    509:        fprintf(outfp, "%d   %.5g %.5g %.5g %.5g Sp %c",
                    510:                        n-1, p[2].f,p[3].f,p[0].f,p[1].f, close? 'c' : ' ');
                    511:        fill_or_stroke ();
                    512: }
                    513: 
                    514: pline(n, close, p, r)
                    515:        int     n;
                    516:        valtype *p;
                    517:        double  r;      /* "corner" radius */
                    518: {
                    519:        int     i;
                    520:        float   x, y;
                    521: 
                    522:        if (close && r > MINRAD) {
                    523:                fprintf(outfp, "%.5g %.5g\n",
                    524:                                x=(p[0].f+p[2].f)/2, y=(p[1].f+p[3].f)/2);
                    525:                for (i = 2*n; i > 0; i -= 2)
                    526:                        fprintf(outfp, "%.5g %.5g%c",
                    527:                                        p[i].f, p[i+1].f, i%8==7 ?'\n':' ');
                    528:                fprintf(outfp, "%.5g %d %.5g %.5g rL", r, n+1, x, y);
                    529:        }
                    530:        else {
                    531:                n -= close;
                    532:                for (i = 2*n; i > 0; i -= 2)
                    533:                        fprintf(outfp, "%.5g %.5g%c",
                    534:                                        p[i].f, p[i+1].f, i%8==7 ?'\n':' ');
                    535:                if (r > MINRAD)
                    536:                        fprintf(outfp, "%.5g %d %.5g %.5g rL",
                    537:                                        r, n, p[0].f, p[1].f);
                    538:                else
                    539:                        fprintf(outfp, "%d %.5g %.5g L", n, p[0].f, p[1].f);
                    540:                if (close)
                    541:                        fprintf(outfp, " c");
                    542:        }
                    543:        fill_or_stroke ();
                    544: }
                    545: 
                    546: ellipse(xc, yc, x0, y0, x1, y1, ang1, ang2, type)      /* general elliptical */
                    547:        double  xc, yc, x0, y0, x1, y1, ang1, ang2;     /* arc/sector routine */
                    548:        int     type;
                    549: {
                    550:        double  c, s, phi, r1, r2;
                    551:        int     iang1, iang2;
                    552: 
                    553:        iang1 = (int)(180 * (ang1 * M_1_PI) + 0.5);
                    554:        iang2 = (int)(180 * (ang2 * M_1_PI) + 0.5);
                    555: 
                    556: /* This finds the angle at which the ellipse is inclined to the axes; the */
                    557: /* most common case will have phi==0 or pi/2, and it seems worthwhile to  */
                    558: /* check for that case without doing all the trigonometric stuff below.   */
                    559: 
                    560:        if (y0 == 0 && x1 == 0 || x0 == 0 && y1 == 0) {
                    561:                phi = 0;
                    562:                r1 = fabs(x0);
                    563:                r2 = fabs(y1);
                    564:        }
                    565:        else {
                    566:                phi = atan2(x0*x0 + y0*y0 - x1*x1 - y1*y1, 2*(x0*x1 + y0*y1))/2;
                    567:                c = cos(phi);
                    568:                s = sin(phi);
                    569:                r1 = hypot(c*x0 + s*x1, c*y0 + s*y1);
                    570:                r2 = hypot(c*x1 - s*x0, c*y1 - s*y0);
                    571:        }
                    572:        if (fabs(r1-r2) < MINRAD)
                    573:                fprintf(outfp, "n %.5g %.5g %.5g %d %d arc",
                    574:                                xc, yc, (r1+r2)/2, iang1, iang2);
                    575:        else {
                    576:                /* note: if phi != 0, non-postScript displays need to call a */
                    577:                /*       special elliptical arc generation routine here:     */
                    578:                /*                                                           */
                    579:                /*              gen_ellipse(xc,yc,x0,y0,x1,y1,ang1,ang2)     */
                    580: 
                    581:                fprintf(outfp,"0 0 1 %d %d [%.5g %.5g %.5g %.5g %.5g %.5g] E",
                    582:                                  iang1, iang2, x0, y0, x1, y1,   xc, yc);
                    583:        }
                    584:        if (type == SECTOR)
                    585:                fprintf(outfp, " %.5g %.5g l c", xc, yc);
                    586:        fill_or_stroke();
                    587: }
                    588: 
                    589: extra_bs()
                    590: {
                    591:        fputc('\\', outfp);
                    592:        extra_chars++;
                    593: }
                    594: 
                    595: octal_char(c)
                    596:        char    c;
                    597: {
                    598:        if (pass_thru)
                    599:                extra_bs();
                    600:        fprintf(outfp,"\\%o", c);
                    601: }
                    602: 
                    603: char   escapes[] = "()\\";     /* chars needing to be escaped in PostScript */
                    604: 
                    605: escstr(s)
                    606:        char    *s;
                    607: {
                    608:        char    *ptr;
                    609: 
                    610:        fputc('(', outfp);
                    611:        while ((ptr = strpbrk(s,escapes)) != NULL) {
                    612:                while (s < ptr)
                    613:                        if (*s >= ' ' && *s <= '~')
                    614:                                fputc(*s++, outfp);
                    615:                        else
                    616:                                octal_char(*s++);
                    617:                if (pass_thru) {        /* troff changes \\ to \ */
                    618:                        extra_bs();
                    619:                        if (*s == '\\')         /* for a total of 3 extras! */
                    620:                                extra_bs();
                    621:                }
                    622:                fputc('\\', outfp);
                    623:                fputc(*s++, outfp);
                    624:        }
                    625:        while (*s)
                    626:                if (*s >= ' ' && *s <= '~')
                    627:                        fputc(*s++, outfp);
                    628:                else
                    629:                        octal_char(*s++);
                    630:        fputc(')', outfp);
                    631: }
                    632: 
                    633: spacecount(s)
                    634:        char    *s;
                    635: {
                    636:        int     count = 0;
                    637: 
                    638:        while (*s)
                    639:                if (*s++ == ' ') count++;
                    640:        
                    641:        return(count);
                    642: }
                    643: 
                    644: double lastx, lasty;
                    645: 
                    646: newlabel(type, str, font, x, y, size, w)
                    647:        char    *str;
                    648:        int     type, font;
                    649:        double  x, y, size, w;
                    650: {
                    651:        if (type & EQNTXT)
                    652:                puteqn(x, y, type, atoi(str));
                    653:        else {
                    654:                resetfont(font, size);
                    655:                escstr(str);
                    656:                fprintf(outfp," %d %.5g %.5g %.5g T\n",spacecount(str),w,x,y);
                    657:        }
                    658:        lastx = x+w;
                    659:        lasty = y;
                    660: }
                    661: 
                    662: addlabel(type, str, font, size, w)
                    663:        char    *str;
                    664:        int     type, font;
                    665:        double  size, w;
                    666: {
                    667:        if (type & EQNTXT)
                    668:                puteqn(lastx, lasty, type, atoi(str));
                    669:        else {
                    670:                resetfont(font, size);
                    671:                escstr(str);
                    672:                fprintf(outfp, " %d %.5g AT\n", spacecount(str), w);
                    673:        }
                    674:        lastx += w;
                    675: }
                    676: 
                    677: resetfont (font, size)
                    678:        int     font;
                    679:        double  size;
                    680: {
                    681:        if (font < 0) font = -font;
                    682:        if (size < 0) size = -size;
                    683:        if (font != psfont || size != pssize) {
                    684:                fprintf(outfp, "%s findfont %.5g scalefont setfont\n",
                    685:                                        mount[font]->name, size);
                    686:                if (!have_temp) {
                    687:                        psfont = font; pssize = size;
                    688:                }
                    689:        }
                    690: }
                    691: 
                    692: int
                    693: catfile(s)
                    694:        char *s;
                    695: {
                    696:        FILE *fp, *fopen();
                    697:        char buf[BUFSIZ];
                    698:        int count;
                    699: 
                    700:        if ((fp = fopen(s, "r")) == NULL) return(0);
                    701:        while ((count = fread(buf, sizeof(*buf), BUFSIZ, fp)) > 0)
                    702:                fwrite(buf, sizeof(*buf), count, outfp);
                    703:        fclose(fp);
                    704:        return(1);
                    705: }
                    706: 
                    707: int
                    708: transparent(fp)
                    709:        FILE *fp;
                    710: {
                    711:        char buf[BUFSIZ];
                    712: 
                    713:        while (fgets(buf, BUFSIZ, fp) != NULL) {
                    714:                putchar('\\'); putchar('!');
                    715:                fputs(buf, stdout);
                    716:        }
                    717: }
                    718: /*
                    719:  *     include an encapsulated postscript file.  Apply any scaling and
                    720:  *     transformation specified by p.
                    721:  */
                    722: puteps(o)
                    723:        obj     *o;
                    724: {
                    725:        FILE    *fp;
                    726: 
                    727:        if ((fp = fopen(o->o_val[N_VAL-1].p, "r")) == NULL) {
                    728:                yyerror("can't open EPS file %s", o->o_val[N_VAL-1].p);
                    729:                return;
                    730:        }
                    731:        pic_include(fp, outfp, 1, o);
                    732:        fclose(fp);
                    733: }

unix.superglobalmegacorp.com

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