home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / tools / bgi_tool / dfont.c < prev    next >
Text File  |  1989-05-30  |  7KB  |  234 lines

  1.  
  2. /*
  3.  
  4.   DFONT - Dump Font file program
  5.  
  6.   Copyright (c)  1988,89 Borland International
  7.  
  8. */
  9.  
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14.  
  15. #include "font.h"
  16.  
  17. FILE    *ffile, *OFile;
  18.  
  19. char           *Font;            /* Pointer to font storage    */
  20. char        Prefix[Prefix_Size];    /* File Prefix Holder        */
  21. HEADER        Header;         /* File Data Header        */
  22.  
  23. int        Offset[256];        /* Font data offsets        */
  24. char        Char_Width[256];    /* Character Width Table    */
  25. int        Stroke_Count[256];    /* Stroke Count Table        */
  26. STROKE           *Strokes[256];        /* Stroke Data Base        */
  27.  
  28. char  *OpName[] = {
  29.   "End    ",
  30.   "Do Scan",
  31.   "Move To",
  32.   "Line To"
  33.   };
  34.  
  35. char help[] = "Dump Font File Copyright (c) 1987,1989 Borland International, Inc.\n\n"
  36.           "Usage is:  DFONT [font file name] \n";
  37.  
  38.  
  39.  
  40. void dvalue( char *str, unsigned int value );
  41. int unpack( char *buf, int index, STROKE **new );
  42. int decode( unsigned int *iptr, int *x, int *y );
  43.  
  44. void main( int argc, char **argv )
  45. {
  46.   long length, current, base;
  47.   char *cptr;
  48.   FHEADER *fptr;
  49.   int last_chr, i, j;
  50.   STROKE *sptr;
  51.  
  52.   if( argc < 2 || argc > 3 ){        /* Invalid 3 of arguments    */
  53.     fprintf( stderr, help);
  54.     exit( 1 );                /* Exit the program        */
  55.     }
  56.  
  57.   ffile = fopen( argv[1], "rb" );       /* Open the input font file     */
  58.   if( NULL == ffile ){            /* Can not open font file    */
  59.     fprintf( stderr, "\nFontDisplay: Can not open input file %s.\n", argv[1] );
  60.     exit( 1 );                /* Exit the program        */
  61.     }
  62.  
  63.   if( 3 == argc ){            /* Is there an output file?    */
  64.     OFile = fopen( argv[2], "rb" );       /* Open the input font file     */
  65.     if( NULL == OFile ){          /* Can not open font file      */
  66.       fprintf( stderr, "\nFontDisplay: Can not open output file %s.\n", argv[2] );
  67.       exit( 1 );              /* Exit the program          */
  68.       }
  69.     }
  70.   else    OFile = stdout;         /* Write it to screen        */
  71.  
  72. /*    Read in and display the file prefix record.            */
  73.  
  74.   base = ftell( ffile );        /* Remember the address of table*/
  75.   fread(Prefix, Prefix_Size, 1, ffile); /* Read in the file prefix    */
  76.  
  77.   fprintf( stdout, "Prefix Record   File Base: %lx\n\n", base );
  78.  
  79.   cptr = Prefix;            /* Begin at base of prefix    */
  80.   while( 0x1a != *cptr ) ++cptr;    /* Move to EOF in prefix    */
  81.   *cptr = '\0';                         /* Cut prefix at EOF            */
  82.   fptr = (FHEADER *)(cptr+1);        /* Point at Font Header Record    */
  83.  
  84.   fprintf( stdout, "Text:\n\n%s\n", Prefix );
  85.   dvalue( "Prefix Size", fptr->header_size );
  86.   fprintf( stdout, "Prefix Name: %-.4s\n", fptr->font_name );
  87.   dvalue( "Font Size", fptr->font_size );
  88.   fprintf( stdout, "Revision:    %d.%d\n", fptr->font_major, fptr->font_minor );
  89.   fprintf( stdout, "BGI Version: %d.%d\n", fptr->min_major, fptr->min_minor );
  90.  
  91. /*    Read in and display the font header record.            */
  92.  
  93.   base = ftell( ffile );        /* Remember the address of table*/
  94.   fread(&Header, sizeof(HEADER), 1, ffile);  /* Read in the file prefix */
  95.  
  96.   fprintf( stdout, "\nHeader Record   File Base: %lx\n\n", base );
  97.  
  98.   fprintf( stdout, "Signature:    %c\n", Header.sig );
  99.   fprintf( stdout, "# Characters: %d.\n", Header.nchrs );
  100.   fprintf( stdout, "First Char:   %02x\n", Header.first );
  101.   fprintf( stdout, "Definition Offset:   %04x\n", Header.cdefs );
  102.   fprintf( stdout, "Scanable Font:       %s\n", Header.scan_flag ? "Yes" : "No" );
  103.   fprintf( stdout, "Origin to Cap  Height: %d\n", Header.org_to_cap );
  104.   fprintf( stdout, "Origin to Base Height: %d\n", Header.org_to_base );
  105.   fprintf( stdout, "Origin to Dec  Height: %d\n", Header.org_to_dec );
  106.   fprintf( stdout, "Header Name: %-.4s\n\n", Header.fntname );
  107.  
  108. /*    Read file offset table into memory.                */
  109.  
  110.   base = ftell( ffile );        /* Remember the address of table*/
  111.   fread( &Offset[Header.first], Header.nchrs, sizeof(int), ffile );
  112.  
  113. /*    Display the offset table                    */
  114.  
  115.   last_chr = Header.first + Header.nchrs;
  116.  
  117.   fprintf( stdout, "Offset Table    File Base: %lx\n", base );
  118.  
  119.   for( i=Header.first ; i<last_chr ; ++i ){
  120.     if( !((i+3) % 4) ) fprintf( stdout, "\n" );
  121.     fprintf( stdout, " %c (%02x) : %04x ",
  122.             isprint(i) ? i : '.', i, Offset[i] );
  123.     }
  124.  
  125. /*    Load the character width table into memory.            */
  126.  
  127.   base = ftell( ffile );
  128.   fread( &Char_Width[Header.first], Header.nchrs, sizeof(char), ffile );
  129.  
  130. /*    Determine the length of the stroke database.            */
  131.  
  132.   current = ftell( ffile );        /* Current file location    */
  133.   fseek( ffile, 0, SEEK_END );        /* Go to the end of the file    */
  134.   length = ftell( ffile );        /* Get the file length        */
  135.   fseek( ffile, current, SEEK_SET );    /* Restore old file location    */
  136.  
  137. /*    Load the stroke database.                    */
  138.  
  139.   Font = malloc( (int) length );    /* Create space for font data    */
  140.   if( NULL == Font ){            /* Was there enough memory    */
  141.     fprintf( stderr, "FontDisplay: Not Enough Memory to load Font.\n\n" );
  142.     exit( 1 );
  143.     }
  144.  
  145.   fread( Font, (int)length, 1 , ffile ); /* Load the stroke data    */
  146.  
  147. /*    Font is now loaded, display the internal data            */
  148.  
  149.   fprintf( stdout, "\n\nWidth Table File Base:  %lx\n", base );
  150.   fprintf( stdout, "Stroke Table File Base: %lx\n", current );
  151.   fprintf( stdout, "\n\nStroke Information\n\n" );
  152.  
  153.   for( i=Header.first ; i<last_chr ; ++i ){
  154.     if( !Offset[i] && i!=Header.first ) continue;
  155.     printf( "Char %02x (%c)    ", i, i );
  156.     Stroke_Count[i] = unpack( Font, Offset[i], &Strokes[i] );
  157.     printf( "Offset: %04x   Width: %-5d   Stroke Count: %d\n",
  158.       Offset[i], Char_Width[i], Stroke_Count[i] );
  159.     sptr = Strokes[i];
  160.     for( j=0 ; j<Stroke_Count[i] ; ++j, ++sptr ){
  161.       printf( "  %3d : OpCode: %s (%d)   X: %4d   Y: %4d\n",
  162.     j, OpName[sptr->opcode], sptr->opcode, sptr->x, sptr->y );
  163.       }
  164.     }
  165.  
  166. }
  167.  
  168. void dvalue( char *str, unsigned int value )
  169. {
  170.  
  171.   fprintf( OFile, "%-50s  %04xh  (%6u. )\n", str, value, value );
  172.  
  173. }
  174.  
  175. /*    UNPACK: This routine decodes the file format into a more    */
  176. /*    reasonable internal structure                    */
  177.  
  178. int unpack( char *buf, int index, STROKE **new )    /* FUNCTION    */
  179. {
  180.   unsigned int *pb;
  181.   STROKE *po;
  182.   int      num_ops = 0;
  183.   int      jx, jy, opcode, i, opc;
  184.  
  185.   pb = (unsigned int *)(buf + index);    /* Reset pointer to buffer    */
  186.  
  187.   while( FOREVER ){            /* For each byte in buffer    */
  188.     num_ops += 1;            /* Count the operation        */
  189.     opcode = decode( pb++, &jx, &jy );    /* Decode the data record    */
  190.     if( opcode == END_OF_CHAR ) break;    /* Exit loop at end of char    */
  191.     }
  192.  
  193.   po = *new = calloc( num_ops, sizeof(STROKE) );
  194.  
  195.   if( !po ){                /* Out of memory loading font    */
  196.     fprintf( stderr, "DMPFNT: Out of memory decoding font\n" );
  197.     exit( 100 );
  198.     }
  199.  
  200.   pb = (unsigned int *)(buf + index);    /* Reset pointer to buffer    */
  201.  
  202.   for( i=0 ; i<num_ops ; ++i ){     /* For each opcode in buffer    */
  203.     opc = decode(pb++, &po->x, &po->y); /* Decode the data field    */
  204.     po->opcode = opc;            /* Save the opcode        */
  205.     po++;
  206.     }
  207.  
  208.   return( num_ops );            /* return OPS count        */
  209.  
  210. }
  211.  
  212.  
  213. /*    DECODE: This routine decodes a single word in file to a     */
  214. /*    stroke record.                            */
  215.  
  216. int decode( unsigned int *iptr, int *x, int *y )  /* FUNCTION        */
  217. {
  218.   struct DECODE {
  219.     signed   int xoff  : 7;
  220.     unsigned int flag1 : 1;
  221.     signed   int yoff  : 7;
  222.     unsigned int flag2 : 1;
  223.   } cword;
  224.  
  225.   cword = *(struct DECODE *)iptr;
  226.  
  227.   *x = cword.xoff;
  228.   *y = cword.yoff;
  229.  
  230.   return( (cword.flag1 << 1) + cword.flag2 );
  231.  
  232. }
  233.  
  234.