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;