[Commit] twin ChangeLog, 1.10, 1.11 Makefile.am, 1.5, 1.6 twin.h, 1.7, 1.8 twin_convolve.c, 1.6, 1.7 twin_fixed.c, NONE, 1.1 twin_font.c, 1.6, 1.7 twin_geom.c, 1.1, 1.2 twin_hull.c, 1.1, 1.2 twin_matrix.c, NONE, 1.1 twin_path.c, 1.4, 1.5 twin_poly.c, 1.4, 1.5 twin_spline.c, 1.2, 1.3 twin_trig.c, NONE, 1.1 twinint.h, 1.5, 1.6 xtwin.c, 1.9, 1.10

Keith Packard commit at keithp.com
Mon Sep 27 14:28:34 PDT 2004


Committed by: keithp

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

Modified Files:
	ChangeLog Makefile.am twin.h twin_convolve.c twin_font.c 
	twin_geom.c twin_hull.c twin_path.c twin_poly.c twin_spline.c 
	twinint.h xtwin.c 
Added Files:
	twin_fixed.c twin_matrix.c twin_trig.c 
Log Message:
2004-09-27  Keith Packard  <keithp at keithp.com>

	* Makefile.am:
	* twin.h:
	* twin_convolve.c: (_twin_path_leftpoint), (_around_order),
	(_angle), (_twin_subpath_convolve):
	* twin_fixed.c: (twin_fixed_mul):
	* twin_font.c: (twin_path_ucs4), (twin_width_ucs4),
	(twin_path_utf8):
	* twin_geom.c: (_twin_distance_to_point_squared),
	(_twin_distance_to_line_squared):
	* twin_hull.c: (_twin_slope_init), (_twin_hull_create),
	(_twin_hull_vertex_compare), (_twin_hull_eliminate_concave),
	(_twin_hull_to_path):
	* twin_matrix.c: (_twin_dump_matrix), (_twin_matrix_multiply),
	(twin_matrix_identity), (twin_matrix_translate),
	(twin_matrix_scale), (_twin_matrix_determinant),
	(twin_matrix_rotate), (_twin_matrix_x), (_twin_matrix_y),
	(_twin_matrix_dx), (_twin_matrix_dy):
	* twin_path.c: (_twin_current_subpath_len),
	(_twin_path_current_spoint), (_twin_path_subpath_first_spoint),
	(_twin_path_smove), (_twin_path_sdraw), (twin_path_move),
	(twin_path_draw), (twin_path_close), (twin_path_circle),
	(twin_path_set_matrix), (twin_path_current_matrix),
	(twin_path_identity), (twin_path_translate), (twin_path_scale),
	(twin_path_rotate), (twin_path_set_font_size),
	(twin_path_current_font_size), (twin_path_set_font_style),
	(twin_path_current_font_style), (twin_path_append),
	(twin_path_save), (twin_path_restore), (twin_path_create):
	* twin_poly.c: (_edge_step_by), (_twin_sfixed_grid_ceil),
	(_twin_edge_build), (_span_fill), (_twin_edge_fill),
	(twin_fill_path):
	* twin_spline.c: (_lerp_half), (_de_casteljau),
	(_twin_spline_decompose), (_twin_path_scurve), (twin_path_curve):
	* twin_trig.c: (twin_sin), (twin_cos), (twin_tan):
	* twinint.h:
	* xtwin.c: (main):
	Add affine transformation support.
	Fix convex hull to eliminate all points colinear with extreme.
	Note that text snapping is currently broken.


Index: ChangeLog
===================================================================
RCS file: /local/src/CVS/twin/ChangeLog,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- ChangeLog	26 Sep 2004 09:44:29 -0000	1.10
+++ ChangeLog	27 Sep 2004 21:28:31 -0000	1.11
@@ -1,3 +1,44 @@
+2004-09-27  Keith Packard  <keithp at keithp.com>
+
+	* Makefile.am:
+	* twin.h:
+	* twin_convolve.c: (_twin_path_leftpoint), (_around_order),
+	(_angle), (_twin_subpath_convolve):
+	* twin_fixed.c: (twin_fixed_mul):
+	* twin_font.c: (twin_path_ucs4), (twin_width_ucs4),
+	(twin_path_utf8):
+	* twin_geom.c: (_twin_distance_to_point_squared),
+	(_twin_distance_to_line_squared):
+	* twin_hull.c: (_twin_slope_init), (_twin_hull_create),
+	(_twin_hull_vertex_compare), (_twin_hull_eliminate_concave),
+	(_twin_hull_to_path):
+	* twin_matrix.c: (_twin_dump_matrix), (_twin_matrix_multiply),
+	(twin_matrix_identity), (twin_matrix_translate),
+	(twin_matrix_scale), (_twin_matrix_determinant),
+	(twin_matrix_rotate), (_twin_matrix_x), (_twin_matrix_y),
+	(_twin_matrix_dx), (_twin_matrix_dy):
+	* twin_path.c: (_twin_current_subpath_len),
+	(_twin_path_current_spoint), (_twin_path_subpath_first_spoint),
+	(_twin_path_smove), (_twin_path_sdraw), (twin_path_move),
+	(twin_path_draw), (twin_path_close), (twin_path_circle),
+	(twin_path_set_matrix), (twin_path_current_matrix),
+	(twin_path_identity), (twin_path_translate), (twin_path_scale),
+	(twin_path_rotate), (twin_path_set_font_size),
+	(twin_path_current_font_size), (twin_path_set_font_style),
+	(twin_path_current_font_style), (twin_path_append),
+	(twin_path_save), (twin_path_restore), (twin_path_create):
+	* twin_poly.c: (_edge_step_by), (_twin_sfixed_grid_ceil),
+	(_twin_edge_build), (_span_fill), (_twin_edge_fill),
+	(twin_fill_path):
+	* twin_spline.c: (_lerp_half), (_de_casteljau),
+	(_twin_spline_decompose), (_twin_path_scurve), (twin_path_curve):
+	* twin_trig.c: (twin_sin), (twin_cos), (twin_tan):
+	* twinint.h:
+	* xtwin.c: (main):
+	Add affine transformation support.
+	Fix convex hull to eliminate all points colinear with extreme.
+	Note that text snapping is currently broken.
+
 2004-09-26  Keith Packard  <keithp at keithp.com>
 
 	* twin_convolve.c: (_twin_subpath_convolve):

Index: Makefile.am
===================================================================
RCS file: /local/src/CVS/twin/Makefile.am,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Makefile.am	25 Sep 2004 06:41:19 -0000	1.5
+++ Makefile.am	27 Sep 2004 21:28:31 -0000	1.6
@@ -21,14 +21,17 @@
 	twin_draw.c \
 	twin_glyphs.c \
 	twin_hull.c \
+	twin_fixed.c \
 	twin_font.c \
 	twin_geom.c \
+	twin_matrix.c \
 	twin_path.c \
 	twin_pixmap.c \
 	twin_poly.c \
 	twin_primitive.c \
 	twin_screen.c \
 	twin_spline.c \
+	twin_trig.c \
 	twin_x11.c \
 	twinint.h \
 	xtwin.c

Index: twin.h
===================================================================
RCS file: /local/src/CVS/twin/twin.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- twin.h	26 Sep 2004 09:23:23 -0000	1.7
+++ twin.h	27 Sep 2004 21:28:31 -0000	1.8
@@ -34,20 +34,6 @@
 typedef uint32_t    twin_argb32_t;
 typedef uint32_t    twin_ucs4_t;
 typedef int	    twin_bool_t;
-typedef int16_t	    twin_fixed_t;   /* 12.4 format */
-typedef int32_t	    twin_dfixed_t;
-
-#define twin_fixed_floor(f) ((f) & ~0xf)
-#define twin_fixed_trunc(f) ((f) >> 4)
-#define twin_fixed_ceil(f)  (((f) + 0xf) & ~0xf)
-
-#define twin_double_to_fixed(d)	((twin_fixed_t) ((d) * 16.0))
-#define twin_fixed_to_double(f)	((double) (f) / 16.0)
-#define twin_int_to_fixed(i)	((twin_fixed_t) ((i) * 16))
-
-#define TWIN_FIXED_ONE		(0x10)
-#define TWIN_FIXED_HALF		(0x08)
-#define TWIN_FIXED_TOLERANCE	(TWIN_FIXED_ONE >> 2)
 
 #define TWIN_FALSE  0
 #define TWIN_TRUE   1
@@ -57,6 +43,20 @@
 #define twin_bytes_per_pixel(format)    (1 << (int) (format))
 
 /*
+ * Angles
+ */
+typedef int16_t	    twin_angle_t;   /* -512 .. 512 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_degrees_to_angle(d)    ((d) * 512 / 180)
+
+/*
  * A rectangle
  */
 typedef struct _twin_rect {
@@ -148,27 +148,34 @@
 
 typedef enum { TWIN_OVER, TWIN_SOURCE } twin_operator_t;
 
-/*
- * A (fixed point) point
- */
+typedef int32_t	    twin_fixed_t;   /* 16.16 format */
 
-typedef struct _twin_point {
-    twin_fixed_t    x, y;
-} twin_point_t;
+#define TWIN_FIXED_ONE	(0x10000)
+#define TWIN_FIXED_HALF	(0x08000)
+#define TWIN_FIXED_MAX	(0x7fffffff)
+#define TWIN_FIXED_MIN	(-0x7fffffff)
 
-typedef struct _twin_path twin_path_t;
+/* 
+ * 'double' is a no-no in any shipping code, but useful during
+ * development
+ */
+#define twin_double_to_fixed(d)    ((twin_fixed_t) ((d) * 65536))
+#define twin_fixed_to_double(f)    ((double) (f) / 65536.0)
 
 /*
- * A font
+ * Place matrices in structures so they can be easily copied
  */
+typedef struct _twin_matrix {
+    twin_fixed_t    m[3][2];
+} twin_matrix_t;
 
-typedef struct _twin_font {
-    const struct _twin_charmap  *charmap;
-    const unsigned char		ncharmap;
-    const char			*outlines;
-    const char			ascender, descender, height;
-    const char			*family, *style;
-} twin_font_t;
+typedef struct _twin_path twin_path_t;
+
+typedef struct _twin_state {
+    twin_matrix_t	matrix;
+    twin_fixed_t	font_size;
+    int			font_style;
+} twin_state_t;
 
 /*
  * twin_convolve.c
@@ -206,42 +213,38 @@
 	   int		    height);
 
 /*
+ * twin_fixed.c
+ */
+
+twin_fixed_t
+twin_fixed_mul (twin_fixed_t af, twin_fixed_t bf);
+
+/*
  * twin_font.c
  */
 
 twin_bool_t
 twin_has_ucs4 (twin_ucs4_t ucs4);
     
-void
-twin_path_ucs4 (twin_path_t	*path, 
-		twin_fixed_t	scale_x,
-		twin_fixed_t	scale_y,
-		int		style,
-		twin_ucs4_t	ucs4);
- 
-int
-twin_ucs4_width (twin_ucs4_t ucs4, twin_fixed_t scale_x);
-
 #define TWIN_TEXT_ROMAN	    0
 #define TWIN_TEXT_BOLD	    1
 #define TWIN_TEXT_OBLIQUE   2
+#define TWIN_TEXT_UNHINTED  4
 
 void
-twin_path_string (twin_path_t	*path, 
-		  twin_fixed_t	scale_x,
-		  twin_fixed_t	scale_y,
-		  int		style,
-		  const char	*string);
+twin_path_ucs4_stroke (twin_path_t *path, twin_ucs4_t ucs4);
 
-#if 0
 void
-twin_path_ucs4 (twin_path_t *path, twin_fixed_t scale_x,
-		twin_fixed_t scale_y, twin_ucs4_t ucs4);
-    
+twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4);
+ 
 void
-twin_path_utf8 (twin_path_t *path, twin_fixed_t scale_x, twin_fixed_t scale_y, 
-		const char *string);
-#endif
+twin_path_utf8 (twin_path_t *path, const char *string);
+
+twin_fixed_t
+twin_width_ucs4 (twin_path_t *path, twin_ucs4_t ucs4);
+ 
+twin_fixed_t
+twin_width_utf8 (twin_path_t *path, const char *string);
 
 /*
  * twin_hull.c
@@ -251,6 +254,22 @@
 twin_path_convex_hull (twin_path_t *path);
 
 /*
+ * twin_matrix.c
+ */
+
+void
+twin_matrix_identity (twin_matrix_t *m);
+
+void
+twin_matrix_translate (twin_matrix_t *m, twin_fixed_t tx, twin_fixed_t ty);
+
+void
+twin_matrix_scale (twin_matrix_t *m, twin_fixed_t sx, twin_fixed_t sy);
+
+void
+twin_matrix_rotate (twin_matrix_t *m, twin_angle_t a);
+
+/*
  * twin_path.c
  */
 
@@ -261,18 +280,12 @@
 twin_path_draw (twin_path_t *path, twin_fixed_t x, twin_fixed_t y);
 
 void
-twin_path_cur_point (twin_path_t *path, twin_fixed_t *xp, twin_fixed_t *yp);
-
-void
 twin_path_circle(twin_path_t *path, twin_fixed_t radius);
 
 void
 twin_path_close (twin_path_t *path);
 
 void
-twin_path_fill (twin_pixmap_t *pixmap, twin_path_t *path);
-
-void
 twin_path_empty (twin_path_t *path);
 
 void
@@ -284,6 +297,42 @@
 void
 twin_path_destroy (twin_path_t *path);
 
+void
+twin_path_identity (twin_path_t *path);
+
+void
+twin_path_translate (twin_path_t *path, twin_fixed_t tx, twin_fixed_t ty);
+
+void
+twin_path_scale (twin_path_t *path, twin_fixed_t sx, twin_fixed_t sy);
+
+void
+twin_path_rotate (twin_path_t *path, twin_angle_t a);
+
+twin_matrix_t
+twin_path_current_matrix (twin_path_t *path);
+
+void
+twin_path_set_matrix (twin_path_t *path, twin_matrix_t matrix);
+
+twin_fixed_t
+twin_path_current_font_size (twin_path_t *path);
+
+void
+twin_path_set_font_size (twin_path_t *path, twin_fixed_t font_size);
+
+int
+twin_path_current_font_style (twin_path_t *path);
+
+void
+twin_path_set_font_style (twin_path_t *path, int font_style);
+
+twin_state_t
+twin_path_save (twin_path_t *path);
+
+void
+twin_path_restore (twin_path_t *path, twin_state_t *state);
+
 /*
  * twin_pixmap.c
  */
@@ -316,7 +365,7 @@
  * twin_poly.c
  */
 void
-twin_polygon (twin_pixmap_t *pixmap, twin_point_t *vertices, int nvertices);
+twin_fill_path (twin_pixmap_t *pixmap, twin_path_t *path);
 
 /*
  * twin_screen.c
@@ -355,6 +404,19 @@
 		 twin_fixed_t	x3, twin_fixed_t y3);
 
 /*
+ * twin_trig.c
+ */
+
+twin_fixed_t
+twin_sin (twin_angle_t a);
+
+twin_fixed_t
+twin_cos (twin_angle_t a);
+
+twin_fixed_t
+twin_tan (twin_angle_t a);
+
+/*
  * twin_x11.c 
  */
 

Index: twin_convolve.c
===================================================================
RCS file: /local/src/CVS/twin/twin_convolve.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- twin_convolve.c	26 Sep 2004 09:44:29 -0000	1.6
+++ twin_convolve.c	27 Sep 2004 21:28:31 -0000	1.7
@@ -28,11 +28,11 @@
  * Find the point in path which is furthest left of the line
  */
 static int
-_twin_path_leftpoint (twin_path_t  *path,
-		      twin_point_t *p1,
-		      twin_point_t *p2)
+_twin_path_leftpoint (twin_path_t   *path,
+		      twin_spoint_t *p1,
+		      twin_spoint_t *p2)
 {
-    twin_point_t    *points = path->points;
+    twin_spoint_t   *points = path->points;
     int		    p;
     int		    best = 0;
     /*
@@ -59,10 +59,10 @@
 }
 
 static int
-_around_order (twin_point_t    *a1,
-	       twin_point_t    *a2,
-	       twin_point_t    *b1,
-	       twin_point_t    *b2)
+_around_order (twin_spoint_t    *a1,
+	       twin_spoint_t    *a2,
+	       twin_spoint_t    *b1,
+	       twin_spoint_t    *b2)
 {
     twin_dfixed_t   adx = (a2->x - a1->x);
     twin_dfixed_t   ady = (a2->y - a1->y);
@@ -78,14 +78,14 @@
 #if 0
 #include <stdio.h>
 #include <math.h>
-#define F(x)	twin_fixed_to_double(x)
+#define F(x)	twin_sfixed_to_double(x)
 #define DBGOUT(x...)	printf(x)
 
 static double
-_angle (twin_point_t *a, twin_point_t *b)
+_angle (twin_spoint_t *a, twin_spoint_t *b)
 {
-    twin_fixed_t    dx = b->x - a->x;
-    twin_fixed_t    dy = b->y - a->y;
+    twin_sfixed_t    dx = b->x - a->x;
+    twin_sfixed_t    dy = b->y - a->y;
     double	    rad;
 
     rad = atan2 ((double) dy, (double) dx);
@@ -104,15 +104,15 @@
 			twin_path_t	*stroke,
 			twin_path_t	*pen)
 {
-    twin_point_t    *sp   = stroke->points;
-    twin_point_t    *pp   = pen->points;
+    twin_spoint_t    *sp   = stroke->points;
+    twin_spoint_t    *pp   = pen->points;
     int		    ns    = stroke->npoints;
     int		    np    = pen->npoints;
-    twin_point_t    *sp0  = &sp[0];
-    twin_point_t    *sp1  = &sp[1];
+    twin_spoint_t    *sp0  = &sp[0];
+    twin_spoint_t    *sp1  = &sp[1];
     int		    start = _twin_path_leftpoint (pen, sp0, sp1);
-    twin_point_t    *spn1 = &sp[ns-1];
-    twin_point_t    *spn2 = &sp[ns-2];
+    twin_spoint_t    *spn1 = &sp[ns-1];
+    twin_spoint_t    *spn2 = &sp[ns-2];
     int		    ret   = _twin_path_leftpoint (pen, spn1, spn2);
     int		    p;
     int		    s;
@@ -134,7 +134,7 @@
 	    s, F(sp[s].x), F(sp[s].y),
 	    p, F(pp[p].x), F(pp[p].y),
 	    F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
-    twin_path_move (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
+    _twin_path_smove (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
     
     /* step along the path first */
     inc = 1;
@@ -178,7 +178,7 @@
 		    s, F(sp[s].x), F(sp[s].y),
 		    p, F(pp[p].x), F(pp[p].y),
 		    F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
-	    twin_path_draw (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
+	    _twin_path_sdraw (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
 	} while (s != starget);
 	
 	/*
@@ -194,7 +194,7 @@
 		    s, F(sp[s].x), F(sp[s].y),
 		    p, F(pp[p].x), F(pp[p].y),
 		    F(sp[s].x + pp[p].x), F(sp[s].y + pp[p].y));
-	    twin_path_draw (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
+	    _twin_path_sdraw (path, sp[s].x + pp[p].x, sp[s].y + pp[p].y);
 	}
 	
 	if (inc == -1)

--- NEW FILE: twin_fixed.c ---
(This appears to be a binary file; contents omitted.)

Index: twin_font.c
===================================================================
RCS file: /local/src/CVS/twin/twin_font.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- twin_font.c	26 Sep 2004 09:44:29 -0000	1.6
+++ twin_font.c	27 Sep 2004 21:28:31 -0000	1.7
@@ -27,14 +27,16 @@
 #if 0
 #include <stdio.h>
 #define F(x) twin_fixed_to_double(x)
-#define DBGOUT(x)	printf x
+#define S(x) twin_sfixed_to_double(x)
+#define G(x) ((double) (x))
+#define DBGMSG(x)	printf x
 #else
-#define DBGOUT(x)
+#define DBGMSG(x)
 #endif
 
-#define S(f,s)	((twin_fixed_t) ((((twin_dfixed_t) (f) * (s)) >> 5)))
-#define SX(x) (((x) * scale_x) >> 5)
-#define SY(y) (((y) * scale_y) >> 5)
+#define Scale(f)	(((twin_fixed_t) (f) * path->state.font_size) >> 5)
+#define ScaleX(x)	Scale(x)
+#define ScaleY(y)	Scale(y)
 
 twin_bool_t
 twin_has_ucs4 (twin_ucs4_t ucs4)
@@ -42,6 +44,7 @@
     return ucs4 <= TWIN_FONT_MAX && _twin_glyph_offsets[ucs4] != 0;
 }
 
+#if 0
 static int
 compare_snap (const void *av, const void *bv)
 {
@@ -89,8 +92,8 @@
     return v;
 }
 
-#define SNAPX(p)	_snap (p, scale_x, snap_x, nsnap_x)
-#define SNAPY(p)	_snap (p, scale_y, snap_y, nsnap_y)
+#define SNAPX(p)	_snap (p, path->state.font_size, snap_x, nsnap_x)
+#define SNAPY(p)	_snap (p, path->state.font_size, snap_y, nsnap_y)
 
 static int
 _add_snap (twin_gfixed_t *snaps, int nsnap, twin_fixed_t snap)
@@ -103,6 +106,7 @@
     snaps[nsnap++] = snap;
     return nsnap;
 }
+#endif
 
 static const twin_gpoint_t *
 _twin_ucs4_base(twin_ucs4_t ucs4)
@@ -115,28 +119,31 @@
 #define TWIN_FONT_BASELINE  9
 
 void
-twin_path_ucs4 (twin_path_t	*path, 
-		twin_fixed_t	scale_x,
-		twin_fixed_t	scale_y,
-		int		style,
-		twin_ucs4_t	ucs4)
+twin_path_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
 {
     const twin_gpoint_t	*p = 0;
     int			i;
-    twin_fixed_t	xo, yo;
+    twin_spoint_t	origin;
     twin_fixed_t	xc, yc;
+    twin_sfixed_t	sx, sy;
     twin_path_t		*stroke;
     twin_path_t		*pen;
+    twin_fixed_t	w;
+    twin_fixed_t	x, y;
     twin_fixed_t	pen_size;
+    twin_matrix_t	pen_matrix;
+#if 0
     twin_fixed_t	pen_adjust;
     twin_gfixed_t    	*snap_x, *snap_y;
     int			nsnap_x, nsnap_y;
     int			npoints;
+#endif
     
     p = _twin_ucs4_base (ucs4);
     
-    twin_path_cur_point (path, &xo, &yo);
+    origin = _twin_path_current_spoint (path);
     
+#if 0
     for (i = 1; p[i].y != -64; i++)
 	;
 
@@ -173,73 +180,97 @@
 
     qsort (snap_x, nsnap_x, sizeof (twin_gfixed_t), compare_snap);
     qsort (snap_y, nsnap_y, sizeof (twin_gfixed_t), compare_snap);
-    
+#endif
+
 #if 0
     DBGOUT (("snap_x:"));
     for (i = 0; i < nsnap_x; i++)
 	DBGOUT ((" %d", snap_x[i])); 
     DBGOUT (("\n"));
     
-    DBGOUT (("snap_y:");
+    DBGOUT (("snap_y:"));
     for (i = 0; i < nsnap_y; i++)
 	DBGOUT ((" %d", snap_y[i])); 
     DBGOUT (("\n"));
 #endif
 
     stroke = twin_path_create ();
+    twin_path_set_matrix (stroke, twin_path_current_matrix (path));
     
+#if 0
     /* snap pen size to half integer value */
-    pen_size = SNAPH(scale_y / 24);
-    if (pen_size < TWIN_FIXED_HALF)
-	pen_size = TWIN_FIXED_HALF;
+    sx = _twin_matrix_dx (&path->state.matrix, 
+			  path->state.font_size, path->state.font_size);
     
-    if (style & TWIN_TEXT_BOLD)
+    pen_size = SNAPH(sx / 24);
+    if (pen_size < TWIN_SFIXED_HALF)
+	pen_size = TWIN_SFIXED_HALF;
+    
+    if (path->state.font_style & TWIN_TEXT_BOLD)
     {
 	twin_fixed_t	pen_add = SNAPH(pen_size >> 1);
 	if (pen_add == 0) 
-	    pen_add = TWIN_FIXED_HALF;
+	    pen_add = TWIN_SFIXED_HALF;
 	pen_size += pen_add;
     }
     
-    pen_adjust = pen_size & TWIN_FIXED_HALF;
+    pen_adjust = pen_size & TWIN_SFIXED_HALF;
+#endif
     
     pen = twin_path_create ();
-    twin_path_circle (pen, pen_size);
+    pen_matrix = twin_path_current_matrix (path);
+    /* eliminate translation part */
+    pen_matrix.m[2][0] = 0;
+    pen_matrix.m[2][1] = 0;
+    twin_path_set_matrix (pen, pen_matrix);
+    pen_size = path->state.font_size / 24;
+    if (path->state.font_style & TWIN_TEXT_BOLD)
+	pen_size += pen_size / 2;
 
-    xc = SNAPI(xo - SX (p[0].x)) + pen_adjust;
-    yc = SNAPI(yo - SY (TWIN_FONT_BASELINE) - pen_size) + pen_adjust;
+    twin_path_circle (pen, pen_size);
 
+    xc = -ScaleX(p[0].x);
+    yc = ScaleY(TWIN_FONT_BASELINE);
+    
     for (i = 1; p[i].y != -64; i++)
 	if (p[i].x == -64)
 	    twin_path_close (stroke);
 	else
 	{
-	    twin_fixed_t    x = SNAPX(p[i].x);
-	    twin_fixed_t    y = SNAPY(p[i].y);
-	    
-	    if (style & TWIN_TEXT_OBLIQUE)
+	    x = xc + ScaleX(p[i].x);
+	    y = yc + ScaleY(p[i].y);
+
+	    if (path->state.font_style & TWIN_TEXT_OBLIQUE)
 		x -= y / 4;
-	    twin_path_draw (stroke, x + xc, y + yc);
+	    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);
 	}
 
     twin_path_convolve (path, stroke, pen);
     twin_path_destroy (stroke);
     twin_path_destroy (pen);
     
+#if 0
     free (snap_x);
+#endif
 
-    xo = xo + twin_ucs4_width (ucs4, scale_x);
-    twin_path_move (path, xo, yo);
+    w = twin_width_ucs4 (path, ucs4);
+    _twin_path_smove (path, 
+		      origin.x + _twin_matrix_dx (&path->state.matrix, w, 0),
+		      origin.y + _twin_matrix_dy (&path->state.matrix, w, 0));
 }
 
 int
-twin_ucs4_width (twin_ucs4_t ucs4, twin_fixed_t scale_x)
+twin_width_ucs4 (twin_path_t *path, twin_ucs4_t ucs4)
 {
     const twin_gpoint_t	*p = _twin_ucs4_base (ucs4);
     twin_fixed_t	left, right;
     
-    left = SNAPI(SX (p[0].x));
-    right = SNAPI(SX (p[0].y));
+    left = ScaleX (p[0].x);
+    right = ScaleX (p[0].y);
     
     return right - left;
 }
@@ -313,18 +344,14 @@
 }
 
 void
-twin_path_string (twin_path_t	*path, 
-		  twin_fixed_t	scale_x,
-		  twin_fixed_t	scale_y,
-		  int		style,
-		  const char	*string)
+twin_path_utf8 (twin_path_t *path, const char *string)
 {
     int		len;
     twin_ucs4_t	ucs4;
 
     while ((len = _twin_utf8_to_ucs4(string, &ucs4)) > 0)
     {
-	twin_path_ucs4 (path, scale_x, scale_y, style, ucs4);
+	twin_path_ucs4 (path, ucs4);
 	string += len;
     }
 }

Index: twin_geom.c
===================================================================
RCS file: /local/src/CVS/twin/twin_geom.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- twin_geom.c	21 Sep 2004 15:42:56 -0000	1.1
+++ twin_geom.c	27 Sep 2004 21:28:31 -0000	1.2
@@ -25,7 +25,7 @@
 #include "twinint.h"
 
 twin_dfixed_t
-_twin_distance_to_point_squared (twin_point_t *a, twin_point_t *b)
+_twin_distance_to_point_squared (twin_spoint_t *a, twin_spoint_t *b)
 {
     twin_dfixed_t dx = (b->x - a->x);
     twin_dfixed_t dy = (b->y - a->y);
@@ -34,7 +34,7 @@
 }
 
 twin_dfixed_t
-_twin_distance_to_line_squared (twin_point_t *p, twin_point_t *p1, twin_point_t *p2)
+_twin_distance_to_line_squared (twin_spoint_t *p, twin_spoint_t *p1, twin_spoint_t *p2)
 {
     /*
      * Convert to normal form (AX + BY + C = 0)

Index: twin_hull.c
===================================================================
RCS file: /local/src/CVS/twin/twin_hull.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- twin_hull.c	25 Sep 2004 01:10:01 -0000	1.1
+++ twin_hull.c	27 Sep 2004 21:28:31 -0000	1.2
@@ -25,19 +25,28 @@
 
 #include "twinint.h"
 
+#if 0
+#include <stdio.h>
+#include <math.h>
+#define S(x)	twin_sfixed_to_double(x)
+#define DBGMSG(x)	printf x
+#else
+#define DBGMSG(x)
+#endif
+
 typedef struct twin_slope {
-    twin_fixed_t dx;
-    twin_fixed_t dy;
+    twin_sfixed_t dx;
+    twin_sfixed_t dy;
 } twin_slope_t, twin_distance_t;
 
 typedef struct _twin_hull {
-    twin_point_t point;
+    twin_spoint_t point;
     twin_slope_t slope;
     int discard;
 } twin_hull_t;
 
 static void
-_twin_slope_init (twin_slope_t *slope, twin_point_t *a, twin_point_t *b)
+_twin_slope_init (twin_slope_t *slope, twin_spoint_t *a, twin_spoint_t *b)
 {
     slope->dx = b->x - a->x;
     slope->dy = b->y - a->y;
@@ -48,7 +57,7 @@
 {
     int		    i, j;
     int		    n = path->npoints;
-    twin_point_t    *p = path->points;
+    twin_spoint_t    *p = path->points;
     twin_hull_t	    *hull;
     int		    e;
     
@@ -62,8 +71,10 @@
 	return NULL;
     *nhull = n;
 
+    DBGMSG (("original polygon: \n"));
     for (i = 0; i < n; i++) 
     {
+	DBGMSG (("\t%d: %9.4f, %9.4f\n", i, S(p[i].x), S(p[i].y)));
 	/* place extremum first in array */
 	if (i == 0) j = e;
 	else if (i == e) j = 0;
@@ -134,9 +145,15 @@
 	b_dist = ((twin_dfixed_t) b->slope.dx * b->slope.dx +
 		  (twin_dfixed_t) b->slope.dy * b->slope.dy);
 	if (a_dist < b_dist)
+	{
 	    a->discard = 1;
+	    ret = -1;
+	}
 	else
+	{
 	    b->discard = 1;
+	    ret = 1;
+	}
     }
 
     return ret;
@@ -178,6 +195,7 @@
     k = _twin_hull_next_valid (hull, num_hull, j);
 
     do {
+	DBGMSG (("i: %d j: %d k: %d\n", i, j, k));
 	_twin_slope_init (&slope_ij, &hull[i].point, &hull[j].point);
 	_twin_slope_init (&slope_jk, &hull[j].point, &hull[k].point);
 
@@ -205,11 +223,15 @@
     twin_path_t	*path = twin_path_create ();
     int		i;
 
+    DBGMSG (("convex hull\n"));
     for (i = 0; i < num_hull; i++) 
     {
+	DBGMSG (("\t%d: %9.4f, %9.4f %c\n",
+		 i, S(hull[i].point.x), S(hull[i].point.y), 
+		 hull[i].discard ? '*' : ' '));
 	if (hull[i].discard)
 	    continue;
-	twin_path_draw (path, hull[i].point.x, hull[i].point.y);
+	_twin_path_sdraw (path, hull[i].point.x, hull[i].point.y);
     }
 
     return path;

--- NEW FILE: twin_matrix.c ---
(This appears to be a binary file; contents omitted.)

Index: twin_path.c
===================================================================
RCS file: /local/src/CVS/twin/twin_path.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- twin_path.c	26 Sep 2004 09:23:23 -0000	1.4
+++ twin_path.c	27 Sep 2004 21:28:31 -0000	1.5
@@ -25,7 +25,7 @@
 #include "twinint.h"
 
 static int
-_twin_cur_subpath_len (twin_path_t *path)
+_twin_current_subpath_len (twin_path_t *path)
 {
     int	start;
     
@@ -36,23 +36,38 @@
     return path->npoints - start;
 }
 
-void
-twin_path_cur_point (twin_path_t *path, twin_fixed_t *x, twin_fixed_t *y)
+twin_spoint_t
+_twin_path_current_spoint (twin_path_t *path)
 {
     if (!path->npoints)
 	twin_path_move (path, 0, 0);
-    *x = path->points[path->npoints - 1].x;
-    *y = path->points[path->npoints - 1].y;
+    return path->points[path->npoints - 1];
+}
+
+twin_spoint_t
+_twin_path_subpath_first_spoint (twin_path_t *path)
+{
+    int	start;
+    
+    if (!path->npoints)
+	twin_path_move (path, 0, 0);
+
+    if (path->nsublen)
+	start = path->sublen[path->nsublen-1];
+    else
+	start = 0;
+    
+    return path->points[start];
 }
 
 void 
-twin_path_move (twin_path_t *path, twin_fixed_t x, twin_fixed_t y)
+_twin_path_smove (twin_path_t *path, twin_sfixed_t x, twin_sfixed_t y)
 {
-    switch (_twin_cur_subpath_len (path)) {
+    switch (_twin_current_subpath_len (path)) {
     default:
 	twin_path_close (path);
     case 0:
-	twin_path_draw (path, x, y);
+	_twin_path_sdraw (path, x, y);
 	break;
     case 1:
 	path->points[path->npoints-1].x = x;
@@ -62,25 +77,25 @@
 }
 
 void
-twin_path_draw (twin_path_t *path, twin_fixed_t x, twin_fixed_t y)
+_twin_path_sdraw (twin_path_t *path, twin_sfixed_t x, twin_sfixed_t y)
 {
-    if (_twin_cur_subpath_len(path) > 0 &&
+    if (_twin_current_subpath_len(path) > 0 &&
 	path->points[path->npoints-1].x == x &&
 	path->points[path->npoints-1].y == y)
 	return;
     if (path->npoints == path->size_points)
     {
 	int		size_points;
-	twin_point_t	*points;
+	twin_spoint_t	*points;
 	
 	if (path->size_points > 0)
 	    size_points = path->size_points * 2;
 	else
 	    size_points = 16;
 	if (path->points)
-	    points = realloc (path->points, size_points * sizeof (twin_point_t));
+	    points = realloc (path->points, size_points * sizeof (twin_spoint_t));
 	else
-	    points = malloc (size_points * sizeof (twin_point_t));
+	    points = malloc (size_points * sizeof (twin_spoint_t));
 	if (!points)
 	    return;
 	path->points = points;
@@ -92,15 +107,36 @@
 }
 
 void
+twin_path_move (twin_path_t *path, twin_fixed_t x, twin_fixed_t y)
+{
+    _twin_path_smove (path, 
+		      _twin_matrix_x (&path->state.matrix, x, y),
+		      _twin_matrix_y (&path->state.matrix, x, y));
+}
+
+void
+twin_path_draw (twin_path_t *path, twin_fixed_t x, twin_fixed_t y)
+{
+    _twin_path_sdraw (path, 
+		      _twin_matrix_x (&path->state.matrix, x, y),
+		      _twin_matrix_y (&path->state.matrix, x, y));
+}
+
+void
 twin_path_close (twin_path_t *path)
 {
-    switch (_twin_cur_subpath_len(path)) {
+    twin_spoint_t   first;
+    
+    switch (_twin_current_subpath_len(path)) {
     case 1:
 	path->npoints--;
     case 0:
 	return;
     }
     
+    first = _twin_path_subpath_first_spoint (path);
+    _twin_path_sdraw (path, first.x, first.y);
+    
     if (path->nsublen == path->size_sublen)
     {
 	int	size_sublen;
@@ -123,165 +159,109 @@
     path->nsublen++;
 }
 
-static const twin_fixed_t _sin_table[] = {
-    0x0000, /*  0 */
-    0x0192, /*  1 */
-    0x0324, /*  2 */
-    0x04b5, /*  3 */
-    0x0646, /*  4 */
-    0x07d6, /*  5 */
-    0x0964, /*  6 */
-    0x0af1, /*  7 */
-    0x0c7c, /*  8 */
-    0x0e06, /*  9 */
-    0x0f8d, /* 10 */
-    0x1112, /* 11 */
-    0x1294, /* 12 */
-    0x1413, /* 13 */
-    0x1590, /* 14 */
-    0x1709, /* 15 */
-    0x187e, /* 16 */
-    0x19ef, /* 17 */
-    0x1b5d, /* 18 */
-    0x1cc6, /* 19 */
-    0x1e2b, /* 20 */
-    0x1f8c, /* 21 */
-    0x20e7, /* 22 */
-    0x223d, /* 23 */
-    0x238e, /* 24 */
-    0x24da, /* 25 */
-    0x2620, /* 26 */
-    0x2760, /* 27 */
-    0x289a, /* 28 */
-    0x29ce, /* 29 */
-    0x2afb, /* 30 */
-    0x2c21, /* 31 */
-    0x2d41, /* 32 */
-    0x2e5a, /* 33 */
-    0x2f6c, /* 34 */
-    0x3076, /* 35 */
-    0x3179, /* 36 */
-    0x3274, /* 37 */
-    0x3368, /* 38 */
-    0x3453, /* 39 */
-    0x3537, /* 40 */
-    0x3612, /* 41 */
-    0x36e5, /* 42 */
-    0x37b0, /* 43 */
-    0x3871, /* 44 */
-    0x392b, /* 45 */
-    0x39db, /* 46 */
-    0x3a82, /* 47 */
-    0x3b21, /* 48 */
-    0x3bb6, /* 49 */
-    0x3c42, /* 50 */
-    0x3cc5, /* 51 */
-    0x3d3f, /* 52 */
-    0x3daf, /* 53 */
-    0x3e15, /* 54 */
-    0x3e72, /* 55 */
-    0x3ec5, /* 56 */
-    0x3f0f, /* 57 */
-    0x3f4f, /* 58 */
-    0x3f85, /* 59 */
-    0x3fb1, /* 60 */
-    0x3fd4, /* 61 */
-    0x3fec, /* 62 */
-    0x3ffb, /* 63 */
-    0x4000, /* 64 */
-};
-
-static twin_fixed_t
-_sin (int i, int n) 
-{
-    int	e = i << (6 - n);
-    twin_fixed_t    v;
-    
-    e &= 0xff;
-    if (e & 0x40)
-	v = _sin_table[0x40 - (e & 0x3f)];
-    else
-	v = _sin_table[e & 0x3f];
-    if (e & 0x80)
-	v = -v;
-    return v;
-}
-
-static twin_fixed_t
-_cos (int i, int n)
-{
-    return _sin (i + (0x40 >> (6 - n)), n);
-}
-
 void
 twin_path_circle (twin_path_t *path, twin_fixed_t radius)
 {
-    int		    sides = (4 * radius) / TWIN_FIXED_TOLERANCE;
+    int		    sides;
     int		    n;
-    twin_fixed_t    cx, cy;
-    twin_dfixed_t   dradius = (twin_dfixed_t) radius;
+    twin_spoint_t   center;
     int		    i;
+    twin_matrix_t   save;
+    twin_fixed_t    det;
 
-    if (sides > 256) sides = 256;
+    save = twin_path_current_matrix (path);
+
+    twin_path_scale (path, radius, radius);
+
+    center = _twin_path_current_spoint (path);
+
+    twin_path_close (path);
+    
+    /* The determinant represents the area expansion factor of the
+       transform. In the worst case, this is entirely in one
+       dimension, which is what we assume here. */
+
+    det = _twin_matrix_determinant (&path->state.matrix);
+    
+    sides = (4 * det) / twin_sfixed_to_fixed (TWIN_SFIXED_TOLERANCE);
+    
     n = 2;
     while ((1 << n) < sides)
 	n++;
 
-    if (!path->npoints)
-    {
-	cx = 0;
-	cy = 0;
-    }
-    else
+    for (i = 0; i < (1 << n); i++)
     {
-	cx = path->points[path->npoints - 1].x;
-	cy = path->points[path->npoints - 1].y;
+	twin_angle_t	a = (i * TWIN_ANGLE_360) >> n;
+	twin_fixed_t	x = twin_cos (a);
+	twin_fixed_t	y = twin_sin (a);
+
+	_twin_path_sdraw (path, 
+			  center.x + _twin_matrix_dx (&path->state.matrix, x, y),
+			  center.y + _twin_matrix_dy (&path->state.matrix, x, y));
     }
+    
+    twin_path_close (path);
+    twin_path_set_matrix (path, save);
+}
 
-    twin_path_move (path, cx + radius, cy);
+void
+twin_path_set_matrix (twin_path_t *path, twin_matrix_t matrix)
+{
+    path->state.matrix = matrix;
+}
 
-    for (i = 1; i < (1 << n); i++)
-    {
-	twin_fixed_t	x = (dradius * _cos (i, n - 2) + (1 << 13)) >> 14;
-	twin_fixed_t	y = (dradius * _sin (i, n - 2) + (1 << 13)) >> 14;
+twin_matrix_t
+twin_path_current_matrix (twin_path_t *path)
+{
+    return path->state.matrix;
+}
 
-	twin_path_draw (path, cx + x, cy + y);
-    }
-    twin_path_close (path);
+void
+twin_path_identity (twin_path_t *path)
+{
+    twin_matrix_identity (&path->state.matrix);
 }
 
 void
-twin_path_fill (twin_pixmap_t *pixmap, twin_path_t *path)
+twin_path_translate (twin_path_t *path, twin_fixed_t tx, twin_fixed_t ty)
 {
-    twin_edge_t	*edges;
-    int		nedges, n;
-    int		nalloc;
-    int		s;
-    int		p;
+    twin_matrix_translate (&path->state.matrix, tx, ty);
+}
 
-    nalloc = path->npoints + path->nsublen + 1;
-    edges = malloc (sizeof (twin_edge_t) * nalloc);
-    p = 0;
-    nedges = 0;
-    for (s = 0; s <= path->nsublen; s++)
-    {
-	int sublen;
-	int npoints;
-	
-	if (s == path->nsublen)
-	    sublen = path->npoints;
-	else
-	    sublen = path->sublen[s];
-	npoints = sublen - p;
-	if (npoints > 1)
-	{
-	    n = _twin_edge_build (path->points + p, npoints, edges + nedges);
-	    p = sublen;
-	    nedges += n;
-	}
-    }
-    _twin_edge_fill (pixmap, edges, nedges);
-    free (edges);
+void
+twin_path_scale (twin_path_t *path, twin_fixed_t sx, twin_fixed_t sy)
+{
+    twin_matrix_scale (&path->state.matrix, sx, sy);
+}
+    
+void
+twin_path_rotate (twin_path_t *path, twin_angle_t a)
+{
+    twin_matrix_rotate (&path->state.matrix, a);
+}
+    
+void
+twin_path_set_font_size (twin_path_t *path, twin_fixed_t font_size)
+{
+    path->state.font_size = font_size;
+}
+
+twin_fixed_t
+twin_path_current_font_size (twin_path_t *path)
+{
+    return path->state.font_size;
+}
+
+void
+twin_path_set_font_style (twin_path_t *path, int font_style)
+{
+    path->state.font_style = font_style;
+}
+
+int
+twin_path_current_font_style (twin_path_t *path)
+{
+    return path->state.font_style;
 }
 
 void
@@ -304,10 +284,22 @@
 	    twin_path_close (dst);
 	    s++;
 	}
-	twin_path_draw (dst, src->points[p].x, src->points[p].y);
+	_twin_path_sdraw (dst, src->points[p].x, src->points[p].y);
     }
 }
 
+twin_state_t
+twin_path_save (twin_path_t *path)
+{
+    return path->state;
+}
+
+void
+twin_path_restore (twin_path_t *path, twin_state_t *state)
+{
+    path->state = *state;
+}
+
 twin_path_t *
 twin_path_create (void)
 {
@@ -318,6 +310,9 @@
     path->nsublen = path->size_sublen = 0;
     path->points = 0;
     path->sublen = 0;
+    twin_matrix_identity (&path->state.matrix);
+    path->state.font_size = TWIN_FIXED_ONE * 15;
+    path->state.font_style = TWIN_TEXT_ROMAN;
     return path;
 }
 

Index: twin_poly.c
===================================================================
RCS file: /local/src/CVS/twin/twin_poly.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- twin_poly.c	26 Sep 2004 09:23:23 -0000	1.4
+++ twin_poly.c	27 Sep 2004 21:28:31 -0000	1.5
@@ -28,7 +28,7 @@
 #define TWIN_POLY_FIXED_SHIFT	(4 - TWIN_POLY_SHIFT)
 #define TWIN_POLY_SAMPLE    (1 << TWIN_POLY_SHIFT)
 #define TWIN_POLY_MASK	    (TWIN_POLY_SAMPLE - 1)
-#define TWIN_POLY_STEP	    (TWIN_FIXED_ONE >> TWIN_POLY_SHIFT)
+#define TWIN_POLY_STEP	    (TWIN_SFIXED_ONE >> TWIN_POLY_SHIFT)
 #define TWIN_POLY_START	    (TWIN_POLY_STEP >> 1)
 #define TWIN_POLY_CEIL(c)   (((c) + (TWIN_POLY_STEP-1)) & ~(TWIN_POLY_STEP-1))
 #define TWIN_POLY_COL(x)    (((x) >> TWIN_POLY_FIXED_SHIFT) & TWIN_POLY_MASK)
@@ -43,7 +43,7 @@
 }
 
 static void
-_edge_step_by (twin_edge_t  *edge, twin_fixed_t dy)
+_edge_step_by (twin_edge_t  *edge, twin_sfixed_t dy)
 {
     twin_dfixed_t   e;
     
@@ -58,27 +58,27 @@
  * Grid coordinates are at TWIN_POLY_STEP/2 + n*TWIN_POLY_STEP
  */
 
-static twin_fixed_t
-_twin_fixed_grid_ceil (twin_fixed_t f)
+static twin_sfixed_t
+_twin_sfixed_grid_ceil (twin_sfixed_t f)
 {
     return ((f + (TWIN_POLY_START - 1)) & ~(TWIN_POLY_STEP - 1)) + TWIN_POLY_START;
 }
 
 #if 0
 #include <stdio.h>
-#define F(x)	twin_fixed_to_double(x)
+#define F(x)	twin_sfixed_to_double(x)
 #define DBGOUT(x...)	printf(x)
 #else
 #define DBGOUT(x...)
 #endif
 
 int
-_twin_edge_build (twin_point_t *vertices, int nvertices, twin_edge_t *edges)
+_twin_edge_build (twin_spoint_t *vertices, int nvertices, twin_edge_t *edges)
 {
     int		    v, nv;
     int		    tv, bv;
     int		    e;
-    twin_fixed_t    y;
+    twin_sfixed_t    y;
 
     e = 0;
     for (v = 0; v < nvertices; v++)
@@ -107,7 +107,7 @@
 	}
 
 	/* snap top to first grid point in pixmap */
-	y = _twin_fixed_grid_ceil (vertices[tv].y);
+	y = _twin_sfixed_grid_ceil (vertices[tv].y);
 	if (y < TWIN_POLY_START)
 	    y = TWIN_POLY_START;
 	
@@ -145,9 +145,9 @@
     
 static void
 _span_fill (twin_pixmap_t   *pixmap,
-	    twin_fixed_t    y,
-	    twin_fixed_t    left,
-	    twin_fixed_t    right)
+	    twin_sfixed_t    y,
+	    twin_sfixed_t    left,
+	    twin_sfixed_t    right)
 {
 #if TWIN_POLY_SHIFT == 0
     /* 1x1 */
@@ -185,10 +185,10 @@
     };
 #endif
     const twin_a8_t *cover = coverage[(y >> TWIN_POLY_FIXED_SHIFT) & TWIN_POLY_MASK];
-    int		    row = twin_fixed_trunc (y);
+    int		    row = twin_sfixed_trunc (y);
     twin_a8_t	    *span = pixmap->p.a8 + row * pixmap->stride;
     twin_a8_t	    *s;
-    twin_fixed_t    x;
+    twin_sfixed_t    x;
     twin_a16_t	    a;
     twin_a16_t	    w;
     int		    col;
@@ -197,12 +197,12 @@
     if (left < 0)
 	left = 0;
     
-    if (right > twin_int_to_fixed (pixmap->width))
-	right = twin_int_to_fixed (pixmap->width);
+    if (right > twin_int_to_sfixed (pixmap->width))
+	right = twin_int_to_sfixed (pixmap->width);
 
     /* convert to sample grid */
-    left = _twin_fixed_grid_ceil (left) >> TWIN_POLY_FIXED_SHIFT;
-    right = _twin_fixed_grid_ceil (right) >> TWIN_POLY_FIXED_SHIFT;
+    left = _twin_sfixed_grid_ceil (left) >> TWIN_POLY_FIXED_SHIFT;
+    right = _twin_sfixed_grid_ceil (right) >> TWIN_POLY_FIXED_SHIFT;
     
     /* check for empty */
     if (right <= left)
@@ -259,8 +259,8 @@
 {
     twin_edge_t	    *active, *a, *n, **prev;
     int		    e;
-    twin_fixed_t    y;
-    twin_fixed_t    x0;
+    twin_sfixed_t    y;
+    twin_sfixed_t    x0;
     int		    w;
     
     qsort (edges, nedges, sizeof (twin_edge_t), _edge_compare_y);
@@ -299,7 +299,7 @@
 	/* step down, clipping to pixmap */
 	y += TWIN_POLY_STEP;
 
-	if (twin_fixed_trunc (y) >= pixmap->height)
+	if (twin_sfixed_trunc (y) >= pixmap->height)
 	    break;
 	
 	/* strip out dead edges */
@@ -336,18 +336,36 @@
 }
 
 void
-twin_polygon (twin_pixmap_t *pixmap, twin_point_t *vertices, int nvertices)
+twin_fill_path (twin_pixmap_t *pixmap, twin_path_t *path)
 {
-    twin_edge_t	    *edges;
-    int		    nedges;
-    
-    /*
-     * Construct the edge table
-     */
-    edges = malloc (sizeof (twin_edge_t) * (nvertices + 1));
-    if (!edges)
-	return;
-    nedges = _twin_edge_build (vertices, nvertices, edges);
+    twin_edge_t	*edges;
+    int		nedges, n;
+    int		nalloc;
+    int		s;
+    int		p;
+
+    nalloc = path->npoints + path->nsublen + 1;
+    edges = malloc (sizeof (twin_edge_t) * nalloc);
+    p = 0;
+    nedges = 0;
+    for (s = 0; s <= path->nsublen; s++)
+    {
+	int sublen;
+	int npoints;
+	
+	if (s == path->nsublen)
+	    sublen = path->npoints;
+	else
+	    sublen = path->sublen[s];
+	npoints = sublen - p;
+	if (npoints > 1)
+	{
+	    n = _twin_edge_build (path->points + p, npoints, edges + nedges);
+	    p = sublen;
+	    nedges += n;
+	}
+    }
     _twin_edge_fill (pixmap, edges, nedges);
     free (edges);
 }
+

Index: twin_spline.c
===================================================================
RCS file: /local/src/CVS/twin/twin_spline.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- twin_spline.c	25 Sep 2004 01:10:01 -0000	1.2
+++ twin_spline.c	27 Sep 2004 21:28:31 -0000	1.3
@@ -25,11 +25,11 @@
 #include "twinint.h"
 
 typedef struct _twin_spline {
-    twin_point_t    a, b, c, d;
+    twin_spoint_t    a, b, c, d;
 } twin_spline_t;
 
 static void
-_lerp_half (twin_point_t *a, twin_point_t *b, twin_point_t *result)
+_lerp_half (twin_spoint_t *a, twin_spoint_t *b, twin_spoint_t *result)
 {
     result->x = a->x + ((b->x - a->x) >> 1);
     result->y = a->y + ((b->y - a->y) >> 1);
@@ -38,9 +38,9 @@
 static void
 _de_casteljau (twin_spline_t *spline, twin_spline_t *s1, twin_spline_t *s2)
 {
-    twin_point_t ab, bc, cd;
-    twin_point_t abbc, bccd;
-    twin_point_t final;
+    twin_spoint_t ab, bc, cd;
+    twin_spoint_t abbc, bccd;
+    twin_spoint_t final;
 
     _lerp_half (&spline->a, &spline->b, &ab);
     _lerp_half (&spline->b, &spline->c, &bc);
@@ -91,7 +91,7 @@
 {
     if (_twin_spline_error_squared (spline) <= tolerance_squared)
     {
-	twin_path_draw (path, spline->a.x, spline->a.y);
+	_twin_path_sdraw (path, spline->a.x, spline->a.y);
     }
     else
     {
@@ -102,16 +102,16 @@
     }
 }
 
-void
-twin_path_curve (twin_path_t	*path,
-		 twin_fixed_t	x1, twin_fixed_t y1,
-		 twin_fixed_t	x2, twin_fixed_t y2,
-		 twin_fixed_t	x3, twin_fixed_t y3)
+static 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)
 {
     twin_spline_t   spline;
 
     if (path->npoints == 0)
-	twin_path_move (path, 0, 0);
+	_twin_path_smove (path, 0, 0);
     spline.a = path->points[path->npoints - 1];
     spline.b.x = x1;
     spline.b.y = y1;
@@ -119,6 +119,21 @@
     spline.c.y = y2;
     spline.d.x = x3;
     spline.d.y = y3;
-    _twin_spline_decompose (path, &spline, TWIN_FIXED_TOLERANCE * TWIN_FIXED_TOLERANCE);
-    twin_path_draw (path, x3, y3);
+    _twin_spline_decompose (path, &spline, TWIN_SFIXED_TOLERANCE * TWIN_SFIXED_TOLERANCE);
+    _twin_path_sdraw (path, x3, y3);
+}
+
+void
+twin_path_curve (twin_path_t	*path,
+		 twin_fixed_t   x1, twin_fixed_t y1,
+		 twin_fixed_t   x2, twin_fixed_t y2,
+		 twin_fixed_t   x3, twin_fixed_t y3)
+{
+    return _twin_path_scurve (path,
+			      _twin_matrix_x (&path->state.matrix, x1, y1),
+			      _twin_matrix_y (&path->state.matrix, x1, y1),
+			      _twin_matrix_x (&path->state.matrix, x2, y2),
+			      _twin_matrix_y (&path->state.matrix, x2, y2),
+			      _twin_matrix_x (&path->state.matrix, x3, y3),
+			      _twin_matrix_y (&path->state.matrix, x3, y3));
 }

--- NEW FILE: twin_trig.c ---
(This appears to be a binary file; contents omitted.)

Index: twinint.h
===================================================================
RCS file: /local/src/CVS/twin/twinint.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- twinint.h	25 Sep 2004 06:41:19 -0000	1.5
+++ twinint.h	27 Sep 2004 21:28:31 -0000	1.6
@@ -29,6 +29,40 @@
 #include <string.h>
 
 /*
+ * Post-transformed points are stored in 12.4 fixed point
+ * values
+ */
+
+typedef int16_t	    twin_sfixed_t;  /* 12.4 format */
+typedef int32_t	    twin_dfixed_t;  /* 24.8 format (12.4 * 12.4) */
+
+#define twin_sfixed_floor(f)	    ((f) & ~0xf)
+#define twin_sfixed_trunc(f)	    ((f) >> 4)
+#define twin_sfixed_ceil(f)	    (((f) + 0xf) & ~0xf)
+
+#define twin_int_to_sfixed(i)	    ((twin_sfixed_t) ((i) * 16))
+
+#define twin_sfixed_to_fixed(s)	    (((twin_fixed_t) (s)) << 12)
+#define twin_fixed_to_sfixed(f)	    ((twin_sfixed_t) ((f) >> 12))
+
+/* 
+ * 'double' is a no-no in any shipping code, but useful during
+ * development
+ */
+#define twin_double_to_sfixed(d)    ((twin_sfixed_t) ((d) * 16.0))
+#define twin_sfixed_to_double(f)    ((double) (f) / 16.0)
+
+#define TWIN_SFIXED_ONE		(0x10)
+#define TWIN_SFIXED_HALF	(0x08)
+#define TWIN_SFIXED_TOLERANCE	(TWIN_SFIXED_ONE >> 2)
+
+/*
+ * Glyph coordinates are stored in 2.6 fixed point
+ */
+
+typedef signed char	twin_gfixed_t;
+
+/*
  * Compositing stuff
  */
 #define twin_int_mult(a,b,t)	((t) = (a) * (b) + 0x80, \
@@ -82,6 +116,24 @@
 			   twin_source_u	src,
 			   int			width);
 
+/* Geometrical objects */
+
+typedef struct _twin_point {
+    twin_sfixed_t    x, y;
+} twin_spoint_t;
+
+struct _twin_path {
+    twin_spoint_t   *points;
+    int		    size_points;
+    int		    npoints;
+    int		    *sublen;
+    int		    size_sublen;
+    int		    nsublen;
+    twin_state_t    state;
+};
+
+typedef struct _twin_gpoint { twin_gfixed_t x, y; } twin_gpoint_t;
+
 /*
  * This needs to be refactored to reduce the number of functions...
  */
@@ -221,10 +273,10 @@
  */
 
 twin_dfixed_t
-_twin_distance_to_point_squared (twin_point_t *a, twin_point_t *b);
+_twin_distance_to_point_squared (twin_spoint_t *a, twin_spoint_t *b);
 
 twin_dfixed_t
-_twin_distance_to_line_squared (twin_point_t *p, twin_point_t *p1, twin_point_t *p2);
+_twin_distance_to_line_squared (twin_spoint_t *p, twin_spoint_t *p1, twin_spoint_t *p2);
 
 
 /*
@@ -233,12 +285,12 @@
 
 typedef struct _twin_edge {
     struct _twin_edge	*next;
-    twin_fixed_t	top, bot;
-    twin_fixed_t	x;
-    twin_fixed_t	e;
-    twin_fixed_t	dx, dy;
-    twin_fixed_t	inc_x;
-    twin_fixed_t	step_x;
+    twin_sfixed_t	top, bot;
+    twin_sfixed_t	x;
+    twin_sfixed_t	e;
+    twin_sfixed_t	dx, dy;
+    twin_sfixed_t	inc_x;
+    twin_sfixed_t	step_x;
     int			winding;
 } twin_edge_t;
 
@@ -247,50 +299,57 @@
  */
 
 int
-_twin_edge_build (twin_point_t *vertices, int nvertices, twin_edge_t *edges);
+_twin_edge_build (twin_spoint_t *vertices, int nvertices, twin_edge_t *edges);
 
 void
 _twin_edge_fill (twin_pixmap_t *pixmap, twin_edge_t *edges, int nedges);
 
 /*
- * Path stuff
+ * Matrix stuff
  */
 
+twin_sfixed_t
+_twin_matrix_x (twin_matrix_t *m, twin_fixed_t x, twin_fixed_t y);
+
+twin_sfixed_t
+_twin_matrix_y (twin_matrix_t *m, twin_fixed_t x, twin_fixed_t y);
+
+twin_sfixed_t
+_twin_matrix_dx (twin_matrix_t *m, twin_fixed_t x, twin_fixed_t y);
+
+twin_sfixed_t
+_twin_matrix_dy (twin_matrix_t *m, twin_fixed_t x, twin_fixed_t y);
+
+twin_fixed_t
+_twin_matrix_determinant (twin_matrix_t *matrix);
+
 /*
- * A (fixed point) path
+ * Path stuff
  */
 
-struct _twin_path {
-    twin_point_t    *points;
-    int		    size_points;
-    int		    npoints;
-    int		    *sublen;
-    int		    size_sublen;
-    int		    nsublen;
-};
-
 /*
- * Glyph stuff
+ * A path
  */
 
-typedef signed char	twin_gfixed_t;
+twin_spoint_t
+_twin_path_current_spoint (twin_path_t *path);
 
-typedef struct _twin_gpoint { twin_gfixed_t x, y; } twin_gpoint_t;
+twin_spoint_t
+_twin_path_subpath_first_spoint (twin_path_t *path);
 
-#define TWIN_FONT_MAX	0x7f
+void 
+_twin_path_smove (twin_path_t *path, twin_sfixed_t x, twin_sfixed_t y);
 
-extern const twin_gpoint_t	*_twin_font[TWIN_FONT_MAX + 1];
-extern const twin_gpoint_t	*_twin_default_char;
+void
+_twin_path_sdraw (twin_path_t *path, twin_sfixed_t x, twin_sfixed_t y);
 
-extern const twin_gpoint_t	_twin_glyphs[];
-extern const uint16_t		_twin_glyph_offsets[];
+/*
+ * Glyph stuff.  Coordinates are stored in 2.6 fixed point format
+ */
 
-#define TWIN_UCS_PAGE_SHIFT 7
-#define TWIN_UCS_PER_PAGE   (1 << TWIN_UCS_PAGE_SHIFT)
+#define TWIN_FONT_MAX	0x7f
 
-typedef struct _twin_charmap {
-    uint16_t	page;
-    uint16_t	offsets[TWIN_UCS_PER_PAGE];
-} twin_charmap_t;
+extern const twin_gpoint_t	_twin_glyphs[];
+extern const uint16_t		_twin_glyph_offsets[];
 
 #endif /* _TWININT_H_ */

Index: xtwin.c
===================================================================
RCS file: /local/src/CVS/twin/xtwin.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- xtwin.c	26 Sep 2004 09:44:29 -0000	1.9
+++ xtwin.c	27 Sep 2004 21:28:31 -0000	1.10
@@ -29,37 +29,47 @@
 
 #define D(x) twin_double_to_fixed(x)
 
-static int styles[] = {
+int styles[] = {
     TWIN_TEXT_ROMAN,
     TWIN_TEXT_OBLIQUE,
     TWIN_TEXT_BOLD,
     TWIN_TEXT_BOLD|TWIN_TEXT_OBLIQUE
 };
 
+#define WIDTH	512
+#define HEIGHT	512
+
 int
 main (int argc, char **argv)
 {
     Display	    *dpy = XOpenDisplay (0);
-    twin_x11_t	    *x11 = twin_x11_create (dpy, 1024, 512);
-    twin_pixmap_t   *red = twin_pixmap_create (TWIN_ARGB32, 1024, 512);
+    twin_x11_t	    *x11 = twin_x11_create (dpy, WIDTH, HEIGHT);
+    twin_pixmap_t   *red = twin_pixmap_create (TWIN_ARGB32, WIDTH, HEIGHT);
     twin_pixmap_t   *blue = twin_pixmap_create (TWIN_ARGB32, 100, 100);
-    twin_pixmap_t   *alpha = twin_pixmap_create (TWIN_A8, 1024, 512);
+    twin_pixmap_t   *alpha = twin_pixmap_create (TWIN_A8, WIDTH, HEIGHT);
     twin_operand_t  source, mask;
     twin_path_t	    *path;
-    twin_path_t	    *pen;
-    twin_path_t	    *stroke;
     XEvent	    ev, motion;
     twin_bool_t	    had_motion;
     int		    x, y;
+    twin_path_t	    *pen;
+    twin_path_t	    *stroke;
+    twin_path_t	    *extra;
+    int		    s;
     twin_fixed_t    fx, fy;
     int		    g;
-    int		    s;
 
+    extra = 0;
+    stroke = 0;
+    s = 0;
+    fx = 0;
+    fy = 0;
+    g = 0 ;
     pen = twin_path_create ();
     twin_path_circle (pen, D (1));
     
-    twin_fill (red, 0x00000000, TWIN_SOURCE, 0, 0, 1024, 512);
-    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, 1024, 512);
+    twin_fill (red, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
+    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
 
     path = twin_path_create ();
 #if 0
@@ -69,13 +79,13 @@
 	int glyph = g;
 	if (!twin_has_glyph (glyph)) glyph = 0;
 	twin_path_cur_point (path, &fx, &fy);
-	if (fx + twin_glyph_width (glyph, D(10)) >= D(1024) || g % 50 == 0)
+	if (fx + twin_glyph_width (glyph, D(10)) >= D(WIDTH) || g % 50 == 0)
 	    twin_path_move (path, D(3), fy + D(10));
 	twin_path_glyph (path, D(10), D(10), TWIN_TEXT_ROMAN,
 			 glyph);
     }
 #endif
-#if 1
+#if 0
     stroke = twin_path_create ();
     twin_path_move (stroke, D(30), D(400));
     twin_path_string (stroke, D(200), D(200), TWIN_TEXT_ROMAN, "jelly world.");
@@ -88,11 +98,45 @@
     twin_path_convolve (path, stroke, pen);
 #endif
     
+#if 0
+    stroke = twin_path_create ();
+    pen = twin_path_create ();
+    twin_path_translate (stroke, D(100), D(100));
+/*    twin_path_rotate (stroke, twin_degrees_to_angle (270)); */
+    twin_path_rotate (stroke, twin_degrees_to_angle (270));
+    twin_path_move (stroke, D(0), D(0));
+    twin_path_draw (stroke, D(100), D(0));
+    twin_path_set_matrix (pen, twin_path_current_matrix (stroke));
+    twin_path_circle (pen, D(20));
+    twin_path_convolve (path, stroke, pen);
+#endif
+    
+#if 0
+    stroke = twin_path_create ();
+    twin_path_translate (stroke, D(250), D(250));
+    twin_path_circle (stroke, 0x42aaa);
+    extra = twin_path_convex_hull (stroke);
+    twin_path_convolve (path, extra, pen);
+#endif
+    
 #if 1
+    twin_path_translate (path, D(300), D(300));
+    twin_path_set_font_size (path, D(15));
+    for (s = 0; s < 41; s++)
+    {
+	twin_state_t	state = twin_path_save (path);
+	twin_path_rotate (path, twin_degrees_to_angle (9 * s));
+	twin_path_move (path, D(100), D(0));
+	twin_path_utf8 (path, "Hello, world!");
+	twin_path_restore (path, &state);
+    }
+#endif
+#if 0
     fx = D(3);
     fy = 0;
     for (g = 8; g < 30; g += 4)
     {
+        twin_path_set_font_size (path, D(g));
 #if 0
         fy += D(g+2);
 	twin_path_move (path, fx, fy);
@@ -112,15 +156,17 @@
 	{
 	    fy += D(g+2);
 	    twin_path_move (path, fx, fy);
-	    twin_path_string (path, D(g), D(g), styles[s],
-			      "the quick brown fox jumps over the lazy dog.");
-	    twin_path_string (path, D(g), D(g), styles[s], 
-			      "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.");
+	    twin_path_set_font_style (path, styles[s]);
+	    twin_path_utf8 (path,
+			    "the quick brown fox jumps over the lazy dog.");
+	    twin_path_utf8 (path,
+			    "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG.");
 	}
 #endif
 #if 0
 	fy += D(g);
-	twin_path_string (path, D(g), D(g), "t");
+	twin_path_move (path, fx, fy);
+	twin_path_utf8 (path, "t");
 #endif
     }
 #endif
@@ -137,7 +183,7 @@
 	fy += D(g);
     }
 #endif
-    twin_path_fill (alpha, path);
+    twin_fill_path (alpha, path);
     
     twin_path_destroy (path);
     
@@ -146,13 +192,91 @@
     mask.source_kind = TWIN_PIXMAP;
     mask.u.pixmap = alpha;
     twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
-		    1024, 512);
+		    WIDTH, HEIGHT);
 
     twin_fill (blue, 0x00000000, TWIN_SOURCE, 0, 0, 100, 100);
 
 #if 0
     path = twin_path_create ();
 
+    twin_path_rotate (path, -TWIN_ANGLE_45);
+    twin_path_translate (path, D(10), D(2));
+    for (s = 0; s < 40; s++)
+    {
+	twin_path_rotate (path, TWIN_ANGLE_11_25 / 16);
+	twin_path_scale (path, D(1.125), D(1.125));
+	twin_path_move (path, D(0), D(0));
+	twin_path_draw (path, D(1), D(0));
+	twin_path_draw (path, D(1), D(1));
+	twin_path_draw (path, D(0), D(1));
+    }
+    
+    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
+    twin_fill_path (alpha, path);
+    
+    source.source_kind = TWIN_SOLID;
+    source.u.argb = 0xffff0000;
+    mask.source_kind = TWIN_PIXMAP;
+    mask.u.pixmap = alpha;
+    twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
+		    WIDTH, HEIGHT);
+#endif
+
+#if 0
+    path = twin_path_create ();
+    stroke = twin_path_create ();
+
+    twin_path_translate (stroke, D(62), D(62));
+    twin_path_scale (stroke,D(60),D(60));
+    for (s = 0; s < 60; s++)
+    {
+        twin_state_t    save = twin_path_save (stroke);
+	twin_angle_t    a = s * TWIN_ANGLE_90 / 15;
+	    
+	twin_path_rotate (stroke, a);
+        twin_path_move (stroke, D(1), 0);
+	if (s % 5 == 0)
+	    twin_path_draw (stroke, D(0.85), 0);
+	else
+	    twin_path_draw (stroke, D(.98), 0);
+        twin_path_restore (stroke, &save);
+    }
+    twin_path_convolve (path, stroke, pen);
+    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
+    twin_fill_path (alpha, path);
+    
+    source.source_kind = TWIN_SOLID;
+    source.u.argb = 0xffff0000;
+    mask.source_kind = TWIN_PIXMAP;
+    mask.u.pixmap = alpha;
+    twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
+		    WIDTH, HEIGHT);
+#endif
+
+#if 0
+    path = twin_path_create ();
+    stroke = twin_path_create ();
+
+    twin_path_translate (stroke, D(100), D(100));
+    twin_path_scale (stroke, D(10), D(10));
+    twin_path_move (stroke, D(0), D(0));
+    twin_path_draw (stroke, D(10), D(0));
+    twin_path_convolve (path, stroke, pen);
+    
+    twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, WIDTH, HEIGHT);
+    twin_fill_path (alpha, path);
+    
+    source.source_kind = TWIN_SOLID;
+    source.u.argb = 0xffff0000;
+    mask.source_kind = TWIN_PIXMAP;
+    mask.u.pixmap = alpha;
+    twin_composite (red, 0, 0, &source, 0, 0, &mask, 0, 0, TWIN_OVER,
+		    WIDTH, HEIGHT);
+#endif
+    
+#if 0
+    path = twin_path_create ();
+
     stroke = twin_path_create ();
     
     twin_path_move (stroke, D (10), D (40));
@@ -165,7 +289,7 @@
     twin_path_destroy (stroke);
 
     twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, 100, 100);
-    twin_path_fill (alpha, path);
+    twin_fill_path (alpha, path);
     source.source_kind = TWIN_SOLID;
     source.u.argb = 0xff00ff00;
     mask.source_kind = TWIN_PIXMAP;
@@ -182,7 +306,7 @@
     twin_path_curve (stroke, D (70), D (70), D (80), D (70), D (100), D (50));
 
     twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, 100, 100);
-    twin_path_fill (alpha, stroke);
+    twin_fill_path (alpha, stroke);
     
     source.source_kind = TWIN_SOLID;
     source.u.argb = 0xffff0000;
@@ -194,7 +318,7 @@
     twin_path_convolve (path, stroke, pen);
     
     twin_fill (alpha, 0x00000000, TWIN_SOURCE, 0, 0, 100, 100);
-    twin_path_fill (alpha, path);
+    twin_fill_path (alpha, path);
 
     source.source_kind = TWIN_SOLID;
     source.u.argb = 0xff0000ff;




More information about the Commit mailing list