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