|
|
|
@ -515,11 +515,8 @@ int ren_set_scissor(int x, int y, int w, int h) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: implement font size
|
|
|
|
|
int ren_render_text(const char *str, int x, int y, int w, int h, int size) |
|
|
|
|
static int ren_push_glyph(const struct font_glyph *g, int gx, int gy) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
/* x4,y4 x3,y3
|
|
|
|
|
* +-------------+ |
|
|
|
|
* |(x,y) /| |
|
|
|
@ -531,8 +528,55 @@ int ren_render_text(const char *str, int x, int y, int w, int h, int size) |
|
|
|
|
* |/ | |
|
|
|
|
* +-------------+ |
|
|
|
|
* x1,y1 x2,y2 */ |
|
|
|
|
struct v_text v; |
|
|
|
|
struct font_glyph c; |
|
|
|
|
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("v: x=%d y=%d u=%d v=%d\n", v.pos.x, v.pos.y, v.uv.u, v.uv.v);
|
|
|
|
|
// x1,y1
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x, .y = gy+c.y+c.h }, |
|
|
|
|
.uv = { .u = c.u, .v = c.v+c.h }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x2,y2
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x+c.w, .y = gy+c.y+c.h }, |
|
|
|
|
.uv = { .u = c.u+c.w, .v = c.v+c.h }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x3,y3
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x+c.w, .y = gy+c.y }, |
|
|
|
|
.uv = { .u = c.u+c.w, .v = c.v }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x1,y1
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x, .y = gy+c.y+c.h }, |
|
|
|
|
.uv = { .u = c.u, .v = c.v+c.h }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x3,y3
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x+c.w, .y = gy+c.y }, |
|
|
|
|
.uv = { .u = c.u+c.w, .v = c.v }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x4,y4
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x, .y = gy+c.y }, |
|
|
|
|
.uv = { .u = c.u, .v = c.v }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TODO: stop drawing when outside the bounding box
|
|
|
|
|
|
|
|
|
|
// 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:
|
|
|
|
@ -540,13 +584,10 @@ int ren_render_text(const char *str, int x, int y, int w, int h, 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; |
|
|
|
|
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
|
|
|
|
@ -557,50 +598,14 @@ int ren_render_text(const char *str, int x, int y, int w, int h, int size) |
|
|
|
|
if (update_font_texture()) |
|
|
|
|
REN_RET(-1, REN_TEXTURE); |
|
|
|
|
} |
|
|
|
|
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("v: x=%d y=%d u=%d v=%d\n", v.pos.x, v.pos.y, v.uv.u, v.uv.v);
|
|
|
|
|
// x1,y1
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x, .y = gy+c.y+c.h }, |
|
|
|
|
.uv = { .u = c.u, .v = c.v+c.h }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x2,y2
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x+c.w, .y = gy+c.y+c.h }, |
|
|
|
|
.uv = { .u = c.u+c.w, .v = c.v+c.h }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x3,y3
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x+c.w, .y = gy+c.y }, |
|
|
|
|
.uv = { .u = c.u+c.w, .v = c.v }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x1,y1
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x, .y = gy+c.y+c.h }, |
|
|
|
|
.uv = { .u = c.u, .v = c.v+c.h }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x3,y3
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x+c.w, .y = gy+c.y }, |
|
|
|
|
.uv = { .u = c.u+c.w, .v = c.v }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
// x4,y4
|
|
|
|
|
v = (struct v_text){ |
|
|
|
|
.pos = { .x = gx+c.x, .y = gy+c.y }, |
|
|
|
|
.uv = { .u = c.u, .v = c.v }, |
|
|
|
|
}; |
|
|
|
|
vtstack_push(&ren.font_stack, &v); |
|
|
|
|
|
|
|
|
|
// 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: handle other unicode control characters such as the
|
|
|
|
|
// right-to-left isolate (\u2067)
|
|
|
|
|
gx += c.x + c.a; |
|
|
|
|
gx += g->x + g->a; |
|
|
|
|
skip_render: |
|
|
|
|
switch (cp) { |
|
|
|
|
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) |
|
|
|
|
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; |
|
|
|
|
vec4_i c = { |
|
|
|
|
.r = RENORM(R(color)), |
|
|
|
|