bdf_font.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. #include <stdlib.h>
  2. #include <stdarg.h>
  3. #include "bdf_font.h"
  4. void bf_Error(bf_t *bf, char *fmt, ...)
  5. {
  6. va_list va;
  7. va_start(va, fmt);
  8. vprintf(fmt, va);
  9. printf("\n");
  10. va_end(va);
  11. }
  12. void bf_Log(bf_t *bf, char *fmt, ...)
  13. {
  14. va_list va;
  15. va_start(va, fmt);
  16. if ( bf->is_verbose != 0 )
  17. {
  18. vprintf(fmt, va);
  19. printf("\n");
  20. }
  21. va_end(va);
  22. }
  23. /*
  24. bf_Open(0, BDF_BBX_MODE_MINIMAL)
  25. */
  26. bf_t *bf_Open(int is_verbose, int bbx_mode)
  27. {
  28. bf_t *bf;
  29. bf = (bf_t *)malloc(sizeof(bf_t));
  30. if ( bf != NULL )
  31. {
  32. bf->is_verbose = is_verbose;
  33. bf->glyph_list = NULL;
  34. bf->glyph_cnt = 0;
  35. bf->glyph_max = 0;
  36. bf->str_font = NULL; /* argument for FONT in bdf file */
  37. bf->str_copyright = NULL; /* argument for COPYRIGHT in bdf file */
  38. bf->target_data = NULL;
  39. bf->target_max = 0;
  40. bf->target_cnt = 0;
  41. bf->selected_glyphs = 0;
  42. bf->enc_w = 0;
  43. bf->enc_h = 0;
  44. bf->enc_x = 0;
  45. bf->enc_y = 0;
  46. bf->bbx_mode = bbx_mode;
  47. bf->tile_h_size = 1;
  48. bf->tile_v_size = 1;
  49. return bf;
  50. }
  51. return NULL;
  52. }
  53. void bf_Clear(bf_t *bf)
  54. {
  55. int i;
  56. for( i = 0; i < bf->glyph_cnt; i++ )
  57. {
  58. free( bf->glyph_list[i] );
  59. }
  60. bf->glyph_cnt = 0;
  61. if ( bf->str_font != NULL )
  62. free(bf->str_font);
  63. bf->str_font = NULL;
  64. if ( bf->str_copyright != NULL )
  65. free(bf->str_copyright);
  66. bf->str_copyright = NULL;
  67. }
  68. void bf_Close(bf_t *bf)
  69. {
  70. bf_Clear(bf);
  71. if ( bf->glyph_list != NULL )
  72. free(bf->glyph_list);
  73. if ( bf->target_data != NULL )
  74. free(bf->target_data);
  75. bf->glyph_list = NULL;
  76. bf->glyph_max = 0;
  77. free(bf);
  78. }
  79. static int bf_extend(bf_t *bf)
  80. {
  81. int extend = 16;
  82. void *ptr;
  83. if ( bf->glyph_list == NULL )
  84. {
  85. ptr = malloc(extend*sizeof(bg_t *));
  86. bf->glyph_max = 0;
  87. }
  88. else
  89. {
  90. ptr = realloc(bf->glyph_list, (bf->glyph_max + extend)*sizeof(bg_t *));
  91. }
  92. if ( ptr == NULL )
  93. return 0;
  94. bf->glyph_max += extend;
  95. bf->glyph_list = (bg_t **)ptr;
  96. return 1;
  97. }
  98. /* returns glyph position or -1 */
  99. int bf_AddGlyph(bf_t *bf)
  100. {
  101. while( bf->glyph_max <= bf->glyph_cnt )
  102. if ( bf_extend(bf) == 0 )
  103. return -1;
  104. bf->glyph_list[bf->glyph_cnt] = bg_Open();
  105. if ( bf->glyph_list[bf->glyph_cnt] == NULL )
  106. return -1;
  107. bf->glyph_list[bf->glyph_cnt]->bf = bf;
  108. bf->glyph_cnt++;
  109. return bf->glyph_cnt-1;
  110. }
  111. static int bf_extend_target_data(bf_t *bf)
  112. {
  113. int extend = 16;
  114. int i;
  115. void *ptr;
  116. if ( bf->target_data == NULL )
  117. {
  118. ptr = malloc(extend*sizeof(uint8_t));
  119. bf->target_max = 0;
  120. }
  121. else
  122. {
  123. ptr = realloc(bf->target_data, (bf->target_max + extend)*sizeof(uint8_t));
  124. }
  125. if ( ptr == NULL )
  126. return 0;
  127. bf->target_data = (uint8_t *)ptr;
  128. for( i = bf->target_max; i < bf->target_max + extend; i++ )
  129. bf->target_data[i] = 0;
  130. bf->target_max += extend;
  131. return 1;
  132. }
  133. int bf_AddTargetData(bf_t *bf, uint8_t data)
  134. {
  135. while( bf->target_max <= bf->target_cnt )
  136. if ( bf_extend_target_data(bf) == 0 )
  137. return -1;
  138. bf->target_data[bf->target_cnt] = data;
  139. bf->target_cnt++;
  140. return bf->target_cnt-1;
  141. }
  142. void bf_ClearTargetData(bf_t *bf)
  143. {
  144. int i;
  145. for( i = 0; i < bf->target_max; i++ )
  146. bf->target_data[i] = 0;
  147. bf->target_cnt = 0;
  148. }
  149. void bf_CalculateSelectedNumberOfGlyphs(bf_t *bf)
  150. {
  151. int i;
  152. bg_t *bg;
  153. bf->selected_glyphs = 0;
  154. for( i = 0; i < bf->glyph_cnt; i++ )
  155. {
  156. bg = bf->glyph_list[i];
  157. if ( bg->map_to >= 0 )
  158. {
  159. bf->selected_glyphs++;
  160. }
  161. }
  162. }
  163. void bf_ReduceAllGlyph(bf_t *bf)
  164. {
  165. int i;
  166. bg_t *bg;
  167. int red_x, red_y;
  168. bf_Log(bf, "Reduce: Start");
  169. for( i = 0; i < bf->glyph_cnt; i++ )
  170. {
  171. bg = bf->glyph_list[i];
  172. if ( bg->map_to >= 0 )
  173. {
  174. bg_ReduceGlyph(bg);
  175. //bg_ShowBitmap(bg, &(bg->bbx));
  176. red_x = bg->bitmap_width - bg->bbx.w;
  177. red_y = bg->bitmap_height - bg->bbx.h;
  178. if ( red_x > 0 || red_y > 0 )
  179. {
  180. //bf_Log(bf, "Reduce: Encoding %ld, x by %d, y by %d", bg->encoding, red_x, red_y);
  181. }
  182. }
  183. }
  184. bf_Log(bf, "Reduce: End");
  185. }
  186. void bf_ShowAllGlyphs(bf_t *bf, bbx_t *bbx)
  187. {
  188. int i;
  189. bg_t *bg;
  190. for( i = 0; i < bf->glyph_cnt; i++ )
  191. {
  192. bg = bf->glyph_list[i];
  193. if ( bg->map_to >= 0 )
  194. {
  195. bg_ShowBitmap(bg, bbx);
  196. }
  197. }
  198. }
  199. int bf_GetIndexByEncoding(bf_t *bf, long encoding)
  200. {
  201. int i;
  202. bg_t *bg;
  203. for( i = 0; i < bf->glyph_cnt; i++ )
  204. {
  205. bg = bf->glyph_list[i];
  206. if ( bg->encoding == encoding )
  207. return i;
  208. }
  209. return -1;
  210. }
  211. void bf_CalculateMaxBBX(bf_t *bf)
  212. {
  213. int i;
  214. int is_first = 1;
  215. int enc_idx;
  216. bg_t *bg;
  217. for( i = 0; i < bf->glyph_cnt; i++ )
  218. {
  219. bg = bf->glyph_list[i];
  220. if ( bg->map_to >= 0 )
  221. {
  222. if ( is_first != 0 )
  223. {
  224. bf->max = bg->bbx;
  225. bf->enc_x = bg->encoding;
  226. bf->enc_y = bg->encoding;
  227. bf->enc_w = bg->encoding;
  228. bf->enc_h = bg->encoding;
  229. is_first = 0;
  230. }
  231. else
  232. {
  233. enc_idx = bg_Max(bg, &(bf->max));
  234. switch(enc_idx)
  235. {
  236. case 1:
  237. bf->enc_w = bg->encoding;
  238. break;
  239. case 2:
  240. bf->enc_h = bg->encoding;
  241. break;
  242. case 3:
  243. bf->enc_x = bg->encoding;
  244. break;
  245. case 4:
  246. bf->enc_y = bg->encoding;
  247. break;
  248. }
  249. }
  250. }
  251. }
  252. if ( bf->bbx_mode == BDF_BBX_MODE_M8 )
  253. {
  254. /* old
  255. bf->max.w = ( bf->max.w + 7 ) & ~7;
  256. bf->max.h = ( bf->max.h + 7 ) & ~7;
  257. */
  258. bf->max.w = 8;
  259. bf->max.h = 7;
  260. }
  261. bf_Log(bf, "CalculateMaxBBX: x=%ld, y=%ld, w=%ld, h=%ld", bf->max.x, bf->max.y, bf->max.w, bf->max.h);
  262. bf_Log(bf, "CalculateMaxBBX: Encodings x=%ld, y=%ld, w=%ld, h=%ld", bf->enc_x, bf->enc_y, bf->enc_w, bf->enc_h);
  263. }
  264. void bf_CalculateMinMaxDWidth(bf_t *bf)
  265. {
  266. int i;
  267. bg_t *bg;
  268. bf->dx_min = 0x07fff;
  269. bf->dx_max = -0x07fff;
  270. bf->x_min = 0x07fff;
  271. bf->x_max = -0x07fff;
  272. for( i = 0; i < bf->glyph_cnt; i++ )
  273. {
  274. bg = bf->glyph_list[i];
  275. if ( bg->map_to >= 0 )
  276. {
  277. if ( bf->dx_min > bg->dwidth_x )
  278. bf->dx_min = bg->dwidth_x;
  279. if ( bf->dx_max < bg->dwidth_x )
  280. bf->dx_max = bg->dwidth_x;
  281. if ( bf->x_min > bg->bbx.x )
  282. bf->x_min = bg->bbx.x;
  283. if ( bf->x_max < bg->bbx.x )
  284. bf->x_max = bg->bbx.x;
  285. }
  286. }
  287. bf_Log(bf, "bf_CalculateMinMaxDWidth: dx_min=%ld, dx_max=%ld", bf->dx_min, bf->dx_max);
  288. bf_Log(bf, "bf_CalculateMinMaxDWidth: x_min=%ld, x_max=%ld", bf->x_min, bf->x_max);
  289. if ( bf->dx_min == bf->dx_max && bf->x_min >= 0 )
  290. {
  291. bf_Log(bf, "bf_CalculateMinMaxDWidth: Monospaced font."); /* not sufficient: also bbx.x must be >= 0 for all glyphs */
  292. /* for a monospaced font, dx must be identical to bbx.w */
  293. }
  294. }
  295. int get_unsigned_bit_size(unsigned long v)
  296. {
  297. int i = 0;
  298. while( v != 0 )
  299. {
  300. v = v / 2;
  301. i++;
  302. }
  303. return i;
  304. }
  305. int get_signed_bit_size(long v)
  306. {
  307. if ( v < 0 )
  308. return get_unsigned_bit_size(-v-1) + 1;
  309. return get_unsigned_bit_size(v) + 1;
  310. }
  311. /*
  312. #define BDF_BBX_MODE_MINIMAL 0
  313. #define BDF_BBX_MODE_HEIGHT 1
  314. #define BDF_BBX_MODE_MAX 2
  315. #define BDF_BBX_MODE_M8 3
  316. */
  317. void bf_copy_bbx_and_update_shift(bf_t *bf, bbx_t *target_bbx, bg_t *bg)
  318. {
  319. /* modifing the following code requires update ind bdf_rle.c also */
  320. if ( bf->bbx_mode == BDF_BBX_MODE_MINIMAL ) // mode 0
  321. {
  322. *target_bbx = bg->bbx;
  323. }
  324. else if ( bf->bbx_mode == BDF_BBX_MODE_MAX ) // mode 2 (monospace)
  325. {
  326. *target_bbx = bf->max;
  327. target_bbx->x = 0;
  328. if ( bg->bbx.x < 0 )
  329. bg->shift_x = bg->bbx.x;
  330. if ( target_bbx->w < bg->dwidth_x )
  331. target_bbx->w = bg->dwidth_x;
  332. }
  333. else if ( bf->bbx_mode == BDF_BBX_MODE_5X7 ) // mode 4 (5x7 displays)
  334. {
  335. *target_bbx = bf->max;
  336. target_bbx->x = 0;
  337. if ( bg->bbx.x < 0 )
  338. bg->shift_x = bg->bbx.x;
  339. target_bbx->w = 5;
  340. }
  341. else if ( bf->bbx_mode == BDF_BBX_MODE_M8 )
  342. {
  343. /* old
  344. target_bbx->w = bf->max.w;
  345. if ( target_bbx->w < bg->dwidth_x )
  346. target_bbx->w = bg->dwidth_x;
  347. target_bbx->w = (target_bbx->w+7) & ~7;
  348. target_bbx->h = (bf->max.h+7) & ~7;
  349. */
  350. target_bbx->w = 8;
  351. target_bbx->h = 8;
  352. target_bbx->x = bf->max.x;
  353. target_bbx->y = bf->max.y;
  354. target_bbx->x = 0;
  355. if ( bg->bbx.x < 0 )
  356. bg->shift_x = bg->bbx.x;
  357. }
  358. else
  359. {
  360. *target_bbx = bf->max;
  361. target_bbx->w = bg->bbx.w;
  362. target_bbx->x = bg->bbx.x;
  363. target_bbx->x = 0;
  364. if ( bg->bbx.x < 0 )
  365. {
  366. /* e.g. "j" */
  367. target_bbx->w -= bg->bbx.x;
  368. bg->shift_x = bg->bbx.x;
  369. }
  370. else
  371. {
  372. /* e.g. "B" */
  373. target_bbx->w += bg->bbx.x;
  374. //bg->shift_x = bg->bbx.x;
  375. }
  376. if ( target_bbx->w < bg->dwidth_x )
  377. target_bbx->w = bg->dwidth_x;
  378. }
  379. bg->width_deviation = target_bbx->w - bg->bbx.w;
  380. }
  381. void bf_CalculateMaxBitFieldSize(bf_t *bf)
  382. {
  383. int i;
  384. bg_t *bg;
  385. int bs;
  386. bbx_t local_bbx;
  387. bf->bbx_x_max_bit_size = 0;
  388. bf->bbx_y_max_bit_size = 0;
  389. bf->bbx_w_max_bit_size = 0;
  390. bf->bbx_h_max_bit_size = 0;
  391. bf->dx_max_bit_size = 0;
  392. for( i = 0; i < bf->glyph_cnt; i++ )
  393. {
  394. bg = bf->glyph_list[i];
  395. if ( bg->map_to >= 0 )
  396. {
  397. bf_copy_bbx_and_update_shift(bf, &local_bbx, bg);
  398. #ifdef OLD_CLODE
  399. /* modifing the following code requires update ind bdf_rle.c also */
  400. if ( bf->bbx_mode == BDF_BBX_MODE_MINIMAL )
  401. {
  402. local_bbx = bg->bbx;
  403. }
  404. else if ( bf->bbx_mode == BDF_BBX_MODE_MAX )
  405. {
  406. local_bbx = bf->max;
  407. local_bbx.x = 0;
  408. if ( bg->bbx.x < 0 )
  409. bg->shift_x = bg->bbx.x;
  410. if ( local_bbx.w < bg->dwidth_x )
  411. local_bbx.w = bg->dwidth_x;
  412. }
  413. else if ( bf->bbx_mode == BDF_BBX_MODE_M8 )
  414. {
  415. local_bbx.w = bf->max.w;
  416. if ( local_bbx.w < bg->dwidth_x )
  417. local_bbx.w = bg->dwidth_x;
  418. local_bbx.w = (local_bbx.w+7) & ~7;
  419. local_bbx.h = (bf->max.h+7) & ~7;
  420. local_bbx.x = bf->max.x;
  421. local_bbx.y = bf->max.y;
  422. local_bbx.x = 0;
  423. if ( bg->bbx.x < 0 )
  424. bg->shift_x = bg->bbx.x;
  425. }
  426. else
  427. {
  428. local_bbx = bf->max;
  429. local_bbx.w = bg->bbx.w;
  430. local_bbx.x = bg->bbx.x;
  431. local_bbx.x = 0;
  432. if ( bg->bbx.x < 0 )
  433. {
  434. /* e.g. "j" */
  435. local_bbx.w -= bg->bbx.x;
  436. bg->shift_x = bg->bbx.x;
  437. }
  438. else
  439. {
  440. /* e.g. "B" */
  441. local_bbx.w += bg->bbx.x;
  442. //bg->shift_x = bg->bbx.x;
  443. }
  444. if ( local_bbx.w < bg->dwidth_x )
  445. local_bbx.w = bg->dwidth_x;
  446. }
  447. #endif
  448. bs = get_unsigned_bit_size(local_bbx.w);
  449. if ( bf->bbx_w_max_bit_size < bs )
  450. bf->bbx_w_max_bit_size = bs;
  451. bs = get_unsigned_bit_size(local_bbx.h);
  452. if ( bf->bbx_h_max_bit_size < bs )
  453. bf->bbx_h_max_bit_size = bs;
  454. //printf("%ld ", local_bbx.x);
  455. bs = get_signed_bit_size(local_bbx.x);
  456. if ( bf->bbx_x_max_bit_size < bs )
  457. bf->bbx_x_max_bit_size = bs;
  458. //printf("%d:%d ",(int)local_bbx->x, (int)bs);
  459. bs = get_signed_bit_size(local_bbx.y);
  460. if ( bf->bbx_y_max_bit_size < bs )
  461. bf->bbx_y_max_bit_size = bs;
  462. if ( bf->bbx_mode == BDF_BBX_MODE_MINIMAL )
  463. {
  464. bs = get_signed_bit_size(bg->dwidth_x);
  465. }
  466. else if ( bf->bbx_mode == BDF_BBX_MODE_MAX )
  467. {
  468. bs = get_signed_bit_size(local_bbx.w);
  469. }
  470. else
  471. {
  472. bs = get_signed_bit_size(local_bbx.w);
  473. }
  474. if ( bf->dx_max_bit_size < bs )
  475. bf->dx_max_bit_size = bs;
  476. }
  477. }
  478. bf_Log(bf, "bf_CalculateMaxBitFieldSize: bbx.x=%d, bbx.y=%d, bbx.w=%d, bbx.h=%d, dwidth=%d",
  479. bf->bbx_x_max_bit_size, bf->bbx_y_max_bit_size, bf->bbx_w_max_bit_size, bf->bbx_h_max_bit_size, bf->dx_max_bit_size);
  480. }
  481. void bf_ShowMonospaceStatistics(bf_t *bf)
  482. {
  483. int i;
  484. bg_t *bg;
  485. long cnt = 0;
  486. long max = 0;
  487. long sum = 0;
  488. for( i = 0; i < bf->glyph_cnt; i++ )
  489. {
  490. bg = bf->glyph_list[i];
  491. if ( bg->map_to >= 0 )
  492. {
  493. if ( max < bg->width_deviation )
  494. max = bg->width_deviation;
  495. sum += bg->width_deviation;
  496. cnt++;
  497. }
  498. }
  499. if ( cnt == 0 )
  500. cnt++;
  501. bf_Log(bf, "Monospace Statistics: Max width extention %ld, average width extention %ld.%ld", max, sum/cnt, (sum*10/cnt) % 10 );
  502. /*
  503. Monospaced font: average width extention does not differ much between -b 1 and --b 2
  504. Variable width font: big difference for the average width extention between modes 1 and 2.
  505. Examples:
  506. ./bdfconv -b 1 -v ../bdf/profont12.bdf
  507. Monospace Statistics: Max width extention 6, average width extention 1.7
  508. ./bdfconv -b 2 -v ../bdf/profont12.bdf
  509. Monospace Statistics: Max width extention 6, average width extention 1.7
  510. --> profont12.bdf is a monospaced font
  511. ./bdfconv -b 1 -v ../bdf/helvR12.bdf
  512. Monospace Statistics: Max width extention 6, average width extention 1.9
  513. ./bdfconv -b 2 -v ../bdf/helvR12.bdf
  514. Monospace Statistics: Max width extention 15, average width extention 8.0
  515. --> helvR12.bdf is not a monospaced font
  516. */
  517. }
  518. int bf_WriteUCGCByFP(bf_t *bf, FILE *out_fp, const char *fontname, const char *indent)
  519. {
  520. int i;
  521. int bytes_per_line = 16;
  522. fprintf(out_fp, "/*\n");
  523. fprintf(out_fp, " Fontname: %s\n", bf->str_font);
  524. fprintf(out_fp, " Copyright: %s\n", bf->str_copyright);
  525. fprintf(out_fp, " Glyphs: %d/%d\n", (int)bf->selected_glyphs, (int)bf->glyph_cnt );
  526. fprintf(out_fp, " BBX Build Mode: %d\n", (int)bf->bbx_mode);
  527. fprintf(out_fp, "*/\n");
  528. fprintf(out_fp, "#include \"ucg.h\"\n");
  529. fprintf(out_fp, "const ucg_fntpgm_uint8_t %s[%d] UCG_FONT_SECTION(\"%s\") = {\n", fontname, bf->target_cnt, fontname);
  530. fprintf(out_fp, " ");
  531. for( i = 0; i < bf->target_cnt; i++ )
  532. {
  533. fprintf(out_fp, "%d", bf->target_data[i]);
  534. if ( i+1 != bf->target_cnt )
  535. fprintf(out_fp, ",");
  536. if ( (i+1) % bytes_per_line == 0 )
  537. fprintf(out_fp, "\n%s", indent);
  538. }
  539. fprintf(out_fp, "};\n");
  540. return 1;
  541. }
  542. int bf_WriteU8G2CByFP(bf_t *bf, FILE *out_fp, const char *fontname, const char *indent)
  543. {
  544. int i;
  545. int bytes_per_line = 32;
  546. int extra1;
  547. fprintf(out_fp, "/*\n");
  548. fprintf(out_fp, " Fontname: %s\n", bf->str_font);
  549. fprintf(out_fp, " Copyright: %s\n", bf->str_copyright);
  550. fprintf(out_fp, " Glyphs: %d/%d\n", (int)bf->selected_glyphs, (int)bf->glyph_cnt );
  551. fprintf(out_fp, " BBX Build Mode: %d\n", (int)bf->bbx_mode);
  552. fprintf(out_fp, "*/\n");
  553. if ( bf->target_data[bf->target_cnt-1] == 0 )
  554. extra1 = 0;
  555. else
  556. extra1 = 1;
  557. if ( bf->target_cnt-1+extra1 > 32760 )
  558. {
  559. fprintf(out_fp, "#ifdef U8G2_USE_LARGE_FONTS\n");
  560. }
  561. if ( bf->bbx_mode == 3 ) // maybe better check for the font_format
  562. {
  563. //fprintf(out_fp, "#include \"u8x8.h\"\n");
  564. fprintf(out_fp, "const uint8_t %s[%d] U8X8_FONT_SECTION(\"%s\") = \n", fontname, bf->target_cnt+extra1, fontname);
  565. }
  566. else
  567. {
  568. //fprintf(out_fp, "#include \"u8g2.h\"\n");
  569. fprintf(out_fp, "const uint8_t %s[%d] U8G2_FONT_SECTION(\"%s\") = \n", fontname, bf->target_cnt+extra1, fontname);
  570. }
  571. fprintf(out_fp, "%s\"", indent);
  572. for( i = 0; i < bf->target_cnt-1+extra1; i++ )
  573. {
  574. if ( bf->target_data[i] < 32 || bf->target_data[i] == '\"' || bf->target_data[i] == '\\' || bf->target_data[i] == '?' || ( bf->target_data[i] >= '0' && bf->target_data[i] <= '9' ))
  575. {
  576. fprintf(out_fp, "\\%o", bf->target_data[i]);
  577. //fprintf(out_fp, "\\x%02x", bf->target_data[i]);
  578. }
  579. else if ( bf->target_data[i] < 127 ) /* issue 482, do not output ASCII char 127, instead use octal code for 127 */
  580. {
  581. fprintf(out_fp, "%c", bf->target_data[i]);
  582. }
  583. else
  584. {
  585. fprintf(out_fp, "\\%o", bf->target_data[i]);
  586. }
  587. if ( (i+1) % bytes_per_line == 0 )
  588. fprintf(out_fp, "\"\n%s\"", indent);
  589. }
  590. fprintf(out_fp, "\";\n");
  591. if ( bf->target_cnt-1+extra1 > 32760 )
  592. {
  593. fprintf(out_fp, "#endif /* U8G2_USE_LARGE_FONTS */\n");
  594. }
  595. return 1;
  596. }
  597. int bf_WriteUCGCByFilename(bf_t *bf, const char *filename, const char *fontname, const char *indent)
  598. {
  599. FILE *fp;
  600. fp = fopen(filename, "wb");
  601. if ( fp == NULL )
  602. {
  603. bf_Log(bf, "bf_WriteUCGCByFilename: Open error '%s'", filename);
  604. return 0;
  605. }
  606. bf_WriteUCGCByFP(bf, fp, fontname, indent);
  607. bf_Log(bf, "bf_WriteUCGCByFilename: Write file '%s'", filename);
  608. fclose(fp);
  609. return 1;
  610. }
  611. /* called from main() */
  612. int bf_WriteU8G2CByFilename(bf_t *bf, const char *filename, const char *fontname, const char *indent)
  613. {
  614. FILE *fp;
  615. fp = fopen(filename, "wb");
  616. if ( fp == NULL )
  617. {
  618. bf_Log(bf, "bf_WriteU8G2CByFilename: Open error '%s'", filename);
  619. return 0;
  620. }
  621. bf_WriteU8G2CByFP(bf, fp, fontname, indent);
  622. bf_Log(bf, "bf_WriteU8G2CByFilename: Write file '%s'", filename);
  623. fclose(fp);
  624. return 1;
  625. }
  626. /*
  627. xo, yo: offset for 8x8 fonts (font_format==2)
  628. called from main()
  629. */
  630. bf_t *bf_OpenFromFile(const char *bdf_filename, int is_verbose, int bbx_mode, const char *map_str, const char *map_file_name, const char *utf8_file_name, int font_format, int xo, int yo, int th, int tv)
  631. {
  632. bf_t *bf;
  633. bf = bf_Open(is_verbose, bbx_mode);
  634. if ( bf != NULL )
  635. {
  636. bf->tile_h_size = th;
  637. bf->tile_v_size = tv;
  638. if ( bf_ParseFile(bf, bdf_filename) != 0 )
  639. {
  640. if ( map_file_name[0] != '\0' )
  641. {
  642. bf_MapFile(bf, map_file_name); // bdf_map.c
  643. }
  644. else
  645. {
  646. bf_Map(bf, map_str); // bdf_map.c
  647. }
  648. if ( utf8_file_name[0] != '\0' )
  649. {
  650. bf_Utf8File(bf, utf8_file_name);
  651. }
  652. bf_CalculateSelectedNumberOfGlyphs(bf);
  653. bf_ReduceAllGlyph(bf);
  654. bf_CalculateMaxBBX(bf);
  655. //bf_ShowAllGlyphs(bf, &(bf->max));
  656. bf_CalculateMinMaxDWidth(bf);
  657. /* issue 669 */
  658. if ( bf->bbx_mode == BDF_BBX_MODE_MAX )
  659. if ( bf->max.w < bf->dx_max )
  660. bf->max.w = bf->dx_max;
  661. bf_CalculateMaxBitFieldSize(bf);
  662. if ( font_format == 0 || font_format == 1 )
  663. {
  664. bf_RLECompressAllGlyphs(bf);
  665. }
  666. else
  667. {
  668. bf_Generate8x8Font(bf, xo, yo); /* bdf_8x8.c */
  669. }
  670. if ( bf->bbx_mode != BDF_BBX_MODE_MINIMAL )
  671. bf_ShowMonospaceStatistics(bf); /* Show stats only for none minimal mode. For minimal mode it will always be zero */
  672. return bf;
  673. }
  674. bf_Close(bf);
  675. }
  676. return NULL;
  677. }