added text drawing

This commit is contained in:
vurtun 2015-03-05 19:50:56 +01:00
parent 03e1e72c62
commit 24688273bb
4 changed files with 89 additions and 36 deletions

View File

@ -6,7 +6,7 @@ CC = gcc
DCC = clang
# Flags
CFLAGS = -std=c89 -pedantic -Wno-deprecated-declarations -D_POSIX_C_SOURCE=200809L
CFLAGS = -std=c89 -pedantic-errors -Wno-deprecated-declarations -D_POSIX_C_SOURCE=200809L
CFLAGS += -g -Wall -Wextra -Werror -Wformat -Wunreachable-code
CFLAGS += -Winline -Wshadow -Wwrite-strings -Wno-unused-variable -Wno-unused-parameter -Wno-unused-function
CFLAGS += -Wstrict-prototypes -Wold-style-definition

110
gui.c
View File

@ -66,7 +66,7 @@ utf_validate(long *u, gui_size i)
return i;
}
static long
static gui_long
utf_decode_byte(gui_char c, gui_size *i)
{
if (!i) return 0;
@ -78,10 +78,10 @@ utf_decode_byte(gui_char c, gui_size *i)
}
static gui_size
utf_decode(gui_char *c, long *u, gui_size clen)
utf_decode(const gui_char *c, gui_long *u, gui_size clen)
{
gui_size i, j, len, type;
long udecoded;
gui_long udecoded;
*u = UTF_INVALID;
if (!c || !u) return 0;
@ -103,13 +103,13 @@ utf_decode(gui_char *c, long *u, gui_size clen)
}
static gui_char
utf_encode_byte(long u, gui_size i)
utf_encode_byte(gui_long u, gui_size i)
{
return utfbyte[i] | (u & ~utfmask[i]);
}
static gui_size
utf_encode(long u, gui_char *c, gui_size clen)
utf_encode(gui_long u, gui_char *c, gui_size clen)
{
gui_size len, i;
len = utf_validate(&u, 0);
@ -159,7 +159,7 @@ void
gui_input_char(struct gui_input *in, gui_glyph glyph)
{
gui_size len = 0;
long unicode;
gui_long unicode;
if (!in) return;
len = utf_decode(glyph, &unicode, GUI_UTF_SIZE);
if (len && in->glyph_count < GUI_INPUT_MAX) {
@ -175,6 +175,23 @@ gui_input_end(struct gui_input *in)
vec2_sub(in->mouse_delta, in->mouse_pos, in->mouse_prev);
}
static gui_size
gui_font_text_width(const struct gui_font *font, const gui_char *t, gui_size l)
{
gui_long unicode;
gui_size len = 0;
const struct gui_font_glyph *g;
gui_size text_len = utf_decode(t, &unicode, l);
while (text_len < l) {
if (unicode == UTF_INVALID) return 0;
g = (unicode < font->glyph_count) ? &font->glyphes[unicode] : font->fallback;
g = (g->code == 0) ? font->fallback : g;
len += g->width + g->xadvance;
text_len += utf_decode(t + text_len, &unicode, l - text_len);
}
return (gui_size)((gui_float)len * font->scale);
}
static struct gui_draw_command*
gui_push_command(struct gui_draw_list *list, gui_size count,
const struct gui_rect *rect, gui_texture tex)
@ -206,7 +223,7 @@ gui_push_command(struct gui_draw_list *list, gui_size count,
static void
gui_vertex(struct gui_draw_command *cmd, gui_float x, gui_float y,
struct gui_color col)
struct gui_color col, gui_float u, gui_float v)
{
gui_size i;
if (!cmd) return;
@ -215,8 +232,8 @@ gui_vertex(struct gui_draw_command *cmd, gui_float x, gui_float y,
cmd->vertexes[i].pos.x = x;
cmd->vertexes[i].pos.y = y;
cmd->vertexes[i].color = col;
cmd->vertexes[i].uv.u = 0.0f;
cmd->vertexes[i].uv.v = 0.0f;
cmd->vertexes[i].uv.u = u;
cmd->vertexes[i].uv.v = v;
cmd->vertex_write++;
}
@ -241,12 +258,12 @@ gui_vertex_line(struct gui_draw_command* cmd, gui_float x0, gui_float y0,
vec2_load(hp0, +hn.y, -hn.x);
vec2_load(hp1, -hn.y, +hn.x);
gui_vertex(cmd, a.x + hp0.x, a.y + hp0.y, col);
gui_vertex(cmd, b.x + hp0.x, b.y + hp0.y, col);
gui_vertex(cmd, a.x + hp1.x, a.y + hp1.y, col);
gui_vertex(cmd, b.x + hp0.x, b.y + hp0.y, col);
gui_vertex(cmd, b.x + hp1.x, b.y + hp1.y, col);
gui_vertex(cmd, a.x + hp1.x, a.y + hp1.y, col);
gui_vertex(cmd, a.x + hp0.x, a.y + hp0.y, col, 0.0f, 0.0f);
gui_vertex(cmd, b.x + hp0.x, b.y + hp0.y, col, 0.0f, 0.0f);
gui_vertex(cmd, a.x + hp1.x, a.y + hp1.y, col, 0.0f, 0.0f);
gui_vertex(cmd, b.x + hp0.x, b.y + hp0.y, col, 0.0f, 0.0f);
gui_vertex(cmd, b.x + hp1.x, b.y + hp1.y, col, 0.0f, 0.0f);
gui_vertex(cmd, a.x + hp1.x, a.y + hp1.y, col, 0.0f, 0.0f);
}
static void
@ -270,9 +287,9 @@ gui_trianglef(struct gui_draw_list *list, gui_float x0, gui_float y0,
if (c.a == 0) return;
cmd = gui_push_command(list, 3, &null_rect, null_tex);
if (!cmd) return;
gui_vertex(cmd, x0, y0, c);
gui_vertex(cmd, x1, y1, c);
gui_vertex(cmd, x2, y2, c);
gui_vertex(cmd, x0, y0, c, 0.0f, 0.0f);
gui_vertex(cmd, x1, y1, c, 0.0f, 0.0f);
gui_vertex(cmd, x2, y2, c, 0.0f, 0.0f);
}
static void
@ -301,19 +318,52 @@ gui_rectf(struct gui_draw_list *list, gui_float x, gui_float y,
cmd = gui_push_command(list, 6, &null_rect, null_tex);
if (!cmd) return;
gui_vertex(cmd, x, y, col);
gui_vertex(cmd, x + w, y, col);
gui_vertex(cmd, x + w, y + h, col);
gui_vertex(cmd, x, y, col);
gui_vertex(cmd, x + w, y + h, col);
gui_vertex(cmd, x, y + h, col);
gui_vertex(cmd, x, y, col, 0.0f, 0.0f);
gui_vertex(cmd, x + w, y, col, 0.0f, 0.0f);
gui_vertex(cmd, x + w, y + h, col, 0.0f, 0.0f);
gui_vertex(cmd, x, y, col, 0.0f, 0.0f);
gui_vertex(cmd, x + w, y + h, col, 0.0f, 0.0f);
gui_vertex(cmd, x, y + h, col, 0.0f, 0.0f);
}
static void
gui_text(const struct gui_draw_list *list, gui_float x, gui_float y,
gui_float w, gui_float h, const gui_char *txt, gui_size len)
{
static void
gui_text(struct gui_draw_list *list, const struct gui_font *font, gui_float x,
gui_float y, gui_float w, gui_float h,
struct gui_color col, const gui_char *t, gui_size len)
{
struct gui_draw_command *cmd;
struct gui_rect clip;
gui_size text_len;
gui_float off = 0;
gui_long unicode;
const struct gui_font_glyph *g;
if (!list) return;
clip.x = x; clip.y = y;
clip.w = w; clip.h = h;
cmd = gui_push_command(list, 6 * len, &clip, font->texture);
if (!cmd) return;
text_len = utf_decode(t, &unicode, len);
while (text_len < len) {
gui_float x1, y1, x2, y2;
if (unicode == UTF_INVALID) break;
g = (unicode < font->glyph_count) ? &font->glyphes[unicode] : font->fallback;
g = (g->code == 0) ? font->fallback : g;
x1 = x + off;
x2 = x + w + off;
off += g->width + g->xadvance;
gui_vertex(cmd, x1, y, col, g->uv[0].u, g->uv[0].v);
gui_vertex(cmd, x2, y, col, g->uv[1].u, g->uv[0].v);
gui_vertex(cmd, x2, y+h, col, g->uv[1].u, g->uv[1].v);
gui_vertex(cmd, x1, y, col, g->uv[0].u, g->uv[0].v);
gui_vertex(cmd, x2, y+h, col, g->uv[1].u, g->uv[1].v);
gui_vertex(cmd, x1, y+h, col, g->uv[0].u, g->uv[1].v);
text_len += utf_decode(t + text_len, &unicode, len - text_len);
}
}
void
@ -358,9 +408,10 @@ gui_int
gui_button(struct gui_draw_list *list, const struct gui_input *in,
const struct gui_font *font, struct gui_color bg, struct gui_color fg,
gui_int x, gui_int y, gui_int w, gui_int h, gui_int pad,
const char *str, gui_int len)
const char *str, gui_int l)
{
gui_int ret = gui_false;
const gui_char *t = (const gui_char*)str;
if (!list || !in) return gui_false;
if (!in->mouse_down && in->mouse_clicked) {
const gui_int clicked_x = in->mouse_clicked_pos.x;
@ -370,6 +421,7 @@ gui_button(struct gui_draw_list *list, const struct gui_input *in,
}
gui_rectf(list, x, y, w, h, bg);
gui_rect(list, x, y, w, h, fg);
gui_text(list, font, x + pad, y + pad, w - 2 * pad, h - 2 * pad, fg, t, l);
return ret;
}

5
gui.h
View File

@ -10,7 +10,8 @@
#define GUI_INPUT_MAX 8
typedef int gui_int;
typedef int gui_short;
typedef short gui_short;
typedef long gui_long;
typedef int gui_bool;
typedef unsigned int gui_flags;
typedef unsigned char gui_char;
@ -87,7 +88,7 @@ struct gui_font {
gui_texture texture;
struct gui_vec2 tex_size;
struct gui_font_glyph *glyphes;
gui_size glyph_count;
gui_long glyph_count;
const struct gui_font_glyph *fallback;
};

8
x11.c
View File

@ -268,9 +268,9 @@ ldfont(const char *name, unsigned char height)
glyphes[id].yoff = *(float*)&iter[14];
glyphes[id].xadvance = *(float*)&iter[18];
glyphes[id].uv[0].u = (gui_float)x/(gui_float)tex_width;
glyphes[id].uv[0].v = (gui_float)y/(gui_float)tex_height;
glyphes[id].uv[0].v = (gui_float)(y+h)/(gui_float)tex_height;
glyphes[id].uv[1].u = (gui_float)(x+w)/(gui_float)tex_width;
glyphes[id].uv[1].v = (gui_float)(y+h)/(gui_float)tex_height;
glyphes[id].uv[1].v = (gui_float)y/(gui_float)tex_height;
if (glyphes[id].height > max_height) max_height = glyphes[id].height;
iter += 22;
}
@ -423,7 +423,7 @@ main(int argc, char *argv[])
xw.running = 1;
gui.win = &xw;
gui.font = ldfont("mono.font", 16);
gui.font = ldfont("mono.font", 12);
while (xw.running) {
XEvent ev;
started = timestamp();
@ -440,7 +440,7 @@ main(int argc, char *argv[])
/* ------------------------- GUI --------------------------*/
gui_begin(&gui.out, buffer, MAX_VERTEX_BUFFER);
if (gui_button(&gui.out, &gui.input, NULL, colorA, colorC, 50,50,150,30,5,"",0))
if (gui_button(&gui.out, &gui.input, gui.font, colorA, colorC, 50,50,150,30,5,"button",6))
fprintf(stdout, "Button pressed!\n");
slider = gui_slider(&gui.out, &gui.input, colorA, colorB,
50, 100, 150, 30, 2, 0.0f, slider, 10.0f, 1.0f);