bdf2u8g.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. /*
  2. general font collections
  3. https://www.smashingmagazine.com/2007/11/08/40-excellent-freefonts-for-professional-design/
  4. https://techmagazine.ws/most-popular-free-quality-fonts/
  5. https://openfontlibrary.org/
  6. bitmap font collections
  7. https://www.orgdot.com/aliasfonts/ (includes links)
  8. https://www.04.jp.org/
  9. https://www.miniml.com
  10. https://www.fontspace.com/010bus
  11. https://en.wikipedia.org/wiki/Unicode_typeface
  12. da könnten auch ein paar fonts dabei sein, die die m2tklib sonderzeichen beinhalten:
  13. Caslon Roman https://en.wikipedia.org/wiki/Caslon_Roman
  14. Charis Sil https://en.wikipedia.org/wiki/Charis_SIL
  15. DejaVu Sans https://en.wikipedia.org/wiki/DejaVu_fonts
  16. Doulos https://en.wikipedia.org/wiki/Doulos_SIL
  17. Free Serif https://en.wikipedia.org/wiki/FreeSerif https://ftp.gnu.org/gnu/freefont/
  18. --> keine box, aber es gibt pfeile/invertierte pfeile und kreise für m2tklib
  19. Gentium Plus ???? https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=Gentium_download#02b091ae
  20. --> keine graphic
  21. GNU Unifont https://en.wikipedia.org/wiki/GNU_Unifont, https://unifoundry.com/unifont.html
  22. Titus cyberbit Basic https://en.wikipedia.org/wiki/TITUS_Cyberbit_Basic
  23. fonts
  24. Gentium
  25. https://openfontlibrary.org/font/gentium
  26. license: OFL
  27. Old-Standard
  28. https://openfontlibrary.org/font/old-standard
  29. license: OFL
  30. Hanuman
  31. https://openfontlibrary.org/font/hanumanb
  32. license: OFL
  33. FreeUniversal
  34. https://openfontlibrary.org/font/freeuniversal
  35. license: OFL
  36. FriendShip-Code <--- nicht so sicher...
  37. https://openfontlibrary.org/font/friendship-code
  38. license: CC-BY-SA
  39. LinuxLibertine
  40. https://de.wikipedia.org/wiki/Linux_Libertine
  41. https://sourceforge.net/projects/linuxlibertine/files/linuxlibertine/5.1.3-2/
  42. license: OFL
  43. DidactGothic
  44. source: https://openfontlibrary.org/
  45. judson
  46. source: https://openfontlibrary.org/
  47. unicons
  48. source: https://openfontlibrary.org/
  49. license: OFL
  50. suggested pt: 26, 30
  51. org_V01, fixed_V0
  52. source: https://www.orgdot.com/aliasfonts/
  53. license: open source, individual, cite required
  54. suggested pt: 8
  55. 04b_03b.zip 04b_03.zip 04b_09.zip 04b_11.zip 04b_19.zip 04b_21.zip 04b_25.zip 04b_30.zip
  56. source: https://www.04.jp.org/
  57. license: "Freeware: You may use them as you like"
  58. 7px4bus
  59. source: https://www.fontspace.com/010bus
  60. license: Licensed as: Freeware, Commercial use allowed!
  61. suggested 7pt
  62. 8pxbus
  63. source: https://www.fontspace.com/010bus
  64. license: Licensed as: Freeware, Commercial use allowed!
  65. suggested 8pt
  66. */
  67. /*
  68. only supports metric set "0"
  69. assume DWIDTH second arg to be 0 for all glyphs
  70. assumes that (0,0) of the BBX is placed on the base line
  71. assumes ISO10646 encoding of the BDF file
  72. font information
  73. offset
  74. 0 font format
  75. 1 FONTBOUNDINGBOX width unsigned
  76. 2 FONTBOUNDINGBOX height unsigned
  77. 3 FONTBOUNDINGBOX x-offset signed
  78. 4 FONTBOUNDINGBOX y-offset signed
  79. 5 capital A height unsigned
  80. 6 start 'A'
  81. 8 start 'a'
  82. 10 encoding start
  83. 11 encoding end
  84. 12 descent 'g' negative: below baseline
  85. 13 font max ascent
  86. 14 font min decent negative: below baseline
  87. 15 xascent (ascent of "(")
  88. 16 xdescent (descent of ")")
  89. format 0
  90. glyph information
  91. offset
  92. 0 BBX width unsigned
  93. 1 BBX height unsigned
  94. 2 data size unsigned (BBX width + 7)/8 * BBX height
  95. 3 DWIDTH signed
  96. 4 BBX xoffset signed
  97. 5 BBX yoffset signed
  98. format 1
  99. 0 BBX xoffset signed --> upper 4 Bit
  100. 0 BBX yoffset signed --> lower 4 Bit
  101. 1 BBX width unsigned --> upper 4 Bit
  102. 1 BBX height unsigned --> lower 4 Bit
  103. 2 data size unsigned -(BBX width + 7)/8 * BBX height --> lower 4 Bit
  104. 2 DWIDTH signed --> upper 4 Bit
  105. byte 0 == 255 indicates empty glyph
  106. format 2
  107. like format 0, but 4 gray levels for the glyph (4 pixel per byte in the glyph data)
  108. The glyph bitmap size is defined by BBX width and BBX height
  109. number of bytes in the bitmap data (BBX width + 7)/8 * BBX height (format 0 and 1)
  110. draw_text(x,y,str)
  111. get_text_frame(x,y,str, &x1, &y1, &width, &height)
  112. frame( x1, y1, width, height)
  113. underline( x1, y-1, width )
  114. size of the surrounding bbox
  115. width = - xoffset(c1) + DWIDTH(c1) + DWIDTH(c2) + ... + DWIDTH(cn-1) + width(cn) + xoffset(cn)
  116. height = FONTBOUNDINGBOX height
  117. x1 = x + xoffset(c1)
  118. y1 = y + yoffset(c1)
  119. ISO-8859-1 was incorporated as the first 256 code points of ISO/IEC 10646 and Unicode.
  120. */
  121. #include <stdio.h>
  122. #include <stdlib.h>
  123. #include <string.h>
  124. #include <assert.h>
  125. #define BDF2U8G_COMPACT_OUTPUT
  126. #define BDF2U8G_VERSION "1.01"
  127. //#define VERBOSE
  128. /*=== forward declaration ===*/
  129. void bdf_aa_ClearDoShow(void);
  130. void bdf_aa_Do(void);
  131. /*=== result data ===*/
  132. #define DATA_BUF_SIZE (1024 * 64)
  133. unsigned char data_buf[DATA_BUF_SIZE];
  134. int data_pos = 0;
  135. void data_Init(void) {
  136. data_pos = 0;
  137. }
  138. void data_Put(unsigned char c) {
  139. data_buf[data_pos] = c;
  140. data_pos++;
  141. }
  142. void data_Write(FILE *out_fp, const char *indent) {
  143. int i;
  144. int bytes_per_line = 16;
  145. for (i = 0; i < data_pos; i++) {
  146. fprintf(out_fp, "0x%02X", data_buf[i]);
  147. if (i + 1 != data_pos)
  148. fprintf(out_fp, ",");
  149. if ((i + 1) % bytes_per_line == 0)
  150. fprintf(out_fp, "\n%s", indent);
  151. }
  152. }
  153. /*=== low level parser ===*/
  154. #define P_BUF_SIZE (1024 * 4)
  155. int p_current_char;
  156. const char *p_line;
  157. char p_buf[P_BUF_SIZE];
  158. /* put next char into p_current_char */
  159. static int p_next_char(void) {
  160. p_current_char = *p_line;
  161. if (p_current_char == '\0')
  162. return 0;
  163. p_line++;
  164. return 1;
  165. }
  166. int p_first_char(const char *line) {
  167. p_line = line;
  168. return p_next_char();
  169. }
  170. void p_err(const char *msg) {
  171. }
  172. int p_skip_space(void) {
  173. for (;;) {
  174. if (p_current_char == 0 || p_current_char > 32)
  175. break;
  176. if (p_next_char() == 0)
  177. return 0;
  178. }
  179. return 1;
  180. }
  181. /* put identifier into p_buf */
  182. int p_get_identifier(void) {
  183. int i = 0;
  184. if (p_current_char == '\0')
  185. return p_err("unexpected EOF (expected identifier)"), 0;
  186. for (;;) {
  187. if (p_current_char <= 32)
  188. break;
  189. p_buf[i++] = p_current_char;
  190. if (p_next_char() == 0)
  191. break;
  192. }
  193. p_buf[i++] = '\0';
  194. p_skip_space();
  195. return 1;
  196. }
  197. /* put identifier into p_buf */
  198. int p_get_identifier_with_blank(void) {
  199. int i = 0;
  200. for (;;) {
  201. if (p_current_char < 32)
  202. break;
  203. p_buf[i++] = p_current_char;
  204. if (p_next_char() == 0)
  205. break;
  206. }
  207. p_buf[i++] = '\0';
  208. p_skip_space();
  209. return 1;
  210. }
  211. int p_get_string(void) {
  212. int i = 0;
  213. if (p_current_char == '\0')
  214. return 0;
  215. if (p_current_char != '\"')
  216. return p_err("\" expected"), 0;
  217. if (p_next_char() == 0)
  218. return p_err("unexpected EOF (\")"), 0;
  219. for (;;) {
  220. if (p_current_char == '\\') {
  221. if (p_next_char() == 0)
  222. return p_err("unexpected EOF (\\)"), 0;
  223. }
  224. else if (p_current_char == '\"') {
  225. p_next_char();
  226. break;
  227. }
  228. p_buf[i++] = p_current_char;
  229. if (p_next_char() == 0)
  230. return p_err("unexpected EOF (\")"), 0;
  231. }
  232. p_buf[i] = '\0';
  233. return 1;
  234. }
  235. int p_get_any(void) {
  236. if (p_current_char == '\"')
  237. return p_get_string();
  238. return p_get_identifier();
  239. }
  240. int p_get_val(void) {
  241. p_get_any();
  242. return atoi(p_buf);
  243. }
  244. int p_get_hex(void) {
  245. int value = 0;
  246. if (p_current_char >= '0' && p_current_char <= '9')
  247. value = p_current_char - '0';
  248. else if (p_current_char >= 'a' && p_current_char <= 'f')
  249. value = p_current_char - 'a' + 10;
  250. else if (p_current_char >= 'A' && p_current_char <= 'F')
  251. value = p_current_char - 'A' + 10;
  252. p_next_char();
  253. return value;
  254. }
  255. int p_get_hex_byte(void) {
  256. int v;
  257. v = p_get_hex();
  258. v *= 16;
  259. v += p_get_hex();
  260. return v;
  261. }
  262. /*=== encoding mapping ===*/
  263. /* the internal u8g index number (0..255) is mapped to the unicode number */
  264. /* for the conversion we need the reverse search */
  265. /* 0 is special and means not found */
  266. int map_u8g_to_unicode[256];
  267. int map_UnicodeToU8G(int unicode) {
  268. int i;
  269. for (i = 0; i < 256; i++)
  270. if (map_u8g_to_unicode[i] == unicode)
  271. return i;
  272. return 0;
  273. }
  274. void map_Init(void) {
  275. int i;
  276. map_u8g_to_unicode[0] = 0;
  277. for (i = 0; i < 256; i++) map_u8g_to_unicode[i] = i;
  278. }
  279. void map_UpperLowerPage(int lower_page, int upper_page, int shift, int upper_shift) {
  280. int i;
  281. int encoding;
  282. int tmp[256];
  283. // map_u8g_to_unicode[0] = 0;
  284. for (i = 0; i < 128; i++) {
  285. encoding = i + lower_page * 128;
  286. map_u8g_to_unicode[i] = encoding;
  287. }
  288. for (i = 128; i < 256; i++) {
  289. encoding = i - 128 + upper_page * 128;
  290. if (i + upper_shift < 256)
  291. map_u8g_to_unicode[i + upper_shift] = encoding;
  292. }
  293. for (i = 0; i < 256; i++) tmp[i] = map_u8g_to_unicode[i];
  294. for (i = 0; i < shift; i++) map_u8g_to_unicode[i] = -1;
  295. for (i = shift; i < 256; i++) map_u8g_to_unicode[i] = tmp[(i + 256 - shift) % 256];
  296. /*
  297. printf("map_u8g_to_unicode[ 32 ] = %d\n", map_u8g_to_unicode[ 32 ]);
  298. printf("map_u8g_to_unicode[ 33 ] = %d\n", map_u8g_to_unicode[ 33 ]);
  299. */
  300. }
  301. /*=== store bdf file positions ===*/
  302. long bdf_last_line_start_pos;
  303. long bdf_encoding_pos[256];
  304. void bdf_InitFilePos(void) {
  305. int i;
  306. for (i = 0; i < 256; i++) bdf_encoding_pos[i] = 0;
  307. }
  308. void bdf_SetFilePos(FILE *fp, int encoding) {
  309. if (encoding < 0)
  310. return;
  311. if (bdf_encoding_pos[encoding] == 0L)
  312. return;
  313. fseek(fp, bdf_encoding_pos[encoding], SEEK_SET);
  314. // fprintf(stderr, "setting file for encoding %d to pos %ld\n", encoding, bdf_encoding_pos[encoding]);
  315. }
  316. int bdf_IsEncodingAvailable(int encoding) {
  317. if (bdf_encoding_pos[encoding] == 0L)
  318. // printf("encoding %d not availabe\n", encoding);
  319. return 0;
  320. return 1;
  321. }
  322. void bdf_StoreFilePos(int encoding, long pos) {
  323. // if ( encoding == 33 )
  324. // printf("encoding %d at pos %ld\n", encoding, pos);
  325. if (bdf_encoding_pos[encoding] != 0L)
  326. return;
  327. bdf_encoding_pos[encoding] = pos;
  328. }
  329. /*=== bdf file read ===*/
  330. int bdf_font_format = 0;
  331. #define BDF_STATE_FONT_DATA 0
  332. #define BDF_STATE_ENCODING 1
  333. int bdf_state = BDF_STATE_FONT_DATA;
  334. int bdf_requested_encoding = 0;
  335. #define BDF_LINE_MAX (1024 * 4)
  336. #define BDF_LINE_STATE_KEYWORDS 0
  337. #define BDF_LINE_STATE_BITMAP 1
  338. #define BDF_MAX_HEIGHT 200
  339. #define BDF_AA_OFFSET 1
  340. char bdf_copyright[BDF_LINE_MAX];
  341. char bdf_font[BDF_LINE_MAX];
  342. unsigned char bdf_bitmap_line[BDF_MAX_HEIGHT][20];
  343. unsigned char bdf_aa_bitmap_line[BDF_MAX_HEIGHT + 2 * BDF_AA_OFFSET][(20 + 2 * BDF_AA_OFFSET) * 8];
  344. int bdf_line_state = BDF_LINE_STATE_KEYWORDS;
  345. int bdf_line_bm_line = 0;
  346. int bdf_font_size; /* point font size */
  347. int bdf_font_width; /* FONTBOUNDINGBOX arg 1 */
  348. int bdf_font_height; /* FONTBOUNDINGBOX arg 2 */
  349. int bdf_font_x; /* FONTBOUNDINGBOX arg 3 */
  350. int bdf_font_y; /* FONTBOUNDINGBOX arg 4 */
  351. int bdf_capital_A_height;
  352. int bdf_capital_1_height;
  353. int bdf_lower_g_descent;
  354. int bdf_char_width; /* BBX arg 1 */
  355. int bdf_char_max_width;
  356. int bdf_char_height; /* BBX arg 2 */
  357. int bdf_char_ascent; /* defined as BBX arg 2 + BBX arg 4 */
  358. int bdf_char_xascent;
  359. int bdf_char_xdescent;
  360. int bdf_char_max_ascent;
  361. int bdf_char_max_height;
  362. int bdf_char_x; /* BBX arg 3 */
  363. int bdf_char_max_x;
  364. int bdf_char_min_x;
  365. int bdf_char_y; /* BBX arg 4 */
  366. int bdf_char_max_y;
  367. int bdf_char_min_y;
  368. int bdf_delta_x_default = -1;
  369. int bdf_delta_x = -1; /* DWIDTH arg 1 */
  370. int bdf_delta_max_x;
  371. int bdf_delta_min_x;
  372. int bdf_delta_y; /* DWIDTH arg 2 */
  373. int bdf_delta_max_y;
  374. int bdf_delta_min_y;
  375. int bdf_glyph_data_len;
  376. int bdf_glyph_data_max_len;
  377. int bdf_encoding;
  378. int bdf_encoding_65_pos;
  379. int bdf_encoding_97_pos;
  380. int bdf_is_encoding_successfully_done;
  381. char bdf_info[32000 * 2];
  382. int bdf_is_put_glyph_completed = 0; /* indicator, when the glyph has been processed */
  383. void bdf_ResetMax(void) {
  384. bdf_char_max_width = 0;
  385. bdf_char_max_height = 0;
  386. bdf_char_max_x = 0;
  387. bdf_char_max_y = 0;
  388. bdf_delta_max_x = 0;
  389. bdf_delta_max_y = 0;
  390. bdf_char_min_x = 0;
  391. bdf_char_min_y = 0;
  392. bdf_delta_min_x = 0;
  393. bdf_delta_min_y = 0;
  394. bdf_glyph_data_max_len = 0;
  395. bdf_char_max_ascent = 0;
  396. bdf_char_xascent = 0;
  397. bdf_char_xdescent = 0;
  398. }
  399. void bdf_UpdateMax(void) {
  400. if (bdf_char_max_width < bdf_char_width)
  401. bdf_char_max_width = bdf_char_width;
  402. if (bdf_char_max_height < bdf_char_height)
  403. bdf_char_max_height = bdf_char_height;
  404. if (bdf_char_max_x < bdf_char_x)
  405. bdf_char_max_x = bdf_char_x;
  406. if (bdf_char_max_y < bdf_char_y)
  407. bdf_char_max_y = bdf_char_y;
  408. if (bdf_delta_max_x < bdf_delta_x)
  409. bdf_delta_max_x = bdf_delta_x;
  410. if (bdf_delta_max_y < bdf_delta_y)
  411. bdf_delta_max_y = bdf_delta_y;
  412. if (bdf_char_min_x > bdf_char_x)
  413. bdf_char_min_x = bdf_char_x;
  414. if (bdf_char_min_y > bdf_char_y)
  415. bdf_char_min_y = bdf_char_y;
  416. if (bdf_delta_min_x > bdf_delta_x)
  417. bdf_delta_min_x = bdf_delta_x;
  418. if (bdf_delta_min_y > bdf_delta_y)
  419. bdf_delta_min_y = bdf_delta_y;
  420. if (bdf_glyph_data_max_len < bdf_glyph_data_len)
  421. bdf_glyph_data_max_len = bdf_glyph_data_len;
  422. if (bdf_char_max_ascent < bdf_char_ascent)
  423. bdf_char_max_ascent = bdf_char_ascent;
  424. }
  425. void bdf_ShowGlyph(void) {
  426. #ifdef VERBOSE
  427. int x, y, byte, bit;
  428. int gx, gy;
  429. char *p;
  430. gy = bdf_char_height - 1 + bdf_char_y;
  431. printf("bbx %d %d %d %d encoding %d\n", bdf_char_width, bdf_char_height, bdf_char_x, bdf_char_y, bdf_encoding);
  432. for (y = 0; y < bdf_line_bm_line; y++) {
  433. printf("%02d ", gy);
  434. gx = bdf_char_x;
  435. for (x = 0; x < bdf_char_width; x++) {
  436. byte = x >> 3;
  437. bit = 7 - (x & 7);
  438. if ((bdf_bitmap_line[y][byte] & (1 << bit)) == 0)
  439. p = " .";
  440. else
  441. p = " *";
  442. if (gy == 0 && gx == 0)
  443. p = " o";
  444. printf("%s", p);
  445. gx++;
  446. }
  447. printf(" ");
  448. for (x = 0; x < ((bdf_char_width + 7) / 8); x++) printf( "%02X", bdf_bitmap_line[y][x]);
  449. gy--;
  450. printf("\n");
  451. }
  452. #else
  453. printf("bbx %d %d %d %d encoding %d\n", bdf_char_width, bdf_char_height, bdf_char_x, bdf_char_y, bdf_encoding);
  454. fflush(stdout);
  455. #endif
  456. }
  457. void bdf_ClearGlyphBuffer(void) {
  458. int x, y;
  459. for (y = 0; y < BDF_MAX_HEIGHT; y++)
  460. for (x = 0; x < 20; x++) bdf_bitmap_line[y][x] = 0;
  461. }
  462. void bdf_PutGlyph(void) {
  463. int len;
  464. int y, x;
  465. if (bdf_state == BDF_STATE_ENCODING) {
  466. //if (bdf_char_width == 0 && bdf_char_height == 0) bdf_char_y = 0;
  467. bdf_char_ascent = bdf_char_height + bdf_char_y;
  468. //printf("h:%d w:%d ascent: %d\n", bdf_char_height, bdf_char_width, bdf_char_ascent);
  469. if (bdf_encoding == 'A')
  470. bdf_capital_A_height = bdf_char_height;
  471. if (bdf_encoding == '1')
  472. bdf_capital_1_height = bdf_char_height;
  473. if (bdf_encoding == 'g')
  474. bdf_lower_g_descent = bdf_char_y;
  475. if (bdf_char_xascent < bdf_capital_A_height)
  476. bdf_char_xascent = bdf_capital_A_height;
  477. if (bdf_char_xascent < bdf_capital_1_height)
  478. bdf_char_xascent = bdf_capital_1_height;
  479. if (bdf_encoding == '(')
  480. if (bdf_char_xascent < bdf_char_ascent)
  481. bdf_char_xascent = bdf_char_ascent;
  482. if (bdf_encoding == '[')
  483. if (bdf_char_xascent < bdf_char_ascent)
  484. bdf_char_xascent = bdf_char_ascent;
  485. if (bdf_char_xdescent > bdf_lower_g_descent)
  486. bdf_char_xdescent = bdf_lower_g_descent;
  487. if (bdf_encoding == '(')
  488. if (bdf_char_xdescent > bdf_char_y)
  489. bdf_char_xdescent = bdf_char_y;
  490. if (bdf_encoding == '[')
  491. if (bdf_char_xdescent > bdf_char_y)
  492. bdf_char_xdescent = bdf_char_y;
  493. if (bdf_requested_encoding != bdf_encoding)
  494. return;
  495. assert( bdf_line_bm_line == bdf_char_height);
  496. bdf_ShowGlyph();
  497. #ifdef VERBOSE
  498. bdf_aa_ClearDoShow();
  499. #endif
  500. bdf_UpdateMax();
  501. if (bdf_font_format <= 1)
  502. len = (bdf_char_width + 7) / 8 * bdf_char_height;
  503. else
  504. len = (bdf_char_width + 2 * BDF_AA_OFFSET + 3) / 4 * (bdf_char_height + 2 * BDF_AA_OFFSET);
  505. if (len > 255) {
  506. fprintf(stderr, "Glyph with encoding %d is too large (%d > 255)\n", bdf_encoding, len);
  507. exit(1);
  508. }
  509. bdf_glyph_data_len = len;
  510. /*
  511. format 0 and format 2
  512. glyph information
  513. offset
  514. 0 BBX width unsigned
  515. 1 BBX height unsigned
  516. 2 data size unsigned (BBX width + 7)/8 * BBX height
  517. 3 DWIDTH signed
  518. 4 BBX xoffset signed
  519. 5 BBX yoffset signed
  520. */
  521. if (bdf_font_format == 0) {
  522. data_Put(bdf_char_width);
  523. data_Put(bdf_char_height);
  524. data_Put(bdf_glyph_data_len);
  525. data_Put(bdf_delta_x);
  526. data_Put(bdf_char_x);
  527. data_Put(bdf_char_y);
  528. // data_Put(bdf_encoding);
  529. bdf_is_encoding_successfully_done = 1;
  530. }
  531. else if (bdf_font_format == 2) {
  532. data_Put(bdf_char_width + 2 * BDF_AA_OFFSET);
  533. data_Put(bdf_char_height + 2 * BDF_AA_OFFSET);
  534. data_Put(bdf_glyph_data_len);
  535. data_Put(bdf_delta_x);
  536. data_Put(bdf_char_x - BDF_AA_OFFSET);
  537. data_Put(bdf_char_y - BDF_AA_OFFSET);
  538. // data_Put(bdf_encoding);
  539. bdf_is_encoding_successfully_done = 1;
  540. }
  541. else {
  542. /**
  543. * format 1
  544. * 0 BBX xoffset signed --> upper 4 Bit
  545. * 0 BBX yoffset signed --> lower 4 Bit
  546. * 1 BBX width unsigned --> upper 4 Bit
  547. * 1 BBX height unsigned --> lower 4 Bit
  548. * 2 data size unsigned -(BBX width + 7)/8 * BBX height --> lower 4 Bit
  549. * 2 DWIDTH signed --> upper 4 Bit
  550. * byte 0 == 255 indicates empty glyph
  551. */
  552. if (bdf_glyph_data_len < 0 || bdf_glyph_data_len > 15) {
  553. fprintf(stderr, "Glyph with encoding %d does not fit for format 1 (data len = %d)\n", bdf_encoding, bdf_glyph_data_len);
  554. exit(1);
  555. }
  556. if (bdf_delta_x < 0 || bdf_delta_x > 15) {
  557. fprintf(stderr, "Glyph with encoding %d does not fit for format 1 (DWIDTH = %d)\n", bdf_encoding, bdf_delta_x);
  558. exit(1);
  559. }
  560. if (bdf_char_x < 0 || bdf_char_x > 15) {
  561. fprintf(stderr, "Glyph with encoding %d does not fit for format 1 (x-off = %d)\n", bdf_encoding, bdf_char_x);
  562. exit(1);
  563. }
  564. if (bdf_char_y < -2 || bdf_char_y > 13) {
  565. fprintf(stderr, "Glyph with encoding %d does not fit for format 1 (y-off = %d [%d..%d])\n", bdf_encoding, bdf_char_y, bdf_char_min_y, bdf_char_max_y);
  566. exit(1);
  567. }
  568. if (bdf_char_width < 0 || bdf_char_width > 15) {
  569. fprintf(stderr, "Glyph with encoding %d does not fit for format 1 (width = %d)\n", bdf_encoding, bdf_char_width);
  570. exit(1);
  571. }
  572. if (bdf_char_height < 0 || bdf_char_height > 15) {
  573. fprintf(stderr, "Glyph with encoding %d does not fit for format 1 (height = %d)\n", bdf_encoding, bdf_char_height);
  574. exit(1);
  575. }
  576. // data_Put(bdf_encoding);
  577. if (((bdf_char_x << 4) | (bdf_char_y + 2)) == 255) {
  578. fprintf(stderr, "Glyph with encoding %d does not fit for format 1 (skip mark generated)\n", bdf_encoding);
  579. exit(1);
  580. }
  581. data_Put((bdf_char_x << 4) | (bdf_char_y + 2));
  582. data_Put((bdf_char_width << 4) | bdf_char_height );
  583. data_Put((bdf_delta_x << 4) | bdf_glyph_data_len );
  584. bdf_is_encoding_successfully_done = 1;
  585. }
  586. sprintf(bdf_info + strlen(bdf_info), "/* encoding %d %c, bbx %d %d %d %d asc %d dx %d*/\n",
  587. bdf_encoding,
  588. bdf_encoding > 32 && bdf_encoding <= 'z' ? bdf_encoding : ' ',
  589. bdf_char_width,
  590. bdf_char_height,
  591. bdf_char_x,
  592. bdf_char_y,
  593. bdf_char_ascent,
  594. bdf_delta_x);
  595. if (bdf_font_format <= 1) {
  596. for (y = 0; y < bdf_char_height; y++)
  597. for (x = 0; x < ((bdf_char_width + 7) / 8); x++) {
  598. data_Put(bdf_bitmap_line[y][x]);
  599. len--;
  600. }
  601. assert( len == 0 );
  602. bdf_is_put_glyph_completed = 1;
  603. }
  604. else { /* format == 2 */
  605. int b, cnt;
  606. bdf_aa_Do();
  607. for (y = 0; y < bdf_char_height + 2 * BDF_AA_OFFSET; y++) {
  608. b = 0;
  609. cnt = 0;
  610. for (x = 0; x < bdf_char_width + 2 * BDF_AA_OFFSET; x++) {
  611. b <<= 2;
  612. b |= bdf_aa_bitmap_line[y][x] & 3;
  613. cnt++;
  614. if (cnt == 4) {
  615. data_Put(b);
  616. b = 0;
  617. cnt = 0;
  618. len--;
  619. }
  620. }
  621. if (cnt != 0) {
  622. b <<= 2 * (4 - cnt);
  623. data_Put(b);
  624. b = 0;
  625. cnt = 0;
  626. len--;
  627. }
  628. }
  629. assert( len == 0 );
  630. }
  631. }
  632. }
  633. /*=========================================================================*/
  634. /* Glyph Clipping */
  635. int bdf_IsColZero(int x) {
  636. int y, byte, bit;
  637. for (y = 0; y < bdf_char_height; y++) {
  638. byte = x >> 3;
  639. bit = 7 - (x & 7);
  640. if ((bdf_bitmap_line[y][byte] & (1 << bit)) != 0)
  641. return 0;
  642. }
  643. return 1;
  644. }
  645. int bdf_IsRowZero(int y) {
  646. int x, byte, bit;
  647. for (x = 0; x < bdf_char_width; x++) {
  648. byte = x >> 3;
  649. bit = 7 - (x & 7);
  650. if ((bdf_bitmap_line[y][byte] & (1 << bit)) != 0)
  651. return 0;
  652. }
  653. return 1;
  654. }
  655. void bdf_DeleteFirstCol(void) {
  656. int m = (bdf_char_width + 7) / 8;
  657. int x, y;
  658. for (y = 0; y < bdf_char_height; y++)
  659. for (x = 0; x < m; x++) {
  660. bdf_bitmap_line[y][x] <<= 1;
  661. bdf_bitmap_line[y][x] |= bdf_bitmap_line[y][x + 1] >> 7;
  662. }
  663. }
  664. void bdf_DeleteFirstRow(void) {
  665. int m = (bdf_char_width + 7) / 8;
  666. int x, y;
  667. for (y = 0; y + 1 < bdf_char_height; y++)
  668. for (x = 0; x < m; x++)
  669. bdf_bitmap_line[y][x] = bdf_bitmap_line[y + 1][x];
  670. }
  671. void bdf_ReduceGlyph(void) {
  672. while (bdf_char_width > 0) {
  673. if (bdf_IsColZero(bdf_char_width - 1) == 0)
  674. break;
  675. bdf_char_width--;
  676. }
  677. while (bdf_char_height > 0) {
  678. if (bdf_IsRowZero(bdf_char_height - 1) == 0)
  679. break;
  680. bdf_line_bm_line--;
  681. bdf_char_height--;
  682. bdf_char_y++;
  683. }
  684. while (bdf_IsColZero(0) != 0 && bdf_char_width > 0) {
  685. bdf_DeleteFirstCol();
  686. bdf_char_x++;
  687. bdf_char_width--;
  688. }
  689. while (bdf_char_height > 0) {
  690. if (bdf_IsRowZero(0) == 0)
  691. break;
  692. bdf_DeleteFirstRow();
  693. bdf_line_bm_line--;
  694. bdf_char_height--;
  695. }
  696. }
  697. /*=========================================================================*/
  698. /* Anti Aliasing / Graylevel Glyph */
  699. int bdf_GetXYVal(int x, int y) {
  700. int byte, bit;
  701. if (x < 0) return 0;
  702. if (y < 0) return 0;
  703. if (x >= bdf_char_width) return 0;
  704. if (y >= bdf_char_height) return 0;
  705. byte = x >> 3;
  706. bit = 7 - (x & 7);
  707. if ((bdf_bitmap_line[y][byte] & (1 << bit)) != 0) return 1;
  708. return 0;
  709. }
  710. void bdf_aa_Clear(void) {
  711. int x, y;
  712. for (y = 0; y < BDF_MAX_HEIGHT + 2 * BDF_AA_OFFSET; y++)
  713. for (x = 0; x < (20 + 2 * BDF_AA_OFFSET) * 8; x++)
  714. bdf_aa_bitmap_line[y][x] = 0;
  715. }
  716. void bdf_aa_SetXYVal(int x, int y, int val) {
  717. bdf_aa_bitmap_line[y][x] = val;
  718. }
  719. int bdf_aa_matrix[9] = {
  720. 1, 3, 1,
  721. 3, 4, 3,
  722. 1, 3, 1
  723. };
  724. int bdf_aa_sum = 20;
  725. int bdf_aa_gray_levels = 4;
  726. void bdf_aa_Do(void) {
  727. int x, y, val, sx, sy, sum, gray;
  728. bdf_aa_Clear();
  729. for (y = 0; y < bdf_char_height + 2 * BDF_AA_OFFSET; y++)
  730. for (x = 0; x < bdf_char_width + 2 * BDF_AA_OFFSET; x++) {
  731. if (bdf_GetXYVal(x - BDF_AA_OFFSET, y - BDF_AA_OFFSET) == 0) {
  732. sum = 0;
  733. for (sy = -BDF_AA_OFFSET; sy <= BDF_AA_OFFSET; sy++)
  734. for (sx = -BDF_AA_OFFSET; sx <= BDF_AA_OFFSET; sx++) {
  735. val = bdf_GetXYVal(x + sx - BDF_AA_OFFSET, y + sy - BDF_AA_OFFSET);
  736. val *= bdf_aa_matrix[(sy + BDF_AA_OFFSET) * (2 * BDF_AA_OFFSET + 1) + sx + BDF_AA_OFFSET];
  737. sum += val;
  738. }
  739. if (sum <= 5)
  740. gray = 0;
  741. else
  742. gray = (sum * (bdf_aa_gray_levels - 1) + (bdf_aa_sum / 2)) / bdf_aa_sum;
  743. if (gray >= bdf_aa_gray_levels)
  744. gray = bdf_aa_gray_levels - 1;
  745. }
  746. else {
  747. gray = bdf_aa_gray_levels - 1;
  748. }
  749. bdf_aa_SetXYVal(x, y, gray);
  750. }
  751. }
  752. void bdf_aa_Show(void) {
  753. int x, y;
  754. if (bdf_font_format == 2) {
  755. for (y = 0; y < bdf_char_height + 2 * BDF_AA_OFFSET; y++) {
  756. for (x = 0; x < bdf_char_width + 2 * BDF_AA_OFFSET; x++)
  757. switch (bdf_aa_bitmap_line[y][x]) {
  758. case 0: printf("."); break;
  759. case 1: printf("-"); break;
  760. case 2: printf("+"); break;
  761. case 3: printf("#"); break;
  762. }
  763. printf("\n");
  764. }
  765. }
  766. }
  767. void bdf_aa_ClearDoShow(void) {
  768. bdf_aa_Do();
  769. bdf_aa_Show();
  770. }
  771. /*=========================================================================*/
  772. /* Parser */
  773. void bdf_ReadLine(const char *s) {
  774. /*
  775. if ( bdf_line_state == BDF_LINE_STATE_BITMAP && bdf_requested_encoding != bdf_encoding && *s != 'E' )
  776. return;
  777. */
  778. if (p_first_char(s) == 0) return;
  779. if (p_skip_space() == 0) return;
  780. if (bdf_line_state == BDF_LINE_STATE_KEYWORDS) {
  781. p_get_identifier();
  782. if (strcmp(p_buf, "COPYRIGHT") == 0) {
  783. p_get_any();
  784. strcpy(bdf_copyright, p_buf);
  785. }
  786. else if (strcmp(p_buf, "FONT") == 0) {
  787. /* p_get_any(); */
  788. p_get_identifier_with_blank();
  789. strcpy(bdf_font, p_buf);
  790. }
  791. else if (strcmp(p_buf, "SIZE") == 0) {
  792. bdf_font_size = p_get_val();
  793. }
  794. else if (strcmp(p_buf, "ENCODING") == 0) {
  795. bdf_encoding = map_UnicodeToU8G(p_get_val());
  796. bdf_StoreFilePos(bdf_encoding, bdf_last_line_start_pos);
  797. }
  798. else if (strcmp(p_buf, "DWIDTH") == 0) {
  799. bdf_delta_x = p_get_val();
  800. bdf_delta_y = p_get_val();
  801. }
  802. else if (strcmp(p_buf, "FONTBOUNDINGBOX") == 0) {
  803. bdf_font_width = p_get_val();
  804. bdf_font_height = p_get_val();
  805. bdf_font_x = p_get_val();
  806. bdf_font_y = p_get_val();
  807. }
  808. else if (strcmp(p_buf, "BBX") == 0) {
  809. bdf_char_width = p_get_val();
  810. bdf_char_height = p_get_val();
  811. bdf_char_x = p_get_val();
  812. bdf_char_y = p_get_val();
  813. bdf_char_ascent = bdf_char_height + bdf_char_y;
  814. // printf("h:%d w:%d ascent: %d\n", bdf_char_height, bdf_char_width, bdf_char_ascent);
  815. }
  816. else if (strcmp(p_buf, "CHARS") == 0) {
  817. if (bdf_delta_x < 0)
  818. bdf_delta_x = 0;
  819. if (bdf_delta_x_default < 0)
  820. bdf_delta_x_default = bdf_delta_x;
  821. }
  822. else if (strcmp(p_buf, "STARTCHAR") == 0) {
  823. if (bdf_delta_x_default < 0)
  824. bdf_delta_x_default = 0;
  825. bdf_delta_x = bdf_delta_x_default;
  826. }
  827. else if (strcmp(p_buf, "BITMAP") == 0) {
  828. bdf_line_state = BDF_LINE_STATE_BITMAP;
  829. bdf_line_bm_line = 0;
  830. }
  831. }
  832. else if (bdf_line_state == BDF_LINE_STATE_BITMAP) {
  833. if (strncmp(s, "ENDCHAR", 7) == 0) {
  834. bdf_ReduceGlyph();
  835. bdf_PutGlyph();
  836. bdf_line_state = BDF_LINE_STATE_KEYWORDS;
  837. bdf_line_bm_line = 0;
  838. }
  839. else if (bdf_requested_encoding == bdf_encoding) {
  840. int i = 0;
  841. for (;;) {
  842. if (p_current_char < '0') break;
  843. bdf_bitmap_line[bdf_line_bm_line][i] = p_get_hex_byte();
  844. i++;
  845. }
  846. bdf_line_bm_line++;
  847. assert(bdf_line_bm_line < BDF_MAX_HEIGHT);
  848. }
  849. }
  850. }
  851. int bdf_ReadFP(FILE *fp) {
  852. static char bdf_line[BDF_LINE_MAX];
  853. bdf_is_put_glyph_completed = 0;
  854. for (;;) {
  855. bdf_last_line_start_pos = ftell(fp);
  856. if (fgets(bdf_line, BDF_LINE_MAX - 1, fp) == NULL)
  857. break;
  858. bdf_ReadLine(bdf_line);
  859. if (bdf_is_put_glyph_completed != 0)
  860. break;
  861. }
  862. return 1;
  863. }
  864. int bdf_ReadFile(const char *filename, int encoding) {
  865. int r;
  866. FILE *fp;
  867. fp = fopen(filename, "rb");
  868. if (fp != NULL) {
  869. bdf_SetFilePos(fp, encoding);
  870. r = bdf_ReadFP(fp);
  871. fclose(fp);
  872. return r;
  873. }
  874. return 0; /* open error */
  875. }
  876. void bdf_GenerateFontData(const char *filename, int begin, int end) {
  877. bdf_state = BDF_STATE_FONT_DATA;
  878. bdf_ReadFile(filename, -1);
  879. /**
  880. * font information
  881. *
  882. * offset
  883. * 0 font format
  884. * 1 FONTBOUNDINGBOX width unsigned
  885. * 2 FONTBOUNDINGBOX height unsigned
  886. * 3 FONTBOUNDINGBOX x-offset signed
  887. * 4 FONTBOUNDINGBOX y-offset signed
  888. * 5 Capital A Height unsigned
  889. * 6 position of encoding 65 'A' high byte first
  890. * 8 position of encoding 97 'a' high byte first
  891. */
  892. data_Put(bdf_font_format);
  893. data_Put(bdf_font_width);
  894. data_Put(bdf_font_height);
  895. data_Put(bdf_font_x);
  896. data_Put(bdf_font_y);
  897. data_Put(bdf_capital_A_height > 0 ? bdf_capital_A_height : bdf_capital_1_height);
  898. data_Put(0);
  899. data_Put(0);
  900. data_Put(0);
  901. data_Put(0);
  902. data_Put(begin);
  903. data_Put(end); /* will be overwritten later */
  904. data_Put(0); /* lower g descent */
  905. data_Put(0); /* max ascent */
  906. data_Put(0); /* min y = descent */
  907. data_Put(0); /* x ascent */
  908. data_Put(0); /* x descent */
  909. }
  910. void bdf_GenerateGlyph(const char *filename, int encoding) {
  911. bdf_ClearGlyphBuffer();
  912. bdf_requested_encoding = encoding;
  913. bdf_state = BDF_STATE_ENCODING;
  914. bdf_ReadFile(filename, encoding);
  915. }
  916. void bdf_Generate(const char *filename, int begin, int end) {
  917. int i;
  918. int last_valid_encoding;
  919. bdf_encoding_65_pos = 0;
  920. bdf_encoding_97_pos = 0;
  921. bdf_InitFilePos();
  922. bdf_ResetMax();
  923. bdf_info[0] = '\0';
  924. bdf_font[0] = '\0';
  925. bdf_copyright[0] = '\0';
  926. bdf_GenerateFontData(filename, begin, end);
  927. for (i = begin; i <= end; i++) {
  928. if (i == 65) bdf_encoding_65_pos = data_pos;
  929. if (i == 97) bdf_encoding_97_pos = data_pos;
  930. bdf_is_encoding_successfully_done = 0;
  931. if (bdf_IsEncodingAvailable(i))
  932. bdf_GenerateGlyph(filename, i);
  933. if (bdf_is_encoding_successfully_done == 0)
  934. data_Put(255); /* no char encoding */
  935. if (bdf_is_encoding_successfully_done != 0)
  936. last_valid_encoding = i;
  937. }
  938. /* data_Put(255); obsolete, not required any more for format 0 */ /* encoding 255, end of font data (format 0) */
  939. data_buf[5] = bdf_capital_A_height > 0 ? bdf_capital_A_height : bdf_capital_1_height;
  940. data_buf[6] = (bdf_encoding_65_pos >> 8);
  941. data_buf[7] = (bdf_encoding_65_pos & 255);
  942. data_buf[8] = (bdf_encoding_97_pos >> 8);
  943. data_buf[9] = (bdf_encoding_97_pos & 255);
  944. data_buf[12] = bdf_lower_g_descent;
  945. data_buf[13] = bdf_char_max_ascent;
  946. data_buf[14] = bdf_char_min_y;
  947. data_buf[15] = bdf_char_xascent;
  948. data_buf[16] = bdf_char_xdescent;
  949. if (0) data_buf[11] = last_valid_encoding;
  950. }
  951. void bdf_WriteC(const char *outname, const char *fontname) {
  952. int capital_ascent;
  953. FILE *out_fp;
  954. out_fp = fopen(outname, "wb");
  955. assert( out_fp != NULL );
  956. capital_ascent = bdf_capital_A_height > 0 ? bdf_capital_A_height : bdf_capital_1_height;
  957. fprintf(out_fp, "/**\n");
  958. fprintf(out_fp, " * Fontname: %s\n", bdf_font);
  959. fprintf(out_fp, " * Copyright: %s\n", bdf_copyright);
  960. fprintf(out_fp, " * Capital A Height: %d, '1' Height: %d\n", bdf_capital_A_height, bdf_capital_1_height);
  961. fprintf(out_fp, " * Calculated Max Values w=%2d h=%2d x=%2d y=%2d dx=%2d dy=%2d ascent=%2d len=%2d\n",
  962. bdf_char_max_width, bdf_char_max_height, bdf_char_max_x, bdf_char_max_y, bdf_delta_max_x, bdf_delta_max_y,
  963. bdf_char_max_ascent, bdf_glyph_data_max_len);
  964. fprintf(out_fp, " * Font Bounding box w=%2d h=%2d x=%2d y=%2d\n",
  965. bdf_font_width, bdf_font_height, bdf_font_x, bdf_font_y);
  966. fprintf(out_fp, " * Calculated Min Values x=%2d y=%2d dx=%2d dy=%2d\n",
  967. bdf_char_min_x, bdf_char_min_y, bdf_delta_min_x, bdf_delta_min_y);
  968. fprintf(out_fp, " * Pure Font ascent =%2d descent=%2d\n", capital_ascent, bdf_lower_g_descent);
  969. fprintf(out_fp, " * X Font ascent =%2d descent=%2d\n", bdf_char_xascent, bdf_char_xdescent);
  970. fprintf(out_fp, " * Max Font ascent =%2d descent=%2d\n", bdf_char_max_ascent, bdf_char_min_y);
  971. fprintf(out_fp, " */\n");
  972. fprintf(out_fp, "const u8g_fntpgm_uint8_t %s[%d] U8G_FONT_SECTION(\"%s\") = {\n", fontname, data_pos, fontname);
  973. fprintf(out_fp, " ");
  974. data_Write(out_fp, " ");
  975. fprintf(out_fp, "};\n");
  976. #ifndef BDF2U8G_COMPACT_OUTPUT
  977. fprintf(out_fp, "%s\n", bdf_info);
  978. #endif
  979. fclose(out_fp);
  980. }
  981. int ga_argc;
  982. char **ga_argv;
  983. void ga_remove_arg(void) {
  984. if (ga_argc == 0) return;
  985. ga_argc--;
  986. ga_argv++;
  987. }
  988. int ga_is_arg(char opt) {
  989. if (ga_argc == 0) return 0;
  990. if (ga_argv[0] == NULL) return 0;
  991. if (ga_argv[0][0] != '-') return 0;
  992. if (ga_argv[0][1] != opt) return 0;
  993. ga_remove_arg();
  994. return 1;
  995. }
  996. int main(int argc, char **argv) {
  997. int lower_page = 0;
  998. int upper_page = 1;
  999. int mapping_shift = 0;
  1000. int upper_mapping_shift = 0;
  1001. int begin = 32;
  1002. int end = 255;
  1003. if (argc < 4) {
  1004. printf("bdf to u8glib font format converter v" BDF2U8G_VERSION "\n");
  1005. printf("%s [-l page] [-u page] [-s shift] [-S upper-shift] [-b begin] [-e end] [-f format] fontfile fontname outputfile\n", argv[0]);
  1006. return 1;
  1007. }
  1008. ga_argc = argc;
  1009. ga_argv = argv;
  1010. ga_remove_arg(); /* remove program name */
  1011. for (;;) {
  1012. if (ga_is_arg('l')) {
  1013. lower_page = atoi(ga_argv[0]);
  1014. ga_remove_arg();
  1015. }
  1016. else if (ga_is_arg('u')) {
  1017. upper_page = atoi(ga_argv[0]);
  1018. ga_remove_arg();
  1019. }
  1020. else if (ga_is_arg('s')) {
  1021. mapping_shift = atoi(ga_argv[0]);
  1022. ga_remove_arg();
  1023. }
  1024. else if (ga_is_arg('S')) {
  1025. upper_mapping_shift = atoi(ga_argv[0]);
  1026. ga_remove_arg();
  1027. }
  1028. else if (ga_is_arg('b')) {
  1029. begin = atoi(ga_argv[0]);
  1030. ga_remove_arg();
  1031. }
  1032. else if (ga_is_arg('e')) {
  1033. end = atoi(ga_argv[0]);
  1034. ga_remove_arg();
  1035. }
  1036. else if (ga_is_arg('f')) {
  1037. bdf_font_format = atoi(ga_argv[0]);
  1038. ga_remove_arg();
  1039. }
  1040. else {
  1041. break;
  1042. }
  1043. }
  1044. printf("encoding range %d..%d\n", begin, end);
  1045. data_Init();
  1046. map_Init();
  1047. map_UpperLowerPage(lower_page, upper_page, mapping_shift, upper_mapping_shift);
  1048. /*
  1049. puts(bdf_font);
  1050. puts(bdf_copyright);
  1051. if (ga_argc < 3) {
  1052. printf("from page %d to page %d\n", lower_page, upper_page);
  1053. return 1;
  1054. }
  1055. */
  1056. bdf_Generate(ga_argv[0], begin, end);
  1057. bdf_WriteC(ga_argv[2], ga_argv[1]);
  1058. printf("input file '%s'\n", ga_argv[0]);
  1059. printf("u8g font name '%s'\n", ga_argv[1]);
  1060. printf("output file '%s'\n", ga_argv[2]);
  1061. return 0;
  1062. }