home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / hershey / part1 / hershey.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  11.2 KB  |  410 lines

  1. #include "cgksincl.h"
  2. #include <stdio.h>
  3.  
  4. #ifndef TRUE
  5. #define TRUE 1
  6. #define FALSE 0
  7. #endif
  8.  
  9. /*
  10.  * hershey.c   Display all of the Hershey font data in a font file
  11.  *
  12.  * This sample program is intended more so the user can see how the
  13.  * font data is read and used in an (admittedly minimal) application,
  14.  * than as a useable program.
  15.  *
  16.  * Its function is to display all of the hershey font characters on-screen,
  17.  * in a format 8 characters across and 8 vertical.
  18.  *
  19.  * usage:
  20.  *    hershey <device> <fontfile>
  21.  *
  22.  *       where <device> is a supported device ('c' for pc-cga is all
  23.  *                      in this version)
  24.  *             <fontfile> is the name of a hershey font file, e.g.
  25.  *                      hersh.oc1
  26.  *
  27.  * Translated from Fortran to C and GKS (that's why it looks wierd!)
  28.  *    (PRIOR Data Sciences non-ANSI GKS binding used here. Sorry!
  29.  *     Somebody else is welcome to translate to the ANSI binding)
  30.  *
  31.  */
  32.  
  33. /*
  34.      Translated by Pete Holzmann
  35.          Octopus Enterprises
  36.          19611 La Mar Court
  37.          Cupertino, CA 95014
  38.  
  39.       Original...  
  40.      .. By James Hurt when with
  41.      ..    Deere and Company
  42.      ..    John Deere Road
  43.      ..    Moline, IL 61265
  44.  
  45.      .. now with Cognition, Inc.
  46.      ..          900 Technology Park Drive
  47.      ..          Billerica, MA 01821
  48. */
  49.  
  50. /* local variables */
  51.    /* the next variables set the percent-of-screen used for each
  52.       character. 'colmax' should be left at 100. */
  53.  
  54.       float deltac = 12.5, deltar = 12.5, colmax = 100.0;
  55.  
  56.        FILE    *INfile,*OUTfile,*fopen(); /* some files */
  57.  
  58.       /* some variables to record the largest bounding rectangle of
  59.          the displayed characters. Printed when all finished. */
  60.  
  61.       int minx = 999,miny = 999,maxx=-999,maxy=-999;
  62.  
  63. /*    .. font data file name */
  64.       char name[80];
  65.  
  66. /* a forward referenced function */
  67.       void jnumbr();
  68.  
  69.    float aspect = 1.2;  /* PC graphics screen aspect ratio */
  70.  
  71. /* GKS local variables */
  72.  
  73.    int cga();           /* device initializer function */
  74.     int    (*wsinitf)();  /* pointer to the initializer function */
  75.     Ws_id   wss_xxxx;    /* workstation id (an int) */
  76.     Int     wstyp;         /* ws type, and some vars */
  77.     Drect    maxsurf;       /* max device surface rectangle */
  78.     Int    rastunit[2];   /* device surface in raster units */
  79.  
  80.     Wc    p1[2];            /* two world coordinates */
  81.  
  82. /* world coordinate windows */
  83.     Wrect    wrect  = {-17,-17,17,17};
  84. /* NDC coordinate viewport and windows */
  85.     Nrect    nrect = {0.0, 0.0, 1.0, 1.0};
  86. /* DC coordinate viewport */
  87.     Drect    drect = {0.0, 0.0, 319.0, 199.0}; /* work area */
  88.  
  89.  
  90. /*
  91.  * scanint: a function to scan an integer, using n characters of
  92.  *          the input file, ignoring newlines. (scanf won't work
  93.  *          because it also ignores blanks)
  94.  */
  95. int scanint(file,n)
  96. FILE *file;
  97. int n;
  98. {
  99. char buf[20];
  100. int i,c;
  101.  
  102.    for (i=0;i<n;i++){
  103.       while ((c = fgetc(file)) == '\n') ; /* discard spare newlines */
  104.       if (c == EOF) return(-1);
  105.        buf[i] = c;
  106.    }
  107.    
  108.    buf[i] = 0;
  109.    return(atoi(buf));
  110. }
  111.  
  112. /*
  113.  * Convert desired viewport in percentages into Normalized Device Coords
  114.  * (NDC) for GKS
  115.  */
  116.  
  117. setview(minx,miny,maxx,maxy)
  118. float minx,miny,maxx,maxy;
  119. {
  120.    Nrect newview;
  121.  
  122.    newview.n_ll.n_x = minx*nrect.n_ur.n_x/100.0;
  123.    newview.n_ll.n_y = miny*nrect.n_ur.n_y/100.0;
  124.    newview.n_ur.n_x = maxx*nrect.n_ur.n_x/100.0;
  125.    newview.n_ur.n_y = maxy*nrect.n_ur.n_y/100.0;
  126.    /* use normalization transformation number 1 */
  127.    s_viewport(1,&newview);
  128. }
  129.  
  130. /*
  131.  * GKS uses a polyline function instead of skip, draw and move
  132.  *    functions. The following routines translate from skip/draw/move
  133.  *    to polyline:
  134.  */
  135.  
  136. int skipflag = 1; /* 1 if next draw is 'pen up' */
  137. int oldx,oldy;
  138.  
  139. static void
  140. skip()
  141. {
  142. skipflag = TRUE;
  143. }
  144.  
  145. static void
  146. draw(newx,newy)
  147. int newx,newy;
  148. {
  149.    if (!skipflag) {
  150.       p1[0].w_x = oldx;
  151.       p1[0].w_y = oldy;
  152.       p1[1].w_x = newx;
  153.       p1[1].w_y = newy;
  154.       polyline(2,p1);
  155.    }
  156.    skipflag = FALSE;
  157.    oldx = newx;
  158.    oldy = newy;
  159. }
  160.  
  161. /*
  162.  * The main program...
  163.  */
  164.  
  165. main(argc,argv)
  166. int argc;
  167. char **argv;
  168. {
  169. /*    .. file unit number */
  170.       FILE *kfile,*f1,*f2;
  171. /*    .. font data   */
  172.       char line[2][256];
  173.       int x,y;
  174.       float col,row;
  175. /*    .. which data point and which character */
  176.       int     ipnt,ich,nch,i,ichar;
  177.  
  178.         if (argc != 3) {
  179.          printf("usage: hershey [c,<other devices?>] file\n");
  180.          exit(1);
  181.       }
  182.  
  183.         switch (*argv[1]) {
  184.          case 'c':  wsinitf = cga; break;
  185.              default:
  186.                     printf("usage: hershey [c,<other devices?>] file\n");
  187.                     exit(1);
  188.         }
  189.  
  190.    /* get GKS started */
  191.  
  192.     open_gks((Ercode (*)())NULL,(Erarea *)NULL,(Size)NULL,(String) "");
  193.           OUTfile=stdout;
  194.          INfile = NULL;
  195.  
  196.     wss_xxxx = open_ws(INfile, OUTfile, wsinitf);
  197.  
  198.     activate(wss_xxxx);
  199.  
  200.    nrect.n_ur.n_y /= aspect;  /* correct NDC square for pixel aspect ratio */
  201.  
  202.     /* adjust drect to be the biggest square possible, and adjust for
  203.       aspect ratio */
  204.  
  205.    drect.d_ur.d_x = drect.d_ur.d_y * aspect;
  206.  
  207. /* set up the normalization transformation (number 1) from WC to NDC */
  208.     s_window  (1, &wrect);
  209.     s_viewport(1, &nrect);
  210.    s_clip(FALSE);
  211.     sel_cntran(1);
  212. /* set up the workstation transformation from NDC to DC */
  213.     s_w_wind(wss_xxxx, &nrect);
  214.     s_w_view(wss_xxxx, &drect);
  215.     update(wss_xxxx,1);
  216.  
  217. /*
  218.  * GKS is all set up now, so let's get started...
  219.  */
  220.  
  221. /*    .. get hershey file name */
  222.       if (!(kfile = fopen(argv[2],"r"))) {
  223.          fprintf(stderr,"Can't open font file '%s'\n",argv[1]);
  224.          exit(1);
  225.          }
  226.  
  227. /*    .. loop per screen */
  228. label5:
  229. /*             .. start with a clean sheet */
  230.       clear(wss_xxxx);
  231.  
  232. /*    .. where to display this character */
  233.       col = 0.0;
  234.       row = 100.0;
  235.  
  236. /*             .. loop per character */
  237.       while (TRUE) {
  238.  
  239. /*             .. read character number and data */
  240.       if ((ich = scanint(kfile,5)) < 1) {
  241.              deactivate(wss_xxxx);
  242.             getchar();
  243.              close_ws(wss_xxxx);
  244.              close_gks();
  245.             printf("\nDone\n");
  246.             printf("min,max = (%d,%d) (%d,%d)\n",minx,miny,maxx,maxy);
  247.             exit(0);
  248.       }
  249.       nch = scanint(kfile,3);
  250.  
  251.       for (i=0; i<nch;i++) {
  252.          if ((i==32) ||(i==68) ||(i==104) ||(i==140)) fgetc(kfile); /* skip newlines */
  253.          line[0][i] = fgetc(kfile);
  254.          line[1][i] = fgetc(kfile);
  255.       }
  256.       fgetc(kfile);
  257.  
  258. /*             .. select view port (place character on screen) */
  259.       setview(col,row-deltar,col+deltac,row);
  260.  
  261. /*             .. identify character */
  262.  
  263.         jnumbr(ich,4,-15.0,-16.0,6.0);
  264.  
  265. /*             .. draw left and right lines */
  266. /*             .. Note: this data can be used for proportional spacing */
  267.  
  268.       x=(int)line[0][0] - (int)'R';
  269.       y=(int)line[1][0] - (int)'R';
  270.  
  271.       skip();
  272.       draw(x,-10);draw(x,10);
  273.       skip();
  274.       draw(y,-10);draw(y,10);
  275.  
  276.  
  277. /*             .. first data point is a move */
  278.       skip();
  279. /*             .. loop per line of data */
  280.     for (ipnt=1;ipnt<nch;ipnt++) {
  281.  
  282. /*             .. process vector number ipnt */
  283.       if (line[0][ipnt] == ' ') {
  284. /*                .. next data point is a move */
  285.          skip();
  286.       } else {
  287. /*                .. draw (or move) to this data point */
  288.          x=(int)line[0][ipnt] -(int) 'R';
  289.          y=(int)line[1][ipnt] -(int) 'R';
  290.          if (x < minx) minx = x;
  291.          if (x >maxx) maxx = x;
  292.          if (-y < miny) miny = -y;
  293.          if (-y >maxy) maxy = -y;
  294. /*                .. Note that Hershey Font data is in TV coordinate system */
  295.            draw(x,-y);
  296.       }
  297.     } /* for loop */
  298. /*             .. end of this character */
  299.  
  300.       if( (col += deltac) < colmax )
  301.          continue;
  302.       col = 0.0;
  303.       if( (row -= deltar) >= deltar ) 
  304.          continue;
  305.  
  306.       getchar();     /* wait for user to hit a newline */
  307.       goto label5;
  308.    } /* while true */
  309. /*             .. all done */
  310.       exit();
  311. }
  312.  
  313.  
  314.       long power[] ={ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
  315.           100000000, 1000000000 };
  316.       int  start[] ={0,11,14,22,36,42,55,68,73,91,104};
  317. /*         0:poly(4 9,2 8,1 6,1 3,2 1,4 0,6 1,7 3,7 6,6 8,4 9) */
  318. /*         1:poly(2 7,4 9,4 0) */
  319. /*         2:poly(1 8,3 9,5 9,7 8,7 6,6 4,1 0,7 0) */
  320. /*         3:poly(1 8,3 9,5 9,7 8,7 6,5 5) */
  321. /*           poly(4 5,5 5,7 4,7 1,5 0,3 0,1 1) */
  322. /*         4:poly(5 9,5 0) */
  323. /*           poly(5 9,0 3,8 3) */
  324. /*         5:poly(2 9,1 5,3 6,4 6,6 5,7 3,6 1,4 0,3 0,1 1) */
  325. /*           poly(2 9,6 9) */
  326. /*         6:poly(6 9,4 9,2 8,1 6,1 3,2 1,4 0,6 1,7 3,6 5,4 6,2 5,1 3) */
  327. /*         7:poly(7 9,3 0) */
  328. /*           poly(1 9,7 9) */
  329. /*         8:poly(3 9,1 8,1 6,3 5,5 5,7 6,7 8,5 9,3 9) */
  330. /*           poly(3 5,1 4,1 1,3 0,5 0,7 1,7 4,5 5) */
  331. /*         9:poly(7 6,6 4,4 3,2 4,1 6,2 8,4 9,6 8,7 6,7 3,6 1,4 0,2 0) */
  332. /*         */
  333.     char linedat[]={'R','M','P','N','O','P','O','S','P','U','R','V','T','U',
  334.       'U','S','U','P','T','N','R','M','P','O','R','M','R',
  335.         'V','O','N','Q','M','S','M','U','N','U','P','T','R','O',
  336.       'V','U','V','O','N','Q','M','S','M','U','N','U','P','S','Q',
  337.         ' ','R','R','Q','S','Q','U','R','U','U','S','V','Q','V','O','U',
  338.       'S','M','S','V',' ','R','S','M','N','S','V','S','P',
  339.         'M','O','Q','Q','P','R','P','T','Q','U','S','T','U','R','V','Q',
  340.       'V','O','U',' ','R','P','M','T','M','T','M','R','M','P','N',
  341.         'O','P','O','S','P','U','R','V','T','U','U','S','T','Q','R','P',
  342.       'P','Q','O','S','U','M','Q','V',' ','R','O','M','U','M',
  343.       'Q','M','O','N','O','P','Q','Q','S','Q','U','P','U','N','S',
  344.       'M','Q','M',' ','R','Q','Q','O','R','O','U','Q','V','S','V','U','U',
  345.         'U','R','S','Q','U','P','T','R','R','S','P','R','O','P',
  346.       'P','N','R','M','T','N','U','P','U','S','T','U','R','V','P','V'};
  347.  
  348. #define line(a,b) linedat[(b*2+a)]
  349. void
  350. jnumbr( number, iwidth, x0, y0, height )
  351.       int number, iwidth;
  352.       float x0, y0, height;
  353.  
  354. {
  355. /*             .. draw one of the decimal digits */
  356. /*             .. number = the integer to be displayed */
  357. /*             .. iwidth = the number of characters */
  358. /*             .. (x0, y0) = the lower left corner */
  359. /*             .. height = height of the characters */
  360. /*         */
  361. /*         */
  362. /*             .. By James Hurt when with */
  363. /*             ..    Deere and Company */
  364. /*             ..    John Deere Road */
  365. /*             ..    Moline, IL 61265 */
  366. /*         */
  367. /*             .. Author now with Cognition, Inc. */
  368. /*             ..                 900 Technology Park Drive */
  369. /*             ..                 Billerica, MA 01821 */
  370. /*         */
  371.  
  372. /*             .. local variables used */
  373.       int ipnt, ipos, ival, idigit;
  374.       float x, y, scale;
  375.       float xleft, ylower;
  376.  
  377. /*             .. character data for the ten decimal digit characters */
  378. /*             .. data extracted from one of the Hershey fonts */
  379.  
  380. /*            .. compute scale factor and lower left of first digit */
  381.       scale = height/10.0;
  382.       xleft = x0;
  383.       ylower = y0;
  384.       ival = number;
  385.  
  386. /*             .. loop for each character */
  387.  
  388.       for (ipos = iwidth;ipos>=1;ipos--) {
  389.          idigit = (ival/power[ipos-1])% 10;
  390.  
  391. /*                .. first data point is a move */
  392.          skip();
  393.  
  394. /*                .. loop over data for this digit */
  395.          for ( ipnt=start[idigit]; ipnt < start[idigit+1];ipnt++) {
  396.             if(((char)line(0,ipnt)) == ' ') {
  397.                skip();   /* next data point is a move */
  398.             } else {
  399. /*                      .. draw (or move) to this data point */
  400.                x=(int)line(0,ipnt) -(int) 'N';
  401.                y=(int)line(1,ipnt) -(int) 'V';
  402.  
  403.                  draw((int)(xleft+scale*x),(int)(ylower-scale*y));
  404.             }
  405.           } /* data for this digit */
  406. /*                .. move for next digit */
  407.          xleft += height;
  408.        } /* whole string */
  409. }
  410.