home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume4 / troff2lj-v2 / part01 / dumpfont.c < prev    next >
C/C++ Source or Header  |  1989-02-03  |  8KB  |  371 lines

  1. /*
  2.  * dumpfont - ASCII display of HP LaserJet font
  3.  * Usage: dumpfont [-s] [-c first-last] fontfile
  4.  * Options:
  5.  * -s            summary output only
  6.  * -c first-last    restrict range of chars dumped
  7.  *
  8.  * David MacKenzie
  9.  * Latest revision: 07/26/88
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include "hpfont.h"
  14.  
  15. int     sflag = 0;
  16.  
  17. main(argc, argv)
  18.     int     argc;
  19.     char  **argv;
  20. {
  21.     extern int optind;
  22.     extern char *optarg;
  23.     int     c;
  24.     int     first = 0;        /* First char to dump. */
  25.     int     last = 255;        /* Last char to dump. */
  26.  
  27.     while ((c = getopt(argc, argv, "sc:")) != EOF)
  28.     switch (c) {
  29.     case 's':
  30.         sflag = 1;
  31.         break;
  32.     case 'c':
  33.         parserange(optarg, &first, &last);
  34.         break;
  35.     default:
  36.         usage(argv[0]);
  37.     }
  38.     if (optind != argc - 1)
  39.     usage(argv[0]);
  40.     dumpfont(argv[optind], first, last);
  41.     exit(0);
  42. }
  43. /*
  44.  * Parse a character range of the form a-b, where a and b are
  45.  * optional ASCII characters.
  46.  */
  47.  
  48. parserange(range, first, last)
  49.     char *range;
  50.     int  *first;
  51.     int  *last;
  52. {
  53.     if (!*range) {
  54.     /* Null range: print none of the characters. */
  55.     *first = 256;
  56.     *last = -1;
  57.     return;
  58.     } else if (*range != '-')
  59.     *first = *range++;
  60.     else
  61.     *first = 0;
  62.     if (*range++ != '-')
  63.     err("Illegal character range");
  64.     if (!*range)
  65.     *last = 255;
  66.     else
  67.     *last = *range;
  68.     if (*last < *first)
  69.     err("Last character is less than first character");
  70. }
  71.  
  72. dumpfont(file, first, last)
  73.     char   *file;
  74.     register int first;
  75.     register int last;
  76. {
  77.     FILE   *fp;
  78.     char    path[150];
  79.     fontdesc fd;
  80.     chardesc cde;
  81.     chardata cda;
  82.     register int ccode;
  83.  
  84.     if (*file != '/')
  85.     strcpy(path, FONTDIR);
  86.     else
  87.     path[0] = 0;
  88.     strcat(path, file);
  89.     if (!(fp = fopen(path, "r"))) {
  90.     perror(path);
  91.     exit(1);
  92.     }
  93.     printf("file: %s\n\n", file);
  94.  
  95.     readfontdesc(fp, &fd);
  96.     if (!sflag) {
  97.     dumpfdesc(&fd);
  98.     printf("\n");
  99.     }
  100.     while ((ccode = readchar(fp, &cde, &cda)) != EOF) {
  101.     if (ccode >= first && ccode <= last) {
  102.         printf("character %3d", ccode);
  103.         if (ccode > 32 && ccode < 127)
  104.         printf(" (%c)", ccode);
  105.         printf(":\n");
  106.         if (!sflag) {
  107.         dumpchar(&fd, &cde, &cda);
  108.         printf("\n");
  109.         }
  110.     }
  111.     free(cda.d_data);
  112.     }
  113.     fclose(fp);
  114. }
  115.  
  116. readfontdesc(fp, fdp)
  117.     FILE   *fp;
  118.     fontdesc *fdp;
  119. {
  120.     char    buf[500];        /* Trash receptacle. */
  121.     int     fdlen;        /* No. of bytes in font descriptor. */
  122.  
  123.     if (fscanf(fp, "\033)s%dW", &fdlen) != 1)
  124.     err("Can't read font creation sequence");
  125.     if (!fread(fdp, sizeof(fontdesc), 1, fp))
  126.     err("Can't read font descriptor");
  127.     if (fdlen > sizeof(fontdesc))
  128.     if (!fread(buf, fdlen - sizeof(fontdesc), 1, fp))
  129.         err("Can't read continuation of font descriptor");
  130.     /* Swap byte order in integers if necessary. */
  131.     swap16(fdp->f_baseline);
  132.     swap16(fdp->f_cwidth);
  133.     swap16(fdp->f_cheight);
  134.     swap16(fdp->f_symset);
  135.     swap16(fdp->f_pitch);
  136.     swap16(fdp->f_height);
  137. }
  138.  
  139. dumpfdesc(fdp)
  140.     fontdesc *fdp;
  141. {
  142.     /* From p. 3-14, Technical Reference Manual. */
  143.     static char *tftab[] = {
  144.     "Line Printer", "Pica", "Elite", "Courier", "Helvetica",
  145.     "Times Roman", "Gothic", "Script", "Prestige", "Caslon",
  146.     "Orator"
  147.     };
  148.     /* From p. 3-12, Technical Reference Manual. */
  149.     static struct {
  150.     int field;
  151.     char term;
  152.     char *desc;
  153.     } sstab[] = {
  154.     8, 'U', "Roman-8",
  155.     8, 'K', "Kana-8",
  156.     8, 'M', "Math-8",
  157.     0, 'U', "USASCII",
  158.     0, 'B', "Line Draw",
  159.     0, 'A', "Math Symbols",
  160.     1, 'U', "US Legal",
  161.     0, 'E', "Roman Extension",
  162.     0, 'D', "ISO Denmark/Norway",
  163.     1, 'E', "ISO United Kingdom",
  164.     0, 'F', "ISO France",
  165.     0, 'G', "ISO German",
  166.     0, 'I', "ISO Italy",
  167.     0, 'S', "ISO Sweden/Finland",
  168.     1, 'S', "ISO Spain",
  169.     0, 0, NULL
  170.     };
  171.     
  172.     int field;
  173.     char term;
  174.     register int i;
  175.  
  176.     printf("font type (bits): %d\n", fdp->f_type + 7);
  177.     printf("from top of cell to baseline (dots): %d\n", fdp->f_baseline);
  178.     printf("cell width (dots): %d\n", fdp->f_cwidth);
  179.     printf("cell height (dots): %d\n", fdp->f_cheight);
  180.     printf("orientation: %s\n", fdp->f_orient ?
  181.     "landscape" : "portrait");
  182.     printf("spacing: %s\n", fdp->f_spacing ?
  183.     "proportional" : "fixed");
  184.  
  185.     field = (fdp->f_symset >> 5) & 0x0f;
  186.     term = (fdp->f_symset & 0x1f) | 64;
  187.     printf("symbol set: %d = %d%c", fdp->f_symset, field, term);
  188.     for (i = 0; sstab[i].desc; ++i)
  189.     if (field == sstab[i].field && term == sstab[i].term) {
  190.         printf(" (%s)\n", sstab[i].desc);
  191.         break;
  192.     }
  193.     if (!sstab[i].desc)
  194.     printf(" (unknown)\n");
  195.  
  196.     printf("pitch (horizontal dots per character): %g\n", fdp->f_pitch / 4.0);
  197.     printf("vertical dots per character: %g\n", fdp->f_height / 4.0);
  198.     printf("style: %s\n", fdp->f_style ? "italic" : "upright");
  199.     printf("stroke weight: %d\n", fdp->f_weight);
  200.     printf("typeface: %d", fdp->f_typeface);
  201.     if (fdp->f_typeface < 11)
  202.     printf(" (%s)\n", tftab[fdp->f_typeface]);
  203.     else
  204.     printf(" (unknown)\n");
  205.     /* Points = quarter_dots / 4 * 72 / 300. */
  206.     printf("point size: %d\n", (int) ((double) fdp->f_height * 0.06));
  207. }
  208.  
  209. readchar(fp, cdep, cdap)
  210.     FILE   *fp;
  211.     chardesc *cdep;
  212.     chardata *cdap;
  213. {
  214.     char   *Malloc();
  215.     int     ccode;        /* Character code (character number). */
  216.     int     cdlen;        /* No. of bytes in character descriptor. */
  217.  
  218.     switch (fscanf(fp, "\033*c%dE", &ccode)) {
  219.     case 1:
  220.     break;
  221.     case EOF:
  222.     return EOF;
  223.     default:
  224.     err("Can't read character code");
  225.     }
  226.     if (fscanf(fp, "\033(s%dW", &cdlen) != 1)
  227.     err("Can't read character download sequence");
  228.     if (!fread(cdep, sizeof(chardesc), 1, fp))
  229.     err("Can't read character descriptor");
  230.     /* Swap byte order in integers if necessary. */
  231.     swap16(cdep->c_leftoff);
  232.     swap16(cdep->c_topoff);
  233.     swap16(cdep->c_width);
  234.     swap16(cdep->c_height);
  235.     swap16(cdep->c_delta_x);
  236.  
  237.     cdap->d_len = cdlen - sizeof(chardesc);
  238.     cdap->d_data = Malloc(cdap->d_len);
  239.     if (!fread(cdap->d_data, cdap->d_len, 1, fp))
  240.     err("Can't read character data");
  241.     return ccode;
  242. }
  243.  
  244. dumpchar(fdp, cdep, cdap)
  245.     fontdesc *fdp;
  246.     chardesc *cdep;
  247.     chardata *cdap;
  248. {
  249.     dumpcdesc(cdep);
  250.     plotchar(fdp, cdep, cdap);
  251. }
  252.  
  253. dumpcdesc(cdep)
  254.     chardesc *cdep;
  255. {
  256.     printf("orientation: %s\n", cdep->c_orient ?
  257.     "landscape" : "portrait");
  258. }
  259.  
  260. /*
  261.  * The main loop for plotting a character.
  262.  */
  263.  
  264. plotchar(fdp, cdep, cdap)
  265.     fontdesc *fdp;
  266.     chardesc *cdep;
  267.     chardata *cdap;
  268. {
  269.     register int x,y;        /* First row & col are numbered 1. */
  270.     char graphchar;
  271.  
  272.     initplot(cdap);
  273.     for (y = 1; y <= fdp->f_cheight; ++y) {
  274.     for (x = 1; x <= fdp->f_cwidth; ++x) {
  275.         graphchar = inbox(x, y, fdp, cdep) ? 
  276.         nextdot(cdep) ? '*' : '-' :
  277.         y == fdp->f_baseline + 1 ? '=' :
  278.         '.';
  279.         putchar(graphchar);
  280.     }
  281.     if (y == fdp->f_baseline + 1)
  282.         printf(" baseline");
  283.     putchar('\n');
  284.     }
  285. }
  286.  
  287. static char *bytep;    /* Byte being dissected. */
  288. static char masknum;    /* Index into masktab to mask off bit. */
  289. static int bitcnt;    /* Number of current bit in current row. */
  290.  
  291. /*
  292.  * Set up for nextdot().
  293.  */
  294.  
  295. initplot(cdap)
  296.     chardata *cdap;
  297. {
  298.     bytep = cdap->d_data;
  299.     masknum = 0;
  300.     bitcnt = 0;
  301. }
  302.  
  303. /*
  304.  * Boolean: is the next dot on?
  305.  */
  306.  
  307. nextdot(cdep)
  308.     chardesc *cdep;
  309. {
  310.     /* Table to isolate bit currently being analyzed. */
  311.     static char masktab[] = { 128, 64, 32, 16, 8, 4, 2, 1 };
  312.     int val;        /* Return value. */
  313.  
  314.     val = *bytep & masktab[masknum];
  315.     /* Check if we've reached the end of a row. */
  316.     if (++bitcnt == cdep->c_width) {
  317.     /* Skip the byte boundary padding bits. */
  318.     ++bytep;
  319.     masknum = 0;
  320.     bitcnt = 0;
  321.     } else if (++masknum == 8) {
  322.     /* Go on to the next byte. */
  323.     ++bytep;
  324.     masknum = 0;
  325.     }
  326.     return val;
  327. }
  328.  
  329. /*
  330.  * Boolean: is point (x,y) in the character box?
  331.  */
  332.  
  333. inbox(x, y, fdp, cdep)
  334.     register int x, y;
  335.     fontdesc *fdp;
  336.     chardesc *cdep;
  337. {
  338.     return y >= fdp->f_baseline - cdep->c_topoff + 1 &&
  339.     y <= fdp->f_baseline - cdep->c_topoff + cdep->c_height &&
  340.     x >= cdep->c_leftoff &&
  341.     x <= cdep->c_leftoff + cdep->c_width - 1;
  342. }
  343.  
  344. char   *
  345. Malloc(size)
  346.     unsigned size;
  347. {
  348.     char   *malloc();
  349.     register char *s;
  350.  
  351.     if (!(s = malloc(size))) {
  352.     perror("malloc");
  353.     exit(1);
  354.     }
  355.     return s;
  356. }
  357.  
  358. err(s)
  359.     char   *s;
  360. {
  361.     fprintf(stderr, "%s\n", s);
  362.     exit(1);
  363. }
  364.  
  365. usage(file)
  366.     char   *file;
  367. {
  368.     fprintf(stderr, "Usage: %s [-s] [-c first-last] fontfile\n", file);
  369.     exit(1);
  370. }
  371.