[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