bdf_rle.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. /*
  2. bdf_rle.c
  3. run length glyph encoding
  4. size comparison with old and new font format
  5. 4x6 1500 1469
  6. 4x6r 734 726
  7. 6x10 1866 2009
  8. 6x10r 889 971
  9. 7x13B 2172 2253
  10. 7x13Br 1041 1017
  11. 9x15 2959 2649
  12. 9x15r 1427 1242
  13. 10x20 3453 3053
  14. 10x20r 1667 1417 85%
  15. courB12 3959 3312
  16. courB12r 1857 1538
  17. courB24 10502 6661
  18. courB24r 4775 3015 63%
  19. helvB24 10931 6904 63%
  20. helvB24r 4992 3166 63%
  21. logisoso50r 14375 5248 36%
  22. */
  23. /* font information */
  24. /*
  25. glyph_cnt = *font++;
  26. bits_per_0 = *font++;
  27. bits_per_1 = *font++;
  28. bits_per_char_width = *font++;
  29. bits_per_char_height = *font++;
  30. bits_per_char_x = *font++;
  31. bits_per_char_y = *font++;
  32. bits_per_delta_x = *font++;
  33. */
  34. /* apply glyph information */
  35. /*
  36. ~ encoding unsigned, 1 or 2 byte (high byte first in two byte version)
  37. ~ total size unsigned, 1 byte
  38. ~ BBX width unsigned 5
  39. ~ BBX height unsigned 5
  40. ~ BBX xoffset signed 2
  41. ~ BBX yoffset signed 5
  42. ~ DWIDTH unsigned 3
  43. */
  44. #define BDF_RLE_FONT_GLYPH_START 23
  45. /* max glyphs count is around 7500, 7500/100 = 75 */
  46. /* changed 100 to 101 due to off by one error in the code and in order to keep the current binary data identical https://github.com/olikraus/u8g2/issues/1521 */
  47. #define UNICODE_GLYPHS_PER_LOOKUP_TABLE_ENTRY 101
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <stdint.h>
  51. #include <assert.h>
  52. #include "bdf_font.h"
  53. #ifdef OLD_CODE
  54. #define SCREEN_W 140
  55. #define SCREEN_H 140
  56. uint8_t screen_buf[SCREEN_H][SCREEN_W];
  57. unsigned screen_max_y;
  58. void screen_init(void)
  59. {
  60. unsigned x, y;
  61. screen_max_y = 0;
  62. for( y = 0; y < SCREEN_H; y++ )
  63. {
  64. for( x = 0; x < SCREEN_W; x++ )
  65. {
  66. screen_buf[y][x] = '.';
  67. }
  68. }
  69. }
  70. void screen_set_pixel(unsigned x, unsigned y, uint8_t c)
  71. {
  72. if ( screen_max_y < y)
  73. screen_max_y = y;
  74. screen_buf[y][x] = c;
  75. }
  76. void screen_show(void)
  77. {
  78. unsigned x, y;
  79. printf("\n");
  80. for( y = 0; y <= screen_max_y; y++ )
  81. {
  82. for( x = 0; x < SCREEN_W; x++ )
  83. {
  84. printf("%c", screen_buf[y][x]);
  85. }
  86. printf("\n");
  87. }
  88. }
  89. /*===================================================*/
  90. /* font decode */
  91. struct fd_struct
  92. {
  93. unsigned x; /* local coordinates, (0,0) is upper left */
  94. unsigned y;
  95. unsigned glyph_width;
  96. unsigned glyph_height;
  97. const uint8_t *decode_ptr; /* pointer to the compressed data */
  98. unsigned decode_bit_pos; /* bitpos inside a byte of the compressed data */
  99. uint8_t bbx_x_max_bit_size;
  100. uint8_t bbx_y_max_bit_size;
  101. uint8_t bbx_w_max_bit_size;
  102. uint8_t bbx_h_max_bit_size;
  103. uint8_t dx_max_bit_size;
  104. };
  105. typedef struct fd_struct fd_t;
  106. /* increment x and consider line wrap (inc y)*/
  107. static void fd_inc(fd_t *f)
  108. {
  109. unsigned x = f->x;
  110. x++;
  111. if ( x == f->glyph_width )
  112. {
  113. x = 0;
  114. f->y++;
  115. }
  116. f->x = x;
  117. }
  118. static unsigned fd_get_unsigned_bits(fd_t *f, unsigned cnt)
  119. {
  120. unsigned val;
  121. unsigned bit_pos = f->decode_bit_pos;
  122. val = *(f->decode_ptr);
  123. val >>= bit_pos;
  124. if ( bit_pos + cnt >= 8 )
  125. {
  126. f->decode_ptr++;
  127. val |= *(f->decode_ptr) << (8-bit_pos);
  128. bit_pos -= 8;
  129. }
  130. val &= (1U<<cnt)-1;
  131. bit_pos += cnt;
  132. f->decode_bit_pos = bit_pos;
  133. return val;
  134. }
  135. /*
  136. 2 bit --> cnt = 2
  137. -2,-1,0. 1
  138. 3 bit --> cnt = 3
  139. -2,-1,0. 1
  140. -4,-3,-2,-1,0,1,2,3
  141. if ( x < 0 )
  142. r = bits(x-1)+1;
  143. else
  144. r = bits(x)+1;
  145. */
  146. static int fd_get_signed_bits(fd_t *t, int cnt)
  147. {
  148. return (int)fd_get_unsigned_bits(t, cnt) - ((1<<cnt)>>1);
  149. }
  150. static void fd_draw_pixel(fd_t *f)
  151. {
  152. screen_set_pixel(f->x, f->y, '#');
  153. }
  154. static void fd_decode(bg_t *bg, bbx_t *bbx, fd_t *f, unsigned rle_bits_per_0, unsigned rle_bits_per_1)
  155. {
  156. unsigned a, b;
  157. unsigned i;
  158. screen_init();
  159. if ( bbx == NULL )
  160. bbx = &(bg->bbx);
  161. /* init decode algorithm */
  162. f->decode_ptr = bg->target_data;
  163. f->decode_bit_pos = 0;
  164. f->glyph_width = bbx->w;
  165. f->glyph_height = bbx->h;
  166. /* read glyph info */
  167. f->decode_ptr += 2;
  168. fd_get_unsigned_bits(f, f->bbx_w_max_bit_size);
  169. fd_get_unsigned_bits(f, f->bbx_h_max_bit_size);
  170. fd_get_signed_bits(f, f->bbx_x_max_bit_size);
  171. fd_get_signed_bits(f, f->bbx_y_max_bit_size);
  172. fd_get_signed_bits(f, f->dx_max_bit_size);
  173. /* reset local x/y position */
  174. f->x = 0;
  175. f->y = 0;
  176. //puts("");
  177. /* decode glyph */
  178. for(;;)
  179. {
  180. a = fd_get_unsigned_bits(f, rle_bits_per_0);
  181. b = fd_get_unsigned_bits(f, rle_bits_per_1);
  182. //printf("[%u %u]", a, b);
  183. do
  184. {
  185. for( i = 0; i < a; i++ )
  186. {
  187. fd_inc(f);
  188. }
  189. for( i = 0; i < b; i++ )
  190. {
  191. fd_draw_pixel(f);
  192. fd_inc(f);
  193. }
  194. } while( fd_get_unsigned_bits(f, 1) != 0 );
  195. if ( f->y >= f->glyph_height )
  196. break;
  197. }
  198. screen_show();
  199. }
  200. #endif
  201. /*===================================================*/
  202. /*
  203. Desc:
  204. Output a and b to the stream.
  205. a and b must fit to the target size in bits.
  206. Additionally a repeat code r (one bit) is generated:
  207. It may look like this:
  208. r = 0: 0aaaabb
  209. or
  210. r = 1: 1
  211. If r is 0, then the number of zeros (a) and ones (b) will follow and both
  212. values must be stored as in the decoder.
  213. If r os 1, then the number of zeros and ones is repeated once
  214. Args:
  215. a: number of 0 bits, log2(a) must be smaller or equal to the fieldsize
  216. b: number of 1 bits, log2(b) must be smaller or equal to the fieldsize
  217. */
  218. static void bg_err(const char *s)
  219. {
  220. puts(s);
  221. }
  222. static void bg_init_rle(bg_t *bg, unsigned rle_bits_per_0, unsigned rle_bits_per_1)
  223. {
  224. bg->rle_bitcnt = 0;
  225. bg->rle_is_first = 1;
  226. bg->rle_bits_per_0 = rle_bits_per_0;
  227. bg->rle_bits_per_1 = rle_bits_per_1;
  228. bg->rle_last_0 = 0;
  229. bg->rle_last_1 = 1;
  230. bg_ClearTargetData(bg);
  231. }
  232. static int bg_01_rle(bg_t *bg, unsigned a, unsigned b)
  233. {
  234. if ( bg->rle_is_first == 0 && bg->rle_last_0 == a && bg->rle_last_1 == b )
  235. {
  236. bg->rle_bitcnt++;
  237. if ( bg_AddTargetBits(bg, 1, 1) == 0 )
  238. return bg_err("error in bg_01_rle 1 0"), 0;
  239. }
  240. else
  241. {
  242. if ( bg->rle_is_first == 0 )
  243. {
  244. if ( bg_AddTargetBits(bg, 1, 0) == 0 )
  245. return bg_err("error in bg_01_rle 1 0"), 0;
  246. bg->rle_bitcnt++;
  247. }
  248. if ( bg_AddTargetBits(bg, bg->rle_bits_per_0, a) == 0 )
  249. return bg_err("error in bg_01_rle 1 a"), 0;
  250. if ( bg_AddTargetBits(bg, bg->rle_bits_per_1, b) == 0 )
  251. return bg_err("error in bg_01_rle 1 b"), 0;
  252. /*
  253. if ( bg->encoding == ' ' )
  254. {
  255. printf("[%u %u]", a, b);
  256. }
  257. */
  258. bg->rle_is_first = 0;
  259. bg->rle_bitcnt +=bg->rle_bits_per_0;
  260. bg->rle_bitcnt +=bg->rle_bits_per_1;
  261. bg->rle_last_0 = a;
  262. bg->rle_last_1 = b;
  263. }
  264. return 1;
  265. }
  266. /*
  267. Desc:
  268. Write the number of zeros and ones to the bit stream.
  269. There is no restriction on the size of a and b.
  270. Args:
  271. a: number of 0 bits
  272. b: number of 1 bits
  273. */
  274. static int bg_prepare_01_rle(bg_t *bg, unsigned a, unsigned b)
  275. {
  276. //printf("[%u %u]", a, b);
  277. while( a > (1<<bg->rle_bits_per_0) -1 )
  278. {
  279. if ( bg_01_rle(bg, (1<<bg->rle_bits_per_0) -1, 0) == 0 )
  280. return 0;
  281. a -= (1<<bg->rle_bits_per_0) -1;
  282. }
  283. while( b > (1<<bg->rle_bits_per_1) -1 )
  284. {
  285. if ( bg_01_rle(bg, a, (1<<bg->rle_bits_per_1) -1) == 0 )
  286. return 0;
  287. a = 0;
  288. b -= (1<<bg->rle_bits_per_1) -1;
  289. }
  290. if ( a != 0 || b != 0 )
  291. if ( bg_01_rle(bg, a, b) == 0 )
  292. return 0;
  293. return 1;
  294. }
  295. int bg_rle_compress(bg_t *bg, bbx_t *bbx, unsigned rle_bits_per_0, unsigned rle_bits_per_1, int is_output)
  296. {
  297. int x;
  298. int y;
  299. int i;
  300. int bd_is_one; /* bit delta */
  301. int bd_curr_len;
  302. int bd_max_len;
  303. int bd_chg_cnt;
  304. static int bd_list[1024*2];
  305. if ( bbx == NULL )
  306. bbx = &(bg->bbx);
  307. bg_init_rle(bg, rle_bits_per_0, rle_bits_per_1);
  308. /* step 0: output initial information */
  309. //printf("%ld %ld\n", (long)bg->encoding, (long)bg->map_to);
  310. if ( bg->map_to <= 255 )
  311. {
  312. if ( bg_AddTargetData(bg, bg->map_to) < 0 )
  313. return bg_err("error in bg_rle_compress"), 0;
  314. }
  315. else
  316. {
  317. if ( bg_AddTargetData(bg, bg->map_to >> 8) < 0 )
  318. return bg_err("error in bg_rle_compress"), 0;
  319. if ( bg_AddTargetData(bg, bg->map_to & 255 ) < 0 )
  320. return bg_err("error in bg_rle_compress"), 0;
  321. }
  322. /* size, will be added later */
  323. if ( bg_AddTargetData(bg, 0) < 0 )
  324. return bg_err("error in bg_rle_compress"), 0;
  325. // if ( bbx->w == 0 && bbx->h == 0 )
  326. // {
  327. // printf("blank char: enc=%ld\n", bg->encoding);
  328. // }
  329. // w & h is 0 for the space glyphe (encoding 32)
  330. if ( bg_AddTargetBits(bg, bg->bf->bbx_w_max_bit_size, bbx->w) == 0 )
  331. return bg_err("error in bg_rle_compress"), 0;
  332. if ( bg_AddTargetBits(bg, bg->bf->bbx_h_max_bit_size, bbx->h) == 0 )
  333. return bg_err("error in bg_rle_compress"), 0;
  334. if ( bg_AddTargetBits(bg, bg->bf->bbx_x_max_bit_size, bbx->x + (1<<(bg->bf->bbx_x_max_bit_size-1))) == 0 )
  335. return bg_err("error in bg_rle_compress"), 0;
  336. if ( bg_AddTargetBits(bg, bg->bf->bbx_y_max_bit_size, bbx->y + (1<<(bg->bf->bbx_y_max_bit_size-1))) == 0 )
  337. return bg_err("error in bg_rle_compress"), 0;
  338. if ( bg->bf->bbx_mode == BDF_BBX_MODE_MINIMAL )
  339. {
  340. if ( bg_AddTargetBits(bg, bg->bf->dx_max_bit_size, bg->dwidth_x + (1<<(bg->bf->dx_max_bit_size-1))) == 0 )
  341. return bg_err("error in bg_rle_compress"), 0;
  342. }
  343. else if ( bg->bf->bbx_mode == BDF_BBX_MODE_MAX )
  344. {
  345. if ( bg_AddTargetBits(bg, bg->bf->dx_max_bit_size, bbx->w+ (1<<(bg->bf->dx_max_bit_size-1))) == 0 )
  346. return bg_err("error in bg_rle_compress"), 0;
  347. }
  348. else
  349. {
  350. if ( bg_AddTargetBits(bg, bg->bf->dx_max_bit_size, bbx->w+ (1<<(bg->bf->dx_max_bit_size-1))) == 0 )
  351. return bg_err("error in bg_rle_compress"), 0;
  352. }
  353. bd_is_one = 0;
  354. bd_curr_len = 0;
  355. bd_max_len = 0;
  356. bd_chg_cnt = 0;
  357. /* step 1: build array with pairs of a (number of zero bits) and b (number of one bits) */
  358. for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
  359. {
  360. for( x = bbx->x; x < bbx->x + bbx->w; x++)
  361. {
  362. if ( bg_GetBBXPixel(bg, x, y) == 0 )
  363. {
  364. if ( bd_is_one != 0 )
  365. {
  366. bd_list[bd_chg_cnt] = bd_curr_len;
  367. bd_is_one = 0;
  368. bd_chg_cnt++;
  369. bd_curr_len = 0;
  370. }
  371. bd_curr_len++;
  372. }
  373. else
  374. {
  375. if ( bd_is_one == 0 )
  376. {
  377. bd_list[bd_chg_cnt] = bd_curr_len;
  378. bd_is_one = 1;
  379. bd_chg_cnt++;
  380. bd_curr_len = 0;
  381. }
  382. bd_curr_len++;
  383. }
  384. if ( bd_max_len < bd_curr_len )
  385. bd_max_len = bd_curr_len;
  386. }
  387. }
  388. bd_list[bd_chg_cnt] = bd_curr_len;
  389. bd_chg_cnt++;
  390. if ( (bd_chg_cnt & 1) == 1 )
  391. {
  392. assert(bd_is_one == 0);
  393. bd_list[bd_chg_cnt] = 0;
  394. bd_chg_cnt++;
  395. }
  396. //printf("01 pairs = %d\n", bd_chg_cnt/2);
  397. /* step 2: convert the array into bit stream */
  398. //if ( bg->encoding == ' ' )
  399. // printf("Encoding list, pairs = %d\n", bd_chg_cnt/2);
  400. for( i = 0; i < bd_chg_cnt; i+=2 )
  401. {
  402. //if ( bg->encoding == ' ' )
  403. // printf("(%d %d)", bd_list[i], bd_list[i+1]);
  404. if ( bg_prepare_01_rle(bg, bd_list[i], bd_list[i+1]) == 0 )
  405. return 0;
  406. }
  407. //if ( bg->encoding == 'B' )
  408. // printf("\nEncoding list end\n");
  409. if ( bg_AddTargetBits(bg, 1, 0) == 0 ) // ensure that there is a 0 bit at the end. This will simplify decoding loop
  410. return 0;
  411. if ( bg_FlushTargetBits(bg) == 0 ) // finish the last byte and update bg->target_cnt
  412. return 0;
  413. if ( bg->map_to <= 255 )
  414. {
  415. bg->target_data[1] = bg->target_cnt;
  416. }
  417. else
  418. {
  419. bg->target_data[2] = bg->target_cnt;
  420. }
  421. /*
  422. {
  423. fd_t f;
  424. f.bbx_x_max_bit_size = bg->bf->bbx_x_max_bit_size;
  425. f.bbx_y_max_bit_size = bg->bf->bbx_y_max_bit_size;
  426. f.bbx_w_max_bit_size = bg->bf->bbx_w_max_bit_size;
  427. f.bbx_h_max_bit_size = bg->bf->bbx_h_max_bit_size;
  428. f.dx_max_bit_size = bg->bf->dx_max_bit_size;
  429. fd_decode(bg, bbx, &f, rle_bits_per_0, rle_bits_per_1);
  430. }
  431. */
  432. return 1;
  433. }
  434. unsigned long bf_RLECompressAllGlyphsWithFieldSize(bf_t *bf, int rle_0, int rle_1, int is_output)
  435. {
  436. int i;
  437. bg_t *bg;
  438. unsigned long total_bits = 0;
  439. bbx_t local_bbx;
  440. for( i = 0; i < bf->glyph_cnt; i++ )
  441. {
  442. bg = bf->glyph_list[i];
  443. if ( bg->map_to >= 0 )
  444. {
  445. bf_copy_bbx_and_update_shift(bf, &local_bbx, bg);
  446. #ifdef OLD_CLODE
  447. /* modifing the following code requires update ind bdf_font.c also */
  448. if ( bf->bbx_mode == BDF_BBX_MODE_MINIMAL )
  449. {
  450. local_bbx = bg->bbx;
  451. }
  452. else if ( bf->bbx_mode == BDF_BBX_MODE_MAX )
  453. {
  454. local_bbx = bf->max;
  455. local_bbx.x = 0;
  456. if ( bg->bbx.x < 0 )
  457. bg->shift_x = bg->bbx.x;
  458. if ( local_bbx.w < bg->dwidth_x )
  459. local_bbx.w = bg->dwidth_x;
  460. }
  461. else if ( bf->bbx_mode == BDF_BBX_MODE_M8 )
  462. {
  463. local_bbx.w = bf->max.w;
  464. if ( local_bbx.w < bg->dwidth_x )
  465. local_bbx.w = bg->dwidth_x;
  466. local_bbx.w = (local_bbx.w+7) & ~7;
  467. local_bbx.h = (bf->max.h+7) & ~7;
  468. local_bbx.x = bf->max.x;
  469. local_bbx.y = bf->max.y;
  470. local_bbx.x = 0;
  471. if ( bg->bbx.x < 0 )
  472. bg->shift_x = bg->bbx.x;
  473. }
  474. else
  475. {
  476. local_bbx = bf->max;
  477. local_bbx.w = bg->bbx.w;
  478. local_bbx.x = bg->bbx.x;
  479. local_bbx.x = 0;
  480. if ( bg->bbx.x < 0 )
  481. {
  482. /* e.g. "j" */
  483. local_bbx.w -= bg->bbx.x;
  484. bg->shift_x = bg->bbx.x;
  485. }
  486. else
  487. {
  488. /* e.g. "B" */
  489. local_bbx.w += bg->bbx.x;
  490. //bg->shift_x = bg->bbx.x;
  491. }
  492. if ( local_bbx.w < bg->dwidth_x )
  493. local_bbx.w = bg->dwidth_x;
  494. }
  495. #endif
  496. bg_rle_compress(bg, &local_bbx, rle_0, rle_1, is_output);
  497. total_bits += bg->target_cnt*8+bg->target_bit_pos;
  498. if ( is_output != 0 )
  499. {
  500. bf_Log(bf, "RLE Compress: Encoding %ld bits %u/%u", bg->encoding, bg->rle_bitcnt, bg->target_cnt*8+bg->target_bit_pos);
  501. }
  502. }
  503. }
  504. //bf_Log(bf, "RLE Compress: zero bits %d, one bits %d, total bit size %lu", rle_0, rle_1, total_bits);
  505. return total_bits;
  506. }
  507. unsigned bf_RLE_get_glyph_data(bf_t *bf, uint8_t encoding)
  508. {
  509. uint8_t *font = bf->target_data;
  510. font += BDF_RLE_FONT_GLYPH_START;
  511. for(;;)
  512. {
  513. if ( font[1] == 0 )
  514. break;
  515. if ( font[0] == encoding )
  516. {
  517. return (font-bf->target_data)-BDF_RLE_FONT_GLYPH_START;
  518. }
  519. font += font[1];
  520. }
  521. return 0;
  522. }
  523. void bf_RLECompressAllGlyphs(bf_t *bf)
  524. {
  525. int i, j;
  526. bg_t *bg;
  527. int rle_0, rle_1;
  528. int best_rle_0=0, best_rle_1= 0;
  529. unsigned long total_bits = 0;
  530. unsigned long min_total_bits = 0xffffffff;
  531. int idx_cap_a;
  532. int idx_cap_a_ascent;
  533. int idx_1;
  534. int idx_1_ascent;
  535. int idx_g;
  536. int idx_g_descent;
  537. int idx_para;
  538. int idx_para_ascent;
  539. int idx_para_descent;
  540. unsigned pos;
  541. unsigned ascii_glyphs;
  542. unsigned unicode_start_pos;
  543. unsigned unicode_lookup_table_len;
  544. uint32_t unicode_lookup_table_start;
  545. uint32_t unicode_last_delta;
  546. uint32_t unicode_last_target_cnt;
  547. unsigned unicode_lookup_table_pos;
  548. unsigned unicode_lookup_table_glyph_cnt;
  549. uint32_t unicode_glyph_cnt = 0;
  550. idx_cap_a_ascent = 0;
  551. idx_cap_a = bf_GetIndexByEncoding(bf, 'A');
  552. if ( idx_cap_a >= 0 )
  553. {
  554. idx_cap_a_ascent = bf->glyph_list[idx_cap_a]->bbx.h+bf->glyph_list[idx_cap_a]->bbx.y;
  555. }
  556. idx_1_ascent = 0;
  557. idx_1 = bf_GetIndexByEncoding(bf, '1');
  558. if ( idx_1 >= 0 )
  559. {
  560. idx_1_ascent = bf->glyph_list[idx_1]->bbx.h+bf->glyph_list[idx_1]->bbx.y;
  561. }
  562. idx_g_descent = 0;
  563. idx_g = bf_GetIndexByEncoding(bf, 'g');
  564. if ( idx_g >= 0 )
  565. {
  566. idx_g_descent = bf->glyph_list[idx_g]->bbx.y;
  567. }
  568. idx_para_ascent = 0;
  569. idx_para = bf_GetIndexByEncoding(bf, '(');
  570. if ( idx_para >= 0 )
  571. {
  572. idx_para_ascent = bf->glyph_list[idx_para]->bbx.h+bf->glyph_list[idx_para]->bbx.y;
  573. idx_para_descent = bf->glyph_list[idx_para]->bbx.y;
  574. }
  575. else
  576. {
  577. idx_para_ascent = idx_cap_a_ascent;
  578. if ( idx_para_ascent == 0 )
  579. idx_para_ascent = idx_1_ascent;
  580. idx_para_descent = idx_g_descent;
  581. }
  582. for( rle_0 = 2; rle_0 < 9; rle_0++ )
  583. {
  584. for( rle_1 = 2; rle_1 < 7; rle_1++ )
  585. {
  586. total_bits = bf_RLECompressAllGlyphsWithFieldSize(bf, rle_0, rle_1, 0);
  587. if ( min_total_bits > total_bits )
  588. {
  589. min_total_bits = total_bits;
  590. best_rle_0 = rle_0;
  591. best_rle_1 = rle_1;
  592. }
  593. }
  594. }
  595. bf_Log(bf, "RLE Compress: best zero bits %d, one bits %d, total bit size %lu", best_rle_0, best_rle_1, min_total_bits);
  596. bf_RLECompressAllGlyphsWithFieldSize(bf, best_rle_0, best_rle_1, 0);
  597. bf_ClearTargetData(bf);
  598. /*
  599. glyph_cnt = *font++;
  600. bits_per_0 = *font++;
  601. bits_per_1 = *font++;
  602. bits_per_char_width = *font++;
  603. bits_per_char_height = *font++;
  604. bits_per_char_x = *font++;
  605. bits_per_char_y = *font++;
  606. bits_per_delta_x = *font++;
  607. */
  608. bf_Log(bf, "RLE Compress: Font code generation, selected glyphs=%d, total glyphs=%d", bf->selected_glyphs, bf->glyph_cnt);
  609. /* 0 */
  610. bf_AddTargetData(bf, bf->selected_glyphs);
  611. bf_AddTargetData(bf, bf->bbx_mode);
  612. bf_AddTargetData(bf, best_rle_0);
  613. bf_AddTargetData(bf, best_rle_1);
  614. /* 4 */
  615. bf_AddTargetData(bf, bf->bbx_w_max_bit_size);
  616. bf_AddTargetData(bf, bf->bbx_h_max_bit_size);
  617. bf_AddTargetData(bf, bf->bbx_x_max_bit_size);
  618. bf_AddTargetData(bf, bf->bbx_y_max_bit_size);
  619. bf_AddTargetData(bf, bf->dx_max_bit_size);
  620. /* 9 */
  621. bf_AddTargetData(bf, bf->max.w);
  622. bf_AddTargetData(bf, bf->max.h);
  623. bf_AddTargetData(bf, bf->max.x);
  624. bf_AddTargetData(bf, bf->max.y);
  625. /* 13 */
  626. if ( idx_cap_a_ascent > 0 )
  627. bf_AddTargetData(bf, idx_cap_a_ascent);
  628. else
  629. bf_AddTargetData(bf, idx_1_ascent);
  630. bf_AddTargetData(bf, idx_g_descent);
  631. /* 15 */
  632. bf_AddTargetData(bf, idx_para_ascent);
  633. bf_AddTargetData(bf, idx_para_descent);
  634. /* 17 */
  635. bf_AddTargetData(bf, 0); /* start pos 'A', high/low */
  636. bf_AddTargetData(bf, 0);
  637. /* 19 */
  638. bf_AddTargetData(bf, 0); /* start pos 'a', high/low */
  639. bf_AddTargetData(bf, 0);
  640. /* 21 */
  641. bf_AddTargetData(bf, 0); /* start pos unicode, high/low */
  642. bf_AddTargetData(bf, 0);
  643. /* assumes, that map_to is sorted */
  644. ascii_glyphs = 0;
  645. for( i = 0; i < bf->glyph_cnt; i++ )
  646. {
  647. bg = bf->glyph_list[i];
  648. if ( bg->map_to >= 0 && bg->map_to <= 255L )
  649. {
  650. if ( bg->target_data != NULL )
  651. {
  652. if ( bg->target_cnt >= 255 )
  653. {
  654. bf_Error(bf, "RLE Compress: Error, glyph too large, encoding=%ld cnt=%d", (long)bg->encoding, (int)bg->target_cnt);
  655. exit(1);
  656. }
  657. for( j = 0; j < bg->target_cnt; j++ )
  658. {
  659. bf_AddTargetData(bf, bg->target_data[j]);
  660. }
  661. ascii_glyphs++; /* calculate the numner of ascii glyphs, this is required later for the unicode index table */
  662. }
  663. }
  664. }
  665. /* add empty glyph as end of font marker for the ASCII part (chars from 0 to 255) */
  666. bf_AddTargetData(bf, 0);
  667. bf_AddTargetData(bf, 0);
  668. unicode_start_pos = bf->target_cnt-BDF_RLE_FONT_GLYPH_START;
  669. /*
  670. 1 May 2018: Unicode lookup table
  671. */
  672. bf_Log(bf, "RLE Compress: ASCII gylphs=%d, Unicode glyphs=%d", ascii_glyphs, bf->selected_glyphs-ascii_glyphs);
  673. unicode_lookup_table_len = (bf->selected_glyphs-ascii_glyphs) / UNICODE_GLYPHS_PER_LOOKUP_TABLE_ENTRY;
  674. //if ( unicode_lookup_table_len > 1 )
  675. // unicode_lookup_table_len--;
  676. bf_Log(bf, "RLE Compress: Glyphs per unicode lookup table entry=%d", UNICODE_GLYPHS_PER_LOOKUP_TABLE_ENTRY);
  677. unicode_lookup_table_start = bf->target_cnt;
  678. /* write n-1 entries */
  679. for( i = 1; i < unicode_lookup_table_len; i++ )
  680. {
  681. bf_AddTargetData(bf, 0); /* offset */
  682. bf_AddTargetData(bf, 0);
  683. bf_AddTargetData(bf, 0); /* encoding */
  684. bf_AddTargetData(bf, 0);
  685. }
  686. /* the last entry is special, it contains the encoding 0xffff */
  687. bf_AddTargetData(bf, 0); /* offset */
  688. bf_AddTargetData(bf, 4); /* default, if the table has only one entry, then just skip the table */
  689. bf_AddTargetData(bf, 0xff); /* encoding */
  690. bf_AddTargetData(bf, 0xff);
  691. unicode_lookup_table_pos = 0;
  692. unicode_lookup_table_glyph_cnt = 0;
  693. unicode_last_delta = bf->target_cnt-unicode_lookup_table_start; /* should be 4 if unicode_lookup_table_len == 0 */
  694. unicode_last_target_cnt = bf->target_cnt;
  695. unicode_glyph_cnt = 0;
  696. /* now write chars with code >= 256 from the BMP */
  697. /* assumes, that map_to is sorted */
  698. for( i = 0; i < bf->glyph_cnt; i++ )
  699. {
  700. bg = bf->glyph_list[i];
  701. if ( bg->map_to >= 256 )
  702. {
  703. if ( bg->target_data != NULL )
  704. {
  705. if ( bg->target_cnt >= 255 )
  706. {
  707. bf_Error(bf, "RLE Compress: Error, glyph too large, encoding=%ld", (long)bg->encoding);
  708. exit(1);
  709. }
  710. for( j = 0; j < bg->target_cnt; j++ )
  711. {
  712. bf_AddTargetData(bf, bg->target_data[j]);
  713. }
  714. // Debug output issue 1521
  715. //bf_Log(bf, "RLE Compress: Unicode glyph pos=%d, lookup table=%d, glyph within lut=%d", unicode_glyph_cnt, unicode_lookup_table_pos, unicode_lookup_table_glyph_cnt);
  716. /* update the unicode lookup table entry counter */
  717. unicode_lookup_table_glyph_cnt++;
  718. if ( unicode_lookup_table_glyph_cnt >= UNICODE_GLYPHS_PER_LOOKUP_TABLE_ENTRY )
  719. {
  720. /* ensure, that there is a table entry available */
  721. if ( unicode_lookup_table_pos < unicode_lookup_table_len )
  722. {
  723. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+0] = unicode_last_delta>>8;
  724. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+1] = unicode_last_delta&255;
  725. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+2] |= bg->encoding>>8; // ensure to keep the 0x0ffff encoding at the end
  726. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+3] |= bg->encoding&255; // ensure to keep the 0x0ffff encoding at the end
  727. unicode_lookup_table_pos++;
  728. unicode_lookup_table_glyph_cnt = 0;
  729. unicode_last_delta = bf->target_cnt - unicode_last_target_cnt;
  730. unicode_last_target_cnt = bf->target_cnt;
  731. }
  732. }
  733. unicode_glyph_cnt++;
  734. }
  735. }
  736. }
  737. /* write pending block to the unicode lookup table, ensure, that there is a table entry available */
  738. if ( unicode_lookup_table_pos < unicode_lookup_table_len )
  739. {
  740. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+0] = unicode_last_delta>>8;
  741. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+1] = unicode_last_delta&255;
  742. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+2] = 0xff;
  743. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4+3] = 0xff;
  744. unicode_lookup_table_pos++;
  745. }
  746. /* add empty encoding as end of font marker (note: this differs from the ASCII section) */
  747. bf_AddTargetData(bf, 0);
  748. bf_AddTargetData(bf, 0);
  749. bf_Log(bf, "RLE Compress: Unicode lookup table len=%d, written entries=%d", unicode_lookup_table_len, unicode_lookup_table_pos);
  750. bf_Log(bf, "RLE Compress: Unicode lookup table first entry: delta=%d, encoding=%d",
  751. bf->target_data[unicode_lookup_table_start+0]*256+bf->target_data[unicode_lookup_table_start+1],
  752. bf->target_data[unicode_lookup_table_start+2]*256+bf->target_data[unicode_lookup_table_start+3]);
  753. bf_Log(bf, "RLE Compress: Unicode lookup table last entry: delta=%d, encoding=%d",
  754. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4-4+0]*256+bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4-4+1],
  755. bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4-4+2]*256+bf->target_data[unicode_lookup_table_start+unicode_lookup_table_pos*4-4+3]);
  756. bf_Log(bf, "RLE Compress: Unicode glyphs written=%d", unicode_glyph_cnt);
  757. assert(unicode_lookup_table_len == unicode_lookup_table_pos ); // ensure that all table entries are filled
  758. pos = bf_RLE_get_glyph_data(bf, 'A');
  759. bf->target_data[17] = pos >> 8;
  760. bf->target_data[18] = pos & 255;
  761. pos = bf_RLE_get_glyph_data(bf, 'a');
  762. bf->target_data[19] = pos >> 8;
  763. bf->target_data[20] = pos & 255;
  764. bf->target_data[21] = unicode_start_pos >> 8;
  765. bf->target_data[22] = unicode_start_pos & 255;
  766. bf_Log(bf, "RLE Compress: 'A' pos = %u, 'a' pos = %u", bf_RLE_get_glyph_data(bf, 'A'), bf_RLE_get_glyph_data(bf, 'a'));
  767. bf_Log(bf, "RLE Compress: Font size %d", bf->target_cnt);
  768. }