topti: custom character and word spacing (#13)

This commit introduces custom character spacing with a new fxconv
parameter "char-spacing". Word spacing is also tied to the width of the
space character (0x20). This removes the need for special semantics on
the space character, but requires that its size be specified with gray
pixels for proportional fonts.

This also fixes problems with the size of spaces in dsize() not being
correlated with their size during rendering, since on fx-9860G topti
already used the glyph's with as word spacing.

Since fxconv changes but gint's Makefile does not track updates to
external tools, a full rebuild of gint is required past this commit.
This commit is contained in:
Lephe 2020-10-05 16:11:14 +02:00
parent 2e8b1020cb
commit 240f29f9d5
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
5 changed files with 23 additions and 30 deletions

View File

@ -189,6 +189,11 @@ typedef struct
/* Number of total glyphs */
uint32_t glyph_count;
/* Character spacing (usually 1) */
uint8_t char_spacing;
uint :24;
struct {
/* Unicode point of first character in block */
uint start :20;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -61,9 +61,8 @@ static void topti_render(int x, int y, char const *str_char, font_t const *f,
/* Move to top row */
uint16_t *target = gint_vram + 396 * y;
/* Character spacing and space waiting to be drawn */
int space = 1;
int active_space = 0;
/* Character spacing waiting to be drawn, in pixels */
int space = 0;
/* Read each character from the input string */
while(1)
@ -74,29 +73,23 @@ static void topti_render(int x, int y, char const *str_char, font_t const *f,
int glyph = topti_glyph_index(f, code_point);
if(glyph < 0) continue;
/* Draw the space if background is opaque */
int prop_space = (code_point == ' ' && f->prop) ? 5 : 0;
if(active_space || prop_space)
{
active_space += prop_space;
if(bg >= 0) drect(x, y, x + active_space - 1,
y + height - 1, bg);
}
x += active_space;
if(prop_space) { active_space = space; continue; }
int dataw = f->prop ? f->glyph_width[glyph] : f->width;
/* Draw character spacing if background is opaque */
if(space && bg >= 0) drect(x, y, x+space-1, y+height-1, bg);
x += space;
if(x >= 396) break;
int index = topti_offset(f, glyph);
/* Compute horizontal intersection between glyph and screen */
int dataw = f->prop ? f->glyph_width[glyph] : f->width;
int width = dataw, left = 0;
if(x + dataw <= 0)
{
x += dataw;
active_space = space;
space = f->char_spacing;
continue;
}
if(x < 0) left = -x, width += x;
@ -108,7 +101,7 @@ static void topti_render(int x, int y, char const *str_char, font_t const *f,
dataw, fg, bg);
x += dataw;
active_space = space;
space = f->char_spacing;
}
}

View File

@ -133,7 +133,7 @@ void topti_render(int x, int y, char const *str_char, font_t const *f,
free = topti_split(data+index, width, height, free, operators);
/* Potential space after the glyph */
int space = (*str != 0);
int space = (*str != 0) ? f->char_spacing : 0;
free -= space;
if(free > 0) continue;

View File

@ -105,39 +105,34 @@ uint32_t topti_utf8_next(uint8_t const **str_pointer)
void dsize(char const *str_char, font_t const * f, int *w, int *h)
{
uint8_t const *str = (void *)str_char;
uint32_t code_point;
if(!f) f = topti_font;
if(h) *h = f->line_height;
if(!w) return;
/* Width for monospaced fonts is easy, unfortunately we still need to
compute the length of [str]. Critical applications might do the
product themselves to avoid this cost. */
compute the length and group bytes into Unicode code points. */
if(!f->prop)
{
int length = 0;
while(*str++) length++;
*w = (f->width + CHAR_SPACING) * length - CHAR_SPACING;
while((code_point = topti_utf8_next(&str))) length++;
*w = (f->width + f->char_spacing) * length - f->char_spacing;
return;
}
/* For proportional fonts, fetch the width of each individual glyphs */
int width = 0;
uint32_t code_point;
while(1)
{
code_point = topti_utf8_next(&str);
if(!code_point) break;
if(code_point == ' ')
{
width += PROP_SPACING + CHAR_SPACING;
continue;
}
int glyph = topti_glyph_index(f, code_point);
if(glyph >= 0) width += f->glyph_width[glyph] + CHAR_SPACING;
if(glyph < 0) continue;
width += f->glyph_width[glyph] + f->char_spacing;
}
*w = width - CHAR_SPACING;
*w = width - f->char_spacing;
}