[cairo-commit] 11 commits - src/cairo.c src/cairo-compiler-private.h src/cairo-font-face-twin.c src/cairo-hash.c src/cairoint.h src/cairo-pattern.c src/cairo-scaled-font-subsets.c src/cairo-spline.c src/cairo-xlib-surface.c test/cairo-test-runner.c test/Makefile.am test/twin.c test/twin.pdf.ref.png test/twin.ps2.ref.png test/twin.ps3.ref.png test/twin.ref.png test/twin.svg11.ref.png test/twin.svg12.ref.png util/cairo-script util/cairo-trace

Chris Wilson ickle at kemper.freedesktop.org
Wed Nov 19 03:59:38 PST 2008


 src/cairo-compiler-private.h                 |    8 -
 src/cairo-font-face-twin.c                   |    3 
 src/cairo-hash.c                             |    2 
 src/cairo-pattern.c                          |    2 
 src/cairo-scaled-font-subsets.c              |   20 ++--
 src/cairo-spline.c                           |    6 -
 src/cairo-xlib-surface.c                     |    4 
 src/cairo.c                                  |    1 
 src/cairoint.h                               |    1 
 test/Makefile.am                             |    2 
 test/cairo-test-runner.c                     |  120 ++++++++++++++-------------
 test/twin.c                                  |    2 
 test/twin.pdf.ref.png                        |binary
 test/twin.ps2.ref.png                        |binary
 test/twin.ps3.ref.png                        |binary
 test/twin.ref.png                            |binary
 test/twin.svg11.ref.png                      |binary
 test/twin.svg12.ref.png                      |binary
 util/cairo-script/.gitignore                 |    1 
 util/cairo-script/Makefile.am                |    7 +
 util/cairo-script/cairo-script-interpreter.c |    1 
 util/cairo-script/cairo-script-operators.c   |    1 
 util/cairo-script/cairo-script-private.h     |   17 +++
 util/cairo-script/cairo-script-scanner.c     |    1 
 util/cairo-script/csi-replay.c               |   85 +++++++++++++++++++
 util/cairo-trace/lookup-symbol.c             |   70 +++++++++++++--
 util/cairo-trace/trace.c                     |   26 ++++-
 27 files changed, 286 insertions(+), 94 deletions(-)

New commits:
commit 81ef772aa0bf512ec5ad8752da160117498bdb30
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 19 11:00:35 2008 +0000

    [xlib] Mark GC as dirty if we have an outstanding clip.
    
    Ginn Chen reported a regression with Firefox where "the whole area of web
    page is transparent until it redraws", and bisected it to the change to
    lazily clear the clip.
    
    The bug would appears to be when we have an inconsistent GC clip - i.e.
    the clip on the surface has been cleared, but we have not yet used and
    thus cleared the GC, so that we did not mark the GC as having a clip set
    when we freed it.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 12c2ccc..840e7f5 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -307,7 +307,9 @@ _cairo_xlib_surface_finish (void *abstract_surface)
 	status2 = _cairo_xlib_screen_put_gc (surface->screen_info,
 		                             surface->depth,
 				             surface->gc,
-				             surface->have_clip_rects);
+				             surface->have_clip_rects |
+					     (surface->clip_dirty &
+					      CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC));
 	surface->gc = NULL;
 	if (status == CAIRO_STATUS_SUCCESS)
 	    status = status2;
commit c41b99268dd2424d09ab12ca560d5db30b6b6faf
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 19 11:49:04 2008 +0000

    Conditionally include byteswap.h
    
    Fixup compilation by copying the checks from cairo-wideint-private.h to
    conditionally include byteswap.h and provide fallback implementations.

diff --git a/util/cairo-script/cairo-script-interpreter.c b/util/cairo-script/cairo-script-interpreter.c
index 2163046..fea6a4a 100644
--- a/util/cairo-script/cairo-script-interpreter.c
+++ b/util/cairo-script/cairo-script-interpreter.c
@@ -39,7 +39,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <byteswap.h>
 #include <math.h>
 
 csi_status_t
diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c
index dc1c208..03bd521 100644
--- a/util/cairo-script/cairo-script-operators.c
+++ b/util/cairo-script/cairo-script-operators.c
@@ -40,7 +40,6 @@
 #include <string.h>
 #include <math.h>
 #include <assert.h>
-#include <byteswap.h>
 
 typedef struct _csi_proxy {
     csi_t *ctx;
diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h
index b700977..8ab1f63 100644
--- a/util/cairo-script/cairo-script-private.h
+++ b/util/cairo-script/cairo-script-private.h
@@ -75,6 +75,23 @@
 #error Cannot find definitions for fixed-width integral types (uint8_t, uint32_t, etc.)
 #endif
 
+#if HAVE_BYTESWAP_H
+# include <byteswap.h>
+#endif
+#ifndef bswap_16
+# define bswap_16(p) \
+	(((((uint16_t)(p)) & 0x00ff) << 8) | \
+	  (((uint16_t)(p))           >> 8));
+#endif
+#ifndef bswap_32
+# define bswap_32(p) \
+         (((((uint32_t)(p)) & 0x000000ff) << 24) | \
+	  ((((uint32_t)(p)) & 0x0000ff00) << 8)  | \
+	  ((((uint32_t)(p)) & 0x00ff0000) >> 8)  | \
+	  ((((uint32_t)(p)))              >> 24));
+#endif
+
+
 #if __GNUC__ >= 3 && defined(__ELF__) && !defined(__sun)
 # define slim_hidden_proto(name)		slim_hidden_proto1(name, slim_hidden_int_name(name)) csi_private
 # define slim_hidden_proto_no_warn(name)	slim_hidden_proto1(name, slim_hidden_int_name(name)) csi_private_no_warn
diff --git a/util/cairo-script/cairo-script-scanner.c b/util/cairo-script/cairo-script-scanner.c
index bc3ff2c..484acd9 100644
--- a/util/cairo-script/cairo-script-scanner.c
+++ b/util/cairo-script/cairo-script-scanner.c
@@ -37,7 +37,6 @@
 #include <stdio.h> /* EOF */
 #include <string.h> /* memset */
 #include <math.h> /* pow */
-#include <byteswap.h> /* bswap_32 */
 
 /*
  * whitespace:
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index 1b94ea1..30c915d 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -31,7 +31,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include <pthread.h>
-#include <byteswap.h>
 #include <zlib.h>
 #include <math.h>
 #include <ctype.h>
@@ -45,6 +44,22 @@
 #define CAIRO_TRACE_OUTDIR "."
 #endif
 
+#if HAVE_BYTESWAP_H
+# include <byteswap.h>
+#endif
+#ifndef bswap_16
+# define bswap_16(p) \
+	(((((uint16_t)(p)) & 0x00ff) << 8) | \
+	  (((uint16_t)(p))           >> 8));
+#endif
+#ifndef bswap_32
+# define bswap_32(p) \
+         (((((uint32_t)(p)) & 0x000000ff) << 24) | \
+	  ((((uint32_t)(p)) & 0x0000ff00) << 8)  | \
+	  ((((uint32_t)(p)) & 0x00ff0000) >> 8)  | \
+	  ((((uint32_t)(p)))              >> 24));
+#endif
+
 #include "lookup-symbol.h"
 
 /* Reverse the bits in a byte with 7 operations (no 64-bit):
commit 8345fedbe4d4d003c1f26a78ac7c512c04d04173
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 19 11:44:42 2008 +0000

    [spline] Fix compile.
    
    Do not return the result of a void function. gcc chose to not warn about
    this when removing the return parameter...

diff --git a/src/cairo-spline.c b/src/cairo-spline.c
index 7ec1c56..b528544 100644
--- a/src/cairo-spline.c
+++ b/src/cairo-spline.c
@@ -186,8 +186,10 @@ _cairo_spline_decompose_into (cairo_spline_knots_t *s1, double tolerance_squared
 {
     cairo_spline_knots_t s2;
 
-    if (_cairo_spline_error_squared (s1) < tolerance_squared)
-	return _cairo_spline_add_point (result, &s1->a);
+    if (_cairo_spline_error_squared (s1) < tolerance_squared) {
+	_cairo_spline_add_point (result, &s1->a);
+	return;
+    }
 
     _de_casteljau (s1, &s2);
 
commit b6c371a47f33ec10d4d6130cc15677761df2bdfd
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 19 08:44:24 2008 +0000

    [pattern] Cosmetic.
    
    surface is equal to pattern->surface at this point.

diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c
index c78317e..bdcafe7 100644
--- a/src/cairo-pattern.c
+++ b/src/cairo-pattern.c
@@ -1842,7 +1842,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t   *pat
 	if (status)
 	    goto BAIL;
 
-	status = _cairo_surface_clone_similar (dst, pattern->surface,
+	status = _cairo_surface_clone_similar (dst, surface,
 					       extents.x, extents.y,
 					       extents.width, extents.height,
 					       &extents.x, &extents.y, &src);
commit 7894abbe6d43b10ab2a92d99bdd6a08878e9022c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Wed Nov 19 08:37:26 2008 +0000

    [test] Support foreground only execution.
    
    Add an option to prevent forking - which makes it difficult to
    valgrind/gdb individual tests.

diff --git a/test/Makefile.am b/test/Makefile.am
index eab2328..3afac51 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1296,6 +1296,7 @@ run:
 	$(MAKE) $(AM_MAKEFLAGS) check TESTS_ENVIRONMENT='$(TESTS_ENVIRONMENT) $(top_builddir)/libtool --mode=execute env $(TOOL)'
 
 # Check tests under valgrind.  Saves log to valgrind-log
+check-valgrind: MODE+=,foreground
 check-valgrind:
 	$(MAKE) $(AM_MAKEFLAGS) check TESTS_ENVIRONMENT='$(TESTS_ENVIRONMENT) $(top_builddir)/libtool --mode=execute valgrind $(VALGRIND_FLAGS)' 2>&1 | tee valgrind-log
 
diff --git a/test/cairo-test-runner.c b/test/cairo-test-runner.c
index 34a5725..4fb0cbe 100644
--- a/test/cairo-test-runner.c
+++ b/test/cairo-test-runner.c
@@ -51,6 +51,31 @@ typedef struct _cairo_test_list {
     struct _cairo_test_list *next;
 } cairo_test_list_t;
 
+typedef struct _cairo_test_runner {
+    cairo_test_context_t base;
+
+    unsigned int num_device_offsets;
+
+    int num_passed;
+    int num_xpassed;
+    int num_skipped;
+    int num_failed;
+    int num_xfailed;
+    int num_crashed;
+
+    cairo_test_list_t **crashes_per_target;
+    cairo_test_list_t **fails_per_target;
+    cairo_test_list_t **xpasses_per_target;
+
+    int *num_failed_per_target;
+    int *num_crashed_per_target;
+    int *num_xpassed_per_target;
+
+    cairo_bool_t foreground;
+    cairo_bool_t list_only;
+    cairo_bool_t full_test;
+} cairo_test_runner_t;
+
 typedef enum {
     GE,
     GT
@@ -137,50 +162,54 @@ _cairo_test_wait (pid_t pid)
 #endif
 
 static cairo_test_status_t
-_cairo_test_runner_preamble (cairo_test_context_t *ctx)
+_cairo_test_runner_preamble (cairo_test_runner_t *runner,
+			     cairo_test_context_t *ctx)
 {
 #if HAVE_FORK && HAVE_WAITPID
-    pid_t pid;
+    if (! runner->foreground) {
+	pid_t pid;
 
-    switch ((pid = fork ())) {
-    case -1: /* error */
-	return CAIRO_TEST_UNTESTED;
+	switch ((pid = fork ())) {
+	case -1: /* error */
+	    return CAIRO_TEST_UNTESTED;
 
-    case 0: /* child */
-	exit (ctx->test->preamble (ctx));
+	case 0: /* child */
+	    exit (ctx->test->preamble (ctx));
 
-    default:
-	return _cairo_test_wait (pid);
+	default:
+	    return _cairo_test_wait (pid);
+	}
     }
-#else
-    return ctx->test->preamble (ctx);
 #endif
+    return ctx->test->preamble (ctx);
 }
 
 static cairo_test_status_t
-_cairo_test_runner_draw (cairo_test_context_t *ctx,
+_cairo_test_runner_draw (cairo_test_runner_t *runner,
+			 cairo_test_context_t *ctx,
 			 const cairo_boilerplate_target_t *target,
 			 cairo_bool_t similar,
 			 int device_offset)
 {
 #if HAVE_FORK && HAVE_WAITPID
-    pid_t pid;
+    if (! runner->foreground) {
+	pid_t pid;
 
-    switch ((pid = fork ())) {
-    case -1: /* error */
-	return CAIRO_TEST_UNTESTED;
+	switch ((pid = fork ())) {
+	case -1: /* error */
+	    return CAIRO_TEST_UNTESTED;
 
-    case 0: /* child */
-	exit (_cairo_test_context_run_for_target (ctx, target,
-						  similar, device_offset));
+	case 0: /* child */
+	    exit (_cairo_test_context_run_for_target (ctx, target,
+						      similar, device_offset));
 
-    default:
-	return _cairo_test_wait (pid);
+	default:
+	    return _cairo_test_wait (pid);
+	}
     }
-#else
+#endif
     return _cairo_test_context_run_for_target (ctx, target,
 					       similar, device_offset);
-#endif
 }
 
 static void
@@ -243,43 +272,20 @@ append_argv (int *argc, char ***argv, const char *str)
     *argc += i;
 }
 
-typedef struct _cairo_test_runner {
-    cairo_test_context_t base;
-
-    unsigned int num_device_offsets;
-
-    int num_passed;
-    int num_xpassed;
-    int num_skipped;
-    int num_failed;
-    int num_xfailed;
-    int num_crashed;
-
-    cairo_test_list_t **crashes_per_target;
-    cairo_test_list_t **fails_per_target;
-    cairo_test_list_t **xpasses_per_target;
-
-    int *num_failed_per_target;
-    int *num_crashed_per_target;
-    int *num_xpassed_per_target;
-
-    cairo_bool_t list_only;
-    cairo_bool_t full_test;
-} cairo_test_runner_t;
-
 static void
 usage (const char *argv0)
 {
     fprintf (stderr,
-	     "Usage: %s [-f] [test-names|keywords ...]\n"
+	     "Usage: %s [-af] [test-names|keywords ...]\n"
 	     "       %s -l\n"
 	     "\n"
 	     "Run the cairo conformance test suite over the given tests (all by default)\n"
 	     "The command-line arguments are interpreted as follows:\n"
 	     "\n"
-	     "  -l	list only; just list selected test case names without executing\n"
-	     "  -f	full; run the full set of tests. By default the test suite\n"
+	     "  -a	all; run the full set of tests. By default the test suite\n"
 	     "          skips similar surface and device offset testing.\n"
+	     "  -f	foreground; do not fork\n"
+	     "  -l	list only; just list selected test case names without executing\n"
 	     "\n"
 	     "If test names are given they are used as exact matches either to a specific\n"
 	     "test case or to a keyword, so a command such as\n"
@@ -293,16 +299,19 @@ _parse_cmdline (cairo_test_runner_t *runner, int *argc, char **argv[])
     int c;
 
     while (1) {
-	c = _cairo_getopt (*argc, *argv, ":l");
+	c = _cairo_getopt (*argc, *argv, ":afl");
 	if (c == -1)
 	    break;
 
 	switch (c) {
+	case 'a':
+	    runner->full_test = TRUE;
+	    break;
 	case 'l':
 	    runner->list_only = TRUE;
 	    break;
 	case 'f':
-	    runner->full_test = TRUE;
+	    runner->foreground = TRUE;
 	    break;
 	default:
 	    fprintf (stderr, "Internal error: unhandled option: %c\n", c);
@@ -585,6 +594,9 @@ main (int argc, char **argv)
 	if (strstr (env, "full")) {
 	    runner.full_test = TRUE;
 	}
+	if (strstr (env, "foreground")) {
+	    runner.foreground = TRUE;
+	}
     }
 
     _parse_cmdline (&runner, &argc, &argv);
@@ -706,7 +718,7 @@ main (int argc, char **argv)
 		sizeof (cairo_test_status_t) * ctx.num_targets);
 
 	if (ctx.test->preamble != NULL) {
-	    status = _cairo_test_runner_preamble (&ctx);
+	    status = _cairo_test_runner_preamble (&runner, &ctx);
 	    switch (status) {
 	    case CAIRO_TEST_SUCCESS:
 		skipped = FALSE;
@@ -766,7 +778,7 @@ main (int argc, char **argv)
 		int similar;
 
 		for (similar = 0; similar <= has_similar; similar++) {
-		    status = _cairo_test_runner_draw (&ctx, target,
+		    status = _cairo_test_runner_draw (&runner, &ctx, target,
 						      similar, dev_offset);
 		    switch (status) {
 		    case CAIRO_TEST_SUCCESS:
commit 645df0c6d2a3d9999bb18ddb8bb9995b3d597554
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Nov 18 16:37:59 2008 +0000

    [scaled-font] Clean-up compiler warning.
    
    gcc warns that the status may be used uninitialized, so fix it.

diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c
index 7ec2a2d..d8771bb 100644
--- a/src/cairo-scaled-font-subsets.c
+++ b/src/cairo-scaled-font-subsets.c
@@ -965,17 +965,24 @@ create_string_entry (char *s, cairo_string_entry_t **entry)
     return CAIRO_STATUS_SUCCESS;
 }
 
+static void
+_pluck_entry (void *entry, void *closure)
+{
+    _cairo_hash_table_remove (closure, entry);
+    free (entry);
+}
+
 cairo_int_status_t
 _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset)
 {
     unsigned int i;
-    cairo_status_t status;
     cairo_hash_table_t *names;
     cairo_string_entry_t key, *entry;
     char buf[30];
     char *utf8;
     uint16_t *utf16;
     int utf16_len;
+    cairo_status_t status = CAIRO_STATUS_SUCCESS;
 
     names = _cairo_hash_table_create (_cairo_string_equal);
     if (names == NULL)
@@ -1047,17 +1054,10 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
     }
 
 CLEANUP_HASH:
-    while (1) {
-	entry = _cairo_hash_table_random_entry (names, NULL);
-	if (entry == NULL)
-	    break;
-
-        _cairo_hash_table_remove (names, (cairo_hash_entry_t *) entry);
-        free (entry);
-    }
+    _cairo_hash_table_foreach (names, _pluck_entry, names);
     _cairo_hash_table_destroy (names);
 
-    if (status == CAIRO_STATUS_SUCCESS)
+    if (likely (status == CAIRO_STATUS_SUCCESS))
 	return CAIRO_STATUS_SUCCESS;
 
     if (subset->glyph_names != NULL) {
commit 2fdee490745a6c3a75691907aadf8ae38c57234c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Nov 17 12:22:39 2008 +0000

    [compiler] likelihood macros
    
    Behdad prefers these to be upper-case to be consistent with G_UNLIKELY and
    friends. However, as I intend to use these for nearly all instances of
    if(status), I suggest that we keep to the short and not so loud:
        if (unlikely (status))
           return status;

diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h
index 76b8e80..44d9de3 100644
--- a/src/cairo-compiler-private.h
+++ b/src/cairo-compiler-private.h
@@ -149,11 +149,11 @@
       _cairo_boolean_var_ = 0;                      \
    _cairo_boolean_var_;                             \
 })
-#define _cairo_likely(expr) (__builtin_expect (_CAIRO_BOOLEAN_EXPR(expr), 1))
-#define _cairo_unlikely(expr) (__builtin_expect (_CAIRO_BOOLEAN_EXPR(expr), 0))
+#define likely(expr) (__builtin_expect (_CAIRO_BOOLEAN_EXPR(expr), 1))
+#define unlikely(expr) (__builtin_expect (_CAIRO_BOOLEAN_EXPR(expr), 0))
 #else
-#define _cairo_likely(expr) (expr)
-#define _cairo_unlikely(expr) (expr)
+#define likely(expr) (expr)
+#define unlikely(expr) (expr)
 #endif
 
 #ifndef __GNUC__
diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index 78ea56b..b3f43b0 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -434,7 +434,7 @@ _cairo_hash_table_insert (cairo_hash_table_t *hash_table,
 
     hash_table->live_entries++;
     status = _cairo_hash_table_resize (hash_table);
-    if (_cairo_unlikely (status)) {
+    if (unlikely (status)) {
 	/* abort the insert... */
 	hash_table->live_entries--;
 	return status;
commit 97edc680c189205ac2f4e150009f1f1cbe55ba1a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Nov 18 10:49:27 2008 +0000

    [twin] Reduce tolerance.
    
    As the glyphs are rendered to cache, ensure that they are rendered at the
    highest quality settings.

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index 5485476..5ac2cd2 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -119,6 +119,7 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
       int n_snap_y;
     } info = {FALSE};
 
+    cairo_set_tolerance (cr, 0.01);
     cairo_set_line_width (cr, 0.066);
     cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
     cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
diff --git a/src/cairo.c b/src/cairo.c
index bd31063..ac128dd 100644
--- a/src/cairo.c
+++ b/src/cairo.c
@@ -841,6 +841,7 @@ cairo_set_tolerance (cairo_t *cr, double tolerance)
     if (status)
 	_cairo_set_error (cr, status);
 }
+slim_hidden_def (cairo_set_tolerance);
 
 /**
  * cairo_set_antialias:
diff --git a/src/cairoint.h b/src/cairoint.h
index c0e9b21..3aad4d7 100644
--- a/src/cairoint.h
+++ b/src/cairoint.h
@@ -2567,6 +2567,7 @@ slim_hidden_proto (cairo_set_matrix);
 slim_hidden_proto (cairo_set_operator);
 slim_hidden_proto (cairo_set_source);
 slim_hidden_proto (cairo_set_source_surface);
+slim_hidden_proto (cairo_set_tolerance);
 slim_hidden_proto (cairo_status);
 slim_hidden_proto (cairo_stroke);
 slim_hidden_proto (cairo_stroke_preserve);
diff --git a/test/Makefile.am b/test/Makefile.am
index e092429..eab2328 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -971,6 +971,7 @@ REFERENCE_IMAGES = \
 	trap-clip.ps2.argb32.ref.png \
 	trap-clip.ps2.rgb24.ref.png \
 	twin.ref.png \
+	twin.pdf.ref.png \
 	twin.ps2.ref.png \
 	twin.ps3.ref.png \
 	twin.svg11.ref.png \
diff --git a/test/twin.pdf.ref.png b/test/twin.pdf.ref.png
new file mode 100644
index 0000000..b9121e0
Binary files /dev/null and b/test/twin.pdf.ref.png differ
diff --git a/test/twin.ref.png b/test/twin.ref.png
index b9121e0..29c2e9e 100644
Binary files a/test/twin.ref.png and b/test/twin.ref.png differ
commit e50538863a2c063eba61b36cc08eff6eeb712956
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Nov 18 10:45:19 2008 +0000

    [twin] Tweak line width.
    
    Slightly increase line width to eliminate internal holes in the characters
    where the strokes were not quite overlapping.

diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c
index d8e662f..5485476 100644
--- a/src/cairo-font-face-twin.c
+++ b/src/cairo-font-face-twin.c
@@ -119,7 +119,7 @@ twin_scaled_font_render_glyph (cairo_scaled_font_t  *scaled_font,
       int n_snap_y;
     } info = {FALSE};
 
-    cairo_set_line_width (cr, 0.06);
+    cairo_set_line_width (cr, 0.066);
     cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
     cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
 
diff --git a/test/twin.c b/test/twin.c
index 34851f4..a53b796 100644
--- a/test/twin.c
+++ b/test/twin.c
@@ -48,5 +48,5 @@ CAIRO_TEST (twin,
 	    "Tests the internal font",
 	    "twin, font", /* keywords */
 	    NULL, /* requirements */
-	    128, 20,
+	    132, 20,
 	    NULL, draw)
diff --git a/test/twin.ps2.ref.png b/test/twin.ps2.ref.png
index a58dc5b..7fc3f35 100644
Binary files a/test/twin.ps2.ref.png and b/test/twin.ps2.ref.png differ
diff --git a/test/twin.ps3.ref.png b/test/twin.ps3.ref.png
index a58dc5b..7fc3f35 100644
Binary files a/test/twin.ps3.ref.png and b/test/twin.ps3.ref.png differ
diff --git a/test/twin.ref.png b/test/twin.ref.png
index f2a5636..b9121e0 100644
Binary files a/test/twin.ref.png and b/test/twin.ref.png differ
diff --git a/test/twin.svg11.ref.png b/test/twin.svg11.ref.png
index 5b7d67d..4650396 100644
Binary files a/test/twin.svg11.ref.png and b/test/twin.svg11.ref.png differ
diff --git a/test/twin.svg12.ref.png b/test/twin.svg12.ref.png
index 5b7d67d..4650396 100644
Binary files a/test/twin.svg12.ref.png and b/test/twin.svg12.ref.png differ
commit 91c17d33324b51a3876bc6ce778c684111139303
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Nov 18 00:32:54 2008 +0000

    [trace] Simple unbounded cache for symbol lookups.
    
    Reparsing the dwarf info for every lookup is very slow, so cache the
    symbol lookups. This initial implementation is unbounded in the simple
    belief that the actual number of unique lookups during a program's
    lifetime should be fairly small. (Extending to a bounded MRU list is left
    as an exercise for the reader.)

diff --git a/util/cairo-trace/lookup-symbol.c b/util/cairo-trace/lookup-symbol.c
index 42c9c95..eb1a656 100644
--- a/util/cairo-trace/lookup-symbol.c
+++ b/util/cairo-trace/lookup-symbol.c
@@ -61,6 +61,7 @@
 #include <stdlib.h>
 #include <link.h>
 #include <string.h>
+#include <pthread.h>
 
 #if HAVE_BFD
 #include <bfd.h>
@@ -246,6 +247,15 @@ find_matching_file (struct dl_phdr_info *info, size_t size, void *data)
     return 0;
 }
 
+struct symbol_cache_entry {
+    const void *ptr;
+    struct symbol_cache_entry *hash_prev, *hash_next;
+    char name[0];
+};
+
+static struct symbol_cache_entry *symbol_cache_hash[13477];
+static pthread_mutex_t symbol_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 char *
 lookup_symbol (char *buf, int buflen, const void *ptr)
 {
@@ -254,6 +264,32 @@ lookup_symbol (char *buf, int buflen, const void *ptr)
     struct symtab symtab;
     struct symbol symbol;
 #endif
+    struct symbol_cache_entry *cache;
+    int bucket;
+    int len;
+
+    bucket = (unsigned long) ptr % (sizeof (symbol_cache_hash) / sizeof (symbol_cache_hash[0]));
+    pthread_mutex_lock (&symbol_cache_mutex);
+    for (cache = symbol_cache_hash[bucket];
+	 cache != NULL;
+	 cache = cache->hash_next)
+    {
+	if (cache->ptr == ptr) {
+	    if (cache->hash_prev != NULL) {
+		cache->hash_prev->hash_next = cache->hash_next;
+		if (cache->hash_next != NULL)
+		    cache->hash_next->hash_prev = cache->hash_prev;
+		cache->hash_prev = NULL;
+		cache->hash_next = symbol_cache_hash[bucket];
+		symbol_cache_hash[bucket]->hash_prev = cache;
+		symbol_cache_hash[bucket] = cache;
+	    }
+
+	    pthread_mutex_unlock (&symbol_cache_mutex);
+	    return cache->name;
+	}
+    }
+    pthread_mutex_unlock (&symbol_cache_mutex);
 
     match.file = NULL;
     match.address = (ElfW(Addr)) ptr;
@@ -266,17 +302,31 @@ lookup_symbol (char *buf, int buflen, const void *ptr)
 	match.file = "/proc/self/exe";
 
 #if HAVE_BFD
-    if (! _symtab_init (&symtab, match.file))
-	return buf;
-
-    _symbol_init (&symbol, &symtab, match.address - match.base);
-    bfd_map_over_sections (symtab.bfd, find_address_in_section, &symbol);
-    if (symbol.found)
-	_symbol_print (&symbol, buf, buflen, match.file);
-    _symbol_fini (&symbol);
-
-    _symtab_fini (&symtab);
+    if (_symtab_init (&symtab, match.file)) {
+	_symbol_init (&symbol, &symtab, match.address - match.base);
+	bfd_map_over_sections (symtab.bfd, find_address_in_section, &symbol);
+	if (symbol.found)
+	    _symbol_print (&symbol, buf, buflen, match.file);
+	_symbol_fini (&symbol);
+
+	_symtab_fini (&symtab);
+    }
 #endif
 
+    len = strlen (buf);
+    cache = malloc (sizeof (struct symbol_cache_entry) + len + 1);
+    if (cache != NULL) {
+	cache->ptr = ptr;
+	memcpy (cache->name, buf, len + 1);
+
+	pthread_mutex_lock (&symbol_cache_mutex);
+	cache->hash_prev = NULL;
+	cache->hash_next = symbol_cache_hash[bucket];
+	if (symbol_cache_hash[bucket] != NULL)
+	    symbol_cache_hash[bucket]->hash_prev = cache;
+	symbol_cache_hash[bucket] = cache;
+	pthread_mutex_unlock (&symbol_cache_mutex);
+    }
+
     return buf;
 }
diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c
index fb3a38c..1b94ea1 100644
--- a/util/cairo-trace/trace.c
+++ b/util/cairo-trace/trace.c
@@ -157,8 +157,8 @@ static const cairo_user_data_key_t destroy_key;
     if (_line_info && _write_lock ()) { \
 	void *addr = __builtin_return_address(0); \
 	char caller[1024]; \
-	lookup_symbol (caller, sizeof (caller), addr); \
-	fprintf (logfile, "%% %s() called by %s\n", __FUNCTION__, caller); \
+	fprintf (logfile, "%% %s() called by %s\n", __FUNCTION__, \
+		 lookup_symbol (caller, sizeof (caller), addr)); \
 	_write_unlock (); \
     } \
 } while (0)
@@ -2983,8 +2983,9 @@ cairo_surface_write_to_png_stream (cairo_surface_t *surface,
 	char symbol[1024];
 
 	fprintf (logfile, "%% s%ld ", _get_surface_id (surface));
-	lookup_symbol (symbol, sizeof (symbol), write_func);
-	_emit_string_literal (symbol, -1);
+	_emit_string_literal (lookup_symbol (symbol, sizeof (symbol),
+					     write_func),
+			      -1);
 	fprintf (logfile, " write_to_png_stream\n");
 	_write_unlock ();
     }
commit 2839a0e800d6cc12b28da44f30a9e278ceac65aa
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Nov 16 20:04:55 2008 +0000

    [script] Add a simple replay.
    
    A very simple replay program for trace replay.

diff --git a/util/cairo-script/.gitignore b/util/cairo-script/.gitignore
new file mode 100644
index 0000000..d56f76e
--- /dev/null
+++ b/util/cairo-script/.gitignore
@@ -0,0 +1 @@
+csi-replay
diff --git a/util/cairo-script/Makefile.am b/util/cairo-script/Makefile.am
index 348519f..03cb13e 100644
--- a/util/cairo-script/Makefile.am
+++ b/util/cairo-script/Makefile.am
@@ -1,4 +1,7 @@
 lib_LTLIBRARIES = libcairo-script-interpreter.la
+noinst_PROGRAMS = csi-replay
+
+AM_CPPFLAGS = -I$(top_srcdir)/src
 
 cairoincludedir=$(includedir)/cairo
 cairoinclude_HEADERS = cairo-script-interpreter.h
@@ -12,10 +15,12 @@ libcairo_script_interpreter_la_SOURCES = \
 	cairo-script-scanner.c \
 	cairo-script-stack.c \
 	$(NULL)
-libcairo_script_interpreter_la_CPPFLAGS = -I$(top_srcdir)/src
 libcairo_script_interpreter_la_CFLAGS = $(CAIRO_CFLAGS)
 libcairo_script_interpreter_la_LDFLAGS = -version-info $(CAIRO_LIBTOOL_VERSION_INFO) -no-undefined $(export_symbols)
 libcairo_script_interpreter_la_LIBADD = -lz $(CAIRO_LIBS) -L$(top_builddir)/src -lcairo
 
+csi_replay_SOURCES = csi-replay.c
+csi_replay_LDADD = libcairo-script-interpreter.la $(top_builddir)/src/libcairo.la
+
 EXTRA_DIST = \
 	COPYING
diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c
new file mode 100644
index 0000000..5ca035f
--- /dev/null
+++ b/util/cairo-script/csi-replay.c
@@ -0,0 +1,85 @@
+#include <cairo.h>
+#include <cairo-script-interpreter.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static const cairo_user_data_key_t _key;
+
+#if CAIRO_HAS_XLIB_XRENDER_SURFACE
+#include <cairo-xlib.h>
+#include <cairo-xlib-xrender.h>
+
+static Display *
+_get_display (void)
+{
+    static Display *dpy;
+
+    if (dpy != NULL)
+	return dpy;
+
+    dpy = XOpenDisplay (NULL);
+    if (dpy == NULL) {
+	fprintf (stderr, "Failed to open display.\n");
+	exit (1);
+    }
+
+    return dpy;
+}
+
+static void
+_destroy_window (void *closure)
+{
+    XFlush (_get_display ());
+    XDestroyWindow (_get_display(), (Window) closure);
+}
+
+static cairo_surface_t *
+_surface_create (void *closure,
+		 double width, double height)
+{
+    Display *dpy;
+    Visual *visual;
+    XRenderPictFormat *xrender_format;
+    XSetWindowAttributes attr;
+    Window w;
+    cairo_surface_t *surface;
+
+    dpy = _get_display ();
+
+    visual = DefaultVisual (dpy, DefaultScreen (dpy));
+    xrender_format = XRenderFindVisualFormat (dpy, visual);
+    if (xrender_format == NULL) {
+	fprintf (stderr, "X server does not have the Render extension.\n");
+	exit (1);
+    }
+
+    attr.override_redirect = True;
+    w = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0,
+			width, height, 0, xrender_format->depth,
+			InputOutput, visual, CWOverrideRedirect, &attr);
+    XMapWindow (dpy, w);
+
+    surface = cairo_xlib_surface_create_with_xrender_format (dpy, w,
+							     DefaultScreenOfDisplay (dpy),
+							     xrender_format,
+							     width, height);
+    cairo_surface_set_user_data (surface, &_key, (void *) w, _destroy_window);
+
+    return surface;
+}
+#endif
+
+int
+main (int argc, char **argv)
+{
+    cairo_script_interpreter_t *csi;
+    const cairo_script_interpreter_hooks_t hooks = {
+	.surface_create = _surface_create
+    };
+
+    csi = cairo_script_interpreter_create ();
+    cairo_script_interpreter_install_hooks (csi, &hooks);
+    cairo_script_interpreter_run (csi, argv[1]);
+    return cairo_script_interpreter_destroy (csi);
+}


More information about the cairo-commit mailing list