[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
- Previous message: [Commit] twin ChangeLog, 1.9, 1.10 twin_convolve.c, 1.5,
1.6 twin_font.c, 1.5, 1.6 xtwin.c, 1.8, 1.9
- Next message: [Commit] twin ChangeLog, 1.11, 1.12 twin.h, 1.8, 1.9 twin_fixed.c,
1.1, 1.2 twin_font.c, 1.7, 1.8 twin_matrix.c, 1.1,
1.2 twin_path.c, 1.5, 1.6 twinint.h, 1.6, 1.7 xtwin.c, 1.10, 1.11
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
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;
- Previous message: [Commit] twin ChangeLog, 1.9, 1.10 twin_convolve.c, 1.5,
1.6 twin_font.c, 1.5, 1.6 xtwin.c, 1.8, 1.9
- Next message: [Commit] twin ChangeLog, 1.11, 1.12 twin.h, 1.8, 1.9 twin_fixed.c,
1.1, 1.2 twin_font.c, 1.7, 1.8 twin_matrix.c, 1.1,
1.2 twin_path.c, 1.5, 1.6 twinint.h, 1.6, 1.7 xtwin.c, 1.10, 1.11
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Commit
mailing list