diff --git a/include/gint/display-cg.h b/include/gint/display-cg.h index de0919e..2c513bb 100644 --- a/include/gint/display-cg.h +++ b/include/gint/display-cg.h @@ -32,6 +32,12 @@ extern uint16_t *vram; typedef uint16_t color_t; enum { + /* Compatibility with fx9860g color names */ + color_white = 0xffff, + color_light = 0xaaaa, + color_dark = 0x5555, + color_black = 0x0000, + color_none = -1, }; diff --git a/make/Makefile b/make/Makefile index 0e1affb..cc3818b 100755 --- a/make/Makefile +++ b/make/Makefile @@ -54,7 +54,7 @@ src_obj := $(foreach s,$(src),$(call src2obj,$s)) # Files with special handling 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)) # All object files @@ -112,6 +112,11 @@ $(call src2obj,../src/font10x12.png): ../src/font10x12.png @ mkdir -p $(dir $@) $(call cmd_m,fxconv,font10x12.png)$(conv) -f $< -o $@ name:gint_font10x12 \ 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 # it in the linker script. diff --git a/src/font8x9.png b/src/font8x9.png new file mode 100644 index 0000000..8f9b8ed Binary files /dev/null and b/src/font8x9.png differ diff --git a/src/render-cg/topti.c b/src/render-cg/topti.c index 538b16c..5b4bda0 100644 --- a/src/render-cg/topti.c +++ b/src/render-cg/topti.c @@ -43,13 +43,19 @@ void topti_glyph(uint16_t *vram, uint32_t const * data, int left, int top, } 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) { /* Raw glyph data */ - uint32_t const * data = f->prop - ? (void *)(f->sized_data + charset_size(f->charset)) - : f->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); + } /* Storage height, top position within glyph */ 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 */ uint16_t *target = vram + 396 * y; - /* Character spacing */ - int space = 2; + /* Character spacing and space waiting to be drawn */ + int space = 1; + int active_space = 0; /* Read each character from the input string */ while(size--) { - int glyph = charset_decode(f->charset, *str++); + int c = *str++; + + int glyph = charset_decode(f->charset, c); 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); /* 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) { - x += dataw + space; + x += dataw; + active_space = space; continue; } 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, 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); +} diff --git a/src/render-fx/topti.c b/src/render-fx/topti.c index cea4803..4ad5ef8 100644 --- a/src/render-fx/topti.c +++ b/src/render-fx/topti.c @@ -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_bg Assembler function for background rendering */ 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) { /* Storage height and number of free bits in operators[] */ int height = f->data_height, free; /* Raw glyph data */ - uint32_t const * data = f->prop - ? (void *)(f->sized_data + charset_size(f->charset)) - : f->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); + } /* Basic clipping */ 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 */ 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; topti_render(x, y, str, topti_font, topti_asm_text[fg], diff --git a/src/render/topti.c b/src/render/topti.c index 037097c..8db4d93 100644 --- a/src/render/topti.c +++ b/src/render/topti.c @@ -2,6 +2,10 @@ #include #include +/* 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 */ GSECTION(".pretext") void dfont(font_t const * font) @@ -71,3 +75,38 @@ int topti_offset(font_t const *f, uint glyph) 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; +}