From a0dcd2c0908c6a380f2d0952c2214e29611b004e Mon Sep 17 00:00:00 2001 From: vurtun Date: Thu, 5 Mar 2015 15:37:11 +0100 Subject: [PATCH] on the way to font rendering --- gui.c | 46 ++++------- gui.h | 34 +++++++- mono.font | Bin 0 -> 266492 bytes x11.c | 241 ++++++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 228 insertions(+), 93 deletions(-) create mode 100644 mono.font diff --git a/gui.c b/gui.c index ba45b0e..4035898 100644 --- a/gui.c +++ b/gui.c @@ -193,6 +193,7 @@ gui_push_command(struct gui_draw_list *list, gui_size count, memory += sizeof(struct gui_draw_command); memory += sizeof(struct gui_vertex) * count; list->needed += memory; + list->vertex_count += count; current = (gui_byte*)list->end - (gui_byte*)list->begin; if (list->size <= (current + memory)) return NULL; @@ -352,7 +353,7 @@ gui_end(struct gui_draw_list *list) gui_int gui_button(struct gui_draw_list *list, const struct gui_input *in, - struct gui_color bg, struct gui_color fg, + 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) { @@ -377,10 +378,9 @@ gui_slider(struct gui_draw_list *list, const struct gui_input *in, { gui_int mouse_x, mouse_y; gui_int clicked_x, clicked_y; - - gui_float cursor_w; gui_int cursor_x; gui_int cursor_y; + gui_float cursor_w; gui_int cursor_h; if (step == 0.0f) return value; @@ -428,12 +428,10 @@ gui_progress(struct gui_draw_list *list, const struct gui_input *in, gui_int x, gui_int y, gui_int w, gui_int h, gui_int pad, gui_size value, gui_size max, gui_bool modifyable) { - gui_int mouse_x, mouse_y; gui_float scale; - gui_int cursor_x; - gui_int cursor_y; - gui_int cursor_w; - gui_int cursor_h; + gui_int mouse_x, mouse_y; + gui_int cursor_x, cursor_y; + gui_int cursor_w, cursor_h; if (!list || !in) return 0; mouse_x = in->mouse_pos.x; @@ -466,33 +464,23 @@ gui_scroll(struct gui_draw_list *list, const struct gui_input *in, gui_int x, gui_int y, gui_int w, gui_int h, gui_int offset, gui_int dst) { - gui_int mouse_x; - gui_int mouse_y; - gui_int prev_x; - gui_int prev_y; + gui_int mouse_x, mouse_y; + gui_int prev_x, prev_y; gui_bool up, down; - gui_int button_size; - gui_int button_half; - gui_int button_y; - gui_int bar_h; - gui_int bar_y; + gui_int button_size, button_half, button_y; + gui_int bar_h, bar_y; gui_float ratio; gui_float off; - gui_int cursor_x; - gui_int cursor_y; - gui_int cursor_w; - gui_int cursor_h; - gui_int cursor_px; - gui_int cursor_py; - gui_bool inscroll; - gui_bool incursor; + gui_int cursor_x, cursor_y; + gui_int cursor_w, cursor_h; + gui_int cursor_px, cursor_py; + gui_bool inscroll, incursor; gui_int pad; gui_int xoff, yoff, boff; - gui_int xpad, ypad; - gui_int xmid; + gui_int xpad, ypad, xmid; if (!list || !in) return 0; gui_rectf(list, x, y, w, h, bg); @@ -527,8 +515,8 @@ gui_scroll(struct gui_draw_list *list, const struct gui_input *in, yoff = y + (button_size - pad); boff = button_y + (button_size - pad); - up = gui_button(list, in, fg, bg, x, y, button_size, button_size, 0, "", 0); - down = gui_button(list,in,fg,bg,x,button_y,button_size,button_size,0,"", 0); + up = gui_button(list, in, NULL, fg, bg, x, y, button_size, button_size, 0, "", 0); + down = gui_button(list,in,NULL, fg,bg,x,button_y,button_size,button_size,0,"", 0); gui_trianglef(list, xmid, y + pad, xoff, yoff, xpad, yoff, bg); gui_trianglef(list, xpad, ypad, xoff, ypad, xmid, boff, bg); diff --git a/gui.h b/gui.h index b6d57b5..d4dfcdc 100644 --- a/gui.h +++ b/gui.h @@ -7,11 +7,12 @@ #define TINY_GUI_H_ #define GUI_UTF_SIZE 4 -#define GUI_INPUT_MAX 16 -#define GUI_GLYPHES_MAX 512 +#define GUI_INPUT_MAX 8 typedef int gui_int; +typedef int gui_short; typedef int gui_bool; +typedef unsigned int gui_flags; typedef unsigned char gui_char; typedef float gui_float; typedef void* gui_texture; @@ -43,6 +44,7 @@ struct gui_draw_command { struct gui_draw_list { struct gui_draw_command *begin; struct gui_draw_command *end; + gui_size vertex_count; gui_byte *memory; gui_size size; gui_size needed; @@ -74,11 +76,34 @@ struct gui_input { }; struct gui_font_glyph { - gui_glyph glpyh; + gui_int code; + gui_short xadvance; + gui_short width, height; + gui_float xoff, yoff; + struct gui_texCoord uv[2]; }; struct gui_font { - struct gui_font_glyph glyphes[GUI_GLYPHES_MAX]; + gui_short height; + gui_float scale; + gui_texture texture; + struct gui_vec2 tex_size; + struct gui_font_glyph *glyphes; + gui_size glyph_count; + const struct gui_font_glyph *fallback; +}; + +enum gui_panel_flags { + GUI_PANEL_HEADER = 0x01, + GUI_PANEL_MINIMIZABLE = 0x02, + GUI_PANEL_CLOSEABLE = 0x04, + GUI_PANEL_SCALEABLE = 0x08, + GUI_PANEL_SCROLLBAR = 0x10 +}; + +struct gui_panel { + gui_flags flags; + gui_int at_x, at_y; }; void gui_input_begin(struct gui_input *in); @@ -99,6 +124,7 @@ gui_int gui_button(struct gui_draw_list *list, const struct gui_input *in, gui_int x, gui_int y, gui_int w, gui_int h, gui_int pad, const char *str, gui_int len); gui_int gui_toggle(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, gui_int active); diff --git a/mono.font b/mono.font new file mode 100644 index 0000000000000000000000000000000000000000..eca6aa8a2f409e8006f9361be845155ef9512011 GIT binary patch literal 266492 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 A$^ZZW literal 0 HcmV?d00001 diff --git a/x11.c b/x11.c index 0c76444..6151a2b 100644 --- a/x11.c +++ b/x11.c @@ -28,18 +28,11 @@ #include "gui.h" /* macros */ -#define internal static -#define global static -#define persistent static - #define WIN_WIDTH 800 #define WIN_HEIGHT 600 #define DTIME 33 #define MAX_VERTEX_BUFFER (16 * 1024) -#define CONSOLE_MAX_CMDLINE 1024 -#define CONSOLE_MAX_TEXT (16 * 1024) - #define MIN(a,b)((a) < (b) ? (a) : (b)) #define MAX(a,b)((a) < (b) ? (b) : (a)) #define CLAMP(i,v,x) (MAX(MIN(v,x), i)) @@ -59,30 +52,32 @@ struct XWindow { int running; }; -struct Console { +struct GUI { struct XWindow *win; - struct gui_draw_list gui; + struct gui_draw_list out; struct gui_input input; - struct gui_font font; - /* text */ - int output_len; - char output[CONSOLE_MAX_TEXT]; - char line[CONSOLE_MAX_CMDLINE]; - int line_len; + struct gui_font *font; }; /* functions */ -internal void die(const char*,...); -internal long timestamp(void); -internal void sleep_for(long ms); +static void die(const char*,...); +static void* xcalloc(size_t nmemb, size_t size); +static long timestamp(void); +static void sleep_for(long ms); +static char* ldfile(const char*, int, size_t*); -internal void kpress(struct Console*, XEvent*); -internal void bpress(struct Console*, XEvent*); -internal void brelease(struct Console*, XEvent*); -internal void bmotion(struct Console*, XEvent*); -internal void resize(struct Console*, XEvent*); +static void kpress(struct GUI*, XEvent*); +static void bpress(struct GUI*, XEvent*); +static void brelease(struct GUI*, XEvent*); +static void bmotion(struct GUI*, XEvent*); +static void resize(struct GUI*, XEvent*); -internal void +static struct gui_font *ldfont(const char*, unsigned char); +static void delfont(struct gui_font *font); +static void draw(struct GUI*, int, int , const struct gui_draw_list*); + +/* gobals */ +static void die(const char *fmt, ...) { va_list ap; @@ -92,7 +87,7 @@ die(const char *fmt, ...) exit(EXIT_FAILURE); } -internal void* +static void* xcalloc(size_t nmemb, size_t size) { void *p = calloc(nmemb, size); @@ -101,7 +96,7 @@ xcalloc(size_t nmemb, size_t size) return p; } -internal long +static long timestamp(void) { struct timeval tv; @@ -109,7 +104,7 @@ timestamp(void) return (long)((long)tv.tv_sec * 1000 + (long)tv.tv_usec/1000); } -internal void +static void sleep_for(long t) { const time_t sec = (int)(t/1000); @@ -121,7 +116,7 @@ sleep_for(long t) } static void -kpress(struct Console *con, XEvent* e) +kpress(struct GUI *con, XEvent* e) { int ret; struct XWindow *xw = con->win; @@ -140,7 +135,7 @@ kpress(struct Console *con, XEvent* e) } static void -krelease(struct Console *con, XEvent* e) +krelease(struct GUI *con, XEvent* e) { int ret; struct XWindow *xw = con->win; @@ -158,7 +153,7 @@ krelease(struct Console *con, XEvent* e) } static void -bpress(struct Console *con, XEvent *evt) +bpress(struct GUI *con, XEvent *evt) { const float x = evt->xbutton.x; const float y = evt->xbutton.y; @@ -167,7 +162,7 @@ bpress(struct Console *con, XEvent *evt) } static void -brelease(struct Console *con, XEvent *evt) +brelease(struct GUI *con, XEvent *evt) { const float x = evt->xbutton.x; const float y = evt->xbutton.y; @@ -177,7 +172,7 @@ brelease(struct Console *con, XEvent *evt) } static void -bmotion(struct Console *con, XEvent *evt) +bmotion(struct GUI *con, XEvent *evt) { const gui_int x = evt->xbutton.x; const gui_int y = evt->xbutton.y; @@ -186,21 +181,130 @@ bmotion(struct Console *con, XEvent *evt) } static void -resize(struct Console *con, XEvent* evt) +resize(struct GUI *con, XEvent* evt) { struct XWindow *xw = con->win; XGetWindowAttributes(xw->dpy, xw->win, &xw->gwa); glViewport(0, 0, xw->gwa.width, xw->gwa.height); } +static char* +ldfile(const char* path, int flags, size_t* siz) +{ + char *buf; + int fd = open(path, flags); + struct stat status; + if (fd == -1) + die("Failed to open file: %s (%s)\n", + path, strerror(errno)); + if (fstat(fd, &status) < 0) + die("Failed to call fstat: %s",strerror(errno)); + *siz = status.st_size; + buf = xcalloc(*siz, 1); + if (read(fd, buf, *siz) < 0) + die("Failed to call read: %s",strerror(errno)); + close(fd); + return buf; +} + +static struct gui_font* +ldfont(const char *name, unsigned char height) +{ + union conversion { + gui_texture handle; + uintptr_t ptr; + } convert; + GLuint texture; + size_t size; + struct gui_font *font; + short i = 0; + uint32_t bpp; + short max_height = 0; + + uint32_t iheight; + uint32_t iwidth; + + /* header */ + unsigned char *buffer = (unsigned char*)ldfile(name, O_RDONLY, &size); + uint16_t num = *(uint16_t*)buffer; + uint16_t indexes = *(uint16_t*)&buffer[0x02] + 1; + uint16_t tex_width = *(uint16_t*)&buffer[0x04]; + uint16_t tex_height = *(uint16_t*)&buffer[0x06]; + + /* glyphes */ + unsigned char *header; + unsigned char *data; + unsigned char *iter = &buffer[0x08]; + size_t mem = sizeof(struct gui_font_glyph) * indexes; + struct gui_font_glyph *glyphes = xcalloc(mem, 1); + for(i = 0; i < num; ++i) { + short id = *(uint16_t*)&iter[0]; + short x = *(uint16_t*)&iter[2]; + short y = *(uint16_t*)&iter[4]; + short w = *(uint16_t*)&iter[6]; + short h = *(uint16_t*)&iter[8]; + + glyphes[id].code = id; + glyphes[id].width = w; + glyphes[id].height = h; + glyphes[id].xoff = *(float*)&iter[10]; + 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[1].u = (gui_float)(x+w)/(gui_float)tex_width; + glyphes[id].uv[1].v = (gui_float)(y+h)/(gui_float)tex_height; + if (glyphes[id].height > max_height) max_height = glyphes[id].height; + iter += 22; + } + + /* texture */ + header = iter; + assert(header[0] == 'B'); + assert(header[1] == 'M'); + + data = header + 54; + glGenTextures(1, &texture); + convert.ptr = texture; + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, data); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + /* font */ + font = xcalloc(sizeof(struct gui_font), 1); + font->height = height; + font->scale = (float)height/(float)max_height; + font->texture = convert.handle; + font->tex_size.x = tex_width; + font->tex_size.y = tex_height; + font->fallback = &glyphes['?']; + font->glyphes = glyphes; + font->glyph_count = indexes; + free(buffer); + return font; +} + static void -draw(int width, int height, const struct gui_draw_list *list) +delfont(struct gui_font *font) +{ + if (!font) return; + if (font->glyphes) + free(font->glyphes); + free(font); +} + +static void +draw(struct GUI *con, int width, int height, const struct gui_draw_list *list) { const struct gui_draw_command *cmd; - persistent const size_t v = sizeof(struct gui_vertex); - persistent const size_t p = offsetof(struct gui_vertex, pos); - persistent const size_t t = offsetof(struct gui_vertex, uv); - persistent const size_t c = offsetof(struct gui_vertex, color); + static const size_t v = sizeof(struct gui_vertex); + static const size_t p = offsetof(struct gui_vertex, pos); + static const size_t t = offsetof(struct gui_vertex, uv); + static const size_t c = offsetof(struct gui_vertex, color); if (!list) return; glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); @@ -222,6 +326,20 @@ draw(int width, int height, const struct gui_draw_list *list) glPushMatrix(); glLoadIdentity(); + glBindTexture(GL_TEXTURE_2D, (unsigned long)con->font->texture); + glColor4ub(255,255,255,255); + glBegin(GL_QUADS); + glTexCoord3d(1, 1, 0); + glVertex2f(300, 300); + glTexCoord2d(0, 1); + glVertex2f(50, 300); + glTexCoord2d(0, 0); + glVertex2f(50, 50); + glTexCoord2d(1, 0); + glVertex2f(300, 50); + glEnd(); + +#if 0 cmd = list->begin; while (cmd) { const int x = (int)cmd->clip_rect.x; @@ -237,6 +355,7 @@ draw(int width, int height, const struct gui_draw_list *list) glDrawArrays(GL_TRIANGLES, 0, cmd->vertex_count); cmd = gui_next(list, cmd); } +#endif glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -252,7 +371,7 @@ int main(int argc, char *argv[]) { struct XWindow xw; - struct Console con; + struct GUI gui; long dt, started; gui_byte *buffer; gui_size buffer_size = MAX_VERTEX_BUFFER; @@ -260,6 +379,7 @@ main(int argc, char *argv[]) const struct gui_color colorB = {45, 45, 45, 255}; const struct gui_color colorC = {0, 0, 0, 255}; static GLint att[] = {GLX_RGBA, GLX_DEPTH_SIZE,24, GLX_DOUBLEBUFFER, None}; + GLenum err; gui_float slider = 5.0f; gui_float prog = 60.0f; @@ -268,7 +388,7 @@ main(int argc, char *argv[]) /* x11 */ UNUSED(argc); UNUSED(argv); memset(&xw, 0, sizeof xw); - memset(&con, 0, sizeof con); + memset(&gui, 0, sizeof gui); xw.dpy = XOpenDisplay(NULL); if (!xw.dpy) die("XOpenDisplay failed\n"); @@ -291,7 +411,8 @@ main(int argc, char *argv[]) XMapWindow(xw.dpy, xw.win); XFlush(xw.dpy); XSync(xw.dpy, False); - con.win = &xw; + gui.win = &xw; + gui.font = ldfont("mono.font", 16); /* OpenGL */ xw.glc = glXCreateContext(xw.dpy, xw.vi, NULL, GL_TRUE); @@ -300,37 +421,36 @@ main(int argc, char *argv[]) xw.running = 1; while (xw.running) { - /*----------------------- Input -----------------------------*/ XEvent ev; started = timestamp(); - gui_input_begin(&con.input); + gui_input_begin(&gui.input); while (XCheckWindowEvent(xw.dpy, xw.win, xw.swa.event_mask, &ev)) { - if (ev.type == Expose||ev.type == ConfigureNotify) resize(&con, &ev); - else if (ev.type == MotionNotify) bmotion(&con, &ev); - else if (ev.type == ButtonPress) bpress(&con, &ev); - else if (ev.type == ButtonRelease) brelease(&con, &ev); - else if (ev.type == KeyPress) kpress(&con, &ev); - else if (ev.type == KeyRelease) kpress(&con, &ev); + if (ev.type == Expose||ev.type == ConfigureNotify) resize(&gui, &ev); + else if (ev.type == MotionNotify) bmotion(&gui, &ev); + else if (ev.type == ButtonPress) bpress(&gui, &ev); + else if (ev.type == ButtonRelease) brelease(&gui, &ev); + else if (ev.type == KeyPress) kpress(&gui, &ev); + else if (ev.type == KeyRelease) krelease(&gui, &ev); } - gui_input_end(&con.input); + gui_input_end(&gui.input); /* ------------------------- GUI --------------------------*/ - gui_begin(&con.gui, buffer, MAX_VERTEX_BUFFER); - if (gui_button(&con.gui, &con.input, colorA, colorC, 50,50,150,30,5,"",0)) + gui_begin(&gui.out, buffer, MAX_VERTEX_BUFFER); + if (gui_button(&gui.out, &gui.input, NULL, colorA, colorC, 50,50,150,30,5,"",0)) fprintf(stdout, "Button pressed!\n"); - slider = gui_slider(&con.gui, &con.input, colorA, colorB, - 50,100,150,30,2, 0.0f, slider, 10.0f, 1.0f); - prog = gui_progress(&con.gui, &con.input, colorA, colorB, - 50,150,150,30,2, prog, 100.0f, gui_true); - offset = gui_scroll(&con.gui, &con.input, colorA, colorB, - 250,50,16,300, offset, 600); - gui_end(&con.gui); + slider = gui_slider(&gui.out, &gui.input, colorA, colorB, + 50, 100, 150, 30, 2, 0.0f, slider, 10.0f, 1.0f); + prog = gui_progress(&gui.out, &gui.input, colorA, colorB, + 50, 150, 150, 30, 2, prog, 100.0f, gui_true); + offset = gui_scroll(&gui.out, &gui.input, colorA, colorB, + 250, 50, 16, 300, offset, 600); + gui_end(&gui.out); /* ---------------------------------------------------------*/ /* Draw */ glClearColor(45.0f/255.0f,45.0f/255.0f,45.0f/255.0f,1); glClear(GL_COLOR_BUFFER_BIT); - draw(xw.gwa.width, xw.gwa.height, &con.gui); + draw(&gui, xw.gwa.width, xw.gwa.height, &gui.out); glXSwapBuffers(xw.dpy, xw.win); /* Timing */ @@ -342,6 +462,7 @@ main(int argc, char *argv[]) } /* Cleanup */ + delfont(gui.font); glXMakeCurrent(xw.dpy, None, NULL); glXDestroyContext(xw.dpy, xw.glc); XDestroyWindow(xw.dpy, xw.win);