bdf2xbm.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. Simple program to convert a bdf-font to a bitmap.
  3. The characters are arranged in a 32x8 matrix.
  4. usage: bdf2xbm [identifier] <bdf >xbm
  5. Copyright 1998,1999 by E. Toernig (froese@gmx.de)
  6. */
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include <stdarg.h>
  12. #define not !
  13. #define streq(a,b) (strcmp((a),(b)) == 0)
  14. int lineno;
  15. char *word[64];
  16. int nword;
  17. char *font = "font%dx%d";
  18. int w, h, bpl;
  19. unsigned char *bmap;
  20. static void error(char *fmt, ...)
  21. {
  22. va_list args;
  23. va_start(args, fmt);
  24. fprintf(stderr, "bdf2xbm");
  25. if (lineno)
  26. fprintf(stderr, ":%d", lineno);
  27. fprintf(stderr, ": ");
  28. vfprintf(stderr, fmt, args);
  29. fputc('\n', stderr);
  30. exit(1);
  31. }
  32. static int nextline()
  33. {
  34. static char buf[256];
  35. char *p;
  36. int i;
  37. do
  38. {
  39. nword = 0;
  40. if (fgets(buf, sizeof(buf), stdin) == 0)
  41. return nword;
  42. lineno++;
  43. p = buf;
  44. for (;;)
  45. {
  46. while (isspace(*p))
  47. p++;
  48. if (*p == 0)
  49. break;
  50. word[nword++] = p;
  51. while (*p && not isspace(*p))
  52. *p = toupper(*p), p++;
  53. if (*p == 0)
  54. break;
  55. *p++ = 0;
  56. }
  57. } while (nword == 0);
  58. for (i = nword; i < 64; ++i)
  59. word[i] = "";
  60. return nword;
  61. }
  62. static inline void setbit(int ch, int x, int y)
  63. {
  64. int yo = ch / 32 * h + y;
  65. int xo = ch % 32 * w + x;
  66. bmap[yo * bpl + xo / 8] |= 1 << (xo % 8);
  67. }
  68. static void dobitmap(int ch, int x, int y)
  69. {
  70. int i, j;
  71. for (i = 0; i < y; ++i)
  72. {
  73. nextline();
  74. if (nword > 1 || strlen(word[0]) != (x + 7) / 8 * 2)
  75. error("bad BITMAP");
  76. for (j = 0; j < x; ++j)
  77. {
  78. int c = word[0][j / 4];
  79. if (c >= '0' && c <= '9')
  80. c -= '0';
  81. else if (c >= 'A' && c <= 'F')
  82. c -= 'A' - 10;
  83. else
  84. error("bad hexchar in BITMAP");
  85. if (c & (8 >> (j % 4)))
  86. setbit(ch, j, i);
  87. }
  88. }
  89. }
  90. static void dochar()
  91. {
  92. int ch = -1, x = -1, y = -1;
  93. while (nextline())
  94. {
  95. if (streq(word[0], "ENDCHAR"))
  96. return;
  97. else if (streq(word[0], "ENCODING") && nword == 2)
  98. {
  99. ch = atoi(word[1]);
  100. if (ch < 0 || ch > 255)
  101. error("bad character code %d", ch);
  102. }
  103. else if (streq(word[0], "BBX") && nword == 5)
  104. {
  105. x = atoi(word[1]), y = atoi(word[2]);
  106. if (x < 1 || x > 64 || y < 1 || y > 64)
  107. error("bad BBX (%dx%d)", x, y);
  108. }
  109. else if (streq(word[0], "BITMAP"))
  110. {
  111. if (x < 0)
  112. error("missing BBX");
  113. if (ch < 0)
  114. error("missing ENDCODING");
  115. dobitmap(ch, x, y);
  116. }
  117. }
  118. error("unexpected EOF (missing ENDCHAR)");
  119. }
  120. static void dofile()
  121. {
  122. lineno = 0;
  123. w = h = 0;
  124. bmap = 0;
  125. nextline();
  126. if (nword != 2 || not streq(word[0], "STARTFONT"))
  127. error("not a bdf-file");
  128. while (nextline())
  129. {
  130. if (streq(word[0], "ENDFONT"))
  131. return;
  132. else if (streq(word[0], "FONTBOUNDINGBOX") && nword == 5)
  133. {
  134. if (bmap)
  135. error("multiple FONTBOUNDINGBOXes!?!");
  136. w = atoi(word[1]), h = atoi(word[2]);
  137. if (w < 1 || w > 64 || h < 1 || h > 64)
  138. error("bad bounding box %dx%d\n", w, h);
  139. bpl = (w*32+7)/8; // rounding is unnecessary
  140. bmap = calloc(1, bpl * h*8);
  141. if (bmap == 0)
  142. error("out of memory");
  143. }
  144. else if (streq(word[0], "STARTCHAR"))
  145. {
  146. if (not bmap)
  147. error("no FONTBOUNDINGBOX");
  148. dochar();
  149. }
  150. }
  151. error("unexpected EOF (missing ENDFONT)");
  152. }
  153. static void writexbm()
  154. {
  155. char buf[256];
  156. int i, j;
  157. unsigned char *p = bmap;
  158. if (not bmap)
  159. return;
  160. sprintf(buf, font, w, h);
  161. printf("#define %s_width %d\n", buf, 32 * w);
  162. printf("#define %s_height %d\n", buf, 8 * h);
  163. printf("static unsigned char %s_bits[] = {\n", buf);
  164. for (i = 0; i < 16 * h * w / 8; ++i)
  165. {
  166. for (j = 0; j < 16; ++j)
  167. printf("0x%02x,", *p++);
  168. printf("\n");
  169. }
  170. printf("};\n");
  171. }
  172. int main(int argc, char **argv)
  173. {
  174. if (argc > 1)
  175. font = argv[1];
  176. dofile();
  177. writexbm();
  178. exit(0);
  179. }