home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / FTREE0.3.LHA / ftree / src / RCS / oldafm.c,v < prev    next >
Encoding:
Text File  |  1994-04-27  |  13.9 KB  |  722 lines

  1. head    1.1;
  2. access;
  3. symbols;
  4. locks; strict;
  5. comment    @ * @;
  6.  
  7.  
  8. 1.1
  9. date    94.03.26.11.35.12;    author peteric;    state Exp;
  10. branches;
  11. next    ;
  12.  
  13.  
  14. desc
  15. @original version of afm parser.
  16. @
  17.  
  18.  
  19. 1.1
  20. log
  21. @Initial revision
  22. @
  23. text
  24. @/*************************************************************************
  25.  *
  26.  *     $RCSfile: afm.c,v $
  27.  *
  28.  *    $Author: peteric $
  29.  *
  30.  *    $Date: 1994/03/07 12:43:26 $
  31.  *
  32.  *    $Revision: 1.1 $
  33.  *
  34.  *    Purpose:    Main routine for ftree family tree formatter.
  35.  *            
  36.  *    $Log: afm.c,v $
  37.  * Revision 1.1  1994/03/07  12:43:26  peteric
  38.  * Initial revision
  39.  *
  40.  *    
  41.  *
  42.  *************************************************************************/
  43.  
  44. #include <stdlib.h>
  45. #include <stdarg.h>
  46. #include <string.h>
  47. #include <ctype.h>
  48.  
  49. #include "ftree.h"
  50.  
  51. #define MAXFONTS    8
  52. #define EOS        '\0'
  53. #ifdef TEST_AFM
  54. #define err(str)    printf("%s",str)
  55. #else
  56. #define err(str)    errmsg(str)
  57. #endif
  58.  
  59. typedef struct
  60. {
  61.     char name[64];    /* PostScript name of font */
  62.     double ulpos;    /* underline position */
  63.     double ulthick;    /* underline thickness */
  64.     int nchars;    /* number of characters in font */
  65.     double width;    /* if >= 0 monospaced font of given width */
  66.     short *encoding;    /* encoding array */
  67.     double *cwidths;    /* widths array */
  68.     int nextchar;
  69. } fontd_t;
  70.  
  71. fontd_t fonts[MAXFONTS] = {0};
  72.  
  73. int skipspc(FILE *fp);
  74. int readword(FILE *fp, char *buf);
  75. int readnum(FILE *fp, char *buf);
  76. int readhexnum(FILE *fp, char *buf);
  77. int readtoeol(FILE *fp, char *buf);
  78. int readbool(FILE *fp, char *buf);
  79. int findword(char *word);
  80. int readcharmetrics(FILE *fp, fontd_t *font);
  81. int readkerndata(FILE *fp, fontd_t *font);
  82. int readnextline(FILE *fp, fontd_t *font);
  83. FILE *openfontfile(char *name);
  84. void loadfont(char *name);
  85. double stringwidth(char *font, char *string);
  86.  
  87.  
  88. #define T_ASCENDER    1
  89. #define T_CAPHEIGHT    2
  90. #define T_CHARWIDTH    3
  91. #define T_CHARACTERSET    4
  92. #define T_CHARACTERS    5
  93. #define T_COMMENT    6
  94. #define T_DESCENDER    7
  95. #define T_ENCODINGSCHEME    8
  96. #define T_ENDCHARMETRICS    9
  97. #define T_ENDDIRECTION    10
  98. #define T_ENDFONTMETRICS    11
  99. #define T_ENDKERNDATA    12
  100. #define T_ESCCHAR    13
  101. #define T_FAMILYNAME    14
  102. #define T_FONTBBOX    15
  103. #define T_FONTNAME    16
  104. #define T_FULLNAME    17
  105. #define T_ISBASEFONT    18
  106. #define T_ISFIXEDPITCH    19
  107. #define T_ISFIXEDV    20
  108. #define T_ITALICANGLE    21
  109. #define T_MAPPINGSCHEME    22
  110. #define T_METRICSSETS    23
  111. #define T_NOTICE    24
  112. #define T_STARTCHARMETRICS    25
  113. #define T_STARTDIRECTION    26
  114. #define T_STARTFONTMETRICS    27
  115. #define T_STARTKERNDATA    28
  116. #define T_UNDERLINEPOSITION    29
  117. #define T_UNDERLINETHICKNESS    30
  118. #define T_VVECTOR    31
  119. #define T_VERSION    32
  120. #define T_WEIGHT    33
  121. #define T_XHEIGHT    34
  122.  
  123. struct token
  124. {
  125.     char *name;
  126.     int tok;
  127. }
  128. afmNames[] =
  129. {
  130.     "Ascender",    T_ASCENDER,
  131.     "CapHeight",    T_CAPHEIGHT,
  132.     "CharWidth",    T_CHARWIDTH,
  133.     "CharacterSet",    T_CHARACTERSET,
  134.     "Characters",    T_CHARACTERS,
  135.     "Comment",    T_COMMENT,
  136.     "Descender",    T_DESCENDER,
  137.     "EncodingScheme",    T_ENCODINGSCHEME,
  138.     "EndCharMetrics",    T_ENDCHARMETRICS,
  139.     "EndDirection",    T_ENDDIRECTION,
  140.     "EndFontMetrics",    T_ENDFONTMETRICS,
  141.     "EndKernData",    T_ENDKERNDATA,
  142.     "EscChar",    T_ESCCHAR,
  143.     "FamilyName",    T_FAMILYNAME,
  144.     "FontBBox",    T_FONTBBOX,
  145.     "FontName",    T_FONTNAME,
  146.     "FullName",    T_FULLNAME,
  147.     "IsBaseFont",    T_ISBASEFONT,
  148.     "IsFixedPitch",    T_ISFIXEDPITCH,
  149.     "IsFixedV",    T_ISFIXEDV,
  150.     "ItalicAngle",    T_ITALICANGLE,
  151.     "MappingScheme",    T_MAPPINGSCHEME,
  152.     "MetricsSets",    T_METRICSSETS,
  153.     "Notice",    T_NOTICE,
  154.     "StartCharMetrics",    T_STARTCHARMETRICS,
  155.     "StartDirection",    T_STARTDIRECTION,
  156.     "StartFontMetrics",    T_STARTFONTMETRICS,
  157.     "StartKernData",    T_STARTKERNDATA,
  158.     "UnderlinePosition",    T_UNDERLINEPOSITION,
  159.     "UnderlineThickness",    T_UNDERLINETHICKNESS,
  160.     "VVector",    T_VVECTOR,
  161.     "Version",    T_VERSION,
  162.     "Weight",    T_WEIGHT,
  163.     "XHeight",    T_XHEIGHT,
  164.     NULL
  165. };
  166.  
  167. int skipspc(FILE *fp)
  168. {
  169.     int c;
  170.     
  171.     while((c = getc(fp)) != EOF && (c == ' ' || c == '\t'))
  172.         ;
  173.     
  174.     if (c != EOF)
  175.     {
  176.         ungetc(c, fp);
  177.     }
  178.     
  179.     return !feof(fp);
  180. }
  181.  
  182. int readword(FILE *fp, char *buf)
  183. {
  184.     int c, i;
  185.  
  186.     i = 0;
  187.     while((c = getc(fp)) != EOF && isalnum(c))
  188.     {
  189.         buf[i++] = c;
  190.     }
  191.     ungetc(c, fp);
  192.     buf[i] = EOS;
  193.     return !feof(fp);
  194. }
  195.  
  196. int readnum(FILE *fp, char *buf)
  197. {
  198.     int c, i;
  199.  
  200.     i = 0;
  201.     while((c = getc(fp)) != EOF && (isdigit(c) || c == '.' || c == '-'))
  202.     {
  203.         buf[i++] = c;
  204.     }
  205.     ungetc(c, fp);
  206.     buf[i] = EOS;
  207.     return !feof(fp);
  208. }
  209.  
  210. int readhexnum(FILE *fp, char *buf)
  211. {
  212.     int c, i;
  213.  
  214.     i = 0;
  215.     while((c = getc(fp)) != EOF && (isdigit(c) || c == '.' || c == '-' ||
  216.                     (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') ))
  217.     {
  218.         buf[i++] = c;
  219.     }
  220.     ungetc(c, fp);
  221.     buf[i] = EOS;
  222.     return !feof(fp);
  223. }
  224.  
  225.  
  226. int readtoeol(FILE *fp, char *buf)
  227. {
  228.     int c, i;
  229.  
  230.     if (buf)
  231.     {
  232.         i = 0;
  233.         while((c = getc(fp)) != EOF && c != '\n' && c != '\r')
  234.         {
  235.             buf[i++] = c;
  236.         }
  237.         buf[i] = EOS;
  238.     }
  239.     else
  240.     {
  241.         while((c = getc(fp)) != EOF && c != '\n' && c != '\r')
  242.             ;
  243.     }
  244.     return !feof(fp);
  245. }
  246.  
  247.  
  248. int readbool(FILE *fp, char *buf)
  249. {
  250.     if (readword(fp, buf))
  251.     {
  252.         if (strcmp(buf, "true") == 0)
  253.             return 1;
  254.         else if (strcmp(buf, "false") == 0)
  255.             return 0;
  256.     }
  257.     return -1;
  258. }
  259.  
  260. int findword(char *word)
  261. {
  262.     int r, i;
  263.  
  264.     for (i = 0; afmNames[i].name != NULL; i++)
  265.     {
  266.         r = strcmp(word, afmNames[i].name);
  267.         if (r == 0)
  268.         {
  269.             return afmNames[i].tok;
  270.         }
  271.         else if (r < 0)
  272.         {
  273.             break;
  274.         }
  275.     }
  276.     return -1;
  277. }
  278.  
  279. static int inFontMetrics;
  280. static int inCharMetrics;
  281. static int inKernData;
  282.  
  283. int readcharmetrics(FILE *fp, fontd_t *font)
  284. {
  285.     int eoln = FALSE;
  286.     int c, code;
  287.     double wx[2], wy[2], bb[4], vv[2];
  288.     char ll[2][32];
  289.     char buf[32], nm[32];
  290.     
  291.     wx[0] = wy[0] = 0;
  292.     wx[1] = wy[1] = 0;
  293.     vv[0] = vv[1] = 0;
  294.     bb[0] = bb[1] = bb[2] = bb[3] = 0;
  295.     ll[0][0] = ll[1][0] = EOS;
  296.     code = -1;
  297.     
  298.     while(!eoln)
  299.     {
  300.         if (readword(fp, buf))
  301.         {
  302.             switch(buf[0])
  303.             {
  304.                 case 'C':
  305.                     c = buf[1];
  306.                     skipspc(fp);
  307.                     if (c == 'H')
  308.                     {
  309.                         readhexnum(fp, buf);
  310.                         sscanf(buf, "%x", &code);
  311.                     }
  312.                     else
  313.                     {
  314.                         readnum(fp, buf);
  315.                         sscanf(buf, "%d", &code);
  316.                     }
  317.                     
  318.                     break;
  319.                 case 'W':
  320.                     if (buf[1] == EOS || (buf[1] == '0' && buf[2] == EOS))
  321.                     {
  322.                         if (skipspc(fp) && readnum(fp, buf))
  323.                             sscanf(buf, "%lf", &wx[0]);
  324.                         if (skipspc(fp) && readnum(fp, buf))
  325.                             sscanf(buf, "%lf", &wy[0]);
  326.                     }
  327.                     else if (buf[1] == '1' && buf[2] == EOS)
  328.                     {
  329.                         if (skipspc(fp) && readnum(fp, buf))
  330.                             sscanf(buf, "%lf", &wx[1]);
  331.                         if (skipspc(fp) && readnum(fp, buf))
  332.                             sscanf(buf, "%lf", &wy[1]);
  333.                     }
  334.                     else if ((buf[1] == 'X' && buf[2] == EOS) ||
  335.                             (buf[1] == '0' && buf[2] == 'X' && buf[3] == EOS))
  336.                     {
  337.                         if (skipspc(fp) && readnum(fp, buf))
  338.                             sscanf(buf, "%lf", &wx[0]);
  339.                     }
  340.                     else if ((buf[1] == 'Y' && buf[2] == EOS) ||
  341.                             (buf[1] == '0' && buf[2] == 'Y' && buf[3] == EOS))
  342.                     {
  343.                         if (skipspc(fp) && readnum(fp, buf))
  344.                             sscanf(buf, "%lf", &wy[0]);
  345.                     }
  346.                     else if (buf[1] == '1' && buf[2] == 'X' && buf[3] == EOS)
  347.                     {
  348.                         if (skipspc(fp) && readnum(fp, buf))
  349.                             sscanf(buf, "%lf", &wx[1]);
  350.                     }
  351.                     else if (buf[1] == '1' && buf[2] == 'Y' && buf[3] == EOS)
  352.                     {
  353.                         if (skipspc(fp) && readnum(fp, buf))
  354.                             sscanf(buf, "%lf", &wy[1]);
  355.                     }
  356.                     break;
  357.                 
  358.                 case 'B':
  359.                     if (skipspc(fp) && readnum(fp, buf))
  360.                         sscanf(buf, "%lf", &bb[0]);
  361.                     if (skipspc(fp) && readnum(fp, buf))
  362.                         sscanf(buf, "%lf", &bb[1]);
  363.                     if (skipspc(fp) && readnum(fp, buf))
  364.                         sscanf(buf, "%lf", &bb[2]);
  365.                     if (skipspc(fp) && readnum(fp, buf))
  366.                         sscanf(buf, "%lf", &bb[3]);
  367.                     break;
  368.                 
  369.                 case 'N':
  370.                     if (skipspc(fp))
  371.                         readword(fp, nm);
  372.                     break;
  373.                 
  374.                 case 'V':
  375.                     if (skipspc(fp) && readnum(fp, buf))
  376.                         sscanf(buf, "%lf", &vv[0]);
  377.                     if (skipspc(fp) && readnum(fp, buf))
  378.                         sscanf(buf, "%lf", &vv[1]);
  379.                     break;
  380.                 
  381.                 case 'L':
  382.                     if (skipspc(fp) && readword(fp, ll[0]))
  383.                         readword(fp, ll[1]);
  384.                     break;
  385.                 
  386.                 default:
  387.                     if (findword(buf) == T_ENDCHARMETRICS)
  388.                         inCharMetrics = FALSE;
  389.                     else
  390.                         err("unknown keyword in char metrics\n");
  391.             }
  392.         }
  393.         /*
  394.          * move on, setting eoln or skipping one or more
  395.          * ';' characters to get to the next word.
  396.          */
  397.         if (skipspc(fp))
  398.         {
  399.             do
  400.             {
  401.                 c = getc(fp);
  402.                 if (c == '\n' || c == '\r')
  403.                     eoln = TRUE;
  404.             } while (c == ';' && skipspc(fp));
  405.             
  406.             if (!eoln)
  407.                 ungetc(c, fp);
  408.         }
  409.     }
  410.     if (code != -1)
  411.     {
  412.         if (font->nextchar < font->nchars)
  413.         {
  414.             printf("read: code %d, nm %s, w %6.2f %6.2f %6.2f %6.2f, vv %6.2f %6.2f ll %s %s\n",
  415.                     code, nm, wx[0], wy[0], wx[1], wy[1], vv[0], vv[1], ll[0], ll[1]);
  416.             font->cwidths[code] = wx[0];
  417.             font->encoding[code] = font->nextchar++;
  418.         }
  419.     }
  420.     
  421.     return inCharMetrics && !feof(fp);
  422. }
  423.  
  424. int readkerndata(FILE *fp, fontd_t *font)
  425. {
  426.     char word[32];
  427.     if (readword(fp, word))
  428.     {
  429.         readtoeol(fp, NULL);
  430.         if (findword(word) == T_ENDKERNDATA)
  431.             return 0;
  432.     }
  433.     return !feof(fp);
  434. }
  435.  
  436. int readnextline(FILE *fp, fontd_t *font)
  437. {
  438.     char buf[80], word[32];
  439.     int b;
  440.  
  441.     if (readword(fp, word))
  442.     {
  443.         switch(findword(word))
  444.         {
  445.             case T_CHARWIDTH:
  446.                 if (skipspc(fp) && readnum(fp, buf))
  447.                     font->width = atoi(buf);
  448.                 else
  449.                     err("bad CHARWIDTH setting\n");
  450.                 break;
  451.                 
  452.             case T_CHARACTERS:
  453.                 if (skipspc(fp) && readnum(fp, buf))
  454.                 {
  455.                     font->nchars = atoi(buf);
  456.                     if (font->nchars < 0 || font->nchars > 1024)
  457.                         err("bad number of chars in font!\n");
  458.                     else
  459.                         font->cwidths = malloc(font->nchars * sizeof(int));
  460.                     if (font->cwidths == NULL)
  461.                         err("can't alloc memory for character sizes");
  462.                 }
  463.                 else
  464.                     err("bad CHARACTERS setting\n");
  465.                 break;
  466.  
  467.             case T_ENDCHARMETRICS:
  468.                 err("unexpected ENDCHARMETRICS\n");
  469.                 break;
  470.  
  471.             case T_ENDFONTMETRICS:
  472.                 inFontMetrics = FALSE;
  473.                 break;
  474.  
  475.             case T_ENDKERNDATA:
  476.                 err("unexpected ENDKERNDATA\n");
  477.                 break;
  478.  
  479.             case T_ISBASEFONT:
  480.                 if (skipspc(fp) && (b = readbool(fp, buf)) != -1)
  481.                 {
  482.                     if (b == 0)
  483.                         err("Can't cope with composite fonts, sorry\n");
  484.                 }
  485.                 break;
  486.  
  487.             case T_ISFIXEDPITCH:
  488.                 if (skipspc(fp) && (b = readbool(fp, buf)) != -1)
  489.                 {
  490.                     if (b == 0)
  491.                         font->width = -1;    /* width = -1 ==> prop font */
  492.                     else
  493.                         font->width = 0;    /* width >= 0 ==> mono font */
  494.                 }
  495.                 break;
  496.  
  497.             case T_METRICSSETS:
  498.                 break;
  499.  
  500.             case T_STARTCHARMETRICS:
  501.                 if (skipspc(fp) && readnum(fp, buf))
  502.                 {
  503.                     if (font->cwidths)
  504.                         free(font->cwidths);
  505.                     font->nchars = atoi(buf);
  506.                     if (font->nchars < 0 || font->nchars > 1024)
  507.                         err("bad number of chars in font!\n");
  508.                     else
  509.                         font->cwidths = malloc(font->nchars * sizeof(*font->cwidths));
  510.                     if (font->cwidths == NULL)
  511.                         err("can't alloc memory for character sizes");
  512.                     else
  513.                     {
  514.                         int i;
  515.                         for (i = 0; i < font->nchars; i++)
  516.                             font->cwidths[i] = 0;
  517.                     }
  518.                 }
  519.                 else
  520.                     err("bad STARTCHARMETRICS setting\n");
  521.                 inCharMetrics = TRUE;
  522.                 readtoeol(fp, NULL);
  523.                 while(readcharmetrics(fp,font));
  524.                 break;
  525.  
  526.             case T_STARTFONTMETRICS:
  527.                 inFontMetrics = TRUE;
  528.                 break;
  529.  
  530.             case T_STARTKERNDATA:
  531.                 inKernData = TRUE;
  532.                 readtoeol(fp, NULL);
  533.                 while(readkerndata(fp,font));
  534.                 break;
  535.  
  536.             case T_UNDERLINEPOSITION:
  537.                 if (skipspc(fp) && readnum(fp, buf))
  538.                     sscanf(buf, "%lf", &font->ulpos);
  539.                 else
  540.                     err("bad UNDERLINEPOSITION setting\n");
  541.                 break;
  542.                 
  543.             case T_UNDERLINETHICKNESS:
  544.                 if (skipspc(fp) && readnum(fp, buf))
  545.                     sscanf(buf, "%lf", &font->ulthick);
  546.                 else
  547.                     err("bad UNDERLINETHICKNESS setting\n");
  548.                 break;
  549.                 
  550.             case T_ENCODINGSCHEME:
  551.                 if (skipspc(fp) && readword(fp, buf))
  552.                     printf("encoding: %s\n",buf);
  553.                 break;
  554.             
  555.             case T_FAMILYNAME:
  556.             case T_ASCENDER:
  557.             case T_CAPHEIGHT:
  558.             case T_CHARACTERSET:
  559.             case T_COMMENT:
  560.             case T_DESCENDER:
  561.             case T_ENDDIRECTION:
  562.             case T_ESCCHAR:
  563.             case T_ITALICANGLE:
  564.             case T_FONTNAME:
  565.             case T_FULLNAME:
  566.             case T_FONTBBOX:
  567.             case T_ISFIXEDV:
  568.             case T_MAPPINGSCHEME:
  569.             case T_NOTICE:
  570.             case T_STARTDIRECTION:
  571.             case T_VVECTOR:
  572.             case T_VERSION:
  573.             case T_WEIGHT:
  574.             case T_XHEIGHT:
  575.                 /* dont need to know these */
  576.                 break;
  577.  
  578.             default:
  579.                 /* don't know this one, ignore it */
  580.                 break;
  581.         }
  582.         /*
  583.          * read the newline (at least)
  584.          */
  585.         readtoeol(fp, NULL);
  586.     }
  587.     
  588.     return !feof(fp);
  589. }
  590.  
  591. FILE *openfontfile(char *name)
  592. {
  593.     char filen[128];
  594.     
  595.     strcpy(filen, "afm/");
  596.     strcat(filen, name);
  597.     strcat(filen, ".afm");
  598.     return fopen(filen, "r");
  599. }
  600.  
  601. void loadfont(char *name)
  602. {
  603.     FILE *fp;
  604.     int i, j;
  605.  
  606.     for(i = 0; fonts[i].name[0] != '\0' && i < MAXFONTS; i++)
  607.     {
  608.         if (streq(fonts[i].name, name))
  609.             return;
  610.     }
  611.  
  612.     /*
  613.      * Run out of space!
  614.      */
  615.     if (i == MAXFONTS)
  616.     {
  617.         err("ran out of space in fonts array\n");
  618.         return;
  619.     }
  620.  
  621.     /*
  622.      * if we got here, the font isnt loaded yet and 'i' is
  623.      * the index of a free font struct.
  624.      */
  625.     fp = openfontfile(name);
  626.     if (fp == NULL)
  627.     {
  628.         err("cannot load font file\n");
  629.         return;
  630.     }
  631.     strcpy(fonts[i].name, name);
  632.     fonts[i].nchars = 0;
  633.     fonts[i].nextchar = 0;
  634.     fonts[i].ulpos = 0;
  635.     fonts[i].ulthick = 0;
  636.     fonts[i].width = -1;
  637.     fonts[i].cwidths = NULL;
  638.     fonts[i].encoding = malloc(255 * sizeof(short));
  639.     for(j = 0; i < 255; j++)
  640.         fonts[i].encoding[j] = 0;
  641.     
  642.     while(readnextline(fp, &fonts[i]));
  643.     
  644.     fclose(fp);
  645. }
  646.  
  647. double stringwidth(char *name, char *string)
  648. {
  649.     char *p;
  650.     int i, ec;
  651.     double w;
  652.     fontd_t *font = NULL;
  653.     
  654.     for(i = 0; fonts[i].name[0] != '\0' && i < MAXFONTS; i++)
  655.     {
  656.         if (streq(fonts[i].name, name))
  657.         {
  658.             font = &fonts[i];
  659.             break;
  660.         }
  661.     }
  662.  
  663.     if (font == NULL)
  664.     {
  665.         return -1;
  666.     }
  667.     
  668.     /*
  669.      * check for monospaced fonts.
  670.      */
  671.     if (font->width >= 0)
  672.     {
  673.         return (strlen(string) * font->width) / 1000;
  674.     }
  675.     else
  676.     {
  677.         p = string;
  678.         w = 0.0;
  679.         while(*p)
  680.         {
  681.             ec = font->encoding[(int)*p];
  682.             printf("Char '%c' => %d w(%10.3f)\n", *p, ec, font->cwidths[ec]);
  683.             w += font->cwidths[ec];
  684.             p++;
  685.         }
  686.         return (w / 1000);
  687.     }
  688. }
  689.  
  690. #ifdef TEST_AFM
  691.  
  692. int main(int argc, char *argv[])
  693. {
  694.     int i;
  695.     char *font = NULL;
  696.     char *s1, *s2, *s3, *s4, *s5;
  697.     
  698.     s1 = "abcdefg";
  699.     s2 = "ABCDEFG";
  700.     s3 = "VAflffij";
  701.     s4 = "The Rain in Spain falls Mainly on the Plain";
  702.     s5 = "The Quick Brown Fox Jumped over the Lazy Dog";
  703.  
  704.     for(i = 1; i < argc; i++)
  705.     {
  706.         font = argv[i];
  707.  
  708.         printf("loading %s...\n", font);
  709.         loadfont(font);
  710.         
  711.         printf("%s:\n", font);
  712.         printf("%s width %6.2f\n", s1, stringwidth(font, s1));
  713.         printf("%s width %6.2f\n", s2, stringwidth(font, s2));
  714.         printf("%s width %6.2f\n", s3, stringwidth(font, s3));
  715.         printf("%s width %6.2f\n", s4, stringwidth(font, s4));
  716.         printf("%s width %6.2f\n", s5, stringwidth(font, s5));
  717.     }
  718. }
  719.  
  720. #endif
  721. @
  722.