mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-07-08 21:37:34 +02:00
render-cg: 8x9 font and proportional font rendering
This commit is contained in:
parent
0055199359
commit
11b40b445c
6 changed files with 100 additions and 43 deletions
|
@ -32,6 +32,12 @@ extern uint16_t *vram;
|
||||||
typedef uint16_t color_t;
|
typedef uint16_t color_t;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
/* Compatibility with fx9860g color names */
|
||||||
|
color_white = 0xffff,
|
||||||
|
color_light = 0xaaaa,
|
||||||
|
color_dark = 0x5555,
|
||||||
|
color_black = 0x0000,
|
||||||
|
|
||||||
color_none = -1,
|
color_none = -1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ src_obj := $(foreach s,$(src),$(call src2obj,$s))
|
||||||
|
|
||||||
# Files with special handling
|
# Files with special handling
|
||||||
spe-fx := ../src/font5x7.png
|
spe-fx := ../src/font5x7.png
|
||||||
spe-cg := ../src/font10x12.png
|
spe-cg := ../src/font10x12.png ../src/font8x9.png
|
||||||
spe_obj := version.o $(foreach s,$(spe-$(CONFIG.TARGET)),$(call src2obj,$s))
|
spe_obj := version.o $(foreach s,$(spe-$(CONFIG.TARGET)),$(call src2obj,$s))
|
||||||
|
|
||||||
# All object files
|
# All object files
|
||||||
|
@ -112,6 +112,11 @@ $(call src2obj,../src/font10x12.png): ../src/font10x12.png
|
||||||
@ mkdir -p $(dir $@)
|
@ mkdir -p $(dir $@)
|
||||||
$(call cmd_m,fxconv,font10x12.png)$(conv) -f $< -o $@ name:gint_font10x12 \
|
$(call cmd_m,fxconv,font10x12.png)$(conv) -f $< -o $@ name:gint_font10x12 \
|
||||||
charset:print grid.size:10x12 grid.padding:0 grid.border:3
|
charset:print grid.size:10x12 grid.padding:0 grid.border:3
|
||||||
|
$(call src2obj,../src/font8x9.png): ../src/font8x9.png
|
||||||
|
@ mkdir -p $(dir $@)
|
||||||
|
$(call cmd_m,fxconv,font8x9.png)$(conv) -f $< -o $@ name:gint_font8x9 \
|
||||||
|
charset:print grid.size:8x11 grid.padding:1 grid.border:0 \
|
||||||
|
proportional:true
|
||||||
|
|
||||||
# Version symbol. ld generates a .stack section for unknown reasons; I remove
|
# Version symbol. ld generates a .stack section for unknown reasons; I remove
|
||||||
# it in the linker script.
|
# it in the linker script.
|
||||||
|
|
BIN
src/font8x9.png
Normal file
BIN
src/font8x9.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -43,13 +43,19 @@ void topti_glyph(uint16_t *vram, uint32_t const * data, int left, int top,
|
||||||
}
|
}
|
||||||
|
|
||||||
GSECTION(".pretext")
|
GSECTION(".pretext")
|
||||||
void topti_render(int x, int y, const char *str, size_t size, font_t const *f,
|
void topti_render(int x, int y, char const *str, size_t size, font_t const *f,
|
||||||
int fg, int bg)
|
int fg, int bg)
|
||||||
{
|
{
|
||||||
/* Raw glyph data */
|
/* Raw glyph data */
|
||||||
uint32_t const * data = f->prop
|
uint32_t const * data;
|
||||||
? (void *)(f->sized_data + charset_size(f->charset))
|
if(!f->prop) data = f->data;
|
||||||
: f->data;
|
else
|
||||||
|
{
|
||||||
|
int cs = charset_size(f->charset);
|
||||||
|
/* 4-align the result */
|
||||||
|
cs += (4 - cs) & 3;
|
||||||
|
data = (void *)(f->sized_data + cs);
|
||||||
|
}
|
||||||
|
|
||||||
/* Storage height, top position within glyph */
|
/* Storage height, top position within glyph */
|
||||||
int height = f->data_height, top = 0;
|
int height = f->data_height, top = 0;
|
||||||
|
@ -62,15 +68,29 @@ void topti_render(int x, int y, const char *str, size_t size, font_t const *f,
|
||||||
/* Move to top row */
|
/* Move to top row */
|
||||||
uint16_t *target = vram + 396 * y;
|
uint16_t *target = vram + 396 * y;
|
||||||
|
|
||||||
/* Character spacing */
|
/* Character spacing and space waiting to be drawn */
|
||||||
int space = 2;
|
int space = 1;
|
||||||
|
int active_space = 0;
|
||||||
|
|
||||||
/* Read each character from the input string */
|
/* Read each character from the input string */
|
||||||
while(size--)
|
while(size--)
|
||||||
{
|
{
|
||||||
int glyph = charset_decode(f->charset, *str++);
|
int c = *str++;
|
||||||
|
|
||||||
|
int glyph = charset_decode(f->charset, c);
|
||||||
if(glyph < 0) continue;
|
if(glyph < 0) continue;
|
||||||
|
|
||||||
|
/* Draw the space if background is opaque */
|
||||||
|
int prop_space = (c == ' ' && f->prop) ? 5 : 0;
|
||||||
|
if((active_space && bg >= 0) || prop_space)
|
||||||
|
{
|
||||||
|
active_space += prop_space;
|
||||||
|
drect(x, y, x + active_space - 1, y + height - 1, bg);
|
||||||
|
}
|
||||||
|
x += active_space;
|
||||||
|
if(prop_space) { active_space = space; continue; }
|
||||||
|
if(x >= 396) break;
|
||||||
|
|
||||||
int index = topti_offset(f, glyph);
|
int index = topti_offset(f, glyph);
|
||||||
|
|
||||||
/* Compute horizontal intersection between glyph and screen */
|
/* Compute horizontal intersection between glyph and screen */
|
||||||
|
@ -80,7 +100,8 @@ void topti_render(int x, int y, const char *str, size_t size, font_t const *f,
|
||||||
|
|
||||||
if(x + dataw <= 0)
|
if(x + dataw <= 0)
|
||||||
{
|
{
|
||||||
x += dataw + space;
|
x += dataw;
|
||||||
|
active_space = space;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(x < 0) left = -x, width += x;
|
if(x < 0) left = -x, width += x;
|
||||||
|
@ -91,6 +112,14 @@ void topti_render(int x, int y, const char *str, size_t size, font_t const *f,
|
||||||
topti_glyph(target + x, data + index, left, top, width, height,
|
topti_glyph(target + x, data + index, left, top, width, height,
|
||||||
dataw, fg, bg);
|
dataw, fg, bg);
|
||||||
|
|
||||||
x += dataw + space;
|
x += dataw;
|
||||||
|
active_space = space;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* dtext() - display a string of text */
|
||||||
|
GSECTION(".pretext")
|
||||||
|
void dtext(int x, int y, char const *str, int fg, int bg)
|
||||||
|
{
|
||||||
|
topti_render(x, y, str, strlen(str), topti_font, fg, bg);
|
||||||
|
}
|
||||||
|
|
|
@ -91,15 +91,21 @@ int topti_split(uint32_t const * glyph, int width, int height, int free,
|
||||||
@asm_fg Assembler function for text rendering
|
@asm_fg Assembler function for text rendering
|
||||||
@asm_bg Assembler function for background rendering */
|
@asm_bg Assembler function for background rendering */
|
||||||
GSECTION(".pretext")
|
GSECTION(".pretext")
|
||||||
void topti_render(int x, int y, const char *str, font_t const *f,
|
void topti_render(int x, int y, char const *str, font_t const *f,
|
||||||
asm_text_t *asm_fg, asm_text_t *asm_bg)
|
asm_text_t *asm_fg, asm_text_t *asm_bg)
|
||||||
{
|
{
|
||||||
/* 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 */
|
||||||
uint32_t const * data = f->prop
|
uint32_t const * data;
|
||||||
? (void *)(f->sized_data + charset_size(f->charset))
|
if(!f->prop) data = f->data;
|
||||||
: f->data;
|
else
|
||||||
|
{
|
||||||
|
int cs = charset_size(f->charset);
|
||||||
|
/* 4-align the result */
|
||||||
|
cs += (4 - cs) & 3;
|
||||||
|
data = (void *)(f->sized_data + cs);
|
||||||
|
}
|
||||||
|
|
||||||
/* Basic clipping */
|
/* Basic clipping */
|
||||||
if(x > 127 || y > 63 || y + height <= 0) return;
|
if(x > 127 || y > 63 || y + height <= 0) return;
|
||||||
|
@ -179,37 +185,9 @@ void topti_render(int x, int y, const char *str, font_t const *f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
|
||||||
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. */
|
|
||||||
if(!f->prop)
|
|
||||||
{
|
|
||||||
int length = 0;
|
|
||||||
while(*str++) length++;
|
|
||||||
*w = (f->width + 1) * length - 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For proportional fonts, fetch the width of each individual glyphs */
|
|
||||||
int width = 0;
|
|
||||||
while(*str)
|
|
||||||
{
|
|
||||||
int glyph = charset_decode(f->charset, *str++);
|
|
||||||
if(glyph > 0) width += f->sized_data[glyph] + 1;
|
|
||||||
}
|
|
||||||
*w = width - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dtext() - display a string of text */
|
/* dtext() - display a string of text */
|
||||||
GSECTION(".pretext")
|
GSECTION(".pretext")
|
||||||
void dtext(int x, int y, const char *str, int fg, int bg)
|
void dtext(int x, int y, char const *str, int fg, int bg)
|
||||||
{
|
{
|
||||||
if((uint)fg >= 8 || (uint)bg >= 8) return;
|
if((uint)fg >= 8 || (uint)bg >= 8) return;
|
||||||
topti_render(x, y, str, topti_font, topti_asm_text[fg],
|
topti_render(x, y, str, topti_font, topti_asm_text[fg],
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#include <gint/display.h>
|
#include <gint/display.h>
|
||||||
#include <display/common.h>
|
#include <display/common.h>
|
||||||
|
|
||||||
|
/* These parameters will eventually be specified by the font */
|
||||||
|
#define CHAR_SPACING 1
|
||||||
|
#define PROP_SPACING 5
|
||||||
|
|
||||||
/* dfont(): Set the default font for text rendering */
|
/* dfont(): Set the default font for text rendering */
|
||||||
GSECTION(".pretext")
|
GSECTION(".pretext")
|
||||||
void dfont(font_t const * font)
|
void dfont(font_t const * font)
|
||||||
|
@ -71,3 +75,38 @@ int topti_offset(font_t const *f, uint glyph)
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
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. */
|
||||||
|
if(!f->prop)
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
while(*str++) length++;
|
||||||
|
*w = (f->width + CHAR_SPACING) * length - CHAR_SPACING;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For proportional fonts, fetch the width of each individual glyphs */
|
||||||
|
int width = 0, c;
|
||||||
|
|
||||||
|
while((c = *str++))
|
||||||
|
{
|
||||||
|
if(c == ' ')
|
||||||
|
{
|
||||||
|
width += PROP_SPACING + CHAR_SPACING;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int glyph = charset_decode(f->charset, c);
|
||||||
|
if(glyph > 0) width += f->sized_data[glyph] + CHAR_SPACING;
|
||||||
|
}
|
||||||
|
*w = width - CHAR_SPACING;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue