Commit 041f7bb8 authored by bzt's avatar bzt

Added bounding box calculator

parent 11e7639d
......@@ -68,17 +68,19 @@ Once you have the include, you can start using the library, no need for initiali
make sure that the initial context is zerod out (by putting it in the bss segment it will be, or call
memset zero manually).
As my favourite principle is K.I.S.S., there're only a few, clearly named functions in the API:
- load one or more fonts into the context using `ssfn_load` on program start.
- set up rendering configuration by specifing font family, style, size and rendering mode with `ssfn_select`.
- if you want to change the size for example, you can call `ssfn_select` again, no need to load the fonts again.
- use `ssfn_utf8` to decode an UTF-8 multibyte character into UNICODE code point.
- call `ssfn_render` to rasterize a glyph in the given style and size for that UNICODE code point.
As my favourite principle is K.I.S.S., there's only a few, clearly named functions in the API:
- load one or more fonts into the context using `ssfn_load()` on program start.
- set up rendering configuration by specifing font family, style, size and rendering mode with `ssfn_select()`.
- if you want to change the size for example, you can call `ssfn_select()` again, no need to load the fonts again.
- if you need it, you can get the rendered text's dimensions in advance with `ssfn_bbox()`.
- use `ssfn_utf8()` to decode an UTF-8 multibyte character into UNICODE code point.
- call `ssfn_render()` to rasterize a glyph in the given style and size for that UNICODE code point.
- draw the returned bitmap on your screen at cursor position.
- optionally alter the returned advance offsets with `ssfn_kern()`.
- move the cursor by the returned advance offsets.
- repeat the last 4 steps until you reach the end of the UTF-8 string.
- repeat the last 5 steps until you reach the end of the UTF-8 string.
- when not needed any more, free the rasterized glyphs
- when done with rendering, call `ssfn_free`.
- when done with rendering, call `ssfn_free()`.
Configuration
-------------
......@@ -227,7 +229,7 @@ Parameter defines:
| [mode](https://gitlab.com/bztsrc/scalable-font/blob/master/docs/modes.md) | Description |
| ----------------------- | ----------- |
| `SSFN_MODE_NONE` | do not render the glyph, just select the font (see kerning below) |
| `SSFN_MODE_NONE` | do not render the glyph, just select the font (see kerning and bounding box below) |
| `SSFN_MODE_OUTLINE` | return the glyph's outline |
| `SSFN_MODE_BITMAP` | rasterize glyph as bitmap, 1 bit for each pixel |
| `SSFN_MODE_ALPHA` | rasterize glyph as an alpha channel, 1 byte for each pixel |
......@@ -246,7 +248,7 @@ uint32_t ssfn_utf8(char **str);
Decodes an UTF-8 multibyte character. Be careful, this function does not check its input, expects that pointer is
valid and points to a string with only valid UTF-8 sequences. The behaviour with invalid input is undefined. All
the other functions check for valid input, this is an exception.
the other functions check for valid input, this is an exception because it's expected to be called many times.
### Parameters
......@@ -288,7 +290,7 @@ allocated `ssfn_glyph_t` structure.
| baseline | the baseline of the glyph in pixels (1) |
| w | width of the rendered glyph in pixels |
| h | height of the rendered glyph in pixels |
| adv_x | advance x, you should add this to your cursor poisiton after draw |
| adv_x | advance x, you should add this to your cursor position after draw |
| adv_y | advance y |
| pitch | number of bytes per lines in the data buffer, or number of outline coordinates |
| cmap | if mode `SSFN_MODE_CMAP`, then pointer to a color map, otherwise `NULL` |
......@@ -297,7 +299,7 @@ allocated `ssfn_glyph_t` structure.
Note(1): if advance y is not zero, then it's the vertical baseline, otherwise it's the horizontal.
If mode is `SSFN_MODE_NONE`, then it will not render anything, it just selects the font with the best match
and returns NULL. This mode is useful to select a font for kerning (see `ssfn_kern()`).
and returns NULL. This mode is useful to select a font for kerning (see `ssfn_kern()` and `ssfn_bbox()`).
Otherwise you should iterate on the `data` array `h` times, starting at offset 0 and adding `pitch` to the
pointer for every row. Within a row, you should extract `w` pixels for each row. The description of how to
......@@ -332,6 +334,32 @@ the character or the kerning pair not found, `x`and `y` will be left unchanged.
Error code, and relative kerning offsets adjusted to `x` and `y`.
## Get Bounding Box
```c
int ssfn_bbox(ssfn_t *ctx, char *str, int usekern, int *w, int *h);
```
Returns the dimensions of a rendered text. This function handles horizontal and
vertical texts, but not mixed ones. It does not render the glyphs, and it does not
allocate extra memory either. It does calculate autohinting though, so if you have
cached the glyphs then it's much faster to sum glyph->adv_x and glyph->adv_y values
instead.
### Parameters
| Parameter | Description |
| ----------- | ----------- |
| ctx | pointer to the renderer's context |
| str | pointer to an UTF-8 string |
| usekern | set it to non-zero if you want to apply kerning when calculating sizes |
| w | pointer to an integer, returned width in pixels |
| h | pointer to an integer, returned height in pixels |
### Return value
Error code, and on success the bounding box size in `w`, `h`.
## Get Memory Usage
```c
......
CFLAGS = -Wall -Wextra -ansi -pedantic -g
CFLAGS = -Wall -Wextra -ansi -pedantic
ifneq ("$(wildcard /usr/include/zlib.h)","")
CFLAGS += -DHAS_ZLIB=1
LIBS = -lz
......
SRCS = $(wildcard *.c)
BINS = $(SRCS:.c=)
CFLAGS = -Wall -Wextra -ansi -pedantic -I/usr/include/SDL2 -g
CFLAGS = -Wall -Wextra -ansi -pedantic -I/usr/include/SDL2
LIBS = -lSDL2
ifneq ("$(wildcard /usr/include/zlib.h)","")
CFLAGS += -DHAS_ZLIB=1
......
......@@ -30,7 +30,7 @@
#include <stdio.h>
#define SSFN_NOIMPLEMENTATION
#define SSFN_CONSOLEBITMAP_TRUECOLOR
#define SSFN_CONSOLEBITMAP_CLEARBG
/*#define SSFN_CONSOLEBITMAP_CLEARBG*/
#include "../ssfn.h"
#if HAS_ZLIB
#include <zlib.h>
......@@ -103,7 +103,9 @@ void do_test(SDL_Surface *screen)
ssfn_dst_ptr = (uint8_t*)screen->pixels;
ssfn_dst_pitch = screen->pitch;
ssfn_fg = 0xFFFFFF;
#ifdef SSFN_CONSOLEBITMAP_CLEARBG
ssfn_bg = 0x444444;
#endif
printf("Testing simple renderer with fixed size bitmap font\n");
......
......@@ -167,6 +167,9 @@ void do_test(SDL_Surface *screen, char *fontfn)
err = ssfn_select(&ctx, SSFN_FAMILY_ANY, NULL, SSFN_STYLE_REGULAR | SSFN_STYLE_NOHINTING, 28, SSFN_MODE_ALPHA);
if(err != SSFN_OK) { fprintf(stderr, "ssfn select error: %s\n", ssfn_error(err)); exit(2); }
ssfn_bbox(&ctx, str0, 0, &kx, &ky);
printf("Reported bounding box: %d x %d\n", kx, ky);
px=10; py=30;
for(s = str0; *s;) {
glyph = ssfn_render(&ctx, ssfn_utf8(&s));
......@@ -178,10 +181,14 @@ void do_test(SDL_Surface *screen, char *fontfn)
px += glyph->adv_x; py += glyph->adv_y;
free(glyph);
}
printf("Rendered: %d x %d\n", px-10, py-30);
err = ssfn_select(&ctx, SSFN_FAMILY_ANY, NULL, SSFN_STYLE_REGULAR, 28, SSFN_MODE_ALPHA);
if(err != SSFN_OK) { fprintf(stderr, "ssfn select error: %s\n", ssfn_error(err)); exit(2); }
ssfn_bbox(&ctx, str1, 0, &kx, &ky);
printf("Reported bounding box: %d x %d\n", kx, ky);
px=10; py=70;
for(s = str1; *s;) {
glyph = ssfn_render(&ctx, ssfn_utf8(&s));
......@@ -193,10 +200,14 @@ void do_test(SDL_Surface *screen, char *fontfn)
px += glyph->adv_x; py += glyph->adv_y;
free(glyph);
}
printf("Rendered: %d x %d\n", px-10, py-70);
err = ssfn_select(&ctx, SSFN_FAMILY_ANY, NULL, SSFN_STYLE_REGULAR, 28, SSFN_MODE_ALPHA);
if(err != SSFN_OK) { fprintf(stderr, "ssfn select error: %s\n", ssfn_error(err)); exit(2); }
ssfn_bbox(&ctx, str2, 1, &kx, &ky);
printf("Reported bounding box: %d x %d\n", kx, ky);
px=10; py=110;
for(s = str2, u = ssfn_utf8(&s); u;) {
glyph = ssfn_render(&ctx, u);
......@@ -212,10 +223,14 @@ void do_test(SDL_Surface *screen, char *fontfn)
u = v;
free(glyph);
}
printf("Rendered: %d x %d\n", px-10, py-110);
err = ssfn_select(&ctx, SSFN_FAMILY_ANY, NULL, SSFN_STYLE_REGULAR | SSFN_STYLE_NOHINTING, 60, SSFN_MODE_ALPHA);
if(err != SSFN_OK) { fprintf(stderr, "ssfn select error: %s\n", ssfn_error(err)); exit(2); }
ssfn_bbox(&ctx, str0, 0, &kx, &ky);
printf("Reported bounding box: %d x %d\n", kx, ky);
px=10; py=180;
for(s = str0; *s;) {
glyph = ssfn_render(&ctx, ssfn_utf8(&s));
......@@ -227,10 +242,14 @@ void do_test(SDL_Surface *screen, char *fontfn)
px += glyph->adv_x; py += glyph->adv_y;
free(glyph);
}
printf("Rendered: %d x %d\n", px-10, py-180);
err = ssfn_select(&ctx, SSFN_FAMILY_ANY, NULL, SSFN_STYLE_REGULAR, 60, SSFN_MODE_ALPHA);
if(err != SSFN_OK) { fprintf(stderr, "ssfn select error: %s\n", ssfn_error(err)); exit(2); }
ssfn_bbox(&ctx, str1, 0, &kx, &ky);
printf("Reported bounding box: %d x %d\n", kx, ky);
px=10; py=240;
for(s = str1; *s;) {
glyph = ssfn_render(&ctx, ssfn_utf8(&s));
......@@ -242,10 +261,14 @@ void do_test(SDL_Surface *screen, char *fontfn)
px += glyph->adv_x; py += glyph->adv_y;
free(glyph);
}
printf("Rendered: %d x %d\n", px-10, py-240);
err = ssfn_select(&ctx, SSFN_FAMILY_ANY, NULL, SSFN_STYLE_REGULAR, 60, SSFN_MODE_ALPHA);
if(err != SSFN_OK) { fprintf(stderr, "ssfn select error: %s\n", ssfn_error(err)); exit(2); }
ssfn_bbox(&ctx, str2, 1, &kx, &ky);
printf("Reported bounding box: %d x %d\n", kx, ky);
px=10; py=300;
for(s = str2, u = ssfn_utf8(&s); u;) {
glyph = ssfn_render(&ctx, u);
......@@ -267,6 +290,7 @@ void do_test(SDL_Surface *screen, char *fontfn)
u = v;
free(glyph);
}
printf("Rendered: %d x %d\n", px-10, py-300);
printf("Memory allocated: %d\n", ssfn_mem(&ctx));
ssfn_free(&ctx);
......
......@@ -194,7 +194,6 @@ void do_test(SDL_Surface *screen)
ssfn_dst_ptr = (uint8_t*)screen->pixels;
ssfn_dst_pitch = screen->pitch;
ssfn_fg = 0;
ssfn_bg = 0xEEEEEE;
s = str0;
ssfn_x = 8;
ssfn_y = 48;
......
......@@ -170,7 +170,7 @@ typedef struct {
int size; /* required size */
int mode; /* required mode */
int g; /* shift value for grid size */
int ix, u,uix,uax, lx,ly, mx,my; /* helper variables */
int m, ix, u,uix,uax, lx,ly, mx,my; /* helper variables */
} ssfn_t;
/***** API function protoypes *****/
......@@ -181,6 +181,7 @@ int ssfn_select(ssfn_t *ctx, int family, char *name, int style, int size, int mo
uint32_t ssfn_utf8(char **str); /* decode UTF-8 sequence */
__attribute__((malloc)) ssfn_glyph_t *ssfn_render(ssfn_t *ctx, uint32_t unicode); /* return allocated glyph bitmap */
int ssfn_kern(ssfn_t *ctx, uint32_t unicode, uint32_t nextunicode, int *x, int *y); /* get kerning values */
int ssfn_bbox(ssfn_t *ctx, char *str, int usekern, int *w, int *h); /* get bounding box of a rendered string */
int ssfn_mem(ssfn_t *ctx); /* return how much memory is used */
void ssfn_free(ssfn_t *ctx); /* free context */
#define ssfn_lasterr(ctx) ((ssfn_t*)ctx)->err /* return last error code */
......@@ -261,11 +262,11 @@ const char *ssfn_errstr[] = { "",
/*** Private functions ***/
/* f = file scale, g = grid 4095.15, o = screen point 255.255, i = screen pixel 255, c = ceil */
# define _ssfn_i2g(x) ((x)? (((x) << 16) - (1 << 15)) / ctx->ret->h : 0)
# define _ssfn_g2o(x) (((x) * ctx->ret->h + (1 << 7)) >> 8)
# define _ssfn_g2i(x) (((x) * ctx->ret->h + (1 << 15)) >> 16)
# define _ssfn_g2ic(x) (((x) * ctx->ret->h + (1 << 16) - 1) >> 16)
# define _ssfn_f2i(x) ((((x) << s) * ctx->ret->h + (1 << 15)) >> 16)
# define _ssfn_i2g(x) ((x)? (((x) << 16) - (1 << 15)) / ctx->m : 0)
# define _ssfn_g2o(x) (((x) * ctx->m + (1 << 7)) >> 8)
# define _ssfn_g2i(x) (((x) * ctx->m + (1 << 15)) >> 16)
# define _ssfn_g2ic(x) (((x) * ctx->m + (1 << 16) - 1) >> 16)
# define _ssfn_f2i(x) ((((x) << s) * ctx->m + (1 << 15)) >> 16)
# define _ssfn_o2i(x) (((x) + (1 << 7)) >> 8)
# define _ssfn_o2ic(x) ((x + (1<<8) - 1) >> 8)
# define _ssfn_g2ox(x) ((x)>=(4095 << 4) ? _ssfn_g2o(x) : ctx->h[((x) >> 4)])
......@@ -275,7 +276,7 @@ const char *ssfn_errstr[] = { "",
# define _ssfn_g2iy(y) (_ssfn_g2i(y))
# define _ssfn_g2iyc(y) (_ssfn_g2ic(y))
# define _ssfn_igg(y) (((4096<<4)-(y)) >> (2))
# define _ssfn_igi(y) ((((4096<<4)-(y)) * ctx->ret->h + (1 << (15+3))) >> (16+3))
# define _ssfn_igi(y) ((((4096<<4)-(y)) * ctx->m + (1 << (15+3))) >> (16+3))
/* parse character table */
private uint8_t *_ssfn_c(const ssfn_font_t *font, uint32_t unicode)
......@@ -882,7 +883,6 @@ again: if(p == SSFN_FAMILY_ANY) { n = 0; m = 4; } else n = m = p;
if(!rg && p != SSFN_FAMILY_ANY) { p = SSFN_FAMILY_ANY; goto again; }
}
if(!rg) { ctx->err = SSFN_ERR_NOGLYPH; return NULL; }
if(ctx->mode == SSFN_MODE_NONE) return NULL;
ctx->style &= 0xFF;
if((ctx->style & 1) && !(ctx->f->style & 1)) ctx->style |= 0x100;
......@@ -893,8 +893,6 @@ again: if(p == SSFN_FAMILY_ANY) { n = 0; m = 4; } else n = m = p;
ctx->np = 0;
s = 16 - ctx->g;
bl = ((((rg[3] & 0x0F) << 8) | rg[8])) << s;
bt = ((((rg[3] & 0xF0) << 4) | rg[9])) << s;
if(ctx->mode == SSFN_MODE_OUTLINE) {
h = ctx->size;
p = 0;
......@@ -911,21 +909,7 @@ again: if(p == SSFN_FAMILY_ANY) { n = 0; m = 4; } else n = m = p;
}
if(ctx->mode == SSFN_MODE_BITMAP) p = (p + 7) >> 3;
}
i = p * h;
ctx->ret = (ssfn_glyph_t*)SSFN_realloc(NULL, i + 8 + sizeof(uint8_t*));
if(!ctx->ret) {
erralloc:
ctx->err = SSFN_ERR_ALLOC;
return NULL;
}
SSFN_memset(&ctx->ret->data, ctx->mode == SSFN_MODE_CMAP ? 0xF0 : 0, i);
ctx->ret->cmap = NULL;
ctx->ret->mode = ctx->mode;
ctx->ret->pitch = p;
ctx->ret->w = 0;
ctx->ret->h = h;
ctx->ret->baseline = (((ctx->f->baseline << s) - bt) * h + (1<<16) - 1) >> 16;
ctx->u = ctx->ret->baseline + ((((ctx->f->underline - ctx->f->baseline) << s) * h) >> 16);
ctx->m = h;
if(!ctx->h) ctx->h = (uint16_t*)SSFN_realloc(NULL, 4096*2*sizeof(uint16_t));
if(!ctx->h) goto erralloc;
......@@ -953,9 +937,30 @@ erralloc:
}
x = j;
}
ctx->uix = _ssfn_g2ixc((((rg[2] & 0x0F) << 8) | rg[6]) << s);
ctx->uax = _ssfn_g2iyc((((rg[2] & 0xF0) << 4) | rg[7]) << s);
if(ctx->mode == SSFN_MODE_NONE) return NULL;
ctx->ret->adv_x = _ssfn_g2ixc((((rg[2] & 0x0F) << 8) | rg[6]) << s);
ctx->ret->adv_y = _ssfn_g2iyc((((rg[2] & 0xF0) << 4) | rg[7]) << s);
bl = ((((rg[3] & 0x0F) << 8) | rg[8])) << s;
bt = ((((rg[3] & 0xF0) << 4) | rg[9])) << s;
i = p * h;
ctx->ret = (ssfn_glyph_t*)SSFN_realloc(NULL, i + 8 + sizeof(uint8_t*));
if(!ctx->ret) {
erralloc:
ctx->err = SSFN_ERR_ALLOC;
return NULL;
}
SSFN_memset(&ctx->ret->data, ctx->mode == SSFN_MODE_CMAP ? 0xF0 : 0, i);
ctx->ret->cmap = NULL;
ctx->ret->mode = ctx->mode;
ctx->ret->pitch = p;
ctx->ret->w = 0;
ctx->ret->h = h;
ctx->ret->baseline = (((ctx->f->baseline << s) - bt) * h + (1<<16) - 1) >> 16;
ctx->u = ctx->ret->baseline + ((((ctx->f->underline - ctx->f->baseline) << s) * h) >> 16);
ctx->ret->adv_x = ctx->uix;
ctx->ret->adv_y = ctx->uax;
ctx->ix = ctx->uix = 4096 << 4; ctx->uax = 0;
_ssfn_g(ctx, rg, 1);
......@@ -1060,7 +1065,7 @@ int ssfn_kern(ssfn_t *ctx, uint32_t unicode, uint32_t nextunicode, int *x, int *
else { j = ptr[0] | ((ptr[1] & 0x7F) << 8); l = ptr[1] & 0x80; ptr += 2; }
if(c) { m = (short)(ptr[0] | (ptr[1] << 8)); ptr += 2; } else { m = (signed char)ptr[0]; ptr++; }
if(j == nextunicode) {
a = SSFN_OK; m = (((m) << (16 - ctx->g)) * ctx->ret->h + (1 << 16) - 1) >> 16;
a = SSFN_OK; m = (((m) << (16 - ctx->g)) * ctx->m + (1 << 16) - 1) >> 16;
if(l) *y += m; else *x += m;
}
}
......@@ -1074,6 +1079,41 @@ int ssfn_kern(ssfn_t *ctx, uint32_t unicode, uint32_t nextunicode, int *x, int *
return (ctx->err = SSFN_ERR_NOGLYPH);
}
/**
* Returns the bounding box of the rendered text
*
* @param ctx rendering context
* @param *str string
* @param usekern use kerning when calculating size
* @param *w pointer to an integer, returned width
* @param *h pointer to an integer, returned height
* @return error code, and bounding box size in *w, *h
*/
int ssfn_bbox(ssfn_t *ctx, char *str, int usekern, int *w, int *h)
{
char *s;
int u, v, m;
if(!ctx) return SSFN_ERR_INVINP;
if(!str || !w || !h) return (ctx->err = SSFN_ERR_INVINP);
*w = *h = 0;
m = ctx->mode; ctx->mode = SSFN_MODE_NONE; ctx->m = 0;
for(s = str, u = ssfn_utf8(&s); u;) {
ssfn_render(ctx, u);
if(ctx->err == SSFN_OK) {
*w += ctx->uix;
*h += ctx->uax;
}
v = ssfn_utf8(&s);
if(usekern) ssfn_kern(ctx, u, v, w, h);
u = v;
}
if(!*w) *w = ctx->m;
if(!*h) *h = ctx->m;
ctx->mode = m;
return ctx->err;
}
/**
* Returns how much memory a context consumes
*
......@@ -1152,7 +1192,9 @@ uint32_t ssfn_dst_pitch; /* screen dimensions */
uint32_t ssfn_dst_w = 0;
uint32_t ssfn_dst_h = 0;
uint32_t ssfn_fg; /* colors in screen's native format */
#ifdef SSFN_CONSOLEBITMAP_CLEARBG
uint32_t ssfn_bg;
#endif
uint32_t ssfn_x; /* coordinate to draw to */
uint32_t ssfn_y;
uint32_t ssfn_adv_x; /* advance values */
......@@ -1166,7 +1208,7 @@ uint32_t ssfn_adv_y;
*/
int ssfn_putc(uint32_t unicode)
{
uint32_t i, j, a, b, m, p, q, t;
uint32_t i, j, a, b, m, p, t;
uint8_t *rg, *o, *g, *s, *r, y, n;
#ifdef SSFN_CONSOLEBITMAP_CLEARBG
uint8_t w;
......@@ -1174,6 +1216,7 @@ int ssfn_putc(uint32_t unicode)
t = (ssfn_font->quality < 5 && ssfn_font->characters_offs < 65536) ? 4 : (ssfn_font->characters_offs < 1048576 ? 5 : 6);
rg = (uint8_t*)ssfn_font + ssfn_font->characters_offs;
ssfn_adv_x = ssfn_adv_y = 0;
for(j=i=0;i<0x110000 && j<ssfn_font->characters_num;i++) {
if(rg[0] & 0x80) {
......@@ -1187,14 +1230,13 @@ int ssfn_putc(uint32_t unicode)
w = rg[4]; j = 0;
if(ssfn_dst_w && (ssfn_x + w >= ssfn_dst_w)) w = ssfn_dst_w - ssfn_x;
s = ssfn_dst_ptr + (ssfn_y)*ssfn_dst_pitch;
q = ssfn_x;
# ifdef SSFN_CONSOLEBITMAP_PALETTE
s += q;
s += ssfn_x;
# else
# ifdef SSFN_CONSOLEBITMAP_HICOLOR
s += q << 1;
s += ssfn_x << 1;
# else
s += q << 2;
s += ssfn_x << 2;
# endif
# endif
#endif
......@@ -1204,14 +1246,13 @@ int ssfn_putc(uint32_t unicode)
while(n--) {
#ifndef SSFN_CONSOLEBITMAP_CLEARBG
s = ssfn_dst_ptr + (ssfn_y + y + rg[t-1])*ssfn_dst_pitch;
q = ssfn_x + rg[t-2];
# ifdef SSFN_CONSOLEBITMAP_PALETTE
s += q;
s += ssfn_x;
# else
# ifdef SSFN_CONSOLEBITMAP_HICOLOR
s += q << 1;
s += ssfn_x << 1;
# else
s += q << 2;
s += ssfn_x << 2;
# endif
# endif
#endif
......@@ -1222,7 +1263,7 @@ int ssfn_putc(uint32_t unicode)
default: o += ((rg[3] & 0xF) << 24) | (rg[2] << 16) | a; break;
}
p = ((o[0] & 0xF)+1); a = p << 3; b = o[1]+1; o += 2;
if(ssfn_dst_w && (q + a >= ssfn_dst_w)) a = ssfn_dst_w - q;
if(ssfn_dst_w && (ssfn_x + a >= ssfn_dst_w)) a = ssfn_dst_w - ssfn_x;
#ifdef SSFN_CONSOLEBITMAP_CLEARBG
for(;j<y+rg[t-1];j++,s+=ssfn_dst_pitch)
for(r=s,i=0;i<w;i++) {
......@@ -1284,7 +1325,7 @@ int ssfn_putc(uint32_t unicode)
rg += t;
}
#ifdef SSFN_CONSOLEBITMAP_CLEARBG
for(;j<ssfn_font->bbox_bottom;j++,s+=ssfn_dst_pitch)
for(;j<=ssfn_font->bbox_bottom;j++,s+=ssfn_dst_pitch)
for(r=s,i=0;i<w;i++) {
# ifdef SSFN_CONSOLEBITMAP_PALETTE
*((uint8_t*)r) = (uint8_t)ssfn_bg;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment