bdf_8x8.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. bdf_8x8.c
  3. unencoded font format for 8x8 pixel font
  4. offset bytes desc
  5. 0 1 first char
  6. 1 1 last char
  7. 2 1 horizontal tile count (x), new 2019 format, issue 771
  8. 3 1 vertical tile count (y), new 2019 format, issue 771
  9. 4 n font data, n = (last char - first char + 1)*8
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <assert.h>
  14. #include "bdf_font.h"
  15. static int bg_8x8_convert(bg_t *bg, bbx_t *bbx, int xo, int yo)
  16. {
  17. int x;
  18. int y;
  19. int d;
  20. if ( bbx == NULL )
  21. bbx = &(bg->bbx);
  22. /*
  23. if ( bbx->w != 8 )
  24. return 0;
  25. if ( bbx->h != 8 )
  26. return 0;
  27. */
  28. /*
  29. for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
  30. {
  31. d = 0;
  32. for( x = bbx->x; x < bbx->x + bbx->w; x++)
  33. {
  34. d <<= 1;
  35. if ( bg_GetBBXPixel(bg, x, y) != 0 )
  36. {
  37. d++;
  38. }
  39. }
  40. if ( bg_AddTargetData(bg, d) < 0 )
  41. return 0;
  42. }
  43. */
  44. for( x = bbx->x; x < bbx->x + bbx->w; x++)
  45. {
  46. d = 0;
  47. for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
  48. {
  49. d >>= 1;
  50. if ( bg_GetBBXPixel(bg, x+xo, y+yo) != 0 )
  51. {
  52. d |= 128;
  53. }
  54. }
  55. if ( bg_AddTargetData(bg, d) < 0 )
  56. return 0;
  57. }
  58. return 1;
  59. }
  60. void bf_Generate8x8Font(bf_t *bf, int xo, int yo)
  61. {
  62. int i, j, k;
  63. bg_t *bg;
  64. int first, last;
  65. bbx_t local_bbx;
  66. int is_glyph_written;
  67. int x, y;
  68. /* Step 1: Generate 8x8 bitmap data */
  69. for( i = 0; i < bf->glyph_cnt; i++ )
  70. {
  71. bg = bf->glyph_list[i];
  72. if ( bg->map_to >= 0 )
  73. {
  74. bf_copy_bbx_and_update_shift(bf, &local_bbx, bg);
  75. if ( (local_bbx.w & 7) != 0 )
  76. {
  77. bf_Log(bf, "Generate8x8Font: Error, glyph width is not multiple of 8, width=%d, encoding=%d", local_bbx.w, bg->encoding);
  78. }
  79. else
  80. {
  81. if ( (local_bbx.h & 7) != 0 )
  82. {
  83. bf_Log(bf, "Generate8x8Font: Error, glyph height is not multiple of 8, height=%d, encoding=%d", local_bbx.h, bg->encoding);
  84. }
  85. else
  86. {
  87. bg_ClearTargetData(bg);
  88. for( y = 0; y < bf->tile_v_size; y++ )
  89. {
  90. for( x = 0; x < bf->tile_h_size; x++ )
  91. {
  92. //bf_Log(bf, "Generate8x8Font: Encoding %d, x=%d, y=%d", bg->encoding, x, y);
  93. if ( bg_8x8_convert(bg, &local_bbx, xo+8*x, yo+8*(bf->tile_v_size-y-1)) == 0 )
  94. {
  95. bf_Log(bf, "Generate8x8Font: Error, 8x8 conversion, encoding=%d", bg->target_cnt, bg->encoding);
  96. }
  97. }
  98. }
  99. }
  100. }
  101. }
  102. }
  103. /* Step 2: Calculate first and last char */
  104. first = -1;
  105. last = -1;
  106. for( j = 0; j < 256; j++ )
  107. {
  108. for( i = 0; i < bf->glyph_cnt; i++ )
  109. {
  110. bg = bf->glyph_list[i];
  111. if ( bg->map_to == j )
  112. {
  113. if ( bg->target_data != NULL )
  114. {
  115. //bf_Log(bf, "Generate8x8Font: Encoding %d, size=%d", bg->encoding, bg->target_cnt);
  116. if ( bg->target_cnt != bf->tile_h_size*bf->tile_v_size*8)
  117. {
  118. bf_Log(bf, "Generate8x8Font: Error, glyph size incorrect, size=%d, encoding=%d", bg->target_cnt, bg->encoding);
  119. }
  120. else
  121. {
  122. if ( first < 0 )
  123. first = j;
  124. last = j;
  125. }
  126. }
  127. }
  128. }
  129. }
  130. /* Step 3: Write font data */
  131. bf_AddTargetData(bf, first);
  132. bf_AddTargetData(bf, last);
  133. bf_AddTargetData(bf, bf->tile_h_size);
  134. bf_AddTargetData(bf, bf->tile_v_size);
  135. bf_Log(bf, "Generate8x8Font: Tile multiplier horizontal size (-th) =%d, vertical size (-tv)=%d", bf->tile_h_size, bf->tile_v_size);
  136. for( j = first; j <= last; j++ )
  137. {
  138. is_glyph_written = 0;
  139. for( i = 0; i < bf->glyph_cnt; i++ )
  140. {
  141. bg = bf->glyph_list[i];
  142. if ( bg->map_to == j )
  143. {
  144. if ( bg->target_data != NULL )
  145. {
  146. if ( bg->target_cnt == bf->tile_h_size*bf->tile_v_size*8)
  147. {
  148. for( k = 0; k < bg->target_cnt; k++ )
  149. {
  150. bf_AddTargetData(bf, bg->target_data[k]);
  151. }
  152. is_glyph_written = 1;
  153. }
  154. }
  155. }
  156. }
  157. if ( is_glyph_written == 0 )
  158. {
  159. for( k = 0; k < bf->tile_h_size*bf->tile_v_size*8; k++ )
  160. {
  161. bf_AddTargetData(bf, 0);
  162. }
  163. }
  164. }
  165. bf_Log(bf, "Generate8x8Font: Font size %d", bf->target_cnt);
  166. }