[Commit] twin ChangeLog, 1.14, 1.15 twin.h, 1.11, 1.12 twin_draw.c, 1.3, 1.4 twin_font.c, 1.10, 1.11 twin_glyphs.c, 1.3, 1.4 twin_matrix.c, 1.2, 1.3 twin_path.c, 1.8, 1.9 twin_spline.c, 1.3, 1.4 twin_trig.c, 1.1, 1.2 twin_x11.c, 1.3, 1.4 twinint.h, 1.9, 1.10 xtwin.c, 1.13, 1.14

Keith Packard commit at keithp.com
Mon Oct 4 00:49:52 PDT 2004


Committed by: keithp

Update of /local/src/CVS/twin
In directory home.keithp.com:/tmp/cvs-serv8272

Modified Files:
	ChangeLog twin.h twin_draw.c twin_font.c twin_glyphs.c 
	twin_matrix.c twin_path.c twin_spline.c twin_trig.c twin_x11.c 
	twinint.h xtwin.c 
Log Message:
2004-10-04  Keith Packard  <keithp at keithp.com>

	* twin.h:
	* twin_draw.c: (twin_composite):
	Fix a clipping bug
	
	* twinint.h:
	* twin_font.c: (_snap), (_twin_g_base), (_twin_pen_size),
	(twin_text_metrics_ucs4), (twin_add_snap), (twin_n_in_spline),
	(twin_spline_fit), (_ucs4_string), (px), (py), (twin_dump_glyphs),
	(twin_path_ucs4), (twin_text_metrics_utf8):
	* twin_glyphs.c:
	Change glyph representation to allow splines and include metrics.

	* twin_matrix.c: (_twin_matrix_expand):
	* twin_path.c: (twin_path_rmove), (twin_path_rdraw):
	Add some new helper functions.
	
	* twin_spline.c:
	Expose _twin_path_scurve for glyphs
	
	* twin_trig.c:
	Increase sin table precision.
	
	* twin_x11.c: (_twin_x11_put_span), (twin_x11_screen_damaged),
	(twin_x11_damage):
	Fix off-by-one error in y position.
	Lock screen while adding expose damage
	
	* xtwin.c: (twin_clock_face), (twin_clock), (main):
	Change clock appearance.  Use corrected glyph metrics


Index: ChangeLog
===================================================================
RCS file: /local/src/CVS/twin/ChangeLog,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- ChangeLog	2 Oct 2004 03:07:26 -0000	1.14
+++ ChangeLog	4 Oct 2004 07:49:49 -0000	1.15
@@ -1,3 +1,35 @@
+2004-10-04  Keith Packard  <keithp at keithp.com>
+
+	* twin.h:
+	* twin_draw.c: (twin_composite):
+	Fix a clipping bug
+	
+	* twinint.h:
+	* twin_font.c: (_snap), (_twin_g_base), (_twin_pen_size),
+	(twin_text_metrics_ucs4), (twin_add_snap), (twin_n_in_spline),
+	(twin_spline_fit), (_ucs4_string), (px), (py), (twin_dump_glyphs),
+	(twin_path_ucs4), (twin_text_metrics_utf8):
+	* twin_glyphs.c:
+	Change glyph representation to allow splines and include metrics.
+
+	* twin_matrix.c: (_twin_matrix_expand):
+	* twin_path.c: (twin_path_rmove), (twin_path_rdraw):
+	Add some new helper functions.
+	
+	* twin_spline.c:
+	Expose _twin_path_scurve for glyphs
+	
+	* twin_trig.c:
+	Increase sin table precision.
+	
+	* twin_x11.c: (_twin_x11_put_span), (twin_x11_screen_damaged),
+	(twin_x11_damage):
+	Fix off-by-one error in y position.
+	Lock screen while adding expose damage
+	
+	* xtwin.c: (twin_clock_face), (twin_clock), (main):
+	Change clock appearance.  Use corrected glyph metrics
+
 2004-10-01  Keith Packard  <keithp at keithp.com>
 
 	* twin.h:

Index: twin.h
===================================================================
RCS file: /local/src/CVS/twin/twin.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- twin.h	2 Oct 2004 03:07:26 -0000	1.11
+++ twin.h	4 Oct 2004 07:49:49 -0000	1.12
@@ -49,16 +49,16 @@
 /*
  * Angles
  */
-typedef int16_t	    twin_angle_t;   /* -512 .. 512 for -180 .. 180 */
+typedef int16_t	    twin_angle_t;   /* -2048 .. 2048 for -180 .. 180 */
 
-#define TWIN_ANGLE_360	    1024
-#define TWIN_ANGLE_180	    512
-#define TWIN_ANGLE_90	    256
-#define TWIN_ANGLE_45	    128
-#define TWIN_ANGLE_22_5	    64
-#define TWIN_ANGLE_11_25    32
+#define TWIN_ANGLE_360	    4096
+#define TWIN_ANGLE_180	    (TWIN_ANGLE_360 >> 1)
+#define TWIN_ANGLE_90	    (TWIN_ANGLE_360 >> 2)
+#define TWIN_ANGLE_45	    (TWIN_ANGLE_360 >> 3)
+#define TWIN_ANGLE_22_5	    (TWIN_ANGLE_360 >> 4)
+#define TWIN_ANGLE_11_25    (TWIN_ANGLE_360 >> 5)
 
-#define twin_degrees_to_angle(d)    ((d) * 512 / 180)
+#define twin_degrees_to_angle(d)    ((twin_angle_t) ((((int32_t) (d)) * TWIN_ANGLE_360 / 360)))
 
 /*
  * A rectangle
@@ -182,6 +182,10 @@
 
 #define twin_int_to_fixed(i)	   ((twin_fixed_t) (i) << 16)
 
+typedef struct _twin_point {
+    twin_fixed_t    x, y;
+} twin_point_t;
+
 /*
  * Place matrices in structures so they can be easily copied
  */
@@ -333,10 +337,16 @@
 void 
 twin_path_move (twin_path_t *path, twin_fixed_t x, twin_fixed_t y);
 
+void 
+twin_path_rmove (twin_path_t *path, twin_fixed_t x, twin_fixed_t y);
+
 void
 twin_path_draw (twin_path_t *path, twin_fixed_t x, twin_fixed_t y);
 
 void
+twin_path_rdraw (twin_path_t *path, twin_fixed_t x, twin_fixed_t y);
+
+void
 twin_path_circle(twin_path_t *path, twin_fixed_t radius);
 
 void

Index: twin_draw.c
===================================================================
RCS file: /local/src/CVS/twin/twin_draw.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- twin_draw.c	30 Sep 2004 17:23:07 -0000	1.3
+++ twin_draw.c	4 Oct 2004 07:49:49 -0000	1.4
@@ -298,8 +298,8 @@
 	    right = dst->width;
 	if (top < 0)
 	    top = 0;
-	if (top > dst->height)
-	    top = dst->height;
+	if (bottom > dst->height)
+	    bottom = dst->height;
 
 	op = comp3[operator][operand_index(src)][operand_index(msk)][dst->format];
 	if (op)

Index: twin_font.c
===================================================================
RCS file: /local/src/CVS/twin/twin_font.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- twin_font.c	2 Oct 2004 03:07:26 -0000	1.10
+++ twin_font.c	4 Oct 2004 07:49:49 -0000	1.11
@@ -34,9 +34,7 @@
 #define DBGMSG(x)
 #endif
 
-#define Scale(f)	(((twin_fixed_t) (f) * path->state.font_size) >> 5)
-#define ScaleX(x)	Scale(x)
-#define ScaleY(y)	Scale(y)
+#define Scale(f)	(((twin_fixed_t) (f) * path->state.font_size) >> 6)
 
 #define Hint(p)		(((p)->state.font_style & TWIN_TEXT_UNHINTED) == 0)
 
@@ -46,18 +44,10 @@
     return ucs4 <= TWIN_FONT_MAX && _twin_glyph_offsets[ucs4] != 0;
 }
 
-static int
-compare_snap (const void *av, const void *bv)
-{
-    const twin_gfixed_t   *a = av;
-    const twin_gfixed_t   *b = bv;
-
-    return (int) (*a - *b);
-}
-
-#define SNAPI(path,p)	(Hint(path) ? (((p) + 0x7fff) & ~0xffff) : (p))
-#define SNAPH(path,p)	(Hint(path) ? (((p) + 0x3fff) & ~0x7fff) : (p))
+#define SNAPI(p)	(((p) + 0x7fff) & ~0xffff)
+#define SNAPH(p)	(((p) + 0x3fff) & ~0x7fff)
 
+#if 0
 static twin_fixed_t
 _snap (twin_path_t *path, twin_gfixed_t g, twin_gfixed_t *snap, int nsnap)
 {
@@ -72,8 +62,8 @@
 	    twin_fixed_t    before = Scale(snap[s]);
 	    twin_fixed_t    after = Scale(snap[s+1]);
 	    twin_fixed_t    dist = after - before;
-	    twin_fixed_t    snap_before = SNAPI(path, before);
-	    twin_fixed_t    snap_after = SNAPI(path, after);
+	    twin_fixed_t    snap_before = SNAPI(before);
+	    twin_fixed_t    snap_after = SNAPI(after);
 	    twin_fixed_t    move_before = snap_before - before;
 	    twin_fixed_t    move_after = snap_after - after;
 	    twin_fixed_t    dist_before = v - before;
@@ -92,22 +82,11 @@
     DBGMSG (("_snap: %d => %9.4f\n", g, F(v)));
     return v;
 }
+#endif
 
 #define SNAPX(p)	_snap (path, p, snap_x, nsnap_x)
 #define SNAPY(p)	_snap (path, p, snap_y, nsnap_y)
 
-static int
-_add_snap (twin_gfixed_t *snaps, int nsnap, twin_fixed_t snap)
-{
-    int s;
-
-    for (s = 0; s < nsnap; s++)
-	if (snaps[s] == snap)
-	    return nsnap;
-    snaps[nsnap++] = snap;
-    return nsnap;
-}
-
 static const twin_gpoint_t *
 _twin_ucs4_base(twin_ucs4_t ucs4)
 {
@@ -116,183 +95,409 @@
     return _twin_glyphs + _twin_glyph_offsets[ucs4];
 }
 
-#define TWIN_FONT_BASELINE  9
+static const signed char *
+_twin_g_base (twin_ucs4_t ucs4)
+{
+    if (ucs4 > TWIN_FONT_MAX) ucs4 = 0;
+
+    return _twin_gtable + _twin_g_offsets[ucs4];
+}
 
 static twin_fixed_t
 _twin_pen_size (twin_path_t *path)
 {
     twin_fixed_t    pen_size;
     
-    pen_size = SNAPH(path, path->state.font_size / 24);
-    if (Hint (path) && pen_size < TWIN_FIXED_HALF)
+    pen_size = path->state.font_size / 24;
+    
+    if (Hint (path))
+    {
+	pen_size = SNAPH(pen_size);
+	if( pen_size < TWIN_FIXED_HALF)
 	pen_size = TWIN_FIXED_HALF;
+    }
     
     if (path->state.font_style & TWIN_TEXT_BOLD)
     {
-	twin_fixed_t	pen_add = SNAPH(path, pen_size >> 1);
-	if (Hint (path) && pen_add == 0) 
-	    pen_add = TWIN_FIXED_HALF;
+	twin_fixed_t	pen_add = pen_size >> 1;
+
+	if (Hint (path))
+	{
+	    pen_add = SNAPH (pen_add);
+	    if (pen_add == 0) 
+		pen_add = TWIN_FIXED_HALF;
+	}
 	pen_size += pen_add;
     }
     return pen_size;
 }
 
+#define Margin(pen_size)    ((pen_size) * 2)
+
 void
 twin_text_metrics_ucs4 (twin_path_t	    *path, 
 			twin_ucs4_t	    ucs4, 
 			twin_text_metrics_t *m)
 {
-    const twin_gpoint_t	*p = _twin_ucs4_base (ucs4);
-    twin_fixed_t	x, y;
-    twin_fixed_t	left, right;
-    twin_fixed_t	top, bottom;
+    const signed char	*g = _twin_g_base (ucs4);
     twin_fixed_t	pen_size = _twin_pen_size (path);
-    twin_fixed_t	baseline = SNAPI(path, Scale(TWIN_FONT_BASELINE));
-    int			i;
-    int			skip_xi;
-    int			skip_yi;
-    int			next_xi;
-    int			next_yi;
+    twin_fixed_t	left = Scale(twin_glyph_left(g));
+    twin_fixed_t	right = Scale (twin_glyph_right(g)) + pen_size * 2;
+    twin_fixed_t	ascent = Scale (twin_glyph_ascent(g)) + pen_size * 2;
+    twin_fixed_t	descent = Scale (twin_glyph_descent(g));
+    twin_fixed_t	font_spacing = path->state.font_size;
+    twin_fixed_t	font_descent = font_spacing / 3;
+    twin_fixed_t	font_ascent = font_spacing - font_descent;
+
+    if (Hint(path))
+    {
+	left = SNAPI(left);
+	right = SNAPI(right);
+	ascent = SNAPI(ascent);
+	descent = SNAPI(descent);
+	font_descent = SNAPI(font_descent);
+	font_ascent = SNAPI(font_ascent);
+    }
+    m->left_side_bearing = left + Margin(pen_size);
+    m->right_side_bearing = right + Margin(pen_size);
+    m->ascent = ascent;
+    m->descent = descent;
+    m->width = m->right_side_bearing + Margin(pen_size);
+    m->font_ascent = font_ascent + Margin(pen_size);
+    m->font_descent = font_ascent + Margin(pen_size);
+}
+
+#include <stdio.h>
+
+#define TWIN_MAX_POINTS	    50
+#define TWIN_MAX_STROKE	    50
+
+typedef enum { twin_gmove, twin_gline, twin_gcurve } twin_gcmd_t;
+
+typedef struct _twin_gop {
+    twin_gcmd_t	    cmd;
+    twin_gpoint_t   p[3];
+} twin_gop_t;
     
-    left = TWIN_FIXED_MAX;
-    top = TWIN_FIXED_MAX;
-    right = TWIN_FIXED_MIN;
-    bottom = TWIN_FIXED_MIN;
-    /*
-     * Locate horizontal and vertical segments
-     */
-    skip_xi = 0;
-    skip_yi = 0;
-    for (i = 1; p[i].y != -64; i++)
+typedef struct _twin_stroke {
+    int		    n;
+    twin_gpoint_t   p[TWIN_MAX_STROKE];
+} twin_stroke_t;
+
+typedef struct _twin_snap {
+    int		    n;
+    twin_gfixed_t   s[TWIN_MAX_POINTS];
+} twin_snap_t;
+
+typedef struct _twin_glyph {
+    twin_ucs4_t	    ucs4;
+    int		    offset;
+    twin_bool_t	    exists;
+    twin_gfixed_t   left, right, top, bottom;
+    int		    n;
+    twin_stroke_t   s[TWIN_MAX_STROKE];
+    int		    nop;
+    twin_gop_t	    op[TWIN_MAX_STROKE];
+    twin_snap_t	    snap_x;
+    twin_snap_t	    snap_y;
+} twin_glyph_t;
+
+static twin_glyph_t glyphs[0x80];
+
+static void
+twin_add_snap (twin_snap_t *snap, twin_gfixed_t v)
+{
+    int	    n;
+
+    for (n = 0; n < snap->n; n++)
     {
-	if (p[i].x == -64)
-	    continue;
-	x = Scale (p[i].x);
-	y = Scale (p[i].y);
-	next_xi = skip_xi;
-	next_yi = skip_yi;
-	if (Hint (path) && p[i+1].y != -64 && p[i+1].x != -64)
+	if (snap->s[n] == v)
+	    return;
+	if (snap->s[n] > v)
+	    break;
+    }
+    memmove (&snap->s[n+1], &snap->s[n], snap->n - n);
+    snap->s[n] = v;
+    snap->n++;
+}
+
+static int
+twin_n_in_spline (twin_gpoint_t *p, int n)
+{
+    return 0;
+}
+
+static void
+twin_spline_fit (twin_gpoint_t *p, int n, twin_gpoint_t *c1, twin_gpoint_t *c2)
+{
+}
+
+static char *
+_ucs4_string (twin_ucs4_t ucs4)
+{
+    static char	buf[10];
+    if (ucs4 < ' ' || ucs4 > '~')
+    {
+	if (!ucs4)
+	    return "\\0";
+	sprintf (buf, "\\0%o", ucs4);
+	return buf;
+    }
+    sprintf (buf, "%c", ucs4);
+    return buf;
+}
+
+static twin_gfixed_t
+px (const twin_gpoint_t *p, int i)
+{
+    return p[i].x << 1;
+}
+
+static twin_gfixed_t
+py (const twin_gpoint_t *p, int i)
+{
+    return p[i].y << 1;
+}
+
+static void
+twin_dump_glyphs (void)
+{
+    twin_ucs4_t	ucs4;
+    int		offset = 0;
+    int		i, j;
+    twin_gop_t	*gop;
+
+    for (ucs4 = 0; ucs4 < 0x80; ucs4++)
+    {
+	const twin_gpoint_t	*p = _twin_ucs4_base (ucs4);
+	twin_glyph_t		*g = &glyphs[ucs4];
+	twin_stroke_t		*s;
+	twin_gfixed_t		origin;
+	twin_gfixed_t		left, right, top, bottom;
+	twin_gfixed_t		baseline;
+	twin_gfixed_t		x, y;
+	twin_bool_t		move;
+	
+	g->ucs4 = ucs4;
+	g->n = 0;
+
+	if (ucs4 && p == _twin_glyphs) continue;
+	
+	if (p[1].y == -64)
 	{
-	    if (p[i].x == p[i+1].x)
+	    origin = 0;
+	    left = 0;
+	    right = 4;
+	    top = 18;
+	    bottom = 18;
+	    baseline = 18;
+	}
+	else
+	{
+	    origin = 64;
+	    left = 64;
+	    right = -64;
+	    top = 64;
+	    bottom = -64;
+	    baseline = 18;
+	    for (i = 1, move = TWIN_TRUE; p[i].y != -64; i++)
 	    {
-		x = SNAPI(path, x);
-		skip_xi = i + 2;
+		if (p[i].x == -64) { move = TWIN_TRUE; continue; }
+		if (py(p,i) <= baseline && px(p,i) < origin) origin = px(p,i);
+		if (px(p,i) < left) left = px(p,i);
+		if (px(p,i) > right) right = px(p,i);
+		if (py(p,i) < top) top = py(p,i);
+		if (py(p,i) > bottom) bottom = py(p,i); 
+		move = TWIN_FALSE;
 	    }
-	    if (p[i].y == p[i+1].y)
+	}
+	left -= origin;
+	right -= origin;;
+	bottom -= baseline;
+	top -= baseline;
+
+	/*
+	 * Convert from hershey format to internal format
+	 */
+	for (i = 1, move = TWIN_TRUE; p[i].y != -64; i++)
+	{
+	    if (p[i].x == -64) { move = TWIN_TRUE; continue; }
+
+	    x = px(p,i) - origin;
+	    y = py(p,i) - baseline;
+	    if (move)
+		if (g->s[g->n].n)
+		    ++g->n;
+	    s = &g->s[g->n];
+	    s->p[s->n].x = x;
+	    s->p[s->n].y = y;
+	    s->n++;
+	    
+	    move = TWIN_FALSE;
+	}
+    	if (g->s[g->n].n)
+    	    ++g->n;
+
+	g->left = left;
+	g->right = right;
+	g->top = top;
+	g->bottom = bottom;
+
+	/*
+	 * Find snap points
+	 */
+	twin_add_snap (&g->snap_x, 0);	    /* origin */
+	twin_add_snap (&g->snap_x, right);  /* right */
+	
+	twin_add_snap (&g->snap_y, 0);	    /* baseline */
+	twin_add_snap (&g->snap_y, -15);    /* x height */
+	twin_add_snap (&g->snap_y, -21);    /* cap height */
+	
+	for (i = 0; i < g->n; i++)
+	{
+	    s = &g->s[i];
+	    for (j = 0; j < s->n - 1; j++)
 	    {
-		y = SNAPI(path, y);
-		skip_yi = i + 2;
+		if (s->p[j].x == s->p[j+1].x)
+		    twin_add_snap (&g->snap_x, s->p[j].x);
+		if (s->p[j].y == s->p[j+1].y)
+		    twin_add_snap (&g->snap_y, s->p[j].y);
 	    }
 	}
-	if (i >= next_xi)
+
+	/*
+	 * Now convert to gops and try to locate splines
+	 */
+	
+	gop = &g->op[0];
+	for (i = 0; i < g->n; i++)
 	{
-	    if (x < left)
-		left = x;
-	    if (x > right)
-		right = x;
+	    s = &g->s[i];
+	    gop->cmd = twin_gmove;
+	    gop->p[0] = s->p[0];
+	    gop++;
+	    for (j = 0; j < s->n - 1;)
+	    {
+		int ns = twin_n_in_spline (s->p + j, s->n - j);
+
+		if (ns)
+		{
+		    twin_spline_fit (s->p + j, ns,
+				     &gop->p[0], &gop->p[1]);
+		    gop->cmd = twin_gcurve;
+		    gop->p[2] = s->p[j + ns - 1];
+		    gop++;
+		    j += ns;
+		}
+		else
+		{
+		    gop->cmd = twin_gline;
+		    gop->p[0] = s->p[j+1];
+		    gop++;
+		    j++;
+		}
+	    }
 	}
-	if (i >= next_yi)
+	g->nop = gop - &g->op[0];
+	g->exists = TWIN_TRUE;
+    }
+
+    printf ("const signed char _twin_gtable[] = {\n");
+    for (ucs4 = 0; ucs4 < 0x80; ucs4++)
+    {
+	twin_glyph_t		*g = &glyphs[ucs4];
+	
+	if (!g->exists) continue;
+	
+	g->offset = offset;
+
+	printf ("/* 0x%x '%s' */\n", g->ucs4, _ucs4_string (g->ucs4));
+	printf ("    %d, %d, %d, %d, %d, %d,\n",
+		g->left, g->right, -g->top, g->bottom, g->snap_x.n, g->snap_y.n);
+
+	offset += 6;
+
+	printf ("   ");
+	for (i = 0; i < g->snap_x.n; i++)
+	    printf (" %d,", g->snap_x.s[i]);
+	printf (" /* snap_x */\n");
+
+	offset += g->snap_x.n;
+	
+	printf ("   ");
+	for (i = 0; i < g->snap_y.n; i++)
+	    printf (" %d,", g->snap_y.s[i]);
+	printf (" /* snap_y */\n");
+	
+	offset += g->snap_y.n;
+
+#define CO(n)	gop->p[n].x, gop->p[n].y
+	for (i = 0; i < g->nop; i++)
 	{
-	    if (y < top)
-		top = y;
-	    if (y > bottom)
-		bottom = y;
+	    gop = &g->op[i];
+	    switch (gop->cmd) {
+	    case twin_gmove:
+		printf ("    'm', %d, %d,\n", CO(0));
+		offset += 3;
+		break;
+	    case twin_gline:
+		printf ("    'l', %d, %d,\n", CO(0));
+		offset += 3;
+		break;
+	    case twin_gcurve:
+		printf ("    'c', %d, %d, %d, %d, %d, %d,\n",
+			CO(0), CO(1), CO(2));
+		offset += 7;
+		break;
+	    }
 	}
+	printf ("    'e',\n");
+	offset++;
     }
-    
-    left -= pen_size * 2;
-    right += pen_size * 2;
-
-    if (i == 1)
+    printf ("};\n\n");
+    printf ("const uint16_t _twin_g_offsets[] = {");
+    for (ucs4 = 0; ucs4 < 0x80; ucs4++)
     {
-	left = Scale(p[0].x);
-	top = bottom = baseline;
-	right = Scale(p[0].y);
+	twin_glyph_t		*g = &glyphs[ucs4];
+	
+	if ((ucs4 & 7) == 0)
+	    printf ("\n    ");
+	else
+	    printf (" ");
+	printf ("%4d,", g->offset);
     }
-    m->left_side_bearing = SNAPI(path, -left);
-    m->right_side_bearing = SNAPI(path,right);
-    m->width = m->left_side_bearing + m->right_side_bearing;
-    m->ascent = baseline - SNAPI(path, top);
-    m->descent = SNAPI(path, bottom) - baseline;
-    m->font_descent = SNAPI(path, path->state.font_size / 3);
-    m->font_ascent = SNAPI(path,path->state.font_size) - m->font_descent;
+    printf ("\n};\n");
+    fflush (stdout);
+    exit (0);
 }
 
 void
 twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
 {
-    const twin_gpoint_t	*p = _twin_ucs4_base (ucs4);
-    int			i;
+    const signed char	*b = _twin_g_base (ucs4);
+    const signed char	*g = twin_glyph_draw(b);
     twin_spoint_t	origin;
-    twin_fixed_t	xc, yc;
-    twin_sfixed_t	sx, sy;
+    twin_fixed_t	x1, y1, x2, y2, x3, y3;
+    twin_fixed_t	xo, yo;
     twin_path_t		*stroke;
     twin_path_t		*pen;
-    twin_fixed_t	w;
-    twin_fixed_t	x, y;
-    twin_fixed_t	pen_size;
+    twin_fixed_t	pen_size = _twin_pen_size (path);
     twin_matrix_t	pen_matrix;
-    twin_fixed_t	pen_adjust;
-    twin_gfixed_t    	snap_x[TWIN_GLYPH_MAX_POINTS];
-    twin_gfixed_t    	snap_y[TWIN_GLYPH_MAX_POINTS];
     twin_text_metrics_t	metrics;
-    int			nsnap_x = 0, nsnap_y = 0;
     
+    if (0)
+    {
+	static int been_here = 0;
+	if (!been_here) { been_here = 1; twin_dump_glyphs (); }
+    }
+
     twin_text_metrics_ucs4 (path, ucs4, &metrics);
     
     origin = _twin_path_current_spoint (path);
     
-    if (Hint (path))
-    {
-	nsnap_x = 0;
-	nsnap_y = 0;
-    
-	/* snap left and right boundaries */
-	
-	nsnap_x = _add_snap (snap_x, nsnap_x, p[0].x);
-	nsnap_x = _add_snap (snap_x, nsnap_x, p[0].y);
-	
-	/* snap baseline, x height and cap height  */
-	nsnap_y = _add_snap (snap_y, nsnap_y, 9);
-	nsnap_y = _add_snap (snap_y, nsnap_y, -5);
-	nsnap_y = _add_snap (snap_y, nsnap_y, -12);
-	
-	/*
-	 * Locate horizontal and vertical segments
-	 */
-	for (i = 1; p[i].y != -64 && p[i+1].y != -64; i++)
-	{
-	    if (p[i].x == -64 || p[i+1].x == -64)
-		continue;
-	    if (p[i].x == p[i+1].x)
-		nsnap_x = _add_snap (snap_x, nsnap_x, p[i].x);
-	    if (p[i].y == p[i+1].y)
-		nsnap_y = _add_snap (snap_y, nsnap_y, p[i].y);
-	}
-    
-	qsort (snap_x, nsnap_x, sizeof (twin_gfixed_t), compare_snap);
-	qsort (snap_y, nsnap_y, sizeof (twin_gfixed_t), compare_snap);
-    
-	DBGMSG (("snap_x:"));
-	for (i = 0; i < nsnap_x; i++)
-	    DBGMSG ((" %d", snap_x[i])); 
-	DBGMSG (("\n"));
-	
-	DBGMSG (("snap_y:"));
-	for (i = 0; i < nsnap_y; i++)
-	    DBGMSG ((" %d", snap_y[i])); 
-	DBGMSG (("\n"));
-    }
-
     stroke = twin_path_create ();
-    twin_path_set_matrix (stroke, twin_path_current_matrix (path));
     
-    pen_size = _twin_pen_size (path);
-
-    if (Hint (path))
-	pen_adjust = pen_size & TWIN_FIXED_HALF;
-    else
-	pen_adjust = 0;
+    twin_path_set_matrix (stroke, twin_path_current_matrix (path));
     
     pen = twin_path_create ();
     pen_matrix = twin_path_current_matrix (path);
@@ -303,35 +508,55 @@
 
     twin_path_circle (pen, pen_size);
 
-    xc = metrics.left_side_bearing + pen_adjust;
-    yc = SNAPY(TWIN_FONT_BASELINE) + pen_adjust;
+#define PX(_x,_y)   (origin.x + _twin_matrix_dx (&path->state.matrix, _x, _y))
+#define PY(_x,_y)   (origin.y + _twin_matrix_dy (&path->state.matrix, _x, _y))
     
-    for (i = 1; p[i].y != -64; i++)
-	if (p[i].x == -64)
-	    twin_path_close (stroke);
-	else
-	{
-	    x = xc + SNAPX(p[i].x);
-	    y = yc + SNAPY(p[i].y);
-
+    xo = pen_size * 3;
+    yo = -pen_size;
+    
+    for (;;) {
+	switch (*g++) {
+	case 'm':
+	    x1 = Scale (*g++) + xo;
+	    y1 = Scale (*g++) + yo;
 	    if (path->state.font_style & TWIN_TEXT_OBLIQUE)
-		x -= y / 4;
-	    sx = origin.x + _twin_matrix_dx (&path->state.matrix, x, y);
-	    sy = origin.y + _twin_matrix_dy (&path->state.matrix, x, y);
-	    DBGMSG(("x: %9.4f, y: %9.4f -> sx: %9.4f, sy: %9.4f\n",
-		    F(x), F(y), S(sx), S(sy)));
-	    _twin_path_sdraw (stroke, sx, sy);
+		x1 -= y1 >> 2;
+	    _twin_path_smove (stroke, PX(x1,y1), PY(x1,y1));
+	    continue;
+	case 'l':
+	    x1 = Scale (*g++) + xo;
+	    y1 = Scale (*g++) + yo;
+	    if (path->state.font_style & TWIN_TEXT_OBLIQUE)
+		x1 -= y1 >> 2;
+	    _twin_path_sdraw (stroke, PX(x1,y1), PY(x1,y1));
+	    continue;
+	case 'c':
+	    x1 = Scale (*g++) + xo;
+	    y1 = Scale (*g++) + yo;
+	    x2 = Scale (*g++) + xo;
+	    y2 = Scale (*g++) + yo;
+	    x3 = Scale (*g++) + xo;
+	    y3 = Scale (*g++) + yo;
+	    if (path->state.font_style & TWIN_TEXT_OBLIQUE)
+	    {
+		x1 -= y1 >> 2;
+		x2 -= y2 >> 2;
+		x3 -= y3 >> 2;
+	    }
+	    _twin_path_scurve (stroke, PX(x1,y1), PY(x1,y1),
+			       PX(x2,y2), PY(x2,y2), PX(x3,y3), PY(x3,y3));
+	    continue;
+	case 'e':
+	    break;
 	}
+	break;
+    }
 
     twin_path_convolve (path, stroke, pen);
     twin_path_destroy (stroke);
     twin_path_destroy (pen);
     
-    w = metrics.width;
-
-    _twin_path_smove (path, 
-		      origin.x + _twin_matrix_dx (&path->state.matrix, w, 0),
-		      origin.y + _twin_matrix_dy (&path->state.matrix, w, 0));
+    _twin_path_smove (path, PX(metrics.width, 0), PY(metrics.width,0));
 }
 
 twin_fixed_t
@@ -454,20 +679,23 @@
     {
 	twin_text_metrics_ucs4 (path, ucs4, &c);
 	if (first)
+	{
 	    *m = c;
+	    first = TWIN_FALSE;
+	}
 	else
 	{
 	    c.left_side_bearing += w;
 	    c.right_side_bearing += w;
 	    c.width += w;
 
-	    if (c.left_side_bearing > m->left_side_bearing)
+	    if (c.left_side_bearing < m->left_side_bearing)
 		m->left_side_bearing = c.left_side_bearing;
 	    if (c.right_side_bearing > m->right_side_bearing)
 		m->right_side_bearing = c.right_side_bearing;
 	    if (c.width > m->width)
 		m->width = c.width;
-	    if (c.ascent < m->ascent)
+	    if (c.ascent > m->ascent)
 		m->ascent = c.ascent;
 	    if (c.descent > m->descent)
 		m->descent = c.descent;

Index: twin_glyphs.c
===================================================================
RCS file: /local/src/CVS/twin/twin_glyphs.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- twin_glyphs.c	25 Sep 2004 06:41:19 -0000	1.3
+++ twin_glyphs.c	4 Oct 2004 07:49:49 -0000	1.4
@@ -446,3 +446,1567 @@
 /* 0x78 */
     1233, 1240, 1251, 1261, 1274, 1278, 1291,    0,
 };
+
+const signed char _twin_gtable[] = {
+/* 0x0 '\0' */
+    0, 24, 42, 0, 2, 4,
+    0, 24, /* snap_x */
+    -42, -21, -15, 0, /* snap_y */
+    'm', 0, -2,
+    'l', 0, -42,
[...1536 lines suppressed...]
+};
+
+const uint16_t _twin_g_offsets[] = {
+       0,    0,    0,    0,    0,    0,    0,    0,
+       0,    0,    0,    0,    0,    0,    0,    0,
+       0,    0,    0,    0,    0,    0,    0,    0,
+       0,    0,    0,    0,    0,    0,    0,    0,
+      28,   40,   74,   98,  136,  223,  328,  445,
+     478,  520,  562,  593,  619,  655,  674,  701,
+     718,  782,  806,  863,  922,  951, 1016, 1099,
+    1124, 1226, 1309, 1351, 1402, 1423, 1449, 1470,
+    1541, 1711, 1742, 1819, 1886, 1941, 1979, 2011,
+    2088, 2119, 2136, 2178, 2208, 2232, 2268, 2298,
+    2374, 2424, 2506, 2562, 2635, 2661, 2703, 2727,
+    2763, 2787, 2815, 2846, 2871, 2889, 2914, 2938,
+    2956, 2989, 3050, 3111, 3166, 3227, 3292, 3328,
+    3405, 3445, 3479, 3523, 3553, 3570, 3632, 3672,
+    3736, 3797, 3858, 3892, 3956, 3991, 4030, 4054,
+    4090, 4114, 4151, 4182, 4230, 4247, 4295,    0,
+};

Index: twin_matrix.c
===================================================================
RCS file: /local/src/CVS/twin/twin_matrix.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- twin_matrix.c	28 Sep 2004 05:42:36 -0000	1.2
+++ twin_matrix.c	4 Oct 2004 07:49:49 -0000	1.3
@@ -119,6 +119,21 @@
     return det;
 }
 
+twin_point_t
+_twin_matrix_expand (twin_matrix_t *matrix)
+{
+    twin_fixed_t    a = matrix->m[0][0];
+    twin_fixed_t    d = matrix->m[1][1];
+    twin_fixed_t    aa = twin_fixed_mul (a,a);
+    twin_fixed_t    dd = twin_fixed_mul (d,d);
+    twin_point_t    expand;
+
+    expand.x = twin_fixed_sqrt (aa + dd);
+    expand.y = twin_fixed_div (_twin_matrix_determinant (matrix),
+			       expand.x);
+    return expand;
+}
+
 void
 twin_matrix_rotate (twin_matrix_t *m, twin_angle_t a)
 {

Index: twin_path.c
===================================================================
RCS file: /local/src/CVS/twin/twin_path.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- twin_path.c	2 Oct 2004 03:07:26 -0000	1.8
+++ twin_path.c	4 Oct 2004 07:49:49 -0000	1.9
@@ -115,6 +115,17 @@
 }
 
 void
+twin_path_rmove (twin_path_t *path, twin_fixed_t dx, twin_fixed_t dy)
+{
+    twin_spoint_t   here = _twin_path_current_spoint (path);
+    _twin_path_smove (path, 
+		      here.x + 
+		      _twin_matrix_dx (&path->state.matrix, dx, dy),
+		      here.y + 
+		      _twin_matrix_dy (&path->state.matrix, dx, dy));
+}
+
+void
 twin_path_draw (twin_path_t *path, twin_fixed_t x, twin_fixed_t y)
 {
     _twin_path_sdraw (path, 
@@ -123,6 +134,17 @@
 }
 
 void
+twin_path_rdraw (twin_path_t *path, twin_fixed_t dx, twin_fixed_t dy)
+{
+    twin_spoint_t   here = _twin_path_current_spoint (path);
+    _twin_path_sdraw (path, 
+		      here.x +
+		      _twin_matrix_dx (&path->state.matrix, dx, dy),
+		      here.y + 
+		      _twin_matrix_dy (&path->state.matrix, dx, dy));
+}
+
+void
 twin_path_close (twin_path_t *path)
 {
     switch (_twin_current_subpath_len(path)) {

Index: twin_spline.c
===================================================================
RCS file: /local/src/CVS/twin/twin_spline.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- twin_spline.c	27 Sep 2004 21:28:31 -0000	1.3
+++ twin_spline.c	4 Oct 2004 07:49:49 -0000	1.4
@@ -102,7 +102,7 @@
     }
 }
 
-static void
+void
 _twin_path_scurve (twin_path_t	    *path,
 		   twin_sfixed_t    x1, twin_sfixed_t y1,
 		   twin_sfixed_t    x2, twin_sfixed_t y2,

Index: twin_trig.c
===================================================================
RCS file: /local/src/CVS/twin/twin_trig.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- twin_trig.c	27 Sep 2004 21:28:31 -0000	1.1
+++ twin_trig.c	4 Oct 2004 07:49:49 -0000	1.2
@@ -24,45 +24,149 @@
 
 #include "twinint.h"
 
-#define TWIN_LOG2_SIN	8
+#define TWIN_LOG2_SIN	10
+
+/*
+ * construction:
+  int s = 10; for (int i = 0; i < (1 << s); i++) { 
+ 	if (i % 8 == 0) printf ("\n   ");
+ 	printf (" 0x%04x,", floor (sin(pi/2 * i / (1 << s)) * 2**16 + 0.5));
+  }
+ */
 
 static const uint16_t _twin_sin_table[1 << TWIN_LOG2_SIN] = {
-    0x0000, 0x0192, 0x0324, 0x04b6, 0x0648, 0x07da, 0x096c, 0x0afe,
-    0x0c90, 0x0e21, 0x0fb3, 0x1144, 0x12d5, 0x1466, 0x15f7, 0x1787,
-    0x1918, 0x1aa8, 0x1c38, 0x1dc7, 0x1f56, 0x20e5, 0x2274, 0x2402,
-    0x2590, 0x271e, 0x28ab, 0x2a38, 0x2bc4, 0x2d50, 0x2edc, 0x3067,
-    0x31f1, 0x337c, 0x3505, 0x368e, 0x3817, 0x399f, 0x3b27, 0x3cae,
-    0x3e34, 0x3fba, 0x413f, 0x42c3, 0x4447, 0x45cb, 0x474d, 0x48cf,
-    0x4a50, 0x4bd1, 0x4d50, 0x4ecf, 0x504d, 0x51cb, 0x5348, 0x54c3,
-    0x563e, 0x57b9, 0x5932, 0x5aaa, 0x5c22, 0x5d99, 0x5f0f, 0x6084,
-    0x61f8, 0x636b, 0x64dd, 0x664e, 0x67be, 0x692d, 0x6a9b, 0x6c08,
-    0x6d74, 0x6edf, 0x7049, 0x71b2, 0x731a, 0x7480, 0x75e6, 0x774a,
-    0x78ad, 0x7a10, 0x7b70, 0x7cd0, 0x7e2f, 0x7f8c, 0x80e8, 0x8243,
-    0x839c, 0x84f5, 0x864c, 0x87a1, 0x88f6, 0x8a49, 0x8b9a, 0x8ceb,
-    0x8e3a, 0x8f88, 0x90d4, 0x921f, 0x9368, 0x94b0, 0x95f7, 0x973c,
-    0x9880, 0x99c2, 0x9b03, 0x9c42, 0x9d80, 0x9ebc, 0x9ff7, 0xa130,
-    0xa268, 0xa39e, 0xa4d2, 0xa605, 0xa736, 0xa866, 0xa994, 0xaac1,
-    0xabeb, 0xad14, 0xae3c, 0xaf62, 0xb086, 0xb1a8, 0xb2c9, 0xb3e8,
-    0xb505, 0xb620, 0xb73a, 0xb852, 0xb968, 0xba7d, 0xbb8f, 0xbca0,
-    0xbdaf, 0xbebc, 0xbfc7, 0xc0d1, 0xc1d8, 0xc2de, 0xc3e2, 0xc4e4,
-    0xc5e4, 0xc6e2, 0xc7de, 0xc8d9, 0xc9d1, 0xcac7, 0xcbbc, 0xccae,
-    0xcd9f, 0xce8e, 0xcf7a, 0xd065, 0xd14d, 0xd234, 0xd318, 0xd3fb,
-    0xd4db, 0xd5ba, 0xd696, 0xd770, 0xd848, 0xd91e, 0xd9f2, 0xdac4,
-    0xdb94, 0xdc62, 0xdd2d, 0xddf7, 0xdebe, 0xdf83, 0xe046, 0xe107,
-    0xe1c6, 0xe282, 0xe33c, 0xe3f4, 0xe4aa, 0xe55e, 0xe610, 0xe6bf,
-    0xe76c, 0xe817, 0xe8bf, 0xe966, 0xea0a, 0xeaab, 0xeb4b, 0xebe8,
-    0xec83, 0xed1c, 0xedb3, 0xee47, 0xeed9, 0xef68, 0xeff5, 0xf080,
-    0xf109, 0xf18f, 0xf213, 0xf295, 0xf314, 0xf391, 0xf40c, 0xf484,
-    0xf4fa, 0xf56e, 0xf5df, 0xf64e, 0xf6ba, 0xf724, 0xf78c, 0xf7f1,
-    0xf854, 0xf8b4, 0xf913, 0xf96e, 0xf9c8, 0xfa1f, 0xfa73, 0xfac5,
-    0xfb15, 0xfb62, 0xfbad, 0xfbf5, 0xfc3b, 0xfc7f, 0xfcc0, 0xfcfe,
-    0xfd3b, 0xfd74, 0xfdac, 0xfde1, 0xfe13, 0xfe43, 0xfe71, 0xfe9c,
-    0xfec4, 0xfeeb, 0xff0e, 0xff30, 0xff4e, 0xff6b, 0xff85, 0xff9c,
-    0xffb1, 0xffc4, 0xffd4, 0xffe1, 0xffec, 0xfff5, 0xfffb, 0xffff,
+    0x0000, 0x0065, 0x00c9, 0x012e, 0x0192, 0x01f7, 0x025b, 0x02c0,
+    0x0324, 0x0389, 0x03ed, 0x0452, 0x04b6, 0x051b, 0x057f, 0x05e4,
+    0x0648, 0x06ad, 0x0711, 0x0776, 0x07da, 0x083f, 0x08a3, 0x0908,
+    0x096c, 0x09d1, 0x0a35, 0x0a9a, 0x0afe, 0x0b62, 0x0bc7, 0x0c2b,
+    0x0c90, 0x0cf4, 0x0d59, 0x0dbd, 0x0e21, 0x0e86, 0x0eea, 0x0f4e,
+    0x0fb3, 0x1017, 0x107b, 0x10e0, 0x1144, 0x11a8, 0x120d, 0x1271,
+    0x12d5, 0x1339, 0x139e, 0x1402, 0x1466, 0x14ca, 0x152e, 0x1593,
+    0x15f7, 0x165b, 0x16bf, 0x1723, 0x1787, 0x17eb, 0x1850, 0x18b4,
+    0x1918, 0x197c, 0x19e0, 0x1a44, 0x1aa8, 0x1b0c, 0x1b70, 0x1bd4,
+    0x1c38, 0x1c9b, 0x1cff, 0x1d63, 0x1dc7, 0x1e2b, 0x1e8f, 0x1ef3,
+    0x1f56, 0x1fba, 0x201e, 0x2082, 0x20e5, 0x2149, 0x21ad, 0x2210,
+    0x2274, 0x22d7, 0x233b, 0x239f, 0x2402, 0x2466, 0x24c9, 0x252d,
+    0x2590, 0x25f4, 0x2657, 0x26ba, 0x271e, 0x2781, 0x27e4, 0x2848,
+    0x28ab, 0x290e, 0x2971, 0x29d5, 0x2a38, 0x2a9b, 0x2afe, 0x2b61,
+    0x2bc4, 0x2c27, 0x2c8a, 0x2ced, 0x2d50, 0x2db3, 0x2e16, 0x2e79,
+    0x2edc, 0x2f3f, 0x2fa1, 0x3004, 0x3067, 0x30ca, 0x312c, 0x318f,
+    0x31f1, 0x3254, 0x32b7, 0x3319, 0x337c, 0x33de, 0x3440, 0x34a3,
+    0x3505, 0x3568, 0x35ca, 0x362c, 0x368e, 0x36f1, 0x3753, 0x37b5,
+    0x3817, 0x3879, 0x38db, 0x393d, 0x399f, 0x3a01, 0x3a63, 0x3ac5,
+    0x3b27, 0x3b88, 0x3bea, 0x3c4c, 0x3cae, 0x3d0f, 0x3d71, 0x3dd2,
+    0x3e34, 0x3e95, 0x3ef7, 0x3f58, 0x3fba, 0x401b, 0x407c, 0x40de,
+    0x413f, 0x41a0, 0x4201, 0x4262, 0x42c3, 0x4324, 0x4385, 0x43e6,
+    0x4447, 0x44a8, 0x4509, 0x456a, 0x45cb, 0x462b, 0x468c, 0x46ec,
+    0x474d, 0x47ae, 0x480e, 0x486f, 0x48cf, 0x492f, 0x4990, 0x49f0,
+    0x4a50, 0x4ab0, 0x4b10, 0x4b71, 0x4bd1, 0x4c31, 0x4c90, 0x4cf0,
+    0x4d50, 0x4db0, 0x4e10, 0x4e70, 0x4ecf, 0x4f2f, 0x4f8e, 0x4fee,
+    0x504d, 0x50ad, 0x510c, 0x516c, 0x51cb, 0x522a, 0x5289, 0x52e8,
+    0x5348, 0x53a7, 0x5406, 0x5464, 0x54c3, 0x5522, 0x5581, 0x55e0,
+    0x563e, 0x569d, 0x56fc, 0x575a, 0x57b9, 0x5817, 0x5875, 0x58d4,
+    0x5932, 0x5990, 0x59ee, 0x5a4c, 0x5aaa, 0x5b08, 0x5b66, 0x5bc4,
+    0x5c22, 0x5c80, 0x5cde, 0x5d3b, 0x5d99, 0x5df6, 0x5e54, 0x5eb1,
+    0x5f0f, 0x5f6c, 0x5fc9, 0x6026, 0x6084, 0x60e1, 0x613e, 0x619b,
+    0x61f8, 0x6254, 0x62b1, 0x630e, 0x636b, 0x63c7, 0x6424, 0x6480,
+    0x64dd, 0x6539, 0x6595, 0x65f2, 0x664e, 0x66aa, 0x6706, 0x6762,
+    0x67be, 0x681a, 0x6876, 0x68d1, 0x692d, 0x6989, 0x69e4, 0x6a40,
+    0x6a9b, 0x6af6, 0x6b52, 0x6bad, 0x6c08, 0x6c63, 0x6cbe, 0x6d19,
+    0x6d74, 0x6dcf, 0x6e2a, 0x6e85, 0x6edf, 0x6f3a, 0x6f94, 0x6fef,
+    0x7049, 0x70a3, 0x70fe, 0x7158, 0x71b2, 0x720c, 0x7266, 0x72c0,
+    0x731a, 0x7373, 0x73cd, 0x7427, 0x7480, 0x74da, 0x7533, 0x758d,
+    0x75e6, 0x763f, 0x7698, 0x76f1, 0x774a, 0x77a3, 0x77fc, 0x7855,
+    0x78ad, 0x7906, 0x795f, 0x79b7, 0x7a10, 0x7a68, 0x7ac0, 0x7b18,
+    0x7b70, 0x7bc8, 0x7c20, 0x7c78, 0x7cd0, 0x7d28, 0x7d7f, 0x7dd7,
+    0x7e2f, 0x7e86, 0x7edd, 0x7f35, 0x7f8c, 0x7fe3, 0x803a, 0x8091,
+    0x80e8, 0x813f, 0x8195, 0x81ec, 0x8243, 0x8299, 0x82f0, 0x8346,
+    0x839c, 0x83f2, 0x8449, 0x849f, 0x84f5, 0x854a, 0x85a0, 0x85f6,
+    0x864c, 0x86a1, 0x86f7, 0x874c, 0x87a1, 0x87f6, 0x884c, 0x88a1,
+    0x88f6, 0x894a, 0x899f, 0x89f4, 0x8a49, 0x8a9d, 0x8af2, 0x8b46,
+    0x8b9a, 0x8bef, 0x8c43, 0x8c97, 0x8ceb, 0x8d3f, 0x8d93, 0x8de6,
+    0x8e3a, 0x8e8d, 0x8ee1, 0x8f34, 0x8f88, 0x8fdb, 0x902e, 0x9081,
+    0x90d4, 0x9127, 0x9179, 0x91cc, 0x921f, 0x9271, 0x92c4, 0x9316,
+    0x9368, 0x93ba, 0x940c, 0x945e, 0x94b0, 0x9502, 0x9554, 0x95a5,
+    0x95f7, 0x9648, 0x969a, 0x96eb, 0x973c, 0x978d, 0x97de, 0x982f,
+    0x9880, 0x98d0, 0x9921, 0x9972, 0x99c2, 0x9a12, 0x9a63, 0x9ab3,
+    0x9b03, 0x9b53, 0x9ba3, 0x9bf2, 0x9c42, 0x9c92, 0x9ce1, 0x9d31,
+    0x9d80, 0x9dcf, 0x9e1e, 0x9e6d, 0x9ebc, 0x9f0b, 0x9f5a, 0x9fa8,
+    0x9ff7, 0xa045, 0xa094, 0xa0e2, 0xa130, 0xa17e, 0xa1cc, 0xa21a,
+    0xa268, 0xa2b5, 0xa303, 0xa350, 0xa39e, 0xa3eb, 0xa438, 0xa485,
+    0xa4d2, 0xa51f, 0xa56c, 0xa5b8, 0xa605, 0xa652, 0xa69e, 0xa6ea,
+    0xa736, 0xa782, 0xa7ce, 0xa81a, 0xa866, 0xa8b2, 0xa8fd, 0xa949,
+    0xa994, 0xa9df, 0xaa2a, 0xaa76, 0xaac1, 0xab0b, 0xab56, 0xaba1,
+    0xabeb, 0xac36, 0xac80, 0xacca, 0xad14, 0xad5e, 0xada8, 0xadf2,
+    0xae3c, 0xae85, 0xaecf, 0xaf18, 0xaf62, 0xafab, 0xaff4, 0xb03d,
+    0xb086, 0xb0ce, 0xb117, 0xb160, 0xb1a8, 0xb1f0, 0xb239, 0xb281,
+    0xb2c9, 0xb311, 0xb358, 0xb3a0, 0xb3e8, 0xb42f, 0xb477, 0xb4be,
+    0xb505, 0xb54c, 0xb593, 0xb5da, 0xb620, 0xb667, 0xb6ad, 0xb6f4,
+    0xb73a, 0xb780, 0xb7c6, 0xb80c, 0xb852, 0xb898, 0xb8dd, 0xb923,
+    0xb968, 0xb9ae, 0xb9f3, 0xba38, 0xba7d, 0xbac1, 0xbb06, 0xbb4b,
+    0xbb8f, 0xbbd4, 0xbc18, 0xbc5c, 0xbca0, 0xbce4, 0xbd28, 0xbd6b,
+    0xbdaf, 0xbdf2, 0xbe36, 0xbe79, 0xbebc, 0xbeff, 0xbf42, 0xbf85,
+    0xbfc7, 0xc00a, 0xc04c, 0xc08f, 0xc0d1, 0xc113, 0xc155, 0xc197,
+    0xc1d8, 0xc21a, 0xc25c, 0xc29d, 0xc2de, 0xc31f, 0xc360, 0xc3a1,
+    0xc3e2, 0xc423, 0xc463, 0xc4a4, 0xc4e4, 0xc524, 0xc564, 0xc5a4,
+    0xc5e4, 0xc624, 0xc663, 0xc6a3, 0xc6e2, 0xc721, 0xc761, 0xc7a0,
+    0xc7de, 0xc81d, 0xc85c, 0xc89a, 0xc8d9, 0xc917, 0xc955, 0xc993,
+    0xc9d1, 0xca0f, 0xca4d, 0xca8a, 0xcac7, 0xcb05, 0xcb42, 0xcb7f,
+    0xcbbc, 0xcbf9, 0xcc35, 0xcc72, 0xccae, 0xcceb, 0xcd27, 0xcd63,
+    0xcd9f, 0xcddb, 0xce17, 0xce52, 0xce8e, 0xcec9, 0xcf04, 0xcf3f,
+    0xcf7a, 0xcfb5, 0xcff0, 0xd02a, 0xd065, 0xd09f, 0xd0d9, 0xd113,
+    0xd14d, 0xd187, 0xd1c1, 0xd1fa, 0xd234, 0xd26d, 0xd2a6, 0xd2df,
+    0xd318, 0xd351, 0xd38a, 0xd3c2, 0xd3fb, 0xd433, 0xd46b, 0xd4a3,
+    0xd4db, 0xd513, 0xd54b, 0xd582, 0xd5ba, 0xd5f1, 0xd628, 0xd65f,
+    0xd696, 0xd6cd, 0xd703, 0xd73a, 0xd770, 0xd7a6, 0xd7dc, 0xd812,
+    0xd848, 0xd87e, 0xd8b4, 0xd8e9, 0xd91e, 0xd954, 0xd989, 0xd9be,
+    0xd9f2, 0xda27, 0xda5c, 0xda90, 0xdac4, 0xdaf8, 0xdb2c, 0xdb60,
+    0xdb94, 0xdbc8, 0xdbfb, 0xdc2f, 0xdc62, 0xdc95, 0xdcc8, 0xdcfb,
+    0xdd2d, 0xdd60, 0xdd92, 0xddc5, 0xddf7, 0xde29, 0xde5b, 0xde8c,
+    0xdebe, 0xdef0, 0xdf21, 0xdf52, 0xdf83, 0xdfb4, 0xdfe5, 0xe016,
+    0xe046, 0xe077, 0xe0a7, 0xe0d7, 0xe107, 0xe137, 0xe167, 0xe196,
+    0xe1c6, 0xe1f5, 0xe224, 0xe253, 0xe282, 0xe2b1, 0xe2df, 0xe30e,
+    0xe33c, 0xe36b, 0xe399, 0xe3c7, 0xe3f4, 0xe422, 0xe450, 0xe47d,
+    0xe4aa, 0xe4d7, 0xe504, 0xe531, 0xe55e, 0xe58b, 0xe5b7, 0xe5e3,
+    0xe610, 0xe63c, 0xe667, 0xe693, 0xe6bf, 0xe6ea, 0xe716, 0xe741,
+    0xe76c, 0xe797, 0xe7c2, 0xe7ec, 0xe817, 0xe841, 0xe86b, 0xe895,
+    0xe8bf, 0xe8e9, 0xe913, 0xe93c, 0xe966, 0xe98f, 0xe9b8, 0xe9e1,
+    0xea0a, 0xea32, 0xea5b, 0xea83, 0xeaab, 0xead4, 0xeafc, 0xeb23,
+    0xeb4b, 0xeb73, 0xeb9a, 0xebc1, 0xebe8, 0xec0f, 0xec36, 0xec5d,
+    0xec83, 0xecaa, 0xecd0, 0xecf6, 0xed1c, 0xed42, 0xed68, 0xed8d,
+    0xedb3, 0xedd8, 0xedfd, 0xee22, 0xee47, 0xee6b, 0xee90, 0xeeb4,
+    0xeed9, 0xeefd, 0xef21, 0xef45, 0xef68, 0xef8c, 0xefaf, 0xefd2,
+    0xeff5, 0xf018, 0xf03b, 0xf05e, 0xf080, 0xf0a3, 0xf0c5, 0xf0e7,
+    0xf109, 0xf12b, 0xf14c, 0xf16e, 0xf18f, 0xf1b1, 0xf1d2, 0xf1f3,
+    0xf213, 0xf234, 0xf254, 0xf275, 0xf295, 0xf2b5, 0xf2d5, 0xf2f5,
+    0xf314, 0xf334, 0xf353, 0xf372, 0xf391, 0xf3b0, 0xf3cf, 0xf3ed,
+    0xf40c, 0xf42a, 0xf448, 0xf466, 0xf484, 0xf4a2, 0xf4bf, 0xf4dd,
+    0xf4fa, 0xf517, 0xf534, 0xf551, 0xf56e, 0xf58a, 0xf5a6, 0xf5c3,
+    0xf5df, 0xf5fb, 0xf616, 0xf632, 0xf64e, 0xf669, 0xf684, 0xf69f,
+    0xf6ba, 0xf6d5, 0xf6ef, 0xf70a, 0xf724, 0xf73e, 0xf758, 0xf772,
+    0xf78c, 0xf7a5, 0xf7bf, 0xf7d8, 0xf7f1, 0xf80a, 0xf823, 0xf83b,
+    0xf854, 0xf86c, 0xf885, 0xf89d, 0xf8b4, 0xf8cc, 0xf8e4, 0xf8fb,
+    0xf913, 0xf92a, 0xf941, 0xf958, 0xf96e, 0xf985, 0xf99b, 0xf9b2,
+    0xf9c8, 0xf9de, 0xf9f3, 0xfa09, 0xfa1f, 0xfa34, 0xfa49, 0xfa5e,
+    0xfa73, 0xfa88, 0xfa9c, 0xfab1, 0xfac5, 0xfad9, 0xfaed, 0xfb01,
+    0xfb15, 0xfb28, 0xfb3c, 0xfb4f, 0xfb62, 0xfb75, 0xfb88, 0xfb9a,
+    0xfbad, 0xfbbf, 0xfbd1, 0xfbe3, 0xfbf5, 0xfc07, 0xfc18, 0xfc2a,
+    0xfc3b, 0xfc4c, 0xfc5d, 0xfc6e, 0xfc7f, 0xfc8f, 0xfca0, 0xfcb0,
+    0xfcc0, 0xfcd0, 0xfcdf, 0xfcef, 0xfcfe, 0xfd0e, 0xfd1d, 0xfd2c,
+    0xfd3b, 0xfd49, 0xfd58, 0xfd66, 0xfd74, 0xfd83, 0xfd90, 0xfd9e,
+    0xfdac, 0xfdb9, 0xfdc7, 0xfdd4, 0xfde1, 0xfdee, 0xfdfa, 0xfe07,
+    0xfe13, 0xfe1f, 0xfe2b, 0xfe37, 0xfe43, 0xfe4f, 0xfe5a, 0xfe66,
+    0xfe71, 0xfe7c, 0xfe87, 0xfe91, 0xfe9c, 0xfea6, 0xfeb0, 0xfeba,
+    0xfec4, 0xfece, 0xfed8, 0xfee1, 0xfeeb, 0xfef4, 0xfefd, 0xff06,
+    0xff0e, 0xff17, 0xff1f, 0xff28, 0xff30, 0xff38, 0xff3f, 0xff47,
+    0xff4e, 0xff56, 0xff5d, 0xff64, 0xff6b, 0xff71, 0xff78, 0xff7e,
+    0xff85, 0xff8b, 0xff91, 0xff96, 0xff9c, 0xffa2, 0xffa7, 0xffac,
+    0xffb1, 0xffb6, 0xffbb, 0xffbf, 0xffc4, 0xffc8, 0xffcc, 0xffd0,
+    0xffd4, 0xffd7, 0xffdb, 0xffde, 0xffe1, 0xffe4, 0xffe7, 0xffea,
+    0xffec, 0xffef, 0xfff1, 0xfff3, 0xfff5, 0xfff7, 0xfff8, 0xfffa,
+    0xfffb, 0xfffc, 0xfffd, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff,
 };
 
 /*
- * angles are measured from -512 .. 512
+ * angles are measured from -2048 .. 2048
  */
 
 #if 0

Index: twin_x11.c
===================================================================
RCS file: /local/src/CVS/twin/twin_x11.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- twin_x11.c	2 Oct 2004 03:07:26 -0000	1.3
+++ twin_x11.c	4 Oct 2004 07:49:49 -0000	1.4
@@ -75,7 +75,7 @@
     if (tx->iy == tx->image->height)
     {
 	XPutImage (tx->dpy, tx->win, tx->gc, tx->image, 0, 0, 
-		   x, y - tx->iy, width, tx->image->height);
+		   x, (y + 1) - tx->iy, width, tx->image->height);
 	XDestroyImage (tx->image);
 	tx->image = 0;
     }
@@ -126,9 +126,7 @@
 {
     twin_x11_t	*tx = closure;
 
-    pthread_mutex_unlock (&tx->screen->screen_mutex);
     pthread_cond_broadcast (&tx->damage_cond);
-    pthread_mutex_unlock (&tx->screen->screen_mutex);
 }
 
 twin_x11_t *
@@ -210,8 +208,10 @@
 void
 twin_x11_damage (twin_x11_t *tx, XExposeEvent *ev)
 {
+    twin_screen_lock (tx->screen);
     twin_screen_damage (tx->screen, 
 			ev->x, ev->y, ev->x + ev->width, ev->y + ev->height);
+    twin_screen_unlock (tx->screen);
 }
 
 void

Index: twinint.h
===================================================================
RCS file: /local/src/CVS/twin/twinint.h,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- twinint.h	2 Oct 2004 03:07:26 -0000	1.9
+++ twinint.h	4 Oct 2004 07:49:49 -0000	1.10
@@ -118,7 +118,7 @@
 
 /* Geometrical objects */
 
-typedef struct _twin_point {
+typedef struct _twin_spoint {
     twin_sfixed_t    x, y;
 } twin_spoint_t;
 
@@ -311,6 +311,8 @@
 twin_sfixed_t
 _twin_matrix_len (twin_matrix_t *m, twin_fixed_t dx, twin_fixed_t dy);
 
+twin_point_t
+_twin_matrix_expand (twin_matrix_t *matrix);
 /*
  * Path stuff
  */
@@ -331,6 +333,12 @@
 void
 _twin_path_sdraw (twin_path_t *path, twin_sfixed_t x, twin_sfixed_t y);
 
+void
+_twin_path_scurve (twin_path_t	    *path,
+		   twin_sfixed_t    x1, twin_sfixed_t y1,
+		   twin_sfixed_t    x2, twin_sfixed_t y2,
+		   twin_sfixed_t    x3, twin_sfixed_t y3);
+
 /*
  * Glyph stuff.  Coordinates are stored in 2.6 fixed point format
  */
@@ -342,4 +350,17 @@
 
 #define TWIN_GLYPH_MAX_POINTS	56
 
+extern const signed char _twin_gtable[];
+extern const uint16_t _twin_g_offsets[];
+
+#define twin_glyph_left(g)	((g)[0])
+#define twin_glyph_right(g)	((g)[1])
+#define twin_glyph_ascent(g)	((g)[2])
+#define twin_glyph_descent(g)	((g)[3])
+#define twin_glyph_n_snap_x(g)	((g)[4])
+#define twin_glyph_n_snap_y(g)	((g)[5])
+#define twin_glyph_snap_x(g)	(&g[6])
+#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))
+
 #endif /* _TWININT_H_ */

Index: xtwin.c
===================================================================
RCS file: /local/src/CVS/twin/xtwin.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- xtwin.c	2 Oct 2004 03:07:26 -0000	1.13
+++ xtwin.c	4 Oct 2004 07:49:49 -0000	1.14
@@ -34,13 +34,16 @@
 
 #define TWIN_CLOCK_BACKGROUND	0xff3b80ae
 #define TWIN_CLOCK_HOUR		0x80808080
-#define TWIN_CLOCK_HOUR_OUT	0xffdedede
+#define TWIN_CLOCK_HOUR_OUT	0x30000000
 #define TWIN_CLOCK_MINUTE	0x80808080
-#define TWIN_CLOCK_MINUTE_OUT	0xffdedede
+#define TWIN_CLOCK_MINUTE_OUT	0x30000000
 #define TWIN_CLOCK_SECOND	0x80808080
+#define TWIN_CLOCK_SECOND_OUT	0x30000000
 #define TWIN_CLOCK_TIC		0xffbababa
 #define TWIN_CLOCK_NUMBERS	0xffdedede
-#define TWIN_CLOCK_WATER	0x40404040
+#define TWIN_CLOCK_WATER	0x40000000
+#define TWIN_CLOCK_WATER_OUT	0x40404040
+#define TWIN_CLOCK_WATER_UNDER	0xcccc0000
 #define TWIN_CLOCK_BORDER	0xffbababa
 #define TWIN_CLOCK_BORDER_WIDTH	D(0.01)
 
@@ -97,26 +100,6 @@
     twin_path_destroy (stroke);
 }
 
-static void
-twin_clock_sec (twin_pixmap_t	*clock, 
-		 twin_angle_t	angle, 
-		 twin_fixed_t	len,
-		 twin_fixed_t	width,
-		 twin_argb32_t	pixel)
-{
-    twin_path_t	    *stroke = twin_path_create ();
-
-    twin_clock_set_transform (clock, stroke);
-
-    twin_path_rotate (stroke, angle);
-    twin_path_move (stroke, D(0), D(0));
-    twin_path_draw (stroke, len, D(0));
-
-    twin_paint_stroke (clock, pixel, stroke, width);
-    
-    twin_path_destroy (stroke);
-}
-
 static twin_angle_t
 twin_clock_minute_angle (int min)
 {
@@ -141,7 +124,7 @@
     {
 	twin_state_t	    state = twin_path_save (path);
 	twin_text_metrics_t metrics;
-	twin_fixed_t	    height;
+	twin_fixed_t	    height, width;
 	static char	    *label = "twin";
 
 	twin_path_empty (path);
@@ -150,8 +133,14 @@
 	twin_path_set_font_style (path, TWIN_TEXT_UNHINTED|TWIN_TEXT_OBLIQUE);
 	twin_text_metrics_utf8 (path, label, &metrics);
 	height = metrics.ascent + metrics.descent;
-/*	twin_path_move (path, -metrics.width / 2, height / 2 - metrics.ascent);*/
-	twin_path_move (path, -D(.4), -D(.16));
+	width = metrics.right_side_bearing - metrics.left_side_bearing;
+	
+	twin_path_move (path, -width / 2, metrics.ascent - height/2);
+	twin_path_draw (path, width / 2, metrics.ascent - height/2);
+	twin_paint_stroke (clock, TWIN_CLOCK_WATER_UNDER, path, D(0.02));
+	twin_path_empty (path);
+	
+	twin_path_move (path, -width / 2 - metrics.left_side_bearing, metrics.ascent - height/2);
 	twin_path_utf8 (path, label);
 	twin_paint_path (clock, TWIN_CLOCK_WATER, path);
 	twin_path_restore (path, &state);
@@ -173,12 +162,16 @@
 	}
 	else
 	{
-	    char    hour[3];
+	    char		hour[3];
+	    twin_text_metrics_t	metrics;
+	    twin_fixed_t	width;
+	    twin_fixed_t	left;
 	    
-	    twin_fixed_t    w;
 	    sprintf (hour, "%d", m / 5);
-	    w = twin_width_utf8 (path, hour);
-	    twin_path_move (path, -(w/2), -D(0.95));
+	    twin_text_metrics_utf8 (path, hour, &metrics);
+	    width = metrics.right_side_bearing - metrics.left_side_bearing;
+	    left = -width / 2 - metrics.left_side_bearing;
+	    twin_path_move (path, left, -D(0.98) + metrics.ascent);
 	    twin_path_utf8 (path, hour);
 	    twin_paint_path (clock, TWIN_CLOCK_NUMBERS, path);
 	}
@@ -197,19 +190,11 @@
     struct timeval  tv;
     struct tm	    t;
     twin_angle_t    hour_angle, minute_angle, second_angle;
-#if 0
-    int		    i;
-#endif
 
-    printf ("twin clock\n");
     twin_pixmap_move (clock, x, y);
     twin_pixmap_show (clock, screen, 0);
     
-#if 0
-    for (i = 0; i < 5; i++)
-#else
     for (;;)
-#endif
     {
 	twin_pixmap_disable_update (clock);
 	twin_fill (clock, 0x00000000, TWIN_SOURCE, 0, 0, 
@@ -222,15 +207,16 @@
 	second_angle = ((t.tm_sec * 100 + tv.tv_usec / 10000) * 
 			TWIN_ANGLE_360) / 6000 - TWIN_ANGLE_90;
 	minute_angle = twin_clock_minute_angle (t.tm_min) + second_angle / 60;
-	hour_angle = t.tm_hour * TWIN_ANGLE_360 / 12 - TWIN_ANGLE_90 + minute_angle / 12;
-
+	hour_angle = (t.tm_hour * TWIN_ANGLE_360 / 12 +
+		      (minute_angle + TWIN_ANGLE_90) / 12 -
+		      TWIN_ANGLE_90);
 	twin_clock_face (clock);
 	twin_clock_hand (clock, hour_angle, D(0.4), D(0.07), D(0.01),
 			 TWIN_CLOCK_HOUR, TWIN_CLOCK_HOUR_OUT);
 	twin_clock_hand (clock, minute_angle, D(0.8), D(0.05), D(0.01),
 			 TWIN_CLOCK_MINUTE, TWIN_CLOCK_MINUTE_OUT);
-	twin_clock_sec (clock, second_angle, D(0.9), D(0.02),
-			TWIN_CLOCK_SECOND);
+	twin_clock_hand (clock, second_angle, D(0.9), D(0.01), D(0.01),
+			 TWIN_CLOCK_SECOND, TWIN_CLOCK_SECOND_OUT);
 
 	twin_pixmap_enable_update (clock);
 	
@@ -392,7 +378,7 @@
     twin_path_convolve (path, extra, pen);
 #endif
     
-#if 1
+#if 0
     {
 	twin_state_t	state = twin_path_save (path);
     twin_path_translate (path, D(300), D(300));
@@ -409,12 +395,12 @@
     }
 #endif
 #if 1
-    fx = D(3);
+    fx = D(10);
     fy = 0;
-    for (g = 8; g < 30; g += 4)
+    for (g = 90; g < 91; g += 4)
     {
         twin_path_set_font_size (path, D(g));
-#if 1
+#if 0
         fy += D(g+2);
 	twin_path_move (path, fx, fy);
 	twin_path_utf8 (path,
@@ -443,7 +429,30 @@
 #if 0
 	fy += D(g);
 	twin_path_move (path, fx, fy);
-	twin_path_utf8 (path, "t");
+#define TEXT	"jelly world"
+	twin_path_utf8 (path, TEXT);
+	{
+	    twin_text_metrics_t	m;
+	    
+	    stroke = twin_path_create ();
+	    twin_path_set_matrix (stroke, twin_path_current_matrix (path));
+	    twin_text_metrics_utf8 (path, TEXT, &m);
+	    twin_path_move (stroke, fx, fy);
+	    twin_path_draw (stroke, fx + m.width, fy);
+	    twin_paint_stroke (red, 0xffff0000, stroke, D(1));
+	    twin_path_empty (stroke);
+	    twin_path_move (stroke, 
+			    fx + m.left_side_bearing, fy - m.ascent);
+	    twin_path_draw (stroke,
+			    fx + m.right_side_bearing, fy - m.ascent);
+	    twin_path_draw (stroke,
+			    fx + m.right_side_bearing, fy + m.descent);
+	    twin_path_draw (stroke,
+			    fx + m.left_side_bearing, fy + m.descent);
+	    twin_path_draw (stroke, 
+			    fx + m.left_side_bearing, fy - m.ascent);
+	    twin_paint_stroke (red, 0xff00ff00, stroke, D(1));
+	}
 #endif
     }
 #endif
@@ -461,7 +470,7 @@
 	fy += D(g);
     }
 #endif
-    twin_fill_path (alpha, path);
+    twin_fill_path (alpha, path, 0, 0);
     
     twin_path_destroy (path);
     
@@ -610,53 +619,20 @@
     twin_pixmap_move (blue, 100, 100);
     twin_pixmap_show (red, x11->screen, 0);
     twin_pixmap_show (blue, x11->screen, 0);
+    ++nclock;
 #endif
-    twin_start_clock (x11->screen, 0, 0, 512, 512);
-/*    twin_start_clock (x11->screen, 256, 0, 256, 256);
+
+#if 1
+    twin_start_clock (x11->screen, 0, 0, 256, 256);
+#endif
+#if 0
+    twin_start_clock (x11->screen, 0, 0, 256, 256);
+    twin_start_clock (x11->screen, 256, 0, 256, 256);
     twin_start_clock (x11->screen, 0, 256, 256, 256);
-    twin_start_clock (x11->screen, 256, 256, 256, 256); */
+    twin_start_clock (x11->screen, 256, 256, 256, 256);
+#endif
     while (nclock)
 	sleep (1);
-#if 0
-    had_motion = TWIN_FALSE;
-    for (;;)
-    {
-	if (had_motion)
-	{
-	    x = motion.xmotion.x - 50;
-	    y = motion.xmotion.y - 50;
-	    if (motion.xmotion.state & Button1Mask)
-		twin_pixmap_move (red, x, y);
-	    if (motion.xmotion.state & Button3Mask)
-		twin_pixmap_move (blue, x, y);
-	    had_motion = TWIN_FALSE;
-	}
-	if (twin_screen_damaged (x11->screen))
-	    twin_x11_update (x11);
-	XSync (dpy, False);
-	do {
-	    XNextEvent (dpy, &ev);
-	    switch (ev.type) {
-	    case Expose:
-		twin_x11_damage (x11, &ev.xexpose);
-		break;
-	    case ButtonPress:
-		if (ev.xbutton.button == 2)
-		{
-		    if (red->higher == 0)
-			twin_pixmap_show (red, x11->screen, 0);
-		    else
-			twin_pixmap_show (blue, x11->screen, 0);
-		}
-		break;
-	    case MotionNotify:
-		had_motion = TWIN_TRUE;
-		motion = ev;
-		break;
-	    }
-	} while (QLength (dpy));
-    }
-#endif
     return 0;
 }
 




More information about the Commit mailing list