# HG changeset patch # User John Tsiombikas # Date 1316243398 -10800 # Node ID 7e0c702f12237bb7041874e35709eb87245f7ead # Parent 095ff7ca4e7492d5069a1aa988d838abfecd7e4a implemented the metrics functions diff -r 095ff7ca4e74 -r 7e0c702f1223 src/drawgl.c --- a/src/drawgl.c Fri Sep 16 08:42:07 2011 +0300 +++ b/src/drawgl.c Sat Sep 17 10:09:58 2011 +0300 @@ -39,7 +39,6 @@ struct vertex v[6]; }; -static int init(void); static void cleanup(void); static void add_glyph(struct glyph *g, float x, float y); @@ -51,11 +50,8 @@ static unsigned int font_tex; static int buf_mode = DTX_NBF; -static struct dtx_font *font; -static int font_sz; - -static int init(void) +int dtx_gl_init(void) { if(qbuf) { return 0; /* already initialized */ @@ -78,14 +74,6 @@ } -void dtx_use_font(struct dtx_font *fnt, int sz) -{ - init(); - - font = fnt; - font_sz = sz; -} - void dtx_vertex_attribs(int vert_attr, int tex_attr) { vattr = vert_attr; @@ -120,7 +108,7 @@ { struct dtx_glyphmap *gmap; - if(!font || !(gmap = dtx_get_font_glyphmap(font, font_sz, code))) { + if(!dtx_font || !(gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code))) { return; } set_glyphmap_texture(gmap); @@ -136,39 +124,27 @@ float pos_x = 0.0f; float pos_y = 0.0f; - if(!font) { + if(!dtx_font) { return; } while(*str) { + float px, py; int code = dtx_utf8_char_code(str); str = dtx_utf8_next_char((char*)str); - switch(code) { - case '\n': - if(buf_mode == DTX_LBF) { - should_flush = 1; - } - pos_x = 0.0; - pos_y -= gmap->line_advance; - break; + if(buf_mode == DTX_LBF && code == '\n') { + should_flush = 1; + } - case '\t': - pos_x = fmod(pos_x, 4.0) + 4.0; - break; + px = pos_x; + py = pos_y; - case '\r': - pos_x = 0.0; - break; + if((gmap = dtx_proc_char(code, &pos_x, &pos_y))) { + int idx = code - gmap->cstart; - default: - if((gmap = dtx_get_font_glyphmap(font, font_sz, code))) { - int idx = code - gmap->cstart; - - set_glyphmap_texture(gmap); - add_glyph(gmap->glyphs + idx, pos_x, pos_y); - pos_x += gmap->glyphs[idx].advance; - } + set_glyphmap_texture(gmap); + add_glyph(gmap->glyphs + idx, px, py); } } diff -r 095ff7ca4e74 -r 7e0c702f1223 src/drawtext_impl.h --- a/src/drawtext_impl.h Fri Sep 16 08:42:07 2011 +0300 +++ b/src/drawtext_impl.h Sat Sep 17 10:09:58 2011 +0300 @@ -56,7 +56,17 @@ }; +struct dtx_font *dtx_font; +int dtx_font_sz; + + #define fperror(str) \ fprintf(stderr, "%s: %s: %s\n", __func__, (str), strerror(errno)) +int dtx_gl_init(void); + +/* returns zero if it should NOT be printed and modifies xpos/ypos */ +/* implemented in font.c */ +struct dtx_glyphmap *dtx_proc_char(int code, float *xpos, float *ypos); + #endif /* TEXT_IMPL_H_ */ diff -r 095ff7ca4e74 -r 7e0c702f1223 src/font.c --- a/src/font.c Fri Sep 16 08:42:07 2011 +0300 +++ b/src/font.c Sat Sep 17 10:09:58 2011 +0300 @@ -22,8 +22,10 @@ #include #include #include +#include #include #include +#include #include #ifdef USE_FREETYPE #include @@ -467,6 +469,152 @@ } +void dtx_use_font(struct dtx_font *fnt, int sz) +{ + dtx_gl_init(); + + dtx_font = fnt; + dtx_font_sz = sz; +} + +void dtx_glyph_box(int code, struct dtx_box *box) +{ + int cidx; + struct dtx_glyphmap *gmap; + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); + + cidx = code - gmap->cstart; + + box->x = gmap->glyphs[cidx].orig_x; + box->y = gmap->glyphs[cidx].orig_y; + box->width = gmap->glyphs[cidx].width; + box->height = gmap->glyphs[cidx].height; +} + +float dtx_glyph_width(int code) +{ + struct dtx_box box; + dtx_glyph_box(code, &box); + return box.width; +} + +float dtx_glyph_height(int code) +{ + struct dtx_box box; + dtx_glyph_box(code, &box); + return box.height; +} + +void dtx_string_box(const char *str, struct dtx_box *box) +{ + int code; + float pos_x = 0.0f, pos_y = 0.0f; + struct glyph *g = 0; + float x0, y0, x1, y1; + + x0 = y0 = FLT_MAX; + x1 = y1 = -FLT_MAX; + + while(*str) { + float px, py; + struct dtx_glyphmap *gmap; + + code = dtx_utf8_char_code(str); + str = dtx_utf8_next_char((char*)str); + + px = pos_x; + py = pos_y; + + if((gmap = dtx_proc_char(code, &pos_x, &pos_y))) { + g = gmap->glyphs + code - gmap->cstart; + + if(px + g->orig_x < x0) { + x0 = px + g->orig_x; + } + if(py + g->orig_y < y0) { + y0 = py + g->orig_y; + } + if(px + g->orig_x + g->width > x1) { + x1 = px + g->orig_x + g->width; + } + if(py + g->orig_y + g->height > y1) { + y1 = py + g->orig_y + g->height; + } + } + } + + box->x = x0; + box->y = y0; + box->width = x1 - x0; + box->height = y1 - y0; +} + +float dtx_string_width(const char *str) +{ + struct dtx_box box; + + dtx_string_box(str, &box); + return box.width; +} + +float dtx_string_height(const char *str) +{ + struct dtx_box box; + + dtx_string_box(str, &box); + return box.height; +} + +float dtx_char_pos(const char *str, int n) +{ + int i; + float pos = 0.0; + struct dtx_glyphmap *gmap; + + for(i=0; iglyphs[i].advance; + } + return pos; +} + + +struct dtx_glyphmap *dtx_proc_char(int code, float *xpos, float *ypos) +{ + struct dtx_glyphmap *gmap; + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); + + switch(code) { + case '\n': + *xpos = 0.0; + if(gmap) { + *ypos -= gmap->line_advance; + } + return 0; + + case '\t': + if(gmap) { + *xpos = (fmod(*xpos, 4.0) + 4.0) * gmap->glyphs[0].advance; + } + return 0; + + case '\r': + *xpos = 0.0; + return 0; + + default: + break; + } + + if(gmap) { + *xpos += gmap->glyphs[code - gmap->cstart].advance; + } + return gmap; +} + static void calc_best_size(int total_width, int max_glyph_height, int padding, int pow2, int *imgw, int *imgh) { int xsz, ysz, num_rows;