/*
   unihex2bdf - program to turn a GNU Unifont hex glyph file
                into a BDF file


   Author: Paul Hardy, 6 January 2008
   
   
    Copyright (C) 2008 Paul Hardy

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>

#define MAXBUF 256



main(int argc, char *argv[]) {

   unsigned i, j;             /* loop variables                    */
   unsigned k0, k1;           /* pointers into hex string          */
   unsigned nglyphs;          /* number of glyphs we read in       */
   char inbuf[256];           /* input buffer                      */
   unsigned thischar;         /* the current character             */
   int fullwidth;             /* =1: glyph has 16 columns          */

   char *infile="", *outfile="";  /* names of input and output files   */
   FILE *infp, *outfp;      /* file pointers of input and output files */


   if (argc > 1) {
      for (i = 1; i < argc; i++) {
         if (argv[i][0] == '-') {  /* this is an option argument */
            switch (argv[i][1]) {
               case 'i':  /* name of input file */
                  infile = &argv[i][2];
                  break;
               case 'o':  /* name of output file */
                  outfile = &argv[i][2];
                  break;
               default:   /* if unrecognized option, print list and exit */
                  fprintf(stderr, "\nSyntax:\n\n");
                  fprintf(stderr, "   %s -p<Unicode_Page> ", argv[0]);
                  fprintf(stderr, "-i<Input_File> -o<Output_File> -w\n\n");
                  fprintf(stderr, "\nExample:\n\n");
                  exit(1);
            }
         }
      }
   }
   if (infile == "") {
      fprintf(stderr, "\nError: must specify an input file.\n\n");
      exit(1);
   }
   /*
      Make sure we can open any I/O files that were specified before
      doing anything else.
   */
   if (strlen(infile) > 0) {
      if ((infp = fopen(infile, "r")) == NULL) {
         fprintf(stderr, "Error: can't open %s for input.\n", infile);
         exit(1);
      }
   }
   else {
      infp = stdin;
   }
   if (strlen(outfile) > 0) {
      if ((outfp = fopen(outfile, "w")) == NULL) {
         fprintf(stderr, "Error: can't open %s for output.\n", outfile);
         exit(1);
      }
   }
   else {
      outfp = stdout;
   }
   /*
      Read in the glyphs in the file
   */
   nglyphs=0;
   while (fgets(inbuf, MAXBUF-1, infp) != NULL) {
      sscanf(inbuf, "%x", &thischar);
      nglyphs++;
   }
   /*
      Now that we've counted the number of glyphs in the file,
      rewind it to write them one at a time.  This is why an
      input filename is required -- so we can rewind it without
      any problems.
   */
   rewind(infp);

   /*
      We know how many code points there are.  Now write the BDF file.
   */
   fprintf(outfp, "STARTFONT 2.1\n");
   fprintf(outfp,
      "FONT -gnu-unifont-medium-r-normal--16-160-75-75-c-80-iso10646-1\n");
   fprintf(outfp, "SIZE 16 75 75\n");
   fprintf(outfp, "FONTBOUNDINGBOX 16 16 0 -2\n");
   fprintf(outfp, "STARTPROPERTIES 2\n");
   fprintf(outfp, "FONT_ASCENT 14\n");
   fprintf(outfp, "FONT_DESCENT 2\n");
   fprintf(outfp, "ENDPROPERTIES\n");
   fprintf(outfp, "CHARS %d\n", nglyphs);  /* total glyphs in hex file */
   /*
      Now print the bitmap for each glyph.
   */
   while (fgets(inbuf, MAXBUF-1, infp) != NULL) {
      sscanf(inbuf, "%x", &thischar);
      /* find bitmap in this string and copy it */
      for (k0 = 0; inbuf[k0] != ':'; k0++);
      k0++;  /* point to first hex digit */

      fullwidth = inbuf[k0 + 32] >= '0';

      fprintf(outfp, "STARTCHAR U+%04X\n", thischar);
      fprintf(outfp, "ENCODING %d\n", thischar);
      fprintf(outfp, "SWIDTH %d 0\n", fullwidth ? 1000 : 500);
      fprintf(outfp, "DWIDTH %d 0\n", fullwidth ? 16 : 8);
      fprintf(outfp, "BBX %d 16 0 -2\n", fullwidth ? 16 : 8);
      fprintf(outfp, "BITMAP \n");
      /*
         Print each row as a separate bitmap line.
         A line has 4 hex digits if full width, 2 if half width.
      */
      for (j = 0; j < 16; j++) {
         if (fullwidth) {
            fprintf(outfp, "%c%c", inbuf[k0], inbuf[k0+1]);
            k0 += 2;
         }
         fprintf(outfp, "%c%c\n", inbuf[k0], inbuf[k0+1]);
         k0 += 2;
      }
      fprintf(outfp, "ENDCHAR\n");
   }
   fprintf(outfp, "ENDFONT\n");
}
