Browse Source

Compute font-wide ascent and height

Léo Gaspard 8 years ago
parent
commit
5c13b39345
4 changed files with 19 additions and 5 deletions
  1. 0 1
      TODO
  2. 11 2
      dtext.c
  3. 3 0
      dtext.h
  4. 5 2
      test.c

+ 0 - 1
TODO

@@ -1,7 +1,6 @@
 Still to do:
  * Cleanly report Xlib errors
  * Setup a scheme for error reporting
- * Compute row height (/ char width ?) on font-wide basis
  * In dt_load, gracefully handle case when one face refuses to load (ie. free
    already allocated stuff before returning an error)
  * Support for faces other than the first

+ 11 - 2
dtext.c

@@ -13,6 +13,9 @@
 
 #include "dtext.h"
 
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
 static dt_error load_face(dt_context *ctx, FT_Face *face, char const *name);
 static dt_error load_char(dt_context *ctx, dt_font *fnt, wchar_t c);
 
@@ -83,6 +86,7 @@ dt_load(dt_context *ctx, dt_font **res, char const *name)
 	size_t i;
 	size_t len;
 	char *face;
+	int16_t descent;
 
 	if (!(fnt = malloc(sizeof(*fnt))))
 		return -ENOMEM;
@@ -104,6 +108,13 @@ dt_load(dt_context *ctx, dt_font **res, char const *name)
 	fnt->gs = XRenderCreateGlyphSet(ctx->dpy, ctx->argb32_format);
 	memset(fnt->advance, 0, sizeof(fnt->advance));
 
+	fnt->ascent = descent = 0;
+	for (i = 0; i < fnt->num_faces; ++i) {
+		fnt->ascent = max(fnt->ascent, fnt->faces[i]->ascender >> 6);
+		descent = min(descent, fnt->faces[i]->descender >> 6);
+	}
+	fnt->height = fnt->ascent - descent;
+
 	*res = fnt;
 	return 0;
 }
@@ -142,8 +153,6 @@ dt_box(dt_context *ctx, dt_font *fnt, dt_bbox *bbox, wchar_t const *txt)
 			return err;
 		p = hash_get(fnt->advance, txt[i]);
 		bbox->w += p->adv;
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#define min(a, b) ((a) < (b) ? (a) : (b))
 		bbox->h = max(p->h, bbox->h + max(0, bbox->y - p->asc));
 		bbox->y = min(p->asc, bbox->y);
 	}

+ 3 - 0
dtext.h

@@ -28,6 +28,9 @@ typedef struct {
 
 #define DT_HASH_SIZE 128
 typedef struct {
+	uint16_t height;
+	uint16_t ascent;
+
 	FT_Face *faces;
 	size_t num_faces;
 

+ 5 - 2
test.c

@@ -94,8 +94,11 @@ static void draw()
 	assert(!dt_draw(ctx, fnt, &style, 10, 50, TEXT));
 
 	assert(!dt_box(ctx, fnt, &bbox, TEXT));
-	XFillRectangle(dpy, win, gc, 10 + bbox.x, 90 + bbox.y, bbox.w, bbox.h);
-	assert(!dt_draw(ctx, fnt, &style_inv, 10, 90, TEXT));
+	XFillRectangle(dpy, win, gc, 10 + bbox.x, 100 + bbox.y, bbox.w, bbox.h);
+	assert(!dt_draw(ctx, fnt, &style_inv, 10, 100, TEXT));
+
+	XFillRectangle(dpy, win, gc, 10 + bbox.x, 150 - fnt->ascent, bbox.w, fnt->height);
+	assert(!dt_draw(ctx, fnt, &style_inv, 10, 150, TEXT));
 
 	XFlush(dpy);
 }