URI:
       tmacfont.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
       ---
       tmacfont.c (5672B)
       ---
            1 /*
            2  *
            3  * Program that converts Macintosh font files to a format that works on Unix
            4  * systems. Essentially all the information needed came from the Adobe paper
            5  * "Supporting Downloadable PostScript Fonts". To use the program type,
            6  *
            7  *        macfont font.mac >font.unix
            8  *
            9  * where font.mac is the font file, exactly as it came over from a Macintosh,
           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  * Macintosh 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  *
          118  * Everything else is an input file. No arguments or '-' means stdin.
          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 
          148 /*
          149  *
          150  * The first four bytes (in a block) are the block size, the fifth is the block
          151  * type, and the sixth always appears to be NULL. Type 0 blocks are comments and
          152  * are always skipped. Type 1 blocks are ASCII text, type 2 is binary data that
          153  * should be converted to hex, while type 5 blocks represent the end of the font
          154  * file. Commment block lengths appear to be from the first byte, while other
          155  * lengths seem to be measured from block type byte (ie. the fifth byte). Type
          156  * four blocks aren't used, while type 3 blocks mean an end of file indication
          157  * should be sent to the printer. Haven't done anything with type 3 blocks.
          158  *
          159  */
          160 
          161     while ( 1 ) {
          162         blocksize = getint(fp_in);
          163         blocktype = getc(fp_in);
          164         getc(fp_in);
          165         if ( debug == ON )
          166             fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
          167         switch ( blocktype ) {
          168             case 0:                        /* comment - skip blockcount bytes */
          169                 fseek(fp_in, (long) blocksize - 6, 1);
          170                 break;
          171 
          172             case 1:
          173                 asciitext(blocksize - 2);
          174                 break;
          175 
          176             case 2:
          177                 hexdata(blocksize - 2);
          178                 break;
          179 
          180             case 3:
          181             case 4:
          182                 error(FATAL, "resource type %d not implemented", blocktype);
          183                 break;
          184 
          185             case 5:
          186                 return;
          187 
          188             default:
          189                 error(FATAL, "unknown resource type %d", blocktype);
          190         }   /* End switch */
          191     }        /* End while */
          192 
          193 }   /* End of conv */
          194 
          195 /*****************************************************************************/
          196 
          197 asciitext(count)
          198 
          199     int                count;                        /* bytes left in the block */
          200 
          201 {
          202 
          203     int                ch;
          204     int                i = 0;
          205 
          206 /*
          207  *
          208  * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
          209  * is all I've done.
          210  *
          211  */
          212 
          213     for ( i = 0; i < count; i++ ) {
          214         if ( (ch = getc(fp_in)) == '\r' )
          215             ch = '\n';
          216         putc(ch, fp_out);
          217     }        /* End for */
          218 
          219 }   /* End of asciitext */
          220 
          221 /*****************************************************************************/
          222 
          223 hexdata(count)
          224 
          225     int                count;                        /* bytes left in the block */
          226 
          227 {
          228 
          229     int                i;
          230     int                n;
          231 
          232 /*
          233  *
          234  * Reads the next count bytes and converts each byte to hex. Also starts a new
          235  * line every 80 hex characters.
          236  *
          237  */
          238 
          239     for ( i = 0, n = 0; i < count; i++ ) {
          240         fprintf(fp_out, "%.2X", getc(fp_in));
          241         if ( (++n % 40) == 0 )
          242             putc('\n', fp_out);
          243     }        /* End for */
          244 
          245 }   /* End of hexdata */
          246 
          247 /*****************************************************************************/
          248 
          249 getint()
          250 
          251 {
          252 
          253     int                val;
          254     int                i;
          255 
          256 /*
          257  *
          258  * Reads the next four bytes into an integer and returns the value to the caller.
          259  * First two bytes are probably always 0.
          260  *
          261  */
          262 
          263     for ( i = 0, val = (getc(fp_in) & 0377); i < 3; i++ )
          264         val = (val << 8) | (getc(fp_in) & 0377);
          265 
          266     return(val);
          267 
          268 }   /* End of getint */
          269 
          270 /*****************************************************************************/
          271 
          272 error(kind, mesg, a1, a2, a3)
          273 
          274 
          275     int                kind;
          276     char        *mesg;
          277     unsigned        a1, a2, a3;
          278 
          279 {
          280 
          281 /*
          282  *
          283  * Print *mesg then quit if kind is FATAL.
          284  *
          285  */
          286 
          287     if ( mesg != NULL && *mesg != '\0' ) {
          288         fprintf(stderr, "%s: ", prog_name);
          289         fprintf(stderr, mesg, a1, a2, a3);
          290         putc('\n', stderr);
          291     }        /* End if */
          292 
          293     if ( kind == FATAL && ignore == OFF )
          294         exit(x_stat | 01);
          295 
          296 }   /* End of error */
          297 
          298 /*****************************************************************************/