URI:
       tprint.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tprint.c (6263B)
       ---
            1 #include <stdio.h>
            2 #include <math.h>
            3 #include "pic.h"
            4 #include "y.tab.h"
            5 
            6 void dotext(obj *);
            7 void dotline(double, double, double, double, int, double);
            8 void dotbox(double, double, double, double, int, double);
            9 void ellipse(double, double, double, double);
           10 void circle(double, double, double);
           11 void arc(double, double, double, double, double, double);
           12 void arrow(double, double, double, double, double, double, double, int);
           13 void line(double, double, double, double);
           14 void box(double, double, double, double);
           15 void spline(double x, double y, double n, ofloat *p, int dashed, double ddval);
           16 void move(double, double);
           17 void troff(char *);
           18 void dot(void);
           19 void fillstart(double), fillend(int vis, int noedge);
           20 
           21 void print(void)
           22 {
           23         obj *p;
           24         int i, j, k, m;
           25         int fill, vis, invis;
           26         double x0, y0, x1, y1, ox, oy, dx, dy, ndx, ndy;
           27 
           28         x1 = y1 = 0.0; /* Botch? (gcc) */
           29 
           30         for (i = 0; i < nobj; i++) {
           31                 p = objlist[i];
           32                 ox = p->o_x;
           33                 oy = p->o_y;
           34                 if (p->o_count >= 1)
           35                         x1 = p->o_val[0];
           36                 if (p->o_count >= 2)
           37                         y1 = p->o_val[1];
           38                 m = p->o_mode;
           39                 fill = p->o_attr & FILLBIT;
           40                 invis = p->o_attr & INVIS;
           41                 vis = !invis;
           42                 switch (p->o_type) {
           43                 case TROFF:
           44                         troff(text[p->o_nt1].t_val);
           45                         break;
           46                 case BOX:
           47                 case BLOCK:
           48                         x0 = ox - x1 / 2;
           49                         y0 = oy - y1 / 2;
           50                         x1 = ox + x1 / 2;
           51                         y1 = oy + y1 / 2;
           52                         if (fill) {
           53                                 move(x0, y0);
           54                                 fillstart(p->o_fillval);
           55                         }
           56                         if (p->o_type == BLOCK)
           57                                 ;        /* nothing at all */
           58                         else if (invis && !fill)
           59                                 ;        /* nothing at all */
           60                         else if (p->o_attr & (DOTBIT|DASHBIT))
           61                                 dotbox(x0, y0, x1, y1, p->o_attr, p->o_ddval);
           62                         else
           63                                 box(x0, y0, x1, y1);
           64                         if (fill)
           65                                 fillend(vis, fill);
           66                         move(ox, oy);
           67                         dotext(p);        /* if there are any text strings */
           68                         if (ishor(m))
           69                                 move(isright(m) ? x1 : x0, oy);        /* right side */
           70                         else
           71                                 move(ox, isdown(m) ? y0 : y1);        /* bottom */
           72                         break;
           73                 case BLOCKEND:
           74                         break;
           75                 case CIRCLE:
           76                         if (fill)
           77                                 fillstart(p->o_fillval);
           78                         if (vis || fill)
           79                                 circle(ox, oy, x1);
           80                         if (fill)
           81                                 fillend(vis, fill);
           82                         move(ox, oy);
           83                         dotext(p);
           84                         if (ishor(m))
           85                                 move(ox + isright(m) ? x1 : -x1, oy);
           86                         else
           87                                 move(ox, oy + isup(m) ? x1 : -x1);
           88                         break;
           89                 case ELLIPSE:
           90                         if (fill)
           91                                 fillstart(p->o_fillval);
           92                         if (vis || fill)
           93                                 ellipse(ox, oy, x1, y1);
           94                         if (fill)
           95                                 fillend(vis, fill);
           96                         move(ox, oy);
           97                         dotext(p);
           98                         if (ishor(m))
           99                                 move(ox + isright(m) ? x1 : -x1, oy);
          100                         else
          101                                 move(ox, oy - isdown(m) ? y1 : -y1);
          102                         break;
          103                 case ARC:
          104                         if (fill) {
          105                                 move(ox, oy);
          106                                 fillstart(p->o_fillval);
          107                         }
          108                         if (p->o_attr & HEAD1)
          109                                 arrow(x1 - (y1 - oy), y1 + (x1 - ox),
          110                                       x1, y1, p->o_val[4], p->o_val[5], p->o_val[5]/p->o_val[6]/2, p->o_nhead);
          111                         if (invis && !fill)
          112                                 /* probably wrong when it's cw */
          113                                 move(x1, y1);
          114                         else
          115                                 arc(ox, oy, x1, y1, p->o_val[2], p->o_val[3]);
          116                         if (p->o_attr & HEAD2)
          117                                 arrow(p->o_val[2] + p->o_val[3] - oy, p->o_val[3] - (p->o_val[2] - ox),
          118                                       p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5], -p->o_val[5]/p->o_val[6]/2, p->o_nhead);
          119                         if (fill)
          120                                 fillend(vis, fill);
          121                         if (p->o_attr & CW_ARC)
          122                                 move(x1, y1);        /* because drawn backwards */
          123                         move(ox, oy);
          124                         dotext(p);
          125                         break;
          126                 case LINE:
          127                 case ARROW:
          128                 case SPLINE:
          129                         if (fill) {
          130                                 move(ox, oy);
          131                                 fillstart(p->o_fillval);
          132                         }
          133                         if (vis && p->o_attr & HEAD1)
          134                                 arrow(ox + p->o_val[5], oy + p->o_val[6], ox, oy, p->o_val[2], p->o_val[3], 0.0, p->o_nhead);
          135                         if (invis && !fill)
          136                                 move(x1, y1);
          137                         else if (p->o_type == SPLINE)
          138                                 spline(ox, oy, p->o_val[4], &p->o_val[5], p->o_attr & (DOTBIT|DASHBIT), p->o_ddval);
          139                         else {
          140                                 dx = ox;
          141                                 dy = oy;
          142                                 for (k=0, j=5; k < p->o_val[4]; k++, j += 2) {
          143                                         ndx = dx + p->o_val[j];
          144                                         ndy = dy + p->o_val[j+1];
          145                                         if (p->o_attr & (DOTBIT|DASHBIT))
          146                                                 dotline(dx, dy, ndx, ndy, p->o_attr, p->o_ddval);
          147                                         else
          148                                                 line(dx, dy, ndx, ndy);
          149                                         dx = ndx;
          150                                         dy = ndy;
          151                                 }
          152                         }
          153                         if (vis && p->o_attr & HEAD2) {
          154                                 dx = ox;
          155                                 dy = oy;
          156                                 for (k = 0, j = 5; k < p->o_val[4] - 1; k++, j += 2) {
          157                                         dx += p->o_val[j];
          158                                         dy += p->o_val[j+1];
          159                                 }
          160                                 arrow(dx, dy, x1, y1, p->o_val[2], p->o_val[3], 0.0, p->o_nhead);
          161                         }
          162                         if (fill)
          163                                 fillend(vis, fill);
          164                         move((ox + x1)/2, (oy + y1)/2);        /* center */
          165                         dotext(p);
          166                         break;
          167                 case MOVE:
          168                         move(ox, oy);
          169                         break;
          170                 case TEXT:
          171                         move(ox, oy);
          172                         if (vis)
          173                                 dotext(p);
          174                         break;
          175                 }
          176         }
          177 }
          178 
          179 void dotline(double x0, double y0, double x1, double y1, int ddtype, double ddval) /* dotted line */
          180 {
          181         static double prevval = 0.05;        /* 20 per inch by default */
          182         int i, numdots;
          183         double a, b, dx, dy;
          184 
          185         b = 0.0; /* Botch? (gcc) */
          186 
          187         if (ddval == 0)
          188                 ddval = prevval;
          189         prevval = ddval;
          190         /* don't save dot/dash value */
          191         dx = x1 - x0;
          192         dy = y1 - y0;
          193         if (ddtype & DOTBIT) {
          194                 numdots = sqrt(dx*dx + dy*dy) / prevval + 0.5;
          195                 if (numdots > 0)
          196                         for (i = 0; i <= numdots; i++) {
          197                                 a = (double) i / (double) numdots;
          198                                 move(x0 + (a * dx), y0 + (a * dy));
          199                                 dot();
          200                         }
          201         } else if (ddtype & DASHBIT) {
          202                 double d, dashsize, spacesize;
          203                 d = sqrt(dx*dx + dy*dy);
          204                 if (d <= 2 * prevval) {
          205                         line(x0, y0, x1, y1);
          206                         return;
          207                 }
          208                 numdots = d / (2 * prevval) + 1;        /* ceiling */
          209                 dashsize = prevval;
          210                 spacesize = (d - numdots * dashsize) / (numdots - 1);
          211                 for (i = 0; i < numdots-1; i++) {
          212                         a = i * (dashsize + spacesize) / d;
          213                         b = a + dashsize / d;
          214                         line(x0 + (a*dx), y0 + (a*dy), x0 + (b*dx), y0 + (b*dy));
          215                         a = b;
          216                         b = a + spacesize / d;
          217                         move(x0 + (a*dx), y0 + (a*dy));
          218                 }
          219                 line(x0 + (b * dx), y0 + (b * dy), x1, y1);
          220         }
          221         prevval = 0.05;
          222 }
          223 
          224 void dotbox(double x0, double y0, double x1, double y1, int ddtype, double ddval)        /* dotted or dashed box */
          225 {
          226         dotline(x0, y0, x1, y0, ddtype, ddval);
          227         dotline(x1, y0, x1, y1, ddtype, ddval);
          228         dotline(x1, y1, x0, y1, ddtype, ddval);
          229         dotline(x0, y1, x0, y0, ddtype, ddval);
          230 }
          231 
          232 void dotext(obj *p)        /* print text strings of p in proper vertical spacing */
          233 {
          234         int i, nhalf;
          235         void label(char *, int, int);
          236 
          237         nhalf = p->o_nt2 - p->o_nt1 - 1;
          238         for (i = p->o_nt1; i < p->o_nt2; i++) {
          239                 label(text[i].t_val, text[i].t_type, nhalf);
          240                 nhalf -= 2;
          241         }
          242 }