URI:
       tibmfont.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tibmfont.c (5358B)
       ---
            1 /*
            2  *
            3  * Program that converts IBM font files to a format that works on Unix systems.
            4  * Essentially all the information needed came from the Adobe paper "Supporting
            5  * Downloadable PostScript Fonts". To use the program type,
            6  *
            7  *        ibmfont font.ibm >font.unix
            8  *
            9  * where font.ibm is the font file, exactly as it came over from an IBM PC,
           10  * and font.unix is equivalent host resident font file usable on Unix systems.
           11  *
           12  */
           13 
           14 #include <stdio.h>
           15 #include <signal.h>
           16 
           17 #define OFF                0
           18 #define ON                1
           19 
           20 #define NON_FATAL        0
           21 #define FATAL                1
           22 
           23 #define FALSE                0
           24 #define TRUE                1
           25 
           26 char        **argv;
           27 int        argc;
           28 
           29 char        *prog_name;
           30 
           31 int        x_stat;
           32 int        debug = OFF;
           33 int        ignore = OFF;
           34 
           35 FILE        *fp_in;
           36 FILE        *fp_out;
           37 
           38 /*****************************************************************************/
           39 
           40 main(agc, agv)
           41 
           42     int                agc;
           43     char        *agv[];
           44 
           45 {
           46 
           47 /*
           48  *
           49  * IBM PC to Unix font converter.
           50  *
           51  */
           52 
           53     argc = agc;
           54     argv = agv;
           55     prog_name = argv[0];
           56 
           57     fp_in = stdin;
           58     fp_out = stdout;
           59 
           60     options();
           61     arguments();
           62     exit(x_stat);
           63 
           64 }   /* End of main */
           65 
           66 /*****************************************************************************/
           67 
           68 options()
           69 
           70 {
           71 
           72     int                ch;
           73     char        *names = "DI";
           74 
           75     extern char        *optarg;
           76     extern int        optind;
           77 
           78 /*
           79  *
           80  * Command line options.
           81  *
           82  */
           83 
           84     while ( (ch = getopt(argc, argv, names)) != EOF ) {
           85         switch ( ch ) {
           86             case 'D':                        /* debug flag */
           87                     debug = ON;
           88                     break;
           89 
           90             case 'I':                        /* ignore FATAL errors */
           91                     ignore = ON;
           92                     break;
           93 
           94             case '?':                        /* don't understand the option */
           95                     error(FATAL, "");
           96                     break;
           97 
           98             default:                        /* don't know what to do for ch */
           99                     error(FATAL, "missing case for option %c\n", ch);
          100                     break;
          101         }   /* End switch */
          102     }   /* End while */
          103 
          104     argc -= optind;
          105     argv += optind;
          106 
          107 }   /* End of options */
          108 
          109 /*****************************************************************************/
          110 
          111 arguments()
          112 
          113 {
          114 
          115 /*
          116  *
          117  * Everything esle is an input file. No arguments or '-' means stdin.
          118  *
          119  */
          120 
          121 
          122     if ( argc < 1 )
          123         conv();
          124     else
          125         while ( argc > 0 ) {
          126             if ( strcmp(*argv, "-") == 0 )
          127                 fp_in = stdin;
          128             else if ( (fp_in = fopen(*argv, "r")) == NULL )
          129                 error(FATAL, "can't open %s", *argv);
          130             conv();
          131             if ( fp_in != stdin )
          132                 fclose(fp_in);
          133             argc--;
          134             argv++;
          135         }   /* End while */
          136 
          137 }   /* End of arguments */
          138 
          139 /*****************************************************************************/
          140 
          141 conv()
          142 
          143 {
          144 
          145     int                blocksize;
          146     int                blocktype;
          147     int                seg;
          148     long        ftell();
          149 
          150 /*
          151  *
          152  * Font files on the IBM PC are stored in a compressed binary format. Individual
          153  * segments in the file are preceeded by a header that looks like,
          154  *
          155  *                Byte 1:                128
          156  *                Byte 2:                segment type (1=ASCII, 2=TOHEX, or 3=EOF)
          157  *                Bytes 3-6:        length of the segment
          158  *                Bytes 7 ...        data
          159  *
          160  */
          161 
          162     while ( 1 ) {
          163         seg = ftell(fp_in);
          164         if ( getc(fp_in) != 128 )
          165             error(FATAL, "bad file format");
          166         blocktype = getc(fp_in);
          167         blocksize = getint(fp_in);
          168         if ( debug == ON ) {
          169             fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
          170             fprintf(stderr, "start=0%o, end=0%o\n", seg, seg+blocksize+6);
          171             fprintf(stderr, "start=%d, end=%d\n", seg, seg+blocksize+6);
          172         }   /* End if */
          173         switch ( blocktype ) {
          174             case 1:
          175                 asciitext(blocksize);
          176                 break;
          177 
          178             case 2:
          179                 hexdata(blocksize);
          180                 break;
          181 
          182             case 3:
          183                 return;
          184 
          185             default:
          186                 error(FATAL, "unknown resource type %d", blocktype);
          187         }   /* End switch */
          188     }        /* End while */
          189 
          190 }   /* End of conv */
          191 
          192 /*****************************************************************************/
          193 
          194 asciitext(count)
          195 
          196     int                count;                        /* bytes left in the block */
          197 
          198 {
          199 
          200     int                ch;
          201     int                i = 0;
          202 
          203 /*
          204  *
          205  * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
          206  * is all I've done.
          207  *
          208  */
          209 
          210     for ( i = 0; i < count; i++ ) {
          211         if ( (ch = getc(fp_in)) == '\r' )
          212             ch = '\n';
          213         putc(ch, fp_out);
          214     }        /* End for */
          215 
          216 }   /* End of asciitext */
          217 
          218 /*****************************************************************************/
          219 
          220 hexdata(count)
          221 
          222     int                count;                        /* bytes left in the block */
          223 
          224 {
          225 
          226     int                i;
          227     int                n;
          228 
          229 /*
          230  *
          231  * Reads the next count bytes and converts each byte to hex. Also starts a new
          232  * line every 80 hex characters.
          233  *
          234  */
          235 
          236     for ( i = 0, n = 0; i < count; i++ ) {
          237         fprintf(fp_out, "%.2X", getc(fp_in));
          238         if ( (++n % 40) == 0 )
          239             putc('\n', fp_out);
          240     }        /* End for */
          241 
          242 }   /* End of hexdata */
          243 
          244 /*****************************************************************************/
          245 
          246 getint()
          247 
          248 {
          249 
          250     int                val;
          251 
          252 /*
          253  *
          254  * Reads the next four bytes into an integer and returns the value to the caller.
          255  * First two bytes are probably always 0.
          256  *
          257  */
          258 
          259     val = getc(fp_in);
          260     val |= (getc(fp_in) << 8);
          261     val |= (getc(fp_in) << 16);
          262     val |= (getc(fp_in) << 24);
          263 
          264     return(val);
          265 
          266 }   /* End of getint */
          267 
          268 /*****************************************************************************/
          269 
          270 error(kind, mesg, a1, a2, a3)
          271 
          272     int                kind;
          273     char        *mesg;
          274     unsigned        a1, a2, a3;
          275 
          276 {
          277 
          278 /*
          279  *
          280  * Print mesg and quit if kind is FATAL.
          281  *
          282  */
          283 
          284     if ( mesg != NULL && *mesg != '\0' ) {
          285         fprintf(stderr, "%s: ", prog_name);
          286         fprintf(stderr, mesg, a1, a2, a3);
          287         putc('\n', stderr);
          288     }        /* End if */
          289 
          290     if ( kind == FATAL && ignore == OFF )
          291         exit(x_stat | 01);
          292 
          293 }   /* End of error */
          294 
          295 /*****************************************************************************/