[cairo-commit] 7 commits - src/cairo-font-face-twin.c util/cairo-view

Behdad Esfahbod behdad at kemper.freedesktop.org
Wed Dec 24 22:30:01 PST 2008


 src/cairo-font-face-twin.c |  184 ++++++++++++++++++++++++++++++++++-----------
 util/cairo-view            |    2 
 2 files changed, 141 insertions(+), 45 deletions(-)

New commits:
commit f4c81e18f85c6a68d682301abfd75e7c208c1e1a
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Dec 25 01:29:41 2008 -0500

    [twin] Disable pen hinting if hinting is off

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 796561f..60ed81e 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -304,14 +304,19 @@ typedef struct {
 } twin_snap_info_t;
 
 static void
-_twin_compute_snap (cairo_t           *cr,
-		    twin_snap_info_t  *info,
-		    const signed char *b)
+_twin_compute_snap (cairo_t             *cr,
+		    cairo_scaled_font_t *scaled_font,
+		    twin_snap_info_t    *info,
+		    const signed char   *b)
 {
     int			s, n;
     const signed char	*snap;
     double x, y;
 
+    info->snap = scaled_font->options.hint_style != CAIRO_HINT_STYLE_NONE;
+    if (!info->snap)
+	return;
+
     x = 1; y = 0;
     cairo_user_to_device_distance (cr, &x, &y);
     info->x_scale = sqrt (x*x + y*y);
@@ -343,12 +348,20 @@ _twin_compute_snap (cairo_t           *cr,
 }
 
 static void
-_twin_compute_pen (cairo_t *cr,
+_twin_compute_pen (cairo_t             *cr,
+		   cairo_scaled_font_t *scaled_font,
 		   double width,
 		   double *penx, double *peny)
 {
     double x, y;
     double scale, inv;
+    cairo_bool_t hint;
+
+    hint = scaled_font->options.hint_style != CAIRO_HINT_STYLE_NONE;
+    if (!hint) {
+	*penx = *peny = width;
+	return;
+    }
 
     x = 1; y = 0;
     cairo_user_to_device_distance (cr, &x, &y);
@@ -401,7 +414,7 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
     cairo_scale (cr, stretch, 1);
 
     /* lock pen matrix */
-    _twin_compute_pen (cr, weight, &penx, &peny);
+    _twin_compute_pen (cr, scaled_font, weight, &penx, &peny);
     cairo_save (cr);
 
     /* left margin + pen width, pen width */
@@ -431,9 +444,7 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
 	gw = monow;
     }
 
-    info.snap = scaled_font->options.hint_style != CAIRO_HINT_STYLE_NONE;
-    if (info.snap)
-	_twin_compute_snap (cr, &info, b);
+    _twin_compute_snap (cr, scaled_font, &info, b);
 
     /* advance width */
     metrics->x_advance = gw + penx * 3; /* pen width + margin */
commit af91fc1974ce2dfbaab187e22769cdfb9e6279d9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Dec 25 01:24:46 2008 -0500

    [twin] Optimize hinting

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index ce1a55b..796561f 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -281,13 +281,8 @@ _twin_snap (double v, double *snap, double *snapped, int n)
 	    double dist = after - before;
 	    double snap_before = snapped[s];
 	    double snap_after = snapped[s+1];
-	    double move_before = snap_before - before;
-	    double move_after = snap_after - after;
 	    double dist_before = v - before;
-	    double dist_after = after - v;
-	    double move = (dist_before * move_after + dist_after * move_before) / dist;
-	    /* XXX optimize the above */
-	    v += move;
+	    v = snap_before + (snap_after - snap_before) * dist_before / dist;
 	    break;
 	}
     }
commit 439959d1af1f6c4ce174a3fee524eacfc18a00bd
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Thu Dec 25 01:06:47 2008 -0500

    [twin] Implement hinting

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 207868b..ce1a55b 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -34,6 +34,8 @@
  *      Behdad Esfahbod <behdad at behdad.org>
  */
 
+#define _ISOC99_SOURCE /* for round() */
+#include <math.h>
 #include "cairoint.h"
 
 #include <ctype.h>
@@ -253,15 +255,124 @@ twin_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font,
     return CAIRO_STATUS_SUCCESS;
 }
 
-#define SNAPX(p)	_twin_snap (p, info.snap_x, info.n_snap_x)
-#define SNAPY(p)	_twin_snap (p, info.snap_y, info.n_snap_y)
+#define SNAPX(p)	_twin_snap (p, info.snap_x, info.snapped_x, info.n_snap_x)
+#define SNAPY(p)	_twin_snap (p, info.snap_y, info.snapped_y, info.n_snap_y)
+
+#define TWIN_GLYPH_MAX_SNAP_X 4
+#define TWIN_GLYPH_MAX_SNAP_Y 7
+
+#define SNAPXI(p)	(round ((p) * info->x_scale) * info->x_scale_inv)
+#define SNAPYI(p)	(round ((p) * info->y_scale) * info->y_scale_inv)
 
 static double
-_twin_snap (double v, int a, int b)
+_twin_snap (double v, double *snap, double *snapped, int n)
 {
-    return v; /* XXX */
+    int	s;
+
+    for (s = 0; s < n - 1; s++)
+    {
+	if (snap[s] == v)
+	    return snapped[s];
+
+	if (snap[s] <= v && v <= snap[s+1])
+	{
+	    double before = snap[s];
+	    double after = snap[s+1];
+	    double dist = after - before;
+	    double snap_before = snapped[s];
+	    double snap_after = snapped[s+1];
+	    double move_before = snap_before - before;
+	    double move_after = snap_after - after;
+	    double dist_before = v - before;
+	    double dist_after = after - v;
+	    double move = (dist_before * move_after + dist_after * move_before) / dist;
+	    /* XXX optimize the above */
+	    v += move;
+	    break;
+	}
+    }
+    return v;
 }
 
+typedef struct {
+    cairo_bool_t snap;
+
+    double x_scale, x_scale_inv, x_off;
+    double y_scale, y_scale_inv, y_off;
+
+    int n_snap_x;
+    double snap_x[TWIN_GLYPH_MAX_SNAP_X];
+    double snapped_x[TWIN_GLYPH_MAX_SNAP_X];
+    int n_snap_y;
+    double snap_y[TWIN_GLYPH_MAX_SNAP_Y];
+    double snapped_y[TWIN_GLYPH_MAX_SNAP_Y];
+} twin_snap_info_t;
+
+static void
+_twin_compute_snap (cairo_t           *cr,
+		    twin_snap_info_t  *info,
+		    const signed char *b)
+{
+    int			s, n;
+    const signed char	*snap;
+    double x, y;
+
+    x = 1; y = 0;
+    cairo_user_to_device_distance (cr, &x, &y);
+    info->x_scale = sqrt (x*x + y*y);
+    info->x_scale_inv = 1 / info->x_scale;
+
+    x = 0; y = 1;
+    cairo_user_to_device_distance (cr, &x, &y);
+    info->y_scale = sqrt (x*x + y*y);
+    info->y_scale_inv = 1 / info->y_scale;
+
+
+    snap = twin_glyph_snap_x (b);
+    n = twin_glyph_n_snap_x (b);
+    info->n_snap_x = n;
+    assert (n <= TWIN_GLYPH_MAX_SNAP_X);
+    for (s = 0; s < n; s++) {
+	info->snap_x[s] = FX(snap[s]);
+	info->snapped_x[s] = SNAPXI (info->snap_x[s]);
+    }
+
+    snap = twin_glyph_snap_y (b);
+    n = twin_glyph_n_snap_y (b);
+    info->n_snap_y = n;
+    assert (n <= TWIN_GLYPH_MAX_SNAP_Y);
+    for (s = 0; s < n; s++) {
+	info->snap_y[s] = FY(snap[s]);
+	info->snapped_y[s] = SNAPYI (info->snap_y[s]);
+    }
+}
+
+static void
+_twin_compute_pen (cairo_t *cr,
+		   double width,
+		   double *penx, double *peny)
+{
+    double x, y;
+    double scale, inv;
+
+    x = 1; y = 0;
+    cairo_user_to_device_distance (cr, &x, &y);
+    scale = sqrt (x*x + y*y);
+    inv = 1 / scale;
+    *penx = round (width * scale) * inv;
+    if (*penx < inv)
+	*penx = inv;
+
+    x = 0; y = 1;
+    cairo_user_to_device_distance (cr, &x, &y);
+    scale = sqrt (x*x + y*y);
+    inv = 1 / scale;
+    *peny = round (width * scale) * inv;
+    if (*peny < inv)
+	*peny = inv;
+}
+
+
 static cairo_status_t
 twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
 			       unsigned long         glyph,
@@ -270,20 +381,13 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
 {
     double x1, y1, x2, y2, x3, y3;
     twin_face_properties_t *props;
+    twin_snap_info_t info;
     const int8_t *b;
     const int8_t *g;
     int8_t w;
     double gw;
-    double lw;
-    double stretch;
-
-    struct {
-      cairo_bool_t snap;
-      int snap_x;
-      int snap_y;
-      int n_snap_x;
-      int n_snap_y;
-    } info = {FALSE};
+    double weight, stretch;
+    double penx, peny;
 
     cairo_set_tolerance (cr, 0.01);
     cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
@@ -295,18 +399,18 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
 					   &twin_face_properties_key);
 
     /* weight */
-    lw = props->weight * (5. / 64 / TWIN_WEIGHT_NORMAL);
-    cairo_set_line_width (cr, lw);
+    weight = props->weight * (5. / 64 / TWIN_WEIGHT_NORMAL);
 
     /* stretch */
     stretch = 1 + .05 * ((int) props->stretch - (int) TWIN_STRETCH_NORMAL);
     cairo_scale (cr, stretch, 1);
 
     /* lock pen matrix */
+    _twin_compute_pen (cr, weight, &penx, &peny);
     cairo_save (cr);
 
     /* left margin + pen width, pen width */
-    cairo_translate (cr, lw * 1.5, -lw * .5);
+    cairo_translate (cr, penx * 1.5, -peny * .5);
 
     /* slant */
     if (props->slant != CAIRO_FONT_SLANT_NORMAL) {
@@ -328,12 +432,16 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
     /* monospace */
     if (props->monospace) {
 	double monow = FX(24);
-	cairo_scale (cr, (monow+lw) / (gw+lw), 1);
+	cairo_scale (cr, (monow+penx) / (gw+penx), 1);
 	gw = monow;
     }
 
+    info.snap = scaled_font->options.hint_style != CAIRO_HINT_STYLE_NONE;
+    if (info.snap)
+	_twin_compute_snap (cr, &info, b);
+
     /* advance width */
-    metrics->x_advance = gw + lw * 3; /* pen width + margin */
+    metrics->x_advance = gw + penx * 3; /* pen width + margin */
     metrics->x_advance *= stretch;
     if (info.snap)
 	metrics->x_advance = SNAPX (metrics->x_advance);
@@ -394,6 +502,8 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
 	    /* fall through */
 	case 'e':
 	    cairo_restore (cr);
+	    cairo_scale (cr, penx, peny);
+	    cairo_set_line_width (cr, 1);
 	    cairo_stroke (cr);
 	    break;
 	case 'X':
commit 9f9f5317dca6a9988a0a62aaa60393570157af63
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Dec 24 22:29:59 2008 -0500

    [util] Fix pangram

diff --git a/util/cairo-view b/util/cairo-view
index 83d5702..2bbed69 100755
--- a/util/cairo-view
+++ b/util/cairo-view
@@ -10,7 +10,7 @@ import pango
 import gobject
 
 class CairoView(gtk.Window):
-    def __init__(self, family="", slant=0, weight=0, size=18, text="The Quick Brown Fox Jumped Over The Lazy Dog!"):
+    def __init__(self, family="", slant=0, weight=0, size=18, text="The Quick Brown Fox Jumps Over The Lazy Dog!"):
         gtk.Widget.__init__ (self)
 
 	self.family = family
commit 8296bc74c8687a2f52e06174e9dc70d32d1181c8
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Dec 24 18:00:04 2008 -0500

    [twin] Reduce the weight just a bit, such that bold doesn't look as bad

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 425f6fd..207868b 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -295,7 +295,7 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
 					   &twin_face_properties_key);
 
     /* weight */
-    lw = props->weight * (5.5 / 64 / TWIN_WEIGHT_NORMAL);
+    lw = props->weight * (5. / 64 / TWIN_WEIGHT_NORMAL);
     cairo_set_line_width (cr, lw);
 
     /* stretch */
commit b2f89625453e2a15da175ea5b4ca5af6c2201d96
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Dec 24 17:29:21 2008 -0500

    [twin] Adjust baseline

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 8fb1a1d..425f6fd 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -221,9 +221,6 @@ FREE_PROPS:
 #define twin_glyph_snap_y(g)    (twin_glyph_snap_x(g) + twin_glyph_n_snap_x(g))
 #define twin_glyph_draw(g)      (twin_glyph_snap_y(g) + twin_glyph_n_snap_y(g))
 
-#define SNAPI(p)	(p)
-#define SNAPH(p)	(p)
-
 #define FX(g)		((g) / 72.)
 #define FY(g)		((g) / 72.)
 
@@ -233,7 +230,7 @@ twin_scaled_font_init (cairo_scaled_font_t  *scaled_font,
 		       cairo_t              *cr,
 		       cairo_font_extents_t *metrics)
 {
-  metrics->ascent  = FY (52);
+  metrics->ascent  = FY (54);
   metrics->descent = 1 - metrics->ascent;
   return CAIRO_STATUS_SUCCESS;
 }
@@ -308,8 +305,8 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
     /* lock pen matrix */
     cairo_save (cr);
 
-    /* left margin + pen width */
-    cairo_translate (cr, lw * 1.5, 0);
+    /* left margin + pen width, pen width */
+    cairo_translate (cr, lw * 1.5, -lw * .5);
 
     /* slant */
     if (props->slant != CAIRO_FONT_SLANT_NORMAL) {
@@ -339,7 +336,7 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
     metrics->x_advance = gw + lw * 3; /* pen width + margin */
     metrics->x_advance *= stretch;
     if (info.snap)
-	metrics->x_advance = SNAPI (SNAPX (metrics->x_advance));
+	metrics->x_advance = SNAPX (metrics->x_advance);
 
 
     /* glyph shape */
commit f980d017d2360634f391eb1129317446bfe42cc9
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Dec 24 17:00:43 2008 -0500

    [twin] Remove serif setting
    
    I don't think I'm going to implement serif-drawing soon, so, remove the
    infrastructure.  Can always be added back later.

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index f911005..8fb1a1d 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -87,7 +87,6 @@ typedef struct _twin_face_properties {
 
     /* lets have some fun */
     cairo_bool_t monospace;
-    cairo_bool_t serif;
     cairo_bool_t smallcaps;
 } twin_face_properties_t;
 
@@ -127,8 +126,6 @@ parse_field (twin_face_properties_t *props,
 	     const char *s,
 	     int len)
 {
-    cairo_bool_t sans = FALSE, serif = FALSE;
-
 #define MATCH(s1, var, value) \
 	if (field_matches (s1, s, len)) var = value
 
@@ -158,12 +155,6 @@ parse_field (twin_face_properties_t *props,
 
     else MATCH ("mono",       props->monospace, TRUE);
     else MATCH ("monospace",  props->monospace, TRUE);
-
-    else MATCH ("sans",       sans, TRUE);
-    else MATCH ("sans-serif", sans, TRUE);
-    else MATCH ("serif",      serif, TRUE);
-
-    props->serif = serif && !sans;
 }
 
 static void
@@ -197,7 +188,6 @@ twin_set_face_properties_from_toy (cairo_font_face_t *twin_face,
 
     props->stretch  = TWIN_STRETCH_NORMAL;
     props->monospace = FALSE;
-    props->serif = FALSE;
     props->smallcaps = FALSE;
 
     /* fill in props */
@@ -299,6 +289,8 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
     } info = {FALSE};
 
     cairo_set_tolerance (cr, 0.01);
+    cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
+    cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
 
     /* Prepare face */
 
@@ -309,15 +301,6 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
     lw = props->weight * (5.5 / 64 / TWIN_WEIGHT_NORMAL);
     cairo_set_line_width (cr, lw);
 
-    cairo_set_miter_limit (cr, M_SQRT2);
-    cairo_set_line_join (cr, /* props->serif ?
-			     CAIRO_LINE_JOIN_MITER : */
-			     CAIRO_LINE_JOIN_ROUND);
-    cairo_set_line_cap (cr, /* props->serif ?
-			    CAIRO_LINE_CAP_SQUARE : */
-			    CAIRO_LINE_CAP_ROUND);
-
-
     /* stretch */
     stretch = 1 + .05 * ((int) props->stretch - (int) TWIN_STRETCH_NORMAL);
     cairo_scale (cr, stretch, 1);


More information about the cairo-commit mailing list