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

1.1       root        1: #include <stdio.h>
                      2: #include <math.h>
                      3: #include "pic.h"
                      4: extern int dbg;
                      5: 
                      6: #define        abs(n)  (n >= 0 ? n : -(n))
                      7: #define        max(x,y)        ((x)>(y) ? (x) : (y))
                      8: 
                      9: char   *textshift = "\\v'.2m'";        /* move text this far down */
                     10: 
                     11: /* scaling stuff defined by s command as X0,Y0 to X1,Y1 */
                     12: /* output dimensions set by -l,-w options to 0,0 to hmax, vmax */
                     13: /* default output is 6x6 inches */
                     14: 
                     15: 
                     16: double xscale;
                     17: double yscale;
                     18: 
                     19: double hpos    = 0;    /* current horizontal position in output coordinate system */
                     20: double vpos    = 0;    /* current vertical position; 0 is top of page */
                     21: 
                     22: double htrue   = 0;    /* where we really are */
                     23: double vtrue   = 0;
                     24: 
                     25: double X0, Y0;         /* left bottom of input */
                     26: double X1, Y1;         /* right top of input */
                     27: 
                     28: double hmax;           /* right end of output */
                     29: double vmax;           /* top of output (down is positive) */
                     30: 
                     31: extern double  deltx;
                     32: extern double  delty;
                     33: extern double  xmin, ymin, xmax, ymax;
                     34: 
                     35: double xconv(double), yconv(double), xsc(double), ysc(double);
                     36: void   space(double, double, double, double);
                     37: void   hgoto(double), vgoto(double), hmot(double), vmot(double);
                     38: void   move(double, double), movehv(double, double);
                     39: void   cont(double, double);
                     40: 
                     41: void openpl(char *s)   /* initialize device; s is residue of .PS invocation line */
                     42: {
                     43:        double maxw, maxh, ratio = 1;
                     44:        double odeltx = deltx, odelty = delty;
                     45: 
                     46:        hpos = vpos = 0;
                     47:        maxw = getfval("maxpswid");
                     48:        maxh = getfval("maxpsht");
                     49:        if (deltx > maxw) {     /* shrink horizontal */
                     50:                ratio = maxw / deltx;
                     51:                deltx *= ratio;
                     52:                delty *= ratio;
                     53:        }
                     54:        if (delty > maxh) {     /* shrink vertical */
                     55:                ratio = maxh / delty;
                     56:                deltx *= ratio;
                     57:                delty *= ratio;
                     58:        }
                     59:        if (ratio != 1) {
                     60:                fprintf(stderr, "pic: %g X %g picture shrunk to", odeltx, odelty);
                     61:                fprintf(stderr, " %g X %g\n", deltx, delty);
                     62:        }
                     63:        space(xmin, ymin, xmax, ymax);
                     64:        printf("... %g %g %g %g\n", xmin, ymin, xmax, ymax);
                     65:        printf("... %.3fi %.3fi %.3fi %.3fi\n",
                     66:                xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax));
                     67:        printf(".nr 00 \\n(.u\n");
                     68:        printf(".nf\n");
                     69:        printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s);
                     70:                /* assumes \n comes as part of s */
                     71: }
                     72: 
                     73: void space(double x0, double y0, double x1, double y1) /* set limits of page */
                     74: {
                     75:        X0 = x0;
                     76:        Y0 = y0;
                     77:        X1 = x1;
                     78:        Y1 = y1;
                     79:        xscale = deltx == 0.0 ? 1.0 : deltx / (X1-X0);
                     80:        yscale = delty == 0.0 ? 1.0 : delty / (Y1-Y0);
                     81: }
                     82: 
                     83: double xconv(double x) /* convert x from external to internal form */
                     84: {
                     85:        return (x-X0) * xscale;
                     86: }
                     87: 
                     88: double xsc(double x)   /* convert x from external to internal form, scaling only */
                     89: {
                     90: 
                     91:        return (x) * xscale;
                     92: }
                     93: 
                     94: double yconv(double y) /* convert y from external to internal form */
                     95: {
                     96:        return (Y1-y) * yscale;
                     97: }
                     98: 
                     99: double ysc(double y)   /* convert y from external to internal form, scaling only */
                    100: {
                    101:        return (y) * yscale;
                    102: }
                    103: 
                    104: void closepl(int type) /* clean up after finished */
                    105: {
                    106:        movehv(0.0, 0.0);       /* get back to where we started */
                    107:        if (type == 'F')
                    108:                printf(".PF\n");
                    109:        else {
                    110:                printf(".sp 1+%.3fi\n", yconv(ymin));
                    111:                printf(".PE\n");
                    112:        }
                    113:        printf(".if \\n(00 .fi\n");
                    114: }
                    115: 
                    116: void move(double x, double y)  /* go to position x, y in external coords */
                    117: {
                    118:        hgoto(xconv(x));
                    119:        vgoto(yconv(y));
                    120: }
                    121: 
                    122: void movehv(double h, double v)        /* go to internal position h, v */
                    123: {
                    124:        hgoto(h);
                    125:        vgoto(v);
                    126: }
                    127: 
                    128: void hmot(double n)    /* generate n units of horizontal motion */
                    129: {
                    130:        hpos += n;
                    131: }
                    132: 
                    133: void vmot(double n)    /* generate n units of vertical motion */
                    134: {
                    135:        vpos += n;
                    136: }
                    137: 
                    138: void hgoto(double n)
                    139: {
                    140:        hpos = n;
                    141: }
                    142: 
                    143: void vgoto(double n)
                    144: {
                    145:        vpos = n;
                    146: }
                    147: 
                    148: double fabs(double x)
                    149: {
                    150:        return x < 0 ? -x : x;
                    151: }
                    152: 
                    153: void hvflush(void)     /* get to proper point for output */
                    154: {
                    155:        if (fabs(hpos-htrue) >= 0.0005) {
                    156:                printf("\\h'%.3fi'", hpos - htrue);
                    157:                htrue = hpos;
                    158:        }
                    159:        if (fabs(vpos-vtrue) >= 0.0005) {
                    160:                printf("\\v'%.3fi'", vpos - vtrue);
                    161:                vtrue = vpos;
                    162:        }
                    163: }
                    164: 
                    165: void flyback(void)     /* return to upper left corner (entry point) */
                    166: {
                    167:        printf(".sp -1\n");
                    168:        htrue = vtrue = 0;
                    169: }
                    170: 
                    171: void printlf(int n, char *f)
                    172: {
                    173:        if (f)
                    174:                printf(".lf %d %s\n", n, f);
                    175:        else
                    176:                printf(".lf %d\n", n);
                    177: }
                    178: 
                    179: void troff(char *s)    /* output troff right here */
                    180: {
                    181:        printf("%s\n", s);
                    182: }
                    183: 
                    184: void label(char *s, int t, int nh)     /* text s of type t nh half-lines up */
                    185: {
                    186:        int q;
                    187:        char *p;
                    188: 
                    189:        if (!s)
                    190:                return;
                    191:        hvflush();
                    192:        dprintf("label: %s %o %d\n", s, t, nh);
                    193:        printf("%s", textshift);        /* shift down and left */
                    194:        if (t & ABOVE)
                    195:                nh++;
                    196:        else if (t & BELOW)
                    197:                nh--;
                    198:        if (nh)
                    199:                printf("\\v'%du*\\n(.vu/2u'", -nh);
                    200:        /* just in case the text contains a quote: */
                    201:        q = 0;
                    202:        for (p = s; *p; p++)
                    203:                if (*p == '\'') {
                    204:                        q = 1;
                    205:                        break;
                    206:                }
                    207:        t &= ~(ABOVE|BELOW);
                    208:        if (t & LJUST) {
                    209:                printf("%s", s);
                    210:        } else if (t & RJUST) {
                    211:                if (q)
                    212:                        printf("\\h\\(ts-\\w\\(ts%s\\(tsu\\(ts%s", s, s);
                    213:                else
                    214:                        printf("\\h'-\\w'%s'u'%s", s, s);
                    215:        } else {        /* CENTER */
                    216:                if (q)
                    217:                        printf("\\h\\(ts-\\w\\(ts%s\\(tsu/2u\\(ts%s", s, s);
                    218:                else
                    219:                        printf("\\h'-\\w'%s'u/2u'%s", s, s);
                    220:        }
                    221:        printf("\n");
                    222:        flyback();
                    223: }
                    224: 
                    225: void line(double x0, double y0, double x1, double y1)  /* draw line from x0,y0 to x1,y1 */
                    226: {
                    227:        move(x0, y0);
                    228:        cont(x1, y1);
                    229: }
                    230: 
                    231: void arrow(double x0, double y0, double x1, double y1, double w, double h,
                    232:         double ang, int nhead)         /* draw arrow (without shaft) */
                    233: {
                    234:        double alpha, rot, drot, hyp;
                    235:        double dx, dy;
                    236:        int i;
                    237: 
                    238:        rot = atan2(w / 2, h);
                    239:        hyp = sqrt(w/2 * w/2 + h * h);
                    240:        alpha = atan2(y1-y0, x1-x0) + ang;
                    241:        if (nhead < 2)
                    242:                nhead = 2;
                    243:        dprintf("rot=%g, hyp=%g, alpha=%g\n", rot, hyp, alpha);
                    244:        for (i = nhead-1; i >= 0; i--) {
                    245:                drot = 2 * rot / (double) (nhead-1) * (double) i;
                    246:                dx = hyp * cos(alpha + PI - rot + drot);
                    247:                dy = hyp * sin(alpha + PI - rot + drot);
                    248:                dprintf("dx,dy = %g,%g\n", dx, dy);
                    249:                line(x1+dx, y1+dy, x1, y1);
                    250:        }
                    251: }
                    252: 
                    253: double lastgray = 0;
                    254: 
                    255: void fillstart(double v)       /* this works only for postscript, obviously. */
                    256: {                              /* uses drechsler's dpost conventions... */
                    257:        hvflush();
                    258:        printf("\\X'BeginObject %g setgray'\n", v);
                    259:        lastgray = v;
                    260:        flyback();
                    261: }
                    262: 
                    263: void fillend(int vis, int fill)
                    264: {
                    265:        hvflush();
                    266:        printf("\\X'EndObject gsave eofill grestore %g setgray %s'\n",
                    267:                !vis ? lastgray : 0.0,
                    268:                vis ? "stroke" : "");
                    269:        /* for dashed: [50] 0 setdash just before stroke. */
                    270:        lastgray = 0;
                    271:        flyback();
                    272: }
                    273: 
                    274: void box(double x0, double y0, double x1, double y1)
                    275: {
                    276:        move(x0, y0);
                    277:        cont(x0, y1);
                    278:        cont(x1, y1);
                    279:        cont(x1, y0);
                    280:        cont(x0, y0);
                    281: }
                    282: 
                    283: void cont(double x, double y)  /* continue line from here to x,y */
                    284: {
                    285:        double h1, v1;
                    286:        double dh, dv;
                    287: 
                    288:        h1 = xconv(x);
                    289:        v1 = yconv(y);
                    290:        dh = h1 - hpos;
                    291:        dv = v1 - vpos;
                    292:        hvflush();
                    293:        printf("\\D'l%.3fi %.3fi'\n", dh, dv);
                    294:        flyback();      /* expensive */
                    295:        hpos = h1;
                    296:        vpos = v1;
                    297: }
                    298: 
                    299: void circle(double x, double y, double r)
                    300: {
                    301:        move(x-r, y);
                    302:        hvflush();
                    303:        printf("\\D'c%.3fi'\n", xsc(2 * r));
                    304:        flyback();
                    305: }
                    306: 
                    307: void spline(double x, double y, double n, ofloat *p, int dashed, double ddval)
                    308: {
                    309:        int i;
                    310:        double dx, dy;
                    311:        double xerr, yerr;
                    312: 
                    313:        move(x, y);
                    314:        hvflush();
                    315:        xerr = yerr = 0.0;
                    316:        printf("\\D'~");
                    317:        for (i = 0; i < 2 * n; i += 2) {
                    318:                dx = xsc(xerr += p[i]);
                    319:                xerr -= dx/xscale;
                    320:                dy = ysc(yerr += p[i+1]);
                    321:                yerr -= dy/yscale;
                    322:                printf(" %.3fi %.3fi", dx, -dy);        /* WATCH SIGN */
                    323:        }
                    324:        printf("'\n");
                    325:        flyback();
                    326: }
                    327: 
                    328: void ellipse(double x, double y, double r1, double r2)
                    329: {
                    330:        double ir1, ir2;
                    331: 
                    332:        move(x-r1, y);
                    333:        hvflush();
                    334:        ir1 = xsc(r1);
                    335:        ir2 = ysc(r2);
                    336:        printf("\\D'e%.3fi %.3fi'\n", 2 * ir1, 2 * abs(ir2));
                    337:        flyback();
                    338: }
                    339: 
                    340: void arc(double x, double y, double x0, double y0, double x1, double y1)       /* draw arc with center x,y */
                    341: {
                    342: 
                    343:        move(x0, y0);
                    344:        hvflush();
                    345:        printf("\\D'a%.3fi %.3fi %.3fi %.3fi'\n",
                    346:                xsc(x-x0), -ysc(y-y0), xsc(x1-x), -ysc(y1-y));  /* WATCH SIGNS */
                    347:        flyback();
                    348: }
                    349: 
                    350: void dot(void) {
                    351:        hvflush();
                    352:        /* what character to draw here depends on what's available. */
                    353:        /* on the 202, l. is good but small. */
                    354:        /* in general, use a smaller, shifted period and hope */
                    355: 
                    356:        printf("\\&\\f1\\h'-.1m'\\v'.03m'\\s-3.\\s+3\\fP\n");
                    357:        flyback();
                    358: }

unix.superglobalmegacorp.com

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