URI:
       tlinegen.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
       ---
       tlinegen.c (5351B)
       ---
            1 #include <stdio.h>
            2 #include <math.h>
            3 #include "pic.h"
            4 #include "y.tab.h"
            5 
            6 obj *linegen(int type)
            7 {
            8         static double prevdx = HT;
            9         static double prevdy = 0;
           10         static double prevw = HT10;
           11         static double prevh = HT5;
           12         int i, j, some, head, ddtype, invis, chop, battr, with;
           13         double ddval, chop1, chop2, x0, y0, x1, y1;
           14         double fillval = 0;
           15         double theta;
           16         double defx, defy, xwith, ywith;
           17         obj *p, *ppos;
           18         static int xtab[] = { 1, 0, -1, 0 };        /* R=0, U=1, L=2, D=3 */
           19         static int ytab[] = { 0, 1, 0, -1 };
           20         double dx[500], dy[500];
           21         int ndxy;
           22         double nx, ny;
           23         Attr *ap;
           24 
           25         nx = curx;
           26         ny = cury;
           27         defx = getfval("linewid");
           28         defy = getfval("lineht");
           29         prevh = getfval("arrowht");
           30         prevw = getfval("arrowwid");
           31         dx[0] = dy[0] = ndxy = some = head = invis = battr = with = 0;
           32         chop = chop1 = chop2 = 0;
           33         ddtype = ddval = xwith = ywith = 0;
           34         for (i = 0; i < nattr; i++) {
           35                 ap = &attr[i];
           36                 switch (ap->a_type) {
           37                 case TEXTATTR:
           38                         savetext(ap->a_sub, ap->a_val.p);
           39                         break;
           40                 case HEAD:
           41                         head += ap->a_val.i;
           42                         break;
           43                 case INVIS:
           44                         invis = INVIS;
           45                         break;
           46                 case NOEDGE:
           47                         battr |= NOEDGEBIT;
           48                         break;
           49                 case DOT:
           50                 case DASH:
           51                         ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT;
           52                         if (ap->a_sub == DEFAULT)
           53                                 ddval = getfval("dashwid");
           54                         else
           55                                 ddval = ap->a_val.f;
           56                         break;
           57                 case SAME:
           58                         dx[ndxy] = prevdx;
           59                         dy[ndxy] = prevdy;
           60                         some++;
           61                         break;
           62                 case LEFT:
           63                         dx[ndxy] -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
           64                         some++;
           65                         hvmode = L_DIR;
           66                         break;
           67                 case RIGHT:
           68                         dx[ndxy] += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
           69                         some++;
           70                         hvmode = R_DIR;
           71                         break;
           72                 case UP:
           73                         dy[ndxy] += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
           74                         some++;
           75                         hvmode = U_DIR;
           76                         break;
           77                 case DOWN:
           78                         dy[ndxy] -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
           79                         some++;
           80                         hvmode = D_DIR;
           81                         break;
           82                 case HEIGHT:        /* length of arrowhead */
           83                         prevh = ap->a_val.f;
           84                         break;
           85                 case WIDTH:        /* width of arrowhead */
           86                         prevw = ap->a_val.f;
           87                         break;
           88                 case TO:
           89                         if (some) {
           90                                 nx += dx[ndxy];
           91                                 ny += dy[ndxy];
           92                                 ndxy++;
           93                                 dx[ndxy] = dy[ndxy] = some = 0;
           94                         }
           95                         ppos = attr[i].a_val.o;
           96                         dx[ndxy] = ppos->o_x - nx;
           97                         dy[ndxy] = ppos->o_y - ny;
           98                         some++;
           99                         break;
          100                 case BY:
          101                         if (some) {
          102                                 nx += dx[ndxy];
          103                                 ny += dy[ndxy];
          104                                 ndxy++;
          105                                 dx[ndxy] = dy[ndxy] = some = 0;
          106                         }
          107                         ppos = ap->a_val.o;
          108                         dx[ndxy] = ppos->o_x;
          109                         dy[ndxy] = ppos->o_y;
          110                         some++;
          111                         break;
          112                 case THEN:        /* turn off any previous accumulation */
          113                         if (some) {
          114                                 nx += dx[ndxy];
          115                                 ny += dy[ndxy];
          116                                 ndxy++;
          117                                 dx[ndxy] = dy[ndxy] = some = 0;
          118                         }
          119                         break;
          120                 case FROM:
          121                 case AT:
          122                         ppos = ap->a_val.o;
          123                         nx = curx = ppos->o_x;
          124                         ny = cury = ppos->o_y;
          125                         break;
          126                 case WITH:
          127                         with = ap->a_val.i;
          128                         break;
          129                 case CHOP:
          130                         if (ap->a_sub != PLACENAME) {
          131                                 if( chop == 0)
          132                                         chop1 = chop2 = ap->a_val.f;
          133                                 else
          134                                         chop2 = ap->a_val.f;
          135                         }
          136                         break;
          137                 case FILL:
          138                         battr |= FILLBIT;
          139                         if (ap->a_sub == DEFAULT)
          140                                 fillval = getfval("fillval");
          141                         else
          142                                 fillval = ap->a_val.f;
          143                         break;
          144                 }
          145         }
          146         if (with) {        /* this doesn't work at all */
          147                 switch (with) {
          148                 case CENTER:
          149                         xwith = (dx[1] - dx[0]) / 2; ywith = (dy[1] - dy[0]) / 2; break;
          150                 }
          151                 for (i = 0; i < ndxy; i++) {
          152                         dx[i] -= xwith;
          153                         dy[i] -= ywith;
          154                 }
          155                 curx += xwith;
          156                 cury += ywith;
          157         }
          158         if (some) {
          159                 nx += dx[ndxy];
          160                 ny += dy[ndxy];
          161                 ndxy++;
          162                 defx = dx[ndxy-1];
          163                 defy = dy[ndxy-1];
          164         } else {
          165                 defx *= xtab[hvmode];
          166                 defy *= ytab[hvmode];
          167                 dx[ndxy] = defx;
          168                 dy[ndxy] = defy;
          169                 ndxy++;
          170                 nx += defx;
          171                 ny += defy;
          172         }
          173         prevdx = defx;
          174         prevdy = defy;
          175         if (chop) {
          176                 if (chop == 1 && chop1 == 0)        /* just said "chop", so use default */
          177                         chop1 = chop2 = getfval("circlerad");
          178                 theta = atan2(dy[0], dx[0]);
          179                 x0 = chop1 * cos(theta);
          180                 y0 = chop1 * sin(theta);
          181                 curx += x0;
          182                 cury += y0;
          183                 dx[0] -= x0;
          184                 dy[0] -= y0;
          185 
          186                 theta = atan2(dy[ndxy-1], dx[ndxy-1]);
          187                 x1 = chop2 * cos(theta);
          188                 y1 = chop2 * sin(theta);
          189                 nx -= x1;
          190                 ny -= y1;
          191                 dx[ndxy-1] -= x1;
          192                 dy[ndxy-1] -= y1;
          193                 dprintf("chopping %g %g %g %g; cur=%g,%g end=%g,%g\n",
          194                         x0, y0, x1, y1, curx, cury, nx, ny);
          195         }
          196         p = makenode(type, 5 + 2 * ndxy);
          197         curx = p->o_val[0] = nx;
          198         cury = p->o_val[1] = ny;
          199         if (head || type == ARROW) {
          200                 p->o_nhead = getfval("arrowhead");
          201                 p->o_val[2] = prevw;
          202                 p->o_val[3] = prevh;
          203                 if (head == 0)
          204                         head = HEAD2;        /* default arrow head */
          205         }
          206         p->o_attr = head | invis | ddtype | battr;
          207         p->o_fillval = fillval;
          208         p->o_val[4] = ndxy;
          209         nx = p->o_x;
          210         ny = p->o_y;
          211         for (i = 0, j = 5; i < ndxy; i++, j += 2) {
          212                 p->o_val[j] = dx[i];
          213                 p->o_val[j+1] = dy[i];
          214                 if (type == LINE || type == ARROW)
          215                         extreme(nx += dx[i], ny += dy[i]);
          216                 else if (type == SPLINE && i < ndxy-1) {
          217                         /* to compute approx extreme of spline at p,
          218                         /* compute midway between p-1 and p+1,
          219                         /* then go 3/4 from there to p */
          220                         double ex, ey, xi, yi, xi1, yi1;
          221                         xi = nx + dx[i]; yi = ny + dy[i];        /* p */
          222                         xi1 = xi + dx[i+1]; yi1 = yi + dy[i+1];        /* p+1 */
          223                         ex = (nx+xi1)/2; ey = (ny+yi1)/2;        /* midway */
          224                         ex += 0.75*(xi-ex); ey += 0.75*(yi-ey);
          225                         extreme(ex, ey);
          226                         nx = xi; ny = yi;
          227                 }
          228 
          229         }
          230         p->o_ddval = ddval;
          231         if (dbg) {
          232                 printf("S or L from %g %g to %g %g with %d elements:\n", p->o_x, p->o_y, curx, cury, ndxy);
          233                 for (i = 0, j = 5; i < ndxy; i++, j += 2)
          234                         printf("%g %g\n", p->o_val[j], p->o_val[j+1]);
          235         }
          236         extreme(p->o_x, p->o_y);
          237         extreme(curx, cury);
          238         return(p);
          239 }