libdrawtext
diff src/font.c @ 6:7e0c702f1223
implemented the metrics functions
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Sat, 17 Sep 2011 10:09:58 +0300 |
parents | 095ff7ca4e74 |
children | 10cfb642d0b8 |
line diff
1.1 --- a/src/font.c Fri Sep 16 08:42:07 2011 +0300 1.2 +++ b/src/font.c Sat Sep 17 10:09:58 2011 +0300 1.3 @@ -22,8 +22,10 @@ 1.4 #include <stdio.h> 1.5 #include <stdlib.h> 1.6 #include <string.h> 1.7 +#include <math.h> 1.8 #include <limits.h> 1.9 #include <ctype.h> 1.10 +#include <float.h> 1.11 #include <errno.h> 1.12 #ifdef USE_FREETYPE 1.13 #include <ft2build.h> 1.14 @@ -467,6 +469,152 @@ 1.15 } 1.16 1.17 1.18 +void dtx_use_font(struct dtx_font *fnt, int sz) 1.19 +{ 1.20 + dtx_gl_init(); 1.21 + 1.22 + dtx_font = fnt; 1.23 + dtx_font_sz = sz; 1.24 +} 1.25 + 1.26 +void dtx_glyph_box(int code, struct dtx_box *box) 1.27 +{ 1.28 + int cidx; 1.29 + struct dtx_glyphmap *gmap; 1.30 + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); 1.31 + 1.32 + cidx = code - gmap->cstart; 1.33 + 1.34 + box->x = gmap->glyphs[cidx].orig_x; 1.35 + box->y = gmap->glyphs[cidx].orig_y; 1.36 + box->width = gmap->glyphs[cidx].width; 1.37 + box->height = gmap->glyphs[cidx].height; 1.38 +} 1.39 + 1.40 +float dtx_glyph_width(int code) 1.41 +{ 1.42 + struct dtx_box box; 1.43 + dtx_glyph_box(code, &box); 1.44 + return box.width; 1.45 +} 1.46 + 1.47 +float dtx_glyph_height(int code) 1.48 +{ 1.49 + struct dtx_box box; 1.50 + dtx_glyph_box(code, &box); 1.51 + return box.height; 1.52 +} 1.53 + 1.54 +void dtx_string_box(const char *str, struct dtx_box *box) 1.55 +{ 1.56 + int code; 1.57 + float pos_x = 0.0f, pos_y = 0.0f; 1.58 + struct glyph *g = 0; 1.59 + float x0, y0, x1, y1; 1.60 + 1.61 + x0 = y0 = FLT_MAX; 1.62 + x1 = y1 = -FLT_MAX; 1.63 + 1.64 + while(*str) { 1.65 + float px, py; 1.66 + struct dtx_glyphmap *gmap; 1.67 + 1.68 + code = dtx_utf8_char_code(str); 1.69 + str = dtx_utf8_next_char((char*)str); 1.70 + 1.71 + px = pos_x; 1.72 + py = pos_y; 1.73 + 1.74 + if((gmap = dtx_proc_char(code, &pos_x, &pos_y))) { 1.75 + g = gmap->glyphs + code - gmap->cstart; 1.76 + 1.77 + if(px + g->orig_x < x0) { 1.78 + x0 = px + g->orig_x; 1.79 + } 1.80 + if(py + g->orig_y < y0) { 1.81 + y0 = py + g->orig_y; 1.82 + } 1.83 + if(px + g->orig_x + g->width > x1) { 1.84 + x1 = px + g->orig_x + g->width; 1.85 + } 1.86 + if(py + g->orig_y + g->height > y1) { 1.87 + y1 = py + g->orig_y + g->height; 1.88 + } 1.89 + } 1.90 + } 1.91 + 1.92 + box->x = x0; 1.93 + box->y = y0; 1.94 + box->width = x1 - x0; 1.95 + box->height = y1 - y0; 1.96 +} 1.97 + 1.98 +float dtx_string_width(const char *str) 1.99 +{ 1.100 + struct dtx_box box; 1.101 + 1.102 + dtx_string_box(str, &box); 1.103 + return box.width; 1.104 +} 1.105 + 1.106 +float dtx_string_height(const char *str) 1.107 +{ 1.108 + struct dtx_box box; 1.109 + 1.110 + dtx_string_box(str, &box); 1.111 + return box.height; 1.112 +} 1.113 + 1.114 +float dtx_char_pos(const char *str, int n) 1.115 +{ 1.116 + int i; 1.117 + float pos = 0.0; 1.118 + struct dtx_glyphmap *gmap; 1.119 + 1.120 + for(i=0; i<n; i++) { 1.121 + int code = dtx_utf8_char_code(str); 1.122 + str = dtx_utf8_next_char((char*)str); 1.123 + 1.124 + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); 1.125 + pos += gmap->glyphs[i].advance; 1.126 + } 1.127 + return pos; 1.128 +} 1.129 + 1.130 + 1.131 +struct dtx_glyphmap *dtx_proc_char(int code, float *xpos, float *ypos) 1.132 +{ 1.133 + struct dtx_glyphmap *gmap; 1.134 + gmap = dtx_get_font_glyphmap(dtx_font, dtx_font_sz, code); 1.135 + 1.136 + switch(code) { 1.137 + case '\n': 1.138 + *xpos = 0.0; 1.139 + if(gmap) { 1.140 + *ypos -= gmap->line_advance; 1.141 + } 1.142 + return 0; 1.143 + 1.144 + case '\t': 1.145 + if(gmap) { 1.146 + *xpos = (fmod(*xpos, 4.0) + 4.0) * gmap->glyphs[0].advance; 1.147 + } 1.148 + return 0; 1.149 + 1.150 + case '\r': 1.151 + *xpos = 0.0; 1.152 + return 0; 1.153 + 1.154 + default: 1.155 + break; 1.156 + } 1.157 + 1.158 + if(gmap) { 1.159 + *xpos += gmap->glyphs[code - gmap->cstart].advance; 1.160 + } 1.161 + return gmap; 1.162 +} 1.163 + 1.164 static void calc_best_size(int total_width, int max_glyph_height, int padding, int pow2, int *imgw, int *imgh) 1.165 { 1.166 int xsz, ysz, num_rows;