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