diff --git a/include/gint/display.h b/include/gint/display.h index 2bdf74a..b43830c 100644 --- a/include/gint/display.h +++ b/include/gint/display.h @@ -167,25 +167,38 @@ void dvline(int x, int color); /* font_t: Font data encoded for topti */ typedef struct { - /* Length of font name (not necessarily NUL-terminated!) */ - uint title :5; + /* Font name (NUL-terminated), NULL if no title */ + char const *name; + /* Font shape flags */ - uint bold :1; - uint italic :1; - uint serif :1; - uint mono :1; + uint bold :1; + uint italic :1; + uint serif :1; + uint mono :1; + uint :3; /* Whether data is variable-length (proportional font) */ - uint prop :1; - /* Reserved for future use */ - uint :2; - /* Implemented charcter set */ - uint charset :4; + uint prop :1; + /* Line height */ uint8_t line_height; /* Storage height */ uint8_t data_height; - /* The rest of the data depends on whether the font is proportional */ + /* Number of Unicode blocks */ + uint8_t block_count; + /* Number of total glyphs */ + uint32_t glyph_count; + + struct { + /* Unicode point of first character in block */ + uint start :20; + /* Length of block */ + uint length :12; + } *blocks; + + /* Raw glyph data */ + uint32_t *data; + union { /* For monospaced fonts */ struct { @@ -193,23 +206,16 @@ typedef struct uint16_t width; /* Storage size, in longwords, of each glyph */ uint16_t storage_size; - /* Raw glyph data */ - uint32_t data[]; }; /* For proportional fonts */ struct { /* Storage index to find glyphs quickly */ - uint16_t index[16]; - /* Size array (padded to 4 bytes), 1 byte per entry, - followed by glyph data */ - uint8_t sized_data[]; + uint16_t *glyph_index; + /* Width of each individual glyph */ + uint8_t *glyph_width; }; }; - /* The font name is stored after the data. The size is the length set - in the [title] field, padded to 4 bytes with NULs. There might not - be a NUL at the end. */ - } GPACKED(4) font_t; /* dfont(): Set the default font for text rendering diff --git a/src/render-cg/topti.c b/src/render-cg/topti.c index 6c04039..2d34d2c 100644 --- a/src/render-cg/topti.c +++ b/src/render-cg/topti.c @@ -46,15 +46,7 @@ void topti_render(int x, int y, char const *str, size_t size, font_t const *f, int fg, int bg) { /* Raw glyph data */ - uint32_t const * data; - if(!f->prop) data = f->data; - else - { - int cs = charset_size(f->charset); - /* 4-align the result */ - cs += (4 - cs) & 3; - data = (void *)(f->sized_data + cs); - } + uint32_t const *data = f->data; /* Storage height, top position within glyph */ int height = f->data_height, top = 0; @@ -76,7 +68,7 @@ void topti_render(int x, int y, char const *str, size_t size, font_t const *f, { int c = *str++; - int glyph = charset_decode(f->charset, c); + int glyph = topti_glyph_index(f, c); if(glyph < 0) continue; /* Draw the space if background is opaque */ @@ -95,7 +87,7 @@ void topti_render(int x, int y, char const *str, size_t size, font_t const *f, /* Compute horizontal intersection between glyph and screen */ - int dataw = f->prop ? f->sized_data[glyph] : f->width; + int dataw = f->prop ? f->glyph_width[glyph] : f->width; int width = dataw, left = 0; if(x + dataw <= 0) diff --git a/src/render-fx/topti.c b/src/render-fx/topti.c index e53c0b3..f3da78e 100644 --- a/src/render-fx/topti.c +++ b/src/render-fx/topti.c @@ -88,15 +88,7 @@ void topti_render(int x, int y, char const *str, font_t const *f, /* Storage height and number of free bits in operators[] */ int height = f->data_height, free; /* Raw glyph data */ - uint32_t const * data; - if(!f->prop) data = f->data; - else - { - int cs = charset_size(f->charset); - /* 4-align the result */ - cs += (4 - cs) & 3; - data = (void *)(f->sized_data + cs); - } + uint32_t const *data = f->data; /* Basic clipping */ if(x > 127 || y > 63 || y + height <= 0) return; @@ -126,13 +118,13 @@ void topti_render(int x, int y, char const *str, font_t const *f, /* Pull each character into the operator buffer */ while(*str) { - int glyph = charset_decode(f->charset, *str++); + int glyph = topti_glyph_index(f, *str++); if(glyph < 0) continue; int index = topti_offset(f, glyph); /* Put glyph data into the operators */ - int width = f->prop ? f->sized_data[glyph] : f->width; + int width = f->prop ? f->glyph_width[glyph] : f->width; free = topti_split(data+index, width, height, free, operators); /* Potential space after the glyph */ diff --git a/src/render/render.h b/src/render/render.h index 95522c0..23c963e 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -26,29 +26,12 @@ extern font_t const *topti_font; /* Default font */ extern font_t const *gint_default_font; -/* enum topti_charset: Available character set decoders - Each charset is associated with a reduced character table. */ -enum topti_charset -{ - charset_numeric = 0, /* 10 elements: 0..9 */ - charset_upper = 1, /* 26 elements: A..Z */ - charset_alpha = 2, /* 52 elements: A..Z, a..z */ - charset_alnum = 3, /* 62 elements: A..Z, a..z, 0..9 */ - charset_print = 4, /* 95 elements: 0x20..0x7e */ - charset_ascii = 5, /* 128 elements: 0x00..0x7f */ -}; - -/* charset_size(): Number of elements in each character set - @set Character set ID - Returns the expected number of glyphs, -1 if charset ID is invalid. */ -int charset_size(enum topti_charset set); - -/* charset_decode(): Translate ASCII into reduced character sets - Returns the position of [c] in the character table of the given charset, or - -1 if [c] is not part of that set. - @set Any character set - @c Character to decode */ -int charset_decode(enum topti_charset set, uint c); +/* topti_glyph_index(): Obtain the glyph index of a Unicode code point + Returns the position of code_point in the character table of the given font, + or -1 if code_point is not part of that set. + @f Font object + @code_point Unicode code point to locate the glyph for */ +int topti_glyph_index(font_t const *f, uint32_t code_point); /* topti_offset(): Use a font index to find the location of a glyph @f Font object diff --git a/src/render/topti.c b/src/render/topti.c index 0788beb..25fe0d9 100644 --- a/src/render/topti.c +++ b/src/render/topti.c @@ -16,41 +16,20 @@ font_t const *dfont(font_t const * font) return old_font; } -/* charset_size(): Number of elements in each character set */ -int charset_size(enum topti_charset set) +/* topti_glyph_index(): Obtain the glyph index of a Unicode code point */ +int topti_glyph_index(font_t const *f, uint32_t code_point) { - int size[] = { 10, 26, 52, 62, 95, 128 }; - return (uint)set < 6 ? size[set] : -1; -} + int glyph_start = 0; -/* charset_decode(): Translate ASCII into reduced character sets */ -int charset_decode(enum topti_charset set, uint c) -{ - int x, y; - - switch(set) + for(int i = 0; i < f->block_count; i++) { - case charset_numeric: - x = c - '0'; - return (x < 10) ? x : -1; - case charset_upper: - x = (c - 'A') & ~0x20; - return (x < 26) ? x : -1; - case charset_alnum: - x = c - '0'; - if(x < 10) return x; - /* Intentional fallthrough */ - case charset_alpha: - y = c & 0x20; - x = (c ^ y) - 'A'; - /* Turn 32 into 26 and leave 0 as 0 */ - y = y - (y >> 3) - (y >> 4); - return (x < 26) ? (x + y) : -1; - case charset_print: - x = c - 0x20; - return (x < 0x5f) ? x : -1; - case charset_ascii: - return c; + int diff = code_point - f->blocks[i].start; + if(diff >= 0 && diff < f->blocks[i].length) + { + return glyph_start + diff; + } + + glyph_start += f->blocks[i].length; } return -1; @@ -62,12 +41,12 @@ int topti_offset(font_t const *f, uint glyph) /* Non-proportional fonts don't need an index */ if(!f->prop) return glyph * f->storage_size; - uint8_t const *width = f->sized_data; + uint8_t const *width = f->glyph_width; - /* The index gives us the position of all glyphs whose IDs are mutiples - of 8. Start with a close one and iterate from there. */ + /* The index gives us the position of all glyphs whose IDs are + multiples of 8. Start with a close one and iterate from there. */ uint g = glyph & ~0x7; - int offset = f->index[g >> 3]; + int offset = f->glyph_index[g >> 3]; /* Traverse the width array (which is in bits) while converting to longword size */ @@ -76,7 +55,7 @@ int topti_offset(font_t const *f, uint glyph) return offset; } -/* dsize() - get the width and height of rendered text */ +/* dsize(): Get the width and height of rendered text */ void dsize(const char *str, font_t const * f, int *w, int *h) { if(!f) f = topti_font; @@ -105,8 +84,8 @@ void dsize(const char *str, font_t const * f, int *w, int *h) continue; } - int glyph = charset_decode(f->charset, c); - if(glyph > 0) width += f->sized_data[glyph] + CHAR_SPACING; + int glyph = topti_glyph_index(f, c); + if(glyph >= 0) width += f->glyph_width[glyph] + CHAR_SPACING; } *w = width - CHAR_SPACING; }