fd.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. fd.c
  3. font decode
  4. (obsolete? does not support unicode)
  5. */
  6. #include "fd.h"
  7. #include <stddef.h>
  8. void fd_init(fd_t *fd)
  9. {
  10. fd->is_transparent = 1;
  11. }
  12. void fd_set_font(fd_t *fd, uint8_t *font)
  13. {
  14. fd->glyph_cnt = *font++;
  15. font++; /* bbx mode */
  16. fd->bits_per_0 = *font++;
  17. fd->bits_per_1 = *font++;
  18. fd->bits_per_char_width = *font++;
  19. fd->bits_per_char_height = *font++;
  20. fd->bits_per_char_x = *font++;
  21. fd->bits_per_char_y = *font++;
  22. fd->bits_per_delta_x = *font++;
  23. fd->char_width = *font++;
  24. fd->char_height = *font++;
  25. font++; /* x offset */
  26. fd->char_descent = *(int8_t *)font;
  27. font++;
  28. font++;
  29. font++;
  30. font++;
  31. font++;
  32. fd->capital_a_pos= *font++;
  33. fd->capital_a_pos <<= 8;
  34. fd->capital_a_pos |= *font++;
  35. fd->small_a_pos = *font++;
  36. fd->small_a_pos <<= 8;
  37. fd->small_a_pos |= *font++;
  38. /* TODO: proper unicode update */
  39. font++;
  40. font++;
  41. fd->font = font;
  42. }
  43. uint8_t *fd_get_glyph_data(fd_t *fd, uint8_t encoding)
  44. {
  45. uint8_t *font = fd->font;
  46. if ( encoding >= 'a' ) /* assumes 'a' > 'A' */
  47. {
  48. font += fd->small_a_pos;
  49. }
  50. else if ( encoding >= 'A' )
  51. {
  52. font += fd->capital_a_pos;
  53. }
  54. for(;;)
  55. {
  56. if ( font[1] == 0 )
  57. break;
  58. if ( font[0] == encoding )
  59. {
  60. return font;
  61. }
  62. font += font[1];
  63. }
  64. return NULL;
  65. }
  66. __attribute__((noinline)) unsigned fd_get_unsigned_bits(fd_t *f, unsigned cnt)
  67. {
  68. unsigned val;
  69. unsigned bit_pos = f->decode_bit_pos;
  70. unsigned rem_bits;
  71. val = f->decode_byte;
  72. rem_bits = 8;
  73. rem_bits -= bit_pos;
  74. bit_pos += cnt;
  75. if ( cnt >= rem_bits )
  76. {
  77. f->decode_ptr++;
  78. f->decode_byte = *(f->decode_ptr);
  79. val |= f->decode_byte << (rem_bits);
  80. bit_pos -= 8;
  81. f->decode_byte >>= bit_pos;
  82. }
  83. else
  84. {
  85. f->decode_byte >>= cnt;
  86. }
  87. val &= (1U<<cnt)-1;
  88. f->decode_bit_pos = bit_pos;
  89. return val;
  90. }
  91. int fd_get_signed_bits(fd_t *fd, int cnt)
  92. {
  93. return (int)fd_get_unsigned_bits(fd, cnt) - ((1<<cnt)>>1);
  94. }
  95. void tga_draw_hline(unsigned x,unsigned y, unsigned cnt, unsigned is_foreground);
  96. void fd_draw_pixel(fd_t *f, unsigned cnt, unsigned is_foreground)
  97. {
  98. if ( f->is_transparent != 0 && is_foreground == 0 )
  99. return;
  100. tga_draw_hline(f->target_x+f->x, f->target_y+f->y, cnt, is_foreground);
  101. }
  102. void fd_decode_len(fd_t *fd, unsigned len, unsigned is_foreground)
  103. {
  104. unsigned cnt, rem;
  105. cnt = len;
  106. for(;;)
  107. {
  108. rem = fd->glyph_width;
  109. rem -= fd->x;
  110. if ( cnt < rem )
  111. break;
  112. fd_draw_pixel(fd,rem, is_foreground);
  113. cnt -= rem;
  114. fd->x = 0;
  115. fd->y++;
  116. }
  117. fd_draw_pixel(fd, cnt, is_foreground);
  118. fd->x += cnt;
  119. }
  120. /*
  121. expects:
  122. unsigned target_x;
  123. unsigned target_y;
  124. unsigned is_transparent;
  125. const uint8_t *decode_ptr;
  126. */
  127. unsigned fd_decode(fd_t *f)
  128. {
  129. unsigned a, b;
  130. int x, y;
  131. unsigned d = 0;
  132. f->decode_bit_pos = 0;
  133. f->decode_ptr += 1;
  134. f->decode_ptr += 1;
  135. f->decode_byte = *(f->decode_ptr); /* init decoder */
  136. f->glyph_width = fd_get_unsigned_bits(f, f->bits_per_char_width);
  137. f->glyph_height = fd_get_unsigned_bits(f, f->bits_per_char_height);
  138. x = fd_get_signed_bits(f, f->bits_per_char_x);
  139. y = fd_get_signed_bits(f, f->bits_per_char_y);
  140. d = fd_get_signed_bits(f, f->bits_per_delta_x);
  141. if ( f->glyph_width > 0 )
  142. {
  143. f->target_x += x;
  144. f->target_y -= f->glyph_height ;
  145. f->target_y -=y ;
  146. f->x = 0;
  147. f->y = 0;
  148. for(;;)
  149. {
  150. a = fd_get_unsigned_bits(f, f->bits_per_0);
  151. b = fd_get_unsigned_bits(f, f->bits_per_1);
  152. do
  153. {
  154. fd_decode_len(f, a, 0);
  155. fd_decode_len(f, b, 1);
  156. } while( fd_get_unsigned_bits(f, 1) != 0 );
  157. if ( f->y >= f->glyph_height )
  158. break;
  159. }
  160. }
  161. return d;
  162. }
  163. unsigned fd_draw_glyph(fd_t *fd, unsigned x, unsigned y, uint8_t encoding)
  164. {
  165. unsigned dx = 0;
  166. fd->target_x = x;
  167. fd->target_y = y;
  168. fd->decode_ptr = fd_get_glyph_data(fd, encoding);
  169. if ( fd->decode_ptr != NULL )
  170. {
  171. dx = fd_decode(fd);
  172. }
  173. return dx;
  174. }
  175. unsigned fd_draw_string(fd_t *fd, unsigned x, unsigned y, const char *s)
  176. {
  177. unsigned dx = 0;
  178. while( *s != '\0' )
  179. {
  180. dx += fd_draw_glyph(fd, x+dx,y,*s);
  181. s++;
  182. }
  183. return dx;
  184. }