mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-29 13:03:36 +01:00
topti: support Unicode fonts
This change adds UTF-8 decoding to dtext() to fully use Unicode fonts provided by fxconv.
This commit is contained in:
parent
e3042755d2
commit
e16f3acfa1
4 changed files with 80 additions and 15 deletions
|
@ -42,9 +42,11 @@ static void topti_glyph(uint16_t *vram, uint32_t const * data, int left,
|
||||||
dataw - width, index);
|
dataw - width, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void topti_render(int x, int y, char const *str, size_t size, font_t const *f,
|
static void topti_render(int x, int y, char const *str_char, font_t const *f,
|
||||||
int fg, int bg)
|
int fg, int bg)
|
||||||
{
|
{
|
||||||
|
uint8_t const *str = (void *)str_char;
|
||||||
|
|
||||||
/* Raw glyph data */
|
/* Raw glyph data */
|
||||||
uint32_t const *data = f->data;
|
uint32_t const *data = f->data;
|
||||||
|
|
||||||
|
@ -64,15 +66,16 @@ void topti_render(int x, int y, char const *str, size_t size, font_t const *f,
|
||||||
int active_space = 0;
|
int active_space = 0;
|
||||||
|
|
||||||
/* Read each character from the input string */
|
/* Read each character from the input string */
|
||||||
while(size--)
|
while(1)
|
||||||
{
|
{
|
||||||
int c = *str++;
|
uint32_t code_point = topti_utf8_next(&str);
|
||||||
|
if(!code_point) break;
|
||||||
|
|
||||||
int glyph = topti_glyph_index(f, c);
|
int glyph = topti_glyph_index(f, code_point);
|
||||||
if(glyph < 0) continue;
|
if(glyph < 0) continue;
|
||||||
|
|
||||||
/* Draw the space if background is opaque */
|
/* Draw the space if background is opaque */
|
||||||
int prop_space = (c == ' ' && f->prop) ? 5 : 0;
|
int prop_space = (code_point == ' ' && f->prop) ? 5 : 0;
|
||||||
if(active_space || prop_space)
|
if(active_space || prop_space)
|
||||||
{
|
{
|
||||||
active_space += prop_space;
|
active_space += prop_space;
|
||||||
|
@ -124,5 +127,5 @@ void dtext_opt(int x, int y, int fg, int bg, int halign, int valign,
|
||||||
if(valign == DTEXT_MIDDLE) y -= ((h+1) >> 1);
|
if(valign == DTEXT_MIDDLE) y -= ((h+1) >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
topti_render(x, y, str, strlen(str), topti_font, fg, bg);
|
topti_render(x, y, str, topti_font, fg, bg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,9 +82,11 @@ static int topti_split(uint32_t const * glyph, int width, int height, int free,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* topti_render(): Render a string on the VRAM */
|
/* topti_render(): Render a string on the VRAM */
|
||||||
void topti_render(int x, int y, char const *str, font_t const *f,
|
void topti_render(int x, int y, char const *str_char, font_t const *f,
|
||||||
asm_text_t *asm_fg, asm_text_t *asm_bg, uint32_t *v1, uint32_t *v2)
|
asm_text_t *asm_fg, asm_text_t *asm_bg, uint32_t *v1, uint32_t *v2)
|
||||||
{
|
{
|
||||||
|
uint8_t const *str = (void *)str_char;
|
||||||
|
|
||||||
/* Storage height and number of free bits in operators[] */
|
/* Storage height and number of free bits in operators[] */
|
||||||
int height = f->data_height, free;
|
int height = f->data_height, free;
|
||||||
/* Raw glyph data */
|
/* Raw glyph data */
|
||||||
|
@ -116,9 +118,12 @@ void topti_render(int x, int y, char const *str, font_t const *f,
|
||||||
v2 += (y << 2) + x;
|
v2 += (y << 2) + x;
|
||||||
|
|
||||||
/* Pull each character into the operator buffer */
|
/* Pull each character into the operator buffer */
|
||||||
while(*str)
|
while(1)
|
||||||
{
|
{
|
||||||
int glyph = topti_glyph_index(f, *str++);
|
uint32_t code_point = topti_utf8_next(&str);
|
||||||
|
if(!code_point) break;
|
||||||
|
|
||||||
|
int glyph = topti_glyph_index(f, code_point);
|
||||||
if(glyph < 0) continue;
|
if(glyph < 0) continue;
|
||||||
|
|
||||||
int index = topti_offset(f, glyph);
|
int index = topti_offset(f, glyph);
|
||||||
|
|
|
@ -26,6 +26,11 @@ extern font_t const *topti_font;
|
||||||
/* Default font */
|
/* Default font */
|
||||||
extern font_t const *gint_default_font;
|
extern font_t const *gint_default_font;
|
||||||
|
|
||||||
|
/* topti_utf8_next(): Read the next UTF-8 code point of a string
|
||||||
|
Returns the next code point and advances the string. Returns 0 (NUL) at the
|
||||||
|
end of the string. */
|
||||||
|
uint32_t topti_utf8_next(uint8_t const **str_pointer);
|
||||||
|
|
||||||
/* topti_glyph_index(): Obtain the glyph index of a Unicode code point
|
/* 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,
|
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.
|
or -1 if code_point is not part of that set.
|
||||||
|
|
|
@ -55,9 +55,57 @@ int topti_offset(font_t const *f, uint glyph)
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dsize(): Get the width and height of rendered text */
|
/* topti_utf8_next(): Read the next UTF-8 code point of a string */
|
||||||
void dsize(const char *str, font_t const * f, int *w, int *h)
|
uint32_t topti_utf8_next(uint8_t const **str_pointer)
|
||||||
{
|
{
|
||||||
|
uint8_t const *str = *str_pointer;
|
||||||
|
uint8_t lead = *str++;
|
||||||
|
|
||||||
|
/* Skip non-leaders which are invalid as starting bytes */
|
||||||
|
while((lead >= 0x80 && lead <= 0xbf) ||
|
||||||
|
lead == 0xc0 || lead == 0xc1 || lead == 0xfe || lead == 0xff)
|
||||||
|
{
|
||||||
|
lead = *str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This base case will handle the NUL terminator */
|
||||||
|
if(lead <= 0x7f)
|
||||||
|
{
|
||||||
|
*str_pointer = str;
|
||||||
|
return lead;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t n2 = (*str++ & 0x3f);
|
||||||
|
if(lead <= 0xdf)
|
||||||
|
{
|
||||||
|
*str_pointer = str;
|
||||||
|
return ((lead & 0x1f) << 6) | n2;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t n3 = (*str++ & 0x3f);
|
||||||
|
if(lead <= 0xef)
|
||||||
|
{
|
||||||
|
*str_pointer = str;
|
||||||
|
return ((lead & 0x0f) << 12) | (n2 << 6) | n3;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t n4 = (*str++ & 0x3f);
|
||||||
|
if(lead <= 0xf7)
|
||||||
|
{
|
||||||
|
*str_pointer = str;
|
||||||
|
return ((lead & 0x07) << 18) | (n2 << 12) | (n3 << 6) | n4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It the string is too invalid, force a space and try to continue */
|
||||||
|
*str_pointer = str;
|
||||||
|
return 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dsize(): Get the width and height of rendered text */
|
||||||
|
void dsize(char const *str_char, font_t const * f, int *w, int *h)
|
||||||
|
{
|
||||||
|
uint8_t const *str = (void *)str_char;
|
||||||
|
|
||||||
if(!f) f = topti_font;
|
if(!f) f = topti_font;
|
||||||
if(h) *h = f->line_height;
|
if(h) *h = f->line_height;
|
||||||
if(!w) return;
|
if(!w) return;
|
||||||
|
@ -74,17 +122,21 @@ void dsize(const char *str, font_t const * f, int *w, int *h)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For proportional fonts, fetch the width of each individual glyphs */
|
/* For proportional fonts, fetch the width of each individual glyphs */
|
||||||
int width = 0, c;
|
int width = 0;
|
||||||
|
uint32_t code_point;
|
||||||
|
|
||||||
while((c = *str++))
|
while(1)
|
||||||
{
|
{
|
||||||
if(c == ' ')
|
code_point = topti_utf8_next(&str);
|
||||||
|
if(!code_point) break;
|
||||||
|
|
||||||
|
if(code_point == ' ')
|
||||||
{
|
{
|
||||||
width += PROP_SPACING + CHAR_SPACING;
|
width += PROP_SPACING + CHAR_SPACING;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int glyph = topti_glyph_index(f, c);
|
int glyph = topti_glyph_index(f, code_point);
|
||||||
if(glyph >= 0) width += f->glyph_width[glyph] + CHAR_SPACING;
|
if(glyph >= 0) width += f->glyph_width[glyph] + CHAR_SPACING;
|
||||||
}
|
}
|
||||||
*w = width - CHAR_SPACING;
|
*w = width - CHAR_SPACING;
|
||||||
|
|
Loading…
Reference in a new issue