| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- /*
- fd.c
-
- font decode
-
- (obsolete? does not support unicode)
-
- */
- #include "fd.h"
- #include <stddef.h>
- void fd_init(fd_t *fd)
- {
- fd->is_transparent = 1;
- }
- void fd_set_font(fd_t *fd, uint8_t *font)
- {
- fd->glyph_cnt = *font++;
- font++; /* bbx mode */
- fd->bits_per_0 = *font++;
- fd->bits_per_1 = *font++;
- fd->bits_per_char_width = *font++;
- fd->bits_per_char_height = *font++;
- fd->bits_per_char_x = *font++;
- fd->bits_per_char_y = *font++;
- fd->bits_per_delta_x = *font++;
- fd->char_width = *font++;
- fd->char_height = *font++;
- font++; /* x offset */
- fd->char_descent = *(int8_t *)font;
- font++;
-
- font++;
- font++;
- font++;
- font++;
- fd->capital_a_pos= *font++;
- fd->capital_a_pos <<= 8;
- fd->capital_a_pos |= *font++;
- fd->small_a_pos = *font++;
- fd->small_a_pos <<= 8;
- fd->small_a_pos |= *font++;
- /* TODO: proper unicode update */
- font++;
- font++;
- fd->font = font;
- }
- uint8_t *fd_get_glyph_data(fd_t *fd, uint8_t encoding)
- {
-
- uint8_t *font = fd->font;
- if ( encoding >= 'a' ) /* assumes 'a' > 'A' */
- {
- font += fd->small_a_pos;
- }
- else if ( encoding >= 'A' )
- {
- font += fd->capital_a_pos;
- }
-
- for(;;)
- {
- if ( font[1] == 0 )
- break;
- if ( font[0] == encoding )
- {
- return font;
- }
- font += font[1];
- }
- return NULL;
- }
- __attribute__((noinline)) unsigned fd_get_unsigned_bits(fd_t *f, unsigned cnt)
- {
- unsigned val;
- unsigned bit_pos = f->decode_bit_pos;
- unsigned rem_bits;
-
- val = f->decode_byte;
- rem_bits = 8;
- rem_bits -= bit_pos;
-
- bit_pos += cnt;
- if ( cnt >= rem_bits )
- {
- f->decode_ptr++;
- f->decode_byte = *(f->decode_ptr);
-
- val |= f->decode_byte << (rem_bits);
-
- bit_pos -= 8;
- f->decode_byte >>= bit_pos;
- }
- else
- {
- f->decode_byte >>= cnt;
- }
- val &= (1U<<cnt)-1;
- f->decode_bit_pos = bit_pos;
- return val;
- }
- int fd_get_signed_bits(fd_t *fd, int cnt)
- {
- return (int)fd_get_unsigned_bits(fd, cnt) - ((1<<cnt)>>1);
- }
- void tga_draw_hline(unsigned x,unsigned y, unsigned cnt, unsigned is_foreground);
- void fd_draw_pixel(fd_t *f, unsigned cnt, unsigned is_foreground)
- {
- if ( f->is_transparent != 0 && is_foreground == 0 )
- return;
- tga_draw_hline(f->target_x+f->x, f->target_y+f->y, cnt, is_foreground);
- }
- void fd_decode_len(fd_t *fd, unsigned len, unsigned is_foreground)
- {
- unsigned cnt, rem;
- cnt = len;
- for(;;)
- {
- rem = fd->glyph_width;
- rem -= fd->x;
- if ( cnt < rem )
- break;
- fd_draw_pixel(fd,rem, is_foreground);
- cnt -= rem;
- fd->x = 0;
- fd->y++;
- }
- fd_draw_pixel(fd, cnt, is_foreground);
- fd->x += cnt;
- }
- /*
- expects:
- unsigned target_x;
- unsigned target_y;
- unsigned is_transparent;
- const uint8_t *decode_ptr;
- */
- unsigned fd_decode(fd_t *f)
- {
- unsigned a, b;
- int x, y;
- unsigned d = 0;
-
- f->decode_bit_pos = 0;
-
- f->decode_ptr += 1;
- f->decode_ptr += 1;
-
- f->decode_byte = *(f->decode_ptr); /* init decoder */
-
- f->glyph_width = fd_get_unsigned_bits(f, f->bits_per_char_width);
- f->glyph_height = fd_get_unsigned_bits(f, f->bits_per_char_height);
- x = fd_get_signed_bits(f, f->bits_per_char_x);
- y = fd_get_signed_bits(f, f->bits_per_char_y);
- d = fd_get_signed_bits(f, f->bits_per_delta_x);
-
- if ( f->glyph_width > 0 )
- {
-
- f->target_x += x;
- f->target_y -= f->glyph_height ;
- f->target_y -=y ;
-
- f->x = 0;
- f->y = 0;
-
- for(;;)
- {
- a = fd_get_unsigned_bits(f, f->bits_per_0);
- b = fd_get_unsigned_bits(f, f->bits_per_1);
- do
- {
- fd_decode_len(f, a, 0);
- fd_decode_len(f, b, 1);
- } while( fd_get_unsigned_bits(f, 1) != 0 );
- if ( f->y >= f->glyph_height )
- break;
- }
- }
- return d;
- }
- unsigned fd_draw_glyph(fd_t *fd, unsigned x, unsigned y, uint8_t encoding)
- {
- unsigned dx = 0;
- fd->target_x = x;
- fd->target_y = y;
- fd->decode_ptr = fd_get_glyph_data(fd, encoding);
- if ( fd->decode_ptr != NULL )
- {
- dx = fd_decode(fd);
- }
- return dx;
- }
- unsigned fd_draw_string(fd_t *fd, unsigned x, unsigned y, const char *s)
- {
- unsigned dx = 0;
- while( *s != '\0' )
- {
- dx += fd_draw_glyph(fd, x+dx,y,*s);
- s++;
- }
- return dx;
- }
|