|
|
@ -515,11 +515,8 @@ int ren_set_scissor(int x, int y, int w, int h) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int ren_push_glyph(const struct font_glyph *g, int gx, int gy) |
|
|
|
// TODO: implement font size
|
|
|
|
|
|
|
|
int ren_render_text(const char *str, int x, int y, int w, int h, int size) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
/* x4,y4 x3,y3
|
|
|
|
/* x4,y4 x3,y3
|
|
|
|
* +-------------+ |
|
|
|
* +-------------+ |
|
|
|
* |(x,y) /| |
|
|
|
* |(x,y) /| |
|
|
@ -531,32 +528,8 @@ int ren_render_text(const char *str, int x, int y, int w, int h, int size) |
|
|
|
* |/ | |
|
|
|
* |/ | |
|
|
|
* +-------------+ |
|
|
|
* +-------------+ |
|
|
|
* x1,y1 x2,y2 */ |
|
|
|
* x1,y1 x2,y2 */ |
|
|
|
|
|
|
|
|
|
|
|
// TODO: stop drawing when outside the bounding box
|
|
|
|
|
|
|
|
// TODO: check size, if the current font is not of the same size then load
|
|
|
|
|
|
|
|
// load a new font and use that texture instead, this implies making
|
|
|
|
|
|
|
|
// a system to store and use different fonts, like:
|
|
|
|
|
|
|
|
// struct font_atlas * font_by_size(int size);
|
|
|
|
|
|
|
|
// FIXME: the bounding box (scissor) logic does not work
|
|
|
|
|
|
|
|
// TODO: create a method for calculating the total bounding box of a string
|
|
|
|
|
|
|
|
// given the box size
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const struct font_glyph *g; |
|
|
|
|
|
|
|
struct font_glyph c; |
|
|
|
|
|
|
|
size_t ret, off; |
|
|
|
|
|
|
|
uint_least32_t cp; |
|
|
|
|
|
|
|
int updated, gx = x, gy = y; |
|
|
|
|
|
|
|
struct v_text v; |
|
|
|
struct v_text v; |
|
|
|
for (off = 0; (ret = grapheme_decode_utf8(str+off, SIZE_MAX, &cp)) > 0 && cp != 0; off += ret) { |
|
|
|
struct font_glyph c; |
|
|
|
// skip special characters that render a box (not present in font)
|
|
|
|
|
|
|
|
// FIXME: handle tab
|
|
|
|
|
|
|
|
if (iscntrl(cp)) goto skip_render; |
|
|
|
|
|
|
|
g = font_get_glyph_texture(ren.font, cp, &updated); |
|
|
|
|
|
|
|
if (!g) REN_RET(-1, REN_FONT); |
|
|
|
|
|
|
|
if (updated) { |
|
|
|
|
|
|
|
if (update_font_texture()) |
|
|
|
|
|
|
|
REN_RET(-1, REN_TEXTURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
c = *g; |
|
|
|
c = *g; |
|
|
|
//printf("g: u=%d v=%d w=%d h=%d a=%d x=%d y=%d\n", c.u, c.v, c.w, c.h, c.a, c.x, c.y);
|
|
|
|
//printf("g: u=%d v=%d w=%d h=%d a=%d x=%d y=%d\n", c.u, c.v, c.w, c.h, c.a, c.x, c.y);
|
|
|
|
//printf("v: x=%d y=%d u=%d v=%d\n", v.pos.x, v.pos.y, v.uv.u, v.uv.v);
|
|
|
|
//printf("v: x=%d y=%d u=%d v=%d\n", v.pos.x, v.pos.y, v.uv.u, v.uv.v);
|
|
|
@ -597,10 +570,42 @@ int ren_render_text(const char *str, int x, int y, int w, int h, int size) |
|
|
|
}; |
|
|
|
}; |
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: implement font size
|
|
|
|
|
|
|
|
int ren_render_text(const char *str, int x, int y, int w, int h, int size) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// TODO: check size, if the current font is not of the same size then load
|
|
|
|
|
|
|
|
// load a new font and use that texture instead, this implies making
|
|
|
|
|
|
|
|
// a system to store and use different fonts, like:
|
|
|
|
|
|
|
|
// struct font_atlas * font_by_size(int size);
|
|
|
|
|
|
|
|
// FIXME: the bounding box (scissor) logic does not work
|
|
|
|
|
|
|
|
// TODO: create a method for calculating the total bounding box of a string
|
|
|
|
|
|
|
|
// given the box size
|
|
|
|
|
|
|
|
const struct font_glyph *g; |
|
|
|
|
|
|
|
size_t ret, off; |
|
|
|
|
|
|
|
uint_least32_t cp; |
|
|
|
|
|
|
|
int updated, gx = x, gy = y; |
|
|
|
|
|
|
|
for (off = 0; (ret = grapheme_decode_utf8(str+off, SIZE_MAX, &cp)) > 0 && cp != 0; off += ret) { |
|
|
|
|
|
|
|
// skip special characters that render a box (not present in font)
|
|
|
|
|
|
|
|
// FIXME: handle tab
|
|
|
|
|
|
|
|
if (iscntrl(cp)) goto skip_render; |
|
|
|
|
|
|
|
g = font_get_glyph_texture(ren.font, cp, &updated); |
|
|
|
|
|
|
|
if (!g) REN_RET(-1, REN_FONT); |
|
|
|
|
|
|
|
if (updated) { |
|
|
|
|
|
|
|
if (update_font_texture()) |
|
|
|
|
|
|
|
REN_RET(-1, REN_TEXTURE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// only push the glyph if it is inside the bounding box
|
|
|
|
|
|
|
|
if (gx <= x+w && gy <= y+h) |
|
|
|
|
|
|
|
ren_push_glyph(g, gx, gy); |
|
|
|
// TODO: possible kerning needs to be applied here
|
|
|
|
// TODO: possible kerning needs to be applied here
|
|
|
|
// TODO: handle other unicode control characters such as the
|
|
|
|
// TODO: handle other unicode control characters such as the
|
|
|
|
// right-to-left isolate (\u2067)
|
|
|
|
// right-to-left isolate (\u2067)
|
|
|
|
gx += c.x + c.a; |
|
|
|
gx += g->x + g->a; |
|
|
|
skip_render: |
|
|
|
skip_render: |
|
|
|
switch (cp) { |
|
|
|
switch (cp) { |
|
|
|
case '\r': |
|
|
|
case '\r': |
|
|
@ -632,6 +637,17 @@ int ren_render_text(const char *str, int x, int y, int w, int h, int size) |
|
|
|
#define A(x) ((x>>24)&0xff) |
|
|
|
#define A(x) ((x>>24)&0xff) |
|
|
|
static int ren_push_box(int x, int y, int w, int h, unsigned int color) |
|
|
|
static int ren_push_box(int x, int y, int w, int h, unsigned int color) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
/* x4,y4 x3,y3
|
|
|
|
|
|
|
|
* +-------------+ |
|
|
|
|
|
|
|
* |(x,y) /| |
|
|
|
|
|
|
|
* | / | |
|
|
|
|
|
|
|
* | 2 / | |
|
|
|
|
|
|
|
* | / | |
|
|
|
|
|
|
|
* | / | |
|
|
|
|
|
|
|
* | / 1 | |
|
|
|
|
|
|
|
* |/ | |
|
|
|
|
|
|
|
* +-------------+ |
|
|
|
|
|
|
|
* x1,y1 x2,y2 */ |
|
|
|
struct v_col v; |
|
|
|
struct v_col v; |
|
|
|
vec4_i c = { |
|
|
|
vec4_i c = { |
|
|
|
.r = RENORM(R(color)), |
|
|
|
.r = RENORM(R(color)), |
|
|
|