ibmfont.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. #include <stdio.h>
  14. #include <signal.h>
  15. #define OFF 0
  16. #define ON 1
  17. #define NON_FATAL 0
  18. #define FATAL 1
  19. #define FALSE 0
  20. #define TRUE 1
  21. char **argv;
  22. int argc;
  23. char *prog_name;
  24. int x_stat;
  25. int debug = OFF;
  26. int ignore = OFF;
  27. FILE *fp_in = stdin;
  28. FILE *fp_out = stdout;
  29. /*****************************************************************************/
  30. main(agc, agv)
  31. int agc;
  32. char *agv[];
  33. {
  34. /*
  35. *
  36. * IBM PC to Unix font converter.
  37. *
  38. */
  39. argc = agc;
  40. argv = agv;
  41. prog_name = argv[0];
  42. options();
  43. arguments();
  44. exit(x_stat);
  45. } /* End of main */
  46. /*****************************************************************************/
  47. options()
  48. {
  49. int ch;
  50. char *names = "DI";
  51. extern char *optarg;
  52. extern int optind;
  53. /*
  54. *
  55. * Command line options.
  56. *
  57. */
  58. while ( (ch = getopt(argc, argv, names)) != EOF ) {
  59. switch ( ch ) {
  60. case 'D': /* debug flag */
  61. debug = ON;
  62. break;
  63. case 'I': /* ignore FATAL errors */
  64. ignore = ON;
  65. break;
  66. case '?': /* don't understand the option */
  67. error(FATAL, "");
  68. break;
  69. default: /* don't know what to do for ch */
  70. error(FATAL, "missing case for option %c\n", ch);
  71. break;
  72. } /* End switch */
  73. } /* End while */
  74. argc -= optind;
  75. argv += optind;
  76. } /* End of options */
  77. /*****************************************************************************/
  78. arguments()
  79. {
  80. /*
  81. *
  82. * Everything esle is an input file. No arguments or '-' means stdin.
  83. *
  84. */
  85. if ( argc < 1 )
  86. conv();
  87. else
  88. while ( argc > 0 ) {
  89. if ( strcmp(*argv, "-") == 0 )
  90. fp_in = stdin;
  91. else if ( (fp_in = fopen(*argv, "r")) == NULL )
  92. error(FATAL, "can't open %s", *argv);
  93. conv();
  94. if ( fp_in != stdin )
  95. fclose(fp_in);
  96. argc--;
  97. argv++;
  98. } /* End while */
  99. } /* End of arguments */
  100. /*****************************************************************************/
  101. conv()
  102. {
  103. int blocksize;
  104. int blocktype;
  105. int seg;
  106. long ftell();
  107. /*
  108. *
  109. * Font files on the IBM PC are stored in a compressed binary format. Individual
  110. * segments in the file are preceeded by a header that looks like,
  111. *
  112. * Byte 1: 128
  113. * Byte 2: segment type (1=ASCII, 2=TOHEX, or 3=EOF)
  114. * Bytes 3-6: length of the segment
  115. * Bytes 7 ... data
  116. *
  117. */
  118. while ( 1 ) {
  119. seg = ftell(fp_in);
  120. if ( getc(fp_in) != 128 )
  121. error(FATAL, "bad file format");
  122. blocktype = getc(fp_in);
  123. blocksize = getint(fp_in);
  124. if ( debug == ON ) {
  125. fprintf(stderr, "blocktype = %d, blocksize = %d\n", blocktype, blocksize);
  126. fprintf(stderr, "start=0%o, end=0%o\n", seg, seg+blocksize+6);
  127. fprintf(stderr, "start=%d, end=%d\n", seg, seg+blocksize+6);
  128. } /* End if */
  129. switch ( blocktype ) {
  130. case 1:
  131. asciitext(blocksize);
  132. break;
  133. case 2:
  134. hexdata(blocksize);
  135. break;
  136. case 3:
  137. return;
  138. default:
  139. error(FATAL, "unknown resource type %d", blocktype);
  140. } /* End switch */
  141. } /* End while */
  142. } /* End of conv */
  143. /*****************************************************************************/
  144. asciitext(count)
  145. int count; /* bytes left in the block */
  146. {
  147. int ch;
  148. int i = 0;
  149. /*
  150. *
  151. * Handles type 1 (ie. ASCII text) blocks. Changing carriage returns to newlines
  152. * is all I've done.
  153. *
  154. */
  155. for ( i = 0; i < count; i++ ) {
  156. if ( (ch = getc(fp_in)) == '\r' )
  157. ch = '\n';
  158. putc(ch, fp_out);
  159. } /* End for */
  160. } /* End of asciitext */
  161. /*****************************************************************************/
  162. hexdata(count)
  163. int count; /* bytes left in the block */
  164. {
  165. int i;
  166. int n;
  167. /*
  168. *
  169. * Reads the next count bytes and converts each byte to hex. Also starts a new
  170. * line every 80 hex characters.
  171. *
  172. */
  173. for ( i = 0, n = 0; i < count; i++ ) {
  174. fprintf(fp_out, "%.2X", getc(fp_in));
  175. if ( (++n % 40) == 0 )
  176. putc('\n', fp_out);
  177. } /* End for */
  178. } /* End of hexdata */
  179. /*****************************************************************************/
  180. getint()
  181. {
  182. int val;
  183. /*
  184. *
  185. * Reads the next four bytes into an integer and returns the value to the caller.
  186. * First two bytes are probably always 0.
  187. *
  188. */
  189. val = getc(fp_in);
  190. val |= (getc(fp_in) << 8);
  191. val |= (getc(fp_in) << 16);
  192. val |= (getc(fp_in) << 24);
  193. return(val);
  194. } /* End of getint */
  195. /*****************************************************************************/
  196. error(kind, mesg, a1, a2, a3)
  197. int kind;
  198. char *mesg;
  199. unsigned a1, a2, a3;
  200. {
  201. /*
  202. *
  203. * Print mesg and quit if kind is FATAL.
  204. *
  205. */
  206. if ( mesg != NULL && *mesg != '\0' ) {
  207. fprintf(stderr, "%s: ", prog_name);
  208. fprintf(stderr, mesg, a1, a2, a3);
  209. putc('\n', stderr);
  210. } /* End if */
  211. if ( kind == FATAL && ignore == OFF )
  212. exit(x_stat | 01);
  213. } /* End of error */
  214. /*****************************************************************************/