From a5c1cdf2b030959309e1645bd115f058f1367296 Mon Sep 17 00:00:00 2001 From: M Joonas Pihlaja Date: Thu, 13 Nov 2008 12:11:12 +0200 Subject: [clip] Fix uninitialised status return in _cairo_clip_intersect_mask() for empty extents. This fixes the clip-all test case crashing for me. --- src/cairo-clip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 8a0d4db1..b00ca399 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -423,7 +423,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip, cairo_box_t extents; cairo_rectangle_int_t surface_rect, target_rect; cairo_surface_t *surface = NULL; - cairo_status_t status; + cairo_status_t status = CAIRO_STATUS_SUCCESS; if (clip->all_clipped) return CAIRO_STATUS_SUCCESS; -- cgit v1.2.3 From af5ca7249f7628a8b0758f51934e3c1f6d9f4f36 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 5 Feb 2009 16:46:50 -0500 Subject: [test] Fix the definition of INFINITY In my defence, even with INFINITY as 0, I was seeing new asserts on win32. Caught by Jeremy Lea. --- test/invalid-matrix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c index 62d3220b..86ed0be5 100644 --- a/test/invalid-matrix.c +++ b/test/invalid-matrix.c @@ -30,7 +30,7 @@ #include "cairo-test.h" #if defined(HAVE_IEEE754) && !defined(INFINITY) -#define INFINITY (0./1.) +#define INFINITY (1./0.) #endif #if HAVE_FEDISABLEEXCEPT -- cgit v1.2.3 From a55655a82de8dee0f171efb2f7dfb1da341ecdd6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 6 Feb 2009 12:47:38 -0500 Subject: [test] Fix "make dist" --- doc/public/tmpl/cairo-status.sgml | 1 + test/Makefile.am | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/public/tmpl/cairo-status.sgml b/doc/public/tmpl/cairo-status.sgml index fcc17a9c..16b67d25 100644 --- a/doc/public/tmpl/cairo-status.sgml +++ b/doc/public/tmpl/cairo-status.sgml @@ -70,6 +70,7 @@ code is required before or after each individual cairo function call. @CAIRO_STATUS_INVALID_CLUSTERS: @CAIRO_STATUS_INVALID_SLANT: @CAIRO_STATUS_INVALID_WEIGHT: +@CAIRO_STATUS_INVALID_SIZE: diff --git a/test/Makefile.am b/test/Makefile.am index 0b531167..9c670ed3 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -977,7 +977,6 @@ REFERENCE_IMAGES = \ trap-clip.ps2.argb32.ref.png \ trap-clip.ps2.rgb24.ref.png \ twin.ref.png \ - twin.pdf.ref.png \ twin.ps.ref.png \ twin.svg.ref.png \ unantialiased-shapes.ref.png \ -- cgit v1.2.3 From c22ca79863a54b4293e607c8e4d515868c216842 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 6 Feb 2009 12:56:48 -0500 Subject: Don't distribute cairo-features.h (#19992) Second time I fix this bug. Mabe we should add a test for it! --- src/Makefile.am | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index eb82a149..b017c17a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,9 +14,6 @@ export_symbols = -export-symbols cairo.def cairo_def_dependency = cairo.def endif -EXTRA_DIST += cairo-supported-features.h -MAINTAINERCLEANFILES += cairo-supported-features.h - $(top_builddir)/config.h: $(top_srcdir)/config.h.in cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) config.h @@ -36,9 +33,11 @@ libcairo_la_DEPENDENCIES = $(cairo_def_dependency) # Special headers cairoinclude_HEADERS += $(top_srcdir)/cairo-version.h +libcairo_la_SOURCES += cairo-version.h nodist_cairoinclude_HEADERS = cairo-features.h -libcairo_la_SOURCES += cairo-version.h cairo-features.h +nodist_libcairo_la_SOURCES = cairo-features.h BUILT_SOURCES += cairo-features.h cairo-supported-features.h +DISTCLEANFILES += cairo-features.h cairo-supported-features.h cairo-features.h cairo-supported-features.h: cd $(top_builddir) && ./config.status src/$@ -- cgit v1.2.3 From 3d2fcec948b93f75ba49b898633a84f60d419779 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Mon, 9 Feb 2009 15:12:41 -0500 Subject: [test] Define INFINITY on MSVC 1./0. produces a compiler error on MSVC so we'll use HUGEVAL instead. --- test/cairo-test.h | 3 --- test/invalid-matrix.c | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/test/cairo-test.h b/test/cairo-test.h index 8e068f07..a9dbf19b 100644 --- a/test/cairo-test.h +++ b/test/cairo-test.h @@ -60,9 +60,6 @@ typedef unsigned __int64 uint64_t; #include -/* remove this if you don't have IEEE754 floating point */ -#define HAVE_IEEE754 - typedef enum cairo_test_status { CAIRO_TEST_SUCCESS = 0, CAIRO_TEST_NO_MEMORY, diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c index 86ed0be5..4ac109e5 100644 --- a/test/invalid-matrix.c +++ b/test/invalid-matrix.c @@ -29,8 +29,8 @@ #include "cairo-test.h" -#if defined(HAVE_IEEE754) && !defined(INFINITY) -#define INFINITY (1./0.) +#if !defined(INFINITY) && defined(_MSC_VER) +#define INFINITY HUGE_VAL #endif #if HAVE_FEDISABLEEXCEPT -- cgit v1.2.3 From a6c8f18a391407044b33340cf13c49368a2e810e Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Mon, 9 Feb 2009 15:59:01 -0500 Subject: [test] Avoid C99 designated initializers MSVC doesn't support these so we shouldn't use them. --- test/path-precision.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/path-precision.c b/test/path-precision.c index 447b7a24..b5371021 100644 --- a/test/path-precision.c +++ b/test/path-precision.c @@ -33,20 +33,20 @@ static cairo_test_status_t draw (cairo_t *cr, int width, int height) { cairo_path_data_t path_data[] = { - { .header = { CAIRO_PATH_MOVE_TO, 2 }, }, - { .point = { 95.000000, 40.000000 }, }, + { { CAIRO_PATH_MOVE_TO, 2 }, }, + { { 95.000000, 40.000000 }, }, - { .header = { CAIRO_PATH_LINE_TO, 2 }, }, - { .point = { 94.960533, 41.255810 }, }, + { { CAIRO_PATH_LINE_TO, 2 }, }, + { { 94.960533, 41.255810 }, }, - { .header = { CAIRO_PATH_LINE_TO, 2 }, }, - { .point = { 94.842293, 42.50666 }, }, + { { CAIRO_PATH_LINE_TO, 2 }, }, + { { 94.842293, 42.50666 }, }, - { .header = { CAIRO_PATH_LINE_TO, 2 }, }, - { .point = { 94.645744, 43.747627 }, }, + { { CAIRO_PATH_LINE_TO, 2 }, }, + { { 94.645744, 43.747627 }, }, - { .header = { CAIRO_PATH_LINE_TO, 2 }, }, - { .point = { 94.371666, 44.973797 }, }, + { { CAIRO_PATH_LINE_TO, 2 }, }, + { { 94.371666, 44.973797 }, }, }; const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_path_t path, *path_copy; -- cgit v1.2.3 From dd9fc47418b86610d7896fcf585037c96beaa66f Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Mon, 9 Feb 2009 16:31:08 -0500 Subject: Remove zero size data array for compilation with MSVC MSVC doesn't support zero sized arrays very well. For example, zero sized arrays in arrays. --- src/cairo-tor-scan-converter.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cairo-tor-scan-converter.c b/src/cairo-tor-scan-converter.c index 087f0108..4abafc41 100644 --- a/src/cairo-tor-scan-converter.c +++ b/src/cairo-tor-scan-converter.c @@ -320,7 +320,6 @@ struct _pool_chunk { struct _pool_chunk *prev_chunk; /* Actual data starts here. Well aligned for pointers. */ - unsigned char data[0]; }; /* A memory pool. This is supposed to be embedded on the stack or @@ -623,7 +622,7 @@ _pool_alloc_from_new_chunk( } pool->current = chunk; - obj = &chunk->data[chunk->size]; + obj = ((unsigned char*)chunk + sizeof(*chunk) + chunk->size); chunk->size += size; return obj; } @@ -642,7 +641,7 @@ pool_alloc( struct _pool_chunk *chunk = pool->current; if (size <= chunk->capacity - chunk->size) { - void *obj = &chunk->data[chunk->size]; + void *obj = ((unsigned char*)chunk + sizeof(*chunk) + chunk->size); chunk->size += size; return obj; } -- cgit v1.2.3 From 50f8c2e4f3407ef237afd94c7317b1e185ccc9dc Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Mon, 9 Feb 2009 23:39:38 -0500 Subject: [test] define isnan() on MSVC Needed for user-font-rescale.c --- test/cairo-test.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cairo-test.h b/test/cairo-test.h index a9dbf19b..ac8856b3 100644 --- a/test/cairo-test.h +++ b/test/cairo-test.h @@ -56,6 +56,10 @@ typedef unsigned __int64 uint64_t; #ifdef _MSC_VER #define _USE_MATH_DEFINES + +#include +#define isnan(x) _isnan(x) + #endif #include -- cgit v1.2.3 From fe40d3bdb0d0cb93169b935e44d14b15e014fa6d Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Mon, 9 Feb 2009 23:43:04 -0500 Subject: [test] Allocate glyph array with malloc Keeping it on the stack causes a stack overflow of Window's default 1mb stack. --- test/show-glyphs-many.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/show-glyphs-many.c b/test/show-glyphs-many.c index 7276b076..497db584 100644 --- a/test/show-glyphs-many.c +++ b/test/show-glyphs-many.c @@ -109,7 +109,7 @@ get_glyph (cairo_t *cr, const char *utf8, cairo_glyph_t *glyph) static cairo_test_status_t draw (cairo_t *cr, int width, int height) { - cairo_glyph_t glyphs[NUM_GLYPHS]; + cairo_glyph_t *glyphs = malloc(NUM_GLYPHS * sizeof(cairo_glyph_t)); const char *characters[] = { /* try to exercise different widths of index */ "m", /* Latin letter m, index=0x50 */ "μ", /* Greek letter mu, index=0x349 */ @@ -156,6 +156,8 @@ draw (cairo_t *cr, int width, int height) glyphs[j] = glyphs[i]; cairo_show_glyphs (cr, glyphs, NUM_GLYPHS); + + free(glyphs); return CAIRO_TEST_SUCCESS; } -- cgit v1.2.3 From 41e46c7754fff3a99927979925300a7588b9962f Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 10 Feb 2009 11:44:20 -0500 Subject: [test] Don't embed preprocessor directives inside macros MSVC can't handle this. GCC will warn with -pedantic, but I'm not sure we want to enable that. --- test/user-font-mask.c | 11 ++++++----- test/user-font-proxy.c | 10 +++++----- test/user-font.c | 10 +++++----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/test/user-font-mask.c b/test/user-font-mask.c index 16bd59b7..149f8ee9 100644 --- a/test/user-font-mask.c +++ b/test/user-font-mask.c @@ -36,7 +36,12 @@ #define BORDER 10 #define TEXT_SIZE 64 #define WIDTH (TEXT_SIZE * 15 + 2*BORDER) -#define HEIGHT ((TEXT_SIZE + 2*BORDER)*2) +#ifndef ROTATED + #define HEIGHT ((TEXT_SIZE + 2*BORDER)*2) +#else + #define HEIGHT WIDTH +#endif +#define END_GLYPH 0 #define TEXT "cairo" /* Reverse the bits in a byte with 7 operations (no 64-bit): @@ -238,9 +243,5 @@ CAIRO_TEST (user_font_mask, "Tests a user-font using cairo_mask with bitmap images", "user-font, mask", /* keywords */ NULL, /* requirements */ -#ifndef ROTATED WIDTH, HEIGHT, -#else - WIDTH, WIDTH, -#endif NULL, draw) diff --git a/test/user-font-proxy.c b/test/user-font-proxy.c index 45974d3d..3470a121 100644 --- a/test/user-font-proxy.c +++ b/test/user-font-proxy.c @@ -35,7 +35,11 @@ #define BORDER 10 #define TEXT_SIZE 64 #define WIDTH (TEXT_SIZE * 12 + 2*BORDER) -#define HEIGHT ((TEXT_SIZE + 2*BORDER)*2) +#ifndef ROTATED + #define HEIGHT ((TEXT_SIZE + 2*BORDER)*2) +#else + #define HEIGHT WIDTH +#endif #define TEXT "geez... cairo user-font" static cairo_user_data_key_t fallback_font_key; @@ -208,9 +212,5 @@ CAIRO_TEST (user_font_proxy, "Tests a user-font using a native font in its render_glyph", "font, user-font", /* keywords */ "cairo >= 1.7.4", /* requirements */ -#ifndef ROTATED WIDTH, HEIGHT, -#else - WIDTH, WIDTH, -#endif NULL, draw) diff --git a/test/user-font.c b/test/user-font.c index 38e2b1d5..30bc74e3 100644 --- a/test/user-font.c +++ b/test/user-font.c @@ -35,7 +35,11 @@ #define BORDER 10 #define TEXT_SIZE 64 #define WIDTH (TEXT_SIZE * 15 + 2*BORDER) -#define HEIGHT ((TEXT_SIZE + 2*BORDER)*2) +#ifndef ROTATED + #define HEIGHT ((TEXT_SIZE + 2*BORDER)*2) +#else + #define HEIGHT WIDTH +#endif #define TEXT "geez... cairo user-font" #define END_GLYPH 0 @@ -259,9 +263,5 @@ CAIRO_TEST (user_font, "Tests user font feature", "font, user-font", /* keywords */ "cairo >= 1.7.4", /* requirements */ -#ifndef ROTATED WIDTH, HEIGHT, -#else - WIDTH, WIDTH, -#endif NULL, draw) -- cgit v1.2.3 From dffdbd85157395bceb27d30d6426aa47173f6a18 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 10 Feb 2009 17:53:39 -0500 Subject: Add _cairo_round() _cairo_round() has the same behaviour as _cairo_lround() except it returns a double instead of an integer. --- src/cairoint.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/cairoint.h b/src/cairoint.h index 8115c81a..99185b65 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1024,6 +1024,15 @@ typedef struct _cairo_stroke_face { cairo_private void _cairo_restrict_value (double *value, double min, double max); +/* C99 round() rounds to the nearest integral value with halfway cases rounded + * away from 0. _cairo_round rounds halfway cases toward negative infinity. + * This matches the rounding behaviour of _cairo_lround. */ +static inline double +_cairo_round (double r) +{ + return floor (r + .5); +} + cairo_private int _cairo_lround (double d); -- cgit v1.2.3 From b9f0c4b25223830ce73f7e3adef85a0e97a31c0e Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 10 Feb 2009 17:57:00 -0500 Subject: Use _cairo_round() instead of round() MSVC doesn't have round() and the code probably wants to round in the same direction regardless of whether the values are negative or positive. --- src/cairo-font-face-twin.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c index b8343221..3ced9b02 100644 --- a/src/cairo-font-face-twin.c +++ b/src/cairo-font-face-twin.c @@ -34,8 +34,6 @@ * Behdad Esfahbod */ -#define _ISOC99_SOURCE /* for round() */ - #include "cairoint.h" #include @@ -255,8 +253,8 @@ compute_hinting_scales (cairo_t *cr, compute_hinting_scale (cr, x, y, y_scale, y_scale_inv); } -#define SNAPXI(p) (round ((p) * x_scale) * x_scale_inv) -#define SNAPYI(p) (round ((p) * y_scale) * y_scale_inv) +#define SNAPXI(p) (_cairo_round ((p) * x_scale) * x_scale_inv) +#define SNAPYI(p) (_cairo_round ((p) * y_scale) * y_scale_inv) /* This controls the global font size */ #define F(g) ((g) / 72.) -- cgit v1.2.3 From 70297f257d4dc0accb5183b806d43a033887acb7 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 10 Feb 2009 17:58:28 -0500 Subject: [test] Add crtdbg.h include crtdbg.h is required for _CrtSetReportMode() and _CrtSetReportFile(). --- test/cairo-test-runner.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/cairo-test-runner.c b/test/cairo-test-runner.c index e604d0d9..1d79c7e3 100644 --- a/test/cairo-test-runner.c +++ b/test/cairo-test-runner.c @@ -54,6 +54,10 @@ #include #endif +#ifdef _MSC_VER +#include +#endif + typedef struct _cairo_test_list { const cairo_test_t *test; struct _cairo_test_list *next; -- cgit v1.2.3 From 41cbd935f9dba276db716e2c71ac21dc60505be9 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Wed, 11 Feb 2009 15:24:20 -0500 Subject: [test] Add cairo_test_NaN and use it in place of strtod strtod("NaN") returns 0.0 with the MSVC runtime so we need to generate NaN some other way. --- test/cairo-test.h | 15 +++++++++++++++ test/invalid-matrix.c | 2 +- test/user-font-rescale.c | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/test/cairo-test.h b/test/cairo-test.h index ac8856b3..5a5be44e 100644 --- a/test/cairo-test.h +++ b/test/cairo-test.h @@ -64,6 +64,21 @@ typedef unsigned __int64 uint64_t; #include +static inline double +cairo_test_NaN (void) +{ +#ifdef _MSC_VER + /* MSVC strtod("NaN", NULL) returns 0.0 */ + union { + uint32_t i[2]; + double d; + } nan = {{0xffffffff, 0x7fffffff}}; + return nan.d; +#else + return strtod("NaN", NULL); +#endif +} + typedef enum cairo_test_status { CAIRO_TEST_SUCCESS = 0, CAIRO_TEST_NO_MEMORY, diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c index 4ac109e5..933e81c9 100644 --- a/test/invalid-matrix.c +++ b/test/invalid-matrix.c @@ -74,7 +74,7 @@ if ((status) == CAIRO_STATUS_SUCCESS) { \ #endif /* create a bogus matrix and check results of attempted inversion */ - bogus.x0 = bogus.xy = bogus.xx = strtod ("NaN", NULL); + bogus.x0 = bogus.xy = bogus.xx = cairo_test_NaN (); bogus.y0 = bogus.yx = bogus.yy = bogus.xx; status = cairo_matrix_invert (&bogus); CHECK_STATUS (status, "cairo_matrix_invert(NaN)"); diff --git a/test/user-font-rescale.c b/test/user-font-rescale.c index 04d3f53c..ae56ef84 100644 --- a/test/user-font-rescale.c +++ b/test/user-font-rescale.c @@ -211,7 +211,7 @@ create_rescaled_font (cairo_font_face_t *substitute_font, for (i = 0; i < r->glyph_count; i++) { r->desired_width[i] = desired_width[i]; /* use NaN to specify unset */ - r->rescale_factor[i] = strtod ("NaN", NULL); + r->rescale_factor[i] = cairo_test_NaN (); } status = cairo_font_face_set_user_data (user_font_face, -- cgit v1.2.3 From b3e2433f1e78e8799a9f57bfb6da108016687fc9 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Wed, 11 Feb 2009 17:55:15 -0500 Subject: Correct the reference image for the rotate-image-surface-paint test --- test/rotate-image-surface-paint.ref.png | Bin 190 -> 191 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/rotate-image-surface-paint.ref.png b/test/rotate-image-surface-paint.ref.png index 5c98d7d8..bd30da6e 100644 Binary files a/test/rotate-image-surface-paint.ref.png and b/test/rotate-image-surface-paint.ref.png differ -- cgit v1.2.3 From e7d4bc3d864b1b42bb1cae031036ddf6a4445d3c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 12 Feb 2009 10:42:24 +0000 Subject: [png] Correct documentation to avoid reference to NULL As pointed out by Truc Truong, cairo_image_surface_create_from_png_stream() cannot return NULL and so the documentation was incorrect. Fixes http://bugs.freedesktop.org/show_bug.cgi?id=20075 Bug 20075 There is a misprint in the spec for cairo_image_surface_create_from_png_stream() function --- src/cairo-png.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/cairo-png.c b/src/cairo-png.c index 06e7cb55..93317f36 100644 --- a/src/cairo-png.c +++ b/src/cairo-png.c @@ -631,6 +631,10 @@ stdio_read_func (png_structp png, png_bytep data, png_size_t size) * %CAIRO_STATUS_NO_MEMORY * %CAIRO_STATUS_FILE_NOT_FOUND * %CAIRO_STATUS_READ_ERROR + * + * Alternatively, you can allow errors to propagate through the drawing + * operations and check the status on the context upon completion + * using cairo_status(). **/ cairo_surface_t * cairo_image_surface_create_from_png (const char *filename) @@ -692,8 +696,17 @@ stream_read_func (png_structp png, png_bytep data, png_size_t size) * via the @read_func function. * * Return value: a new #cairo_surface_t initialized with the contents - * of the PNG file or %NULL if the data read is not a valid PNG image or - * memory could not be allocated for the operation. + * of the PNG file or a "nil" surface if the data read is not a valid PNG image + * or memory could not be allocated for the operation. A nil + * surface can be checked for with cairo_surface_status(surface) which + * may return one of the following values: + * + * %CAIRO_STATUS_NO_MEMORY + * %CAIRO_STATUS_READ_ERROR + * + * Alternatively, you can allow errors to propagate through the drawing + * operations and check the status on the context upon completion + * using cairo_status(). **/ cairo_surface_t * cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func, -- cgit v1.2.3 From 8e1f103540392b17c51b4fb4b3c3480430cbc212 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 12 Feb 2009 12:02:17 -0500 Subject: Divert pclose to _pclose for MSVC Commit bf62798b1284533e28b78717dac8070ca6d29e54 added a diversion for popen but not for pclose. This is needed for linking the boilerplate with the test suite. --- src/cairo-compiler-private.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h index 44d9de30..bd7cccd9 100644 --- a/src/cairo-compiler-private.h +++ b/src/cairo-compiler-private.h @@ -164,6 +164,7 @@ #if (defined(__WIN32__) && !defined(__WINE__)) || defined(_MSC_VER) #define snprintf _snprintf #define popen _popen +#define pclose _pclose #endif #ifdef _MSC_VER -- cgit v1.2.3 From 2df611a3810eb64c8ed22dfae5f3d3157eef7e6a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 10 Feb 2009 10:28:28 +0000 Subject: [script] Expose a normal xlib window for replay Provide a visible surface for replaying scripts against. --- util/cairo-script/csi-replay.c | 122 ++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 56 deletions(-) diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c index cfae74c9..4e0b6065 100644 --- a/util/cairo-script/csi-replay.c +++ b/util/cairo-script/csi-replay.c @@ -6,10 +6,8 @@ static const cairo_user_data_key_t _key; -#if CAIRO_HAS_XLIB_XRENDER_SURFACE +#if CAIRO_HAS_XLIB_SURFACE #include -#include - static Display * _get_display (void) { @@ -28,16 +26,49 @@ _get_display (void) } static void -_destroy_pixmap (void *closure) +_destroy_window (void *closure) { - XFreePixmap (_get_display(), (Pixmap) closure); + XFlush (_get_display ()); + XDestroyWindow (_get_display(), (Window) closure); } +static cairo_surface_t * +_xlib_surface_create (void *closure, + cairo_content_t content, + double width, double height) +{ + Display *dpy; + XSetWindowAttributes attr; + Visual *visual; + int depth; + Window w; + cairo_surface_t *surface; + + dpy = _get_display (); + + visual = DefaultVisual (dpy, DefaultScreen (dpy)); + depth = DefaultDepth (dpy, DefaultScreen (dpy)); + attr.override_redirect = True; + w = XCreateWindow (dpy, DefaultRootWindow (dpy), 0, 0, + width <= 0 ? 1 : width, + height <= 0 ? 1 : height, + 0, depth, + InputOutput, visual, CWOverrideRedirect, &attr); + XMapWindow (dpy, w); + + surface = cairo_xlib_surface_create (dpy, w, visual, width, height); + cairo_surface_set_user_data (surface, &_key, (void *) w, _destroy_window); + + return surface; +} + +#if CAIRO_HAS_XLIB_XRENDER_SURFACE +#include + static void -_destroy_window (void *closure) +_destroy_pixmap (void *closure) { - XFlush (_get_display ()); - XDestroyWindow (_get_display(), (Window) closure); + XFreePixmap (_get_display(), (Pixmap) closure); } static cairo_surface_t * @@ -46,66 +77,40 @@ _xrender_surface_create (void *closure, double width, double height) { Display *dpy; + Pixmap pixmap; XRenderPictFormat *xrender_format; cairo_surface_t *surface; dpy = _get_display (); content = CAIRO_CONTENT_COLOR_ALPHA; - if (1) { - Pixmap pixmap; - - switch (content) { - case CAIRO_CONTENT_COLOR_ALPHA: - xrender_format = XRenderFindStandardFormat (dpy, PictStandardARGB32); - break; - case CAIRO_CONTENT_COLOR: - xrender_format = XRenderFindStandardFormat (dpy, PictStandardRGB24); - break; - case CAIRO_CONTENT_ALPHA: - default: - xrender_format = XRenderFindStandardFormat (dpy, PictStandardA8); - } - - pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy), - width, height, xrender_format->depth); - - surface = cairo_xlib_surface_create_with_xrender_format (dpy, pixmap, - DefaultScreenOfDisplay (dpy), - xrender_format, - width, height); - cairo_surface_set_user_data (surface, &_key, - (void *) pixmap, _destroy_pixmap); - } else { - XSetWindowAttributes attr; - Visual *visual; - Window w; - - 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 <= 0 ? 1 : width, - height <= 0 ? 1 : 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); + switch (content) { + case CAIRO_CONTENT_COLOR_ALPHA: + xrender_format = XRenderFindStandardFormat (dpy, PictStandardARGB32); + break; + case CAIRO_CONTENT_COLOR: + xrender_format = XRenderFindStandardFormat (dpy, PictStandardRGB24); + break; + case CAIRO_CONTENT_ALPHA: + default: + xrender_format = XRenderFindStandardFormat (dpy, PictStandardA8); } + pixmap = XCreatePixmap (dpy, DefaultRootWindow (dpy), + width, height, xrender_format->depth); + + surface = cairo_xlib_surface_create_with_xrender_format (dpy, pixmap, + DefaultScreenOfDisplay (dpy), + xrender_format, + width, height); + cairo_surface_set_user_data (surface, &_key, + (void *) pixmap, _destroy_pixmap); + return surface; } #endif +#endif #if CAIRO_HAS_PDF_SURFACE #include @@ -155,6 +160,8 @@ main (int argc, char **argv) cairo_script_interpreter_hooks_t hooks = { #if CAIRO_HAS_XLIB_XRENDER_SURFACE .surface_create = _xrender_surface_create +#elif CAIRO_HAS_XLIB_SURFACE + .surface_create = _xlib_surface_create #elif CAIRO_PDF_SURFACE .surface_create = _pdf_surface_create #elif CAIRO_PS_SURFACE @@ -174,6 +181,9 @@ main (int argc, char **argv) #if CAIRO_HAS_XLIB_XRENDER_SURFACE { "--xrender", _xrender_surface_create }, #endif +#if CAIRO_HAS_XLIB_SURFACE + { "--xlib", _xlib_surface_create }, +#endif #if CAIRO_HAS_PDF_SURFACE { "--pdf", _pdf_surface_create }, #endif -- cgit v1.2.3 From 17ce8584e7142d13bd7a777c9570e5548a06a90c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 12 Feb 2009 18:26:57 +0000 Subject: [NEWS] Add API changes. Scan the public headers for obvious additions. --- NEWS | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index cd694d87..0b485df7 100644 --- a/NEWS +++ b/NEWS @@ -10,9 +10,27 @@ API additions: "image/jpeg" is understood by PDF,PS,SVG,win32-printing. "image/png" is understood by SVG. -New backend: + cairo_pdf_version_t + cairo_pdf_surface_restrict_to_version() + cairo_pdf_get_versions() + cairo_pdf_version_to_string() + Similar to restrict to version and level found in SVG and PS, these + limit the features used in the output to comply with the PDF specification + for that version. + + CAIRO_STATUS_INVALID_SIZE + Indicates that the request surface size is not supported by the backend. + This generally indicates that the request is too large. + + The built-in twin font is now called "@cairo:" and supports a limited set + of options like "@cairo:mono". Where are these specified? + + cairo_in_fill() now uses flash semantics... OTOH, top and left are outside. + +New experimental backends: Simple DirectMedia Layer + CairoScript New utility: -- cgit v1.2.3 From de7270cb1e9510cb230e80045c812fa68fcfa585 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Feb 2009 10:03:22 +0000 Subject: [cairo] Describe the restrictions upon cairo_set_tolerance() Truc Troung reported that the behaviour of cairo_set_tolerance()/cairo_get_tolerance() was inconsistent with the documentation, i.e. we failed to mention that the tolerance would be restricted to the smalled fixed-point value. Add a sentence to the documentation that describes the restriction without mentioning what that is... Hopefully that is sufficient detail to accommodate the reporter, without exposing internal implementation details. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=20095 Bug 20095 - The cairo_set_tolerance() function behavior is inconsistency with the spec --- src/cairo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cairo.c b/src/cairo.c index cefc9253..5f8d2661 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -816,7 +816,10 @@ cairo_get_source (cairo_t *cr) * is less than @tolerance. The default value is 0.1. A larger * value will give better performance, a smaller value, better * appearance. (Reducing the value from the default value of 0.1 - * is unlikely to improve appearance significantly.) + * is unlikely to improve appearance significantly.) The accuracy of paths + * within Cairo is limited by the precision of its internal arithmetic, and + * the prescribed @tolerance is restricted to the smallest + * representable internal value. **/ void cairo_set_tolerance (cairo_t *cr, double tolerance) -- cgit v1.2.3 From adaf70a93f4449e85997bcde531b76c9044758ea Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Feb 2009 12:56:46 +0000 Subject: [surface] Separate the mime-data from the user-data. Move the mime-data into its own array so that it cannot be confused with user-data and we do not need to hard-code the copy list during snapshotting. The copy-on-snapshotting code becomes far simpler and will accommodate all future mime-types. Keeping mime-data separate from user-data is important due to the principle of least surprise - the API is different and so it would be surprising if you queried for user-data and were returned an opaque mime-data pointer, and vice versa. (Note this should have been prevented by using interned strings, but conceptually it is cleaner to make the separation.) Also it aides in trimming the user data arrays which are linearly searched. Based on the original patch by Adrian Johnson: http://cgit.freedesktop.org/~ajohnson/cairo/commit/?h=metadata&id=37e607cc777523ad12a2d214708d79ecbca5b380 --- src/cairo-array.c | 36 ++++++++++++++++++++++++++++++++++++ src/cairo-surface-fallback.c | 27 +++++++-------------------- src/cairo-surface-private.h | 1 + src/cairo-surface.c | 42 +++++++++++++++++++++--------------------- src/cairoint.h | 14 ++++++++++++-- 5 files changed, 77 insertions(+), 43 deletions(-) diff --git a/src/cairo-array.c b/src/cairo-array.c index 9c084b9e..70c16465 100644 --- a/src/cairo-array.c +++ b/src/cairo-array.c @@ -494,3 +494,39 @@ _cairo_user_data_array_set_data (cairo_user_data_array_t *array, return CAIRO_STATUS_SUCCESS; } + +cairo_status_t +_cairo_user_data_array_copy (cairo_user_data_array_t *dst, + cairo_user_data_array_t *src) +{ + /* discard any existing user-data */ + if (dst->num_elements != 0) { + _cairo_user_data_array_fini (dst); + _cairo_user_data_array_init (dst); + } + + if (src->num_elements == 0) + return CAIRO_STATUS_SUCCESS; + + return _cairo_array_append_multiple (dst, + _cairo_array_index (src, 0), + src->num_elements); +} + +void +_cairo_user_data_array_foreach (cairo_user_data_array_t *array, + void (*func) (void *key, + void *elt, + void *closure), + void *closure) +{ + cairo_user_data_slot_t *slots; + int i, num_slots; + + num_slots = array->num_elements; + slots = _cairo_array_index (array, 0); + for (i = 0; i < num_slots; i++) { + if (slots[i].user_data != NULL) + func (slots[i].key, slots[i].user_data, closure); + } +} diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index bcbc9846..9b33d116 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -1121,12 +1121,6 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) cairo_surface_pattern_t pattern; cairo_image_surface_t *image; void *image_extra; - const char *mime_types[] = { - CAIRO_MIME_TYPE_JPEG, - CAIRO_MIME_TYPE_PNG, - CAIRO_MIME_TYPE_JP2, - NULL - }, **mime_type; status = _cairo_surface_acquire_source_image (surface, &image, &image_extra); @@ -1137,13 +1131,11 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) image->width, image->height); if (cairo_surface_status (snapshot)) { - _cairo_surface_release_source_image (surface, - image, image_extra); + _cairo_surface_release_source_image (surface, image, image_extra); return snapshot; } _cairo_pattern_init_for_surface (&pattern, &image->base); - status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE, &pattern.base, NULL, @@ -1153,11 +1145,14 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) 0, 0, image->width, image->height); - _cairo_pattern_fini (&pattern.base); - _cairo_surface_release_source_image (surface, - image, image_extra); + _cairo_surface_release_source_image (surface, image, image_extra); + if (unlikely (status)) { + cairo_surface_destroy (snapshot); + return _cairo_surface_create_in_error (status); + } + status = _cairo_surface_copy_mime_data (snapshot, surface); if (unlikely (status)) { cairo_surface_destroy (snapshot); return _cairo_surface_create_in_error (status); @@ -1166,14 +1161,6 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) snapshot->device_transform = surface->device_transform; snapshot->device_transform_inverse = surface->device_transform_inverse; - for (mime_type = mime_types; *mime_type; mime_type++) { - status = _cairo_surface_copy_mime_data (snapshot, surface, *mime_type); - if (unlikely (status)) { - cairo_surface_destroy (snapshot); - return _cairo_surface_create_in_error (status); - } - } - snapshot->is_snapshot = TRUE; return snapshot; diff --git a/src/cairo-surface-private.h b/src/cairo-surface-private.h index efd4365e..12b38f01 100644 --- a/src/cairo-surface-private.h +++ b/src/cairo-surface-private.h @@ -57,6 +57,7 @@ struct _cairo_surface { cairo_status_t status; cairo_bool_t finished; cairo_user_data_array_t user_data; + cairo_user_data_array_t mime_data; cairo_matrix_t device_transform; cairo_matrix_t device_transform_inverse; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 3b1dfe27..2afc6f66 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -51,6 +51,7 @@ const cairo_surface_t name = { \ status, /* status */ \ FALSE, /* finished */ \ { 0, 0, 0, NULL, }, /* user_data */ \ + { 0, 0, 0, NULL, }, /* mime_data */ \ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ \ { 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform_inverse */ \ 0.0, /* x_resolution */ \ @@ -194,6 +195,7 @@ _cairo_surface_init (cairo_surface_t *surface, surface->finished = FALSE; _cairo_user_data_array_init (&surface->user_data); + _cairo_user_data_array_init (&surface->mime_data); cairo_matrix_init_identity (&surface->device_transform); cairo_matrix_init_identity (&surface->device_transform_inverse); @@ -437,6 +439,7 @@ cairo_surface_destroy (cairo_surface_t *surface) cairo_surface_finish (surface); _cairo_user_data_array_fini (&surface->user_data); + _cairo_user_data_array_fini (&surface->mime_data); free (surface); } @@ -459,6 +462,7 @@ _cairo_surface_reset (cairo_surface_t *surface) assert (CAIRO_REFERENCE_COUNT_GET_VALUE (&surface->ref_count) == 1); _cairo_user_data_array_fini (&surface->user_data); + _cairo_user_data_array_fini (&surface->mime_data); if (surface->backend->reset != NULL) { cairo_status_t status = surface->backend->reset (surface); @@ -620,7 +624,7 @@ cairo_surface_get_mime_data (cairo_surface_t *surface, return; } - mime_data = _cairo_user_data_array_get_data (&surface->user_data, + mime_data = _cairo_user_data_array_get_data (&surface->mime_data, (cairo_user_data_key_t *) mime_type); if (mime_data == NULL) return; @@ -696,7 +700,7 @@ cairo_surface_set_mime_data (cairo_surface_t *surface, } else mime_data = NULL; - status = _cairo_user_data_array_set_data (&surface->user_data, + status = _cairo_user_data_array_set_data (&surface->mime_data, (cairo_user_data_key_t *) mime_type, mime_data, _cairo_mime_data_destroy); @@ -711,13 +715,19 @@ cairo_surface_set_mime_data (cairo_surface_t *surface, } slim_hidden_def (cairo_surface_set_mime_data); +static void +_cairo_mime_data_reference (void *key, void *elt, void *closure) +{ + cairo_mime_data_t *mime_data = elt; + + _cairo_reference_count_inc (&mime_data->ref_count); +} + cairo_status_t _cairo_surface_copy_mime_data (cairo_surface_t *dst, - cairo_surface_t *src, - const char *mime_type) + cairo_surface_t *src) { cairo_status_t status; - cairo_mime_data_t *mime_data; if (dst->status) return dst->status; @@ -725,25 +735,15 @@ _cairo_surface_copy_mime_data (cairo_surface_t *dst, if (src->status) return _cairo_surface_set_error (dst, src->status); - status = _cairo_intern_string (&mime_type, -1); + /* first copy the mime-data, discarding any already set on dst */ + status = _cairo_user_data_array_copy (&dst->mime_data, &src->mime_data); if (unlikely (status)) return _cairo_surface_set_error (dst, status); - mime_data = _cairo_user_data_array_get_data (&src->user_data, - (cairo_user_data_key_t *) mime_type); - if (mime_data == NULL) - return CAIRO_STATUS_SUCCESS; - - _cairo_reference_count_inc (&mime_data->ref_count); - - status = _cairo_user_data_array_set_data (&dst->user_data, - (cairo_user_data_key_t *) mime_type, - mime_data, - _cairo_mime_data_destroy); - if (unlikely (status)) { - _cairo_mime_data_destroy (mime_data); - return _cairo_surface_set_error (dst, status); - } + /* now increment the reference counters for the copies */ + _cairo_user_data_array_foreach (&dst->mime_data, + _cairo_mime_data_reference, + NULL); return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairoint.h b/src/cairoint.h index 99185b65..21f0e491 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -330,6 +330,17 @@ _cairo_user_data_array_set_data (cairo_user_data_array_t *array, void *user_data, cairo_destroy_func_t destroy); +cairo_private cairo_status_t +_cairo_user_data_array_copy (cairo_user_data_array_t *dst, + cairo_user_data_array_t *src); + +cairo_private void +_cairo_user_data_array_foreach (cairo_user_data_array_t *array, + void (*func) (void *key, + void *elt, + void *closure), + void *closure); + #define _CAIRO_HASH_INIT_VALUE 5381 cairo_private unsigned long @@ -1742,8 +1753,7 @@ _cairo_surface_create_in_error (cairo_status_t status); cairo_private cairo_status_t _cairo_surface_copy_mime_data (cairo_surface_t *dst, - cairo_surface_t *src, - const char *mime_type); + cairo_surface_t *src); cairo_private cairo_status_t _cairo_surface_set_error (cairo_surface_t *surface, -- cgit v1.2.3 From cc8a09567ca034e7d95e2ef8a3ec833b12c9f87a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Feb 2009 13:23:50 +0000 Subject: [surface] Move the meta-data copy-on-snapshot to the generic layer. As pointed out by Paolo Bonzini, copying the meta data for a snapshot is common for all backends and so should be handled by the generic layer. --- src/cairo-surface-fallback.c | 11 ----------- src/cairo-surface.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 9b33d116..7c38cbdf 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -1152,17 +1152,6 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) return _cairo_surface_create_in_error (status); } - status = _cairo_surface_copy_mime_data (snapshot, surface); - if (unlikely (status)) { - cairo_surface_destroy (snapshot); - return _cairo_surface_create_in_error (status); - } - - snapshot->device_transform = surface->device_transform; - snapshot->device_transform_inverse = surface->device_transform_inverse; - - snapshot->is_snapshot = TRUE; - return snapshot; } diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 2afc6f66..7bb502b6 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1399,16 +1399,40 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, cairo_surface_t * _cairo_surface_snapshot (cairo_surface_t *surface) { + cairo_surface_t *snapshot; + cairo_status_t status; + if (surface->status) return _cairo_surface_create_in_error (surface->status); if (surface->finished) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED)); - if (surface->backend->snapshot) - return surface->backend->snapshot (surface); + if (surface->is_snapshot) + return cairo_surface_reference (surface); + + snapshot = NULL; + if (surface->backend->snapshot != NULL) + snapshot = surface->backend->snapshot (surface); + + if (snapshot == NULL) + snapshot = _cairo_surface_fallback_snapshot (surface); + + if (unlikely (snapshot->status)) + return snapshot; + + status = _cairo_surface_copy_mime_data (snapshot, surface); + if (unlikely (status)) { + cairo_surface_destroy (snapshot); + return _cairo_surface_create_in_error (status); + } + + snapshot->device_transform = surface->device_transform; + snapshot->device_transform_inverse = surface->device_transform_inverse; + + snapshot->is_snapshot = TRUE; - return _cairo_surface_fallback_snapshot (surface); + return snapshot; } /** -- cgit v1.2.3 From d295942b9d4da3be3318cd5fe2d3b0b1fe005d11 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 31 Jan 2009 00:56:45 +0000 Subject: Inline _cairo_restrict_value() This is one instance where the function call overhead dominated the function call in both time and size. --- src/cairo-misc.c | 9 --------- src/cairo-pattern.c | 32 ++++++++++++++++---------------- src/cairo.c | 14 ++++++++------ src/cairoint.h | 13 +++++++++++-- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/cairo-misc.c b/src/cairo-misc.c index 2ed14139..0c9db901 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -384,15 +384,6 @@ _cairo_operator_bounded_by_source (cairo_operator_t op) } -void -_cairo_restrict_value (double *value, double min, double max) -{ - if (*value < min) - *value = min; - else if (*value > max) - *value = max; -} - /* This function is identical to the C99 function lround(), except that it * performs arithmetic rounding (floor(d + .5) instead of away-from-zero rounding) and * has a valid input range of (INT_MIN, INT_MAX] instead of diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 9f367b5e..e8b1b23f 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -453,9 +453,9 @@ cairo_pattern_create_rgb (double red, double green, double blue) { cairo_color_t color; - _cairo_restrict_value (&red, 0.0, 1.0); - _cairo_restrict_value (&green, 0.0, 1.0); - _cairo_restrict_value (&blue, 0.0, 1.0); + red = _cairo_restrict_value (red, 0.0, 1.0); + green = _cairo_restrict_value (green, 0.0, 1.0); + blue = _cairo_restrict_value (blue, 0.0, 1.0); _cairo_color_init_rgb (&color, red, green, blue); @@ -492,10 +492,10 @@ cairo_pattern_create_rgba (double red, double green, double blue, { cairo_color_t color; - _cairo_restrict_value (&red, 0.0, 1.0); - _cairo_restrict_value (&green, 0.0, 1.0); - _cairo_restrict_value (&blue, 0.0, 1.0); - _cairo_restrict_value (&alpha, 0.0, 1.0); + red = _cairo_restrict_value (red, 0.0, 1.0); + green = _cairo_restrict_value (green, 0.0, 1.0); + blue = _cairo_restrict_value (blue, 0.0, 1.0); + alpha = _cairo_restrict_value (alpha, 0.0, 1.0); _cairo_color_init_rgba (&color, red, green, blue, alpha); @@ -949,10 +949,10 @@ cairo_pattern_add_color_stop_rgb (cairo_pattern_t *pattern, return; } - _cairo_restrict_value (&offset, 0.0, 1.0); - _cairo_restrict_value (&red, 0.0, 1.0); - _cairo_restrict_value (&green, 0.0, 1.0); - _cairo_restrict_value (&blue, 0.0, 1.0); + offset = _cairo_restrict_value (offset, 0.0, 1.0); + red = _cairo_restrict_value (red, 0.0, 1.0); + green = _cairo_restrict_value (green, 0.0, 1.0); + blue = _cairo_restrict_value (blue, 0.0, 1.0); _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern, offset, red, green, blue, 1.0); @@ -1003,11 +1003,11 @@ cairo_pattern_add_color_stop_rgba (cairo_pattern_t *pattern, return; } - _cairo_restrict_value (&offset, 0.0, 1.0); - _cairo_restrict_value (&red, 0.0, 1.0); - _cairo_restrict_value (&green, 0.0, 1.0); - _cairo_restrict_value (&blue, 0.0, 1.0); - _cairo_restrict_value (&alpha, 0.0, 1.0); + offset = _cairo_restrict_value (offset, 0.0, 1.0); + red = _cairo_restrict_value (red, 0.0, 1.0); + green = _cairo_restrict_value (green, 0.0, 1.0); + blue = _cairo_restrict_value (blue, 0.0, 1.0); + alpha = _cairo_restrict_value (alpha, 0.0, 1.0); _cairo_pattern_add_color_stop ((cairo_gradient_pattern_t *) pattern, offset, red, green, blue, alpha); diff --git a/src/cairo.c b/src/cairo.c index 632fac55..4aa52f69 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -648,10 +648,10 @@ _current_source_matches_solid (cairo_t *cr, if (current->type != CAIRO_PATTERN_TYPE_SOLID) return FALSE; - _cairo_restrict_value (&red, 0.0, 1.0); - _cairo_restrict_value (&green, 0.0, 1.0); - _cairo_restrict_value (&blue, 0.0, 1.0); - _cairo_restrict_value (&alpha, 0.0, 1.0); + red = _cairo_restrict_value (red, 0.0, 1.0); + green = _cairo_restrict_value (green, 0.0, 1.0); + blue = _cairo_restrict_value (blue, 0.0, 1.0); + alpha = _cairo_restrict_value (alpha, 0.0, 1.0); _cairo_color_init_rgba (&color, red, green, blue, alpha); return _cairo_color_equal (&color, @@ -868,7 +868,8 @@ cairo_set_tolerance (cairo_t *cr, double tolerance) if (cr->status) return; - _cairo_restrict_value (&tolerance, CAIRO_TOLERANCE_MINIMUM, tolerance); + if (tolerance < CAIRO_TOLERANCE_MINIMUM) + tolerance = CAIRO_TOLERANCE_MINIMUM; status = _cairo_gstate_set_tolerance (cr->gstate, tolerance); if (unlikely (status)) @@ -962,7 +963,8 @@ cairo_set_line_width (cairo_t *cr, double width) if (cr->status) return; - _cairo_restrict_value (&width, 0.0, width); + if (width < 0.) + width = 0.; status = _cairo_gstate_set_line_width (cr->gstate, width); if (unlikely (status)) diff --git a/src/cairoint.h b/src/cairoint.h index 21f0e491..1d6939f9 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1032,8 +1032,17 @@ typedef struct _cairo_stroke_face { } cairo_stroke_face_t; /* cairo.c */ -cairo_private void -_cairo_restrict_value (double *value, double min, double max); + +static inline double +_cairo_restrict_value (double value, double min, double max) +{ + if (value < min) + return min; + else if (value > max) + return max; + else + return value; +} /* C99 round() rounds to the nearest integral value with halfway cases rounded * away from 0. _cairo_round rounds halfway cases toward negative infinity. -- cgit v1.2.3 From 005436758c5679f76cc462841678fb93d6c7e0ac Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Feb 2009 10:20:26 +0000 Subject: [path] Inline path ops during append_to_context() By inlining the operations, and most significantly, precomputing the combined user-to-backend matrix, we can achieve a speed up of over 50%, which is a noticeable performance boost in swfdec - where append-to-path accounts for over 35% [inclusive] of the time for a h/w accelerated backend. --- src/cairo-path.c | 76 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 18 deletions(-) diff --git a/src/cairo-path.c b/src/cairo-path.c index 6572da9c..d62843e7 100644 --- a/src/cairo-path.c +++ b/src/cairo-path.c @@ -36,6 +36,7 @@ #include "cairoint.h" +#include "cairo-private.h" #include "cairo-path-private.h" #include "cairo-path-fixed-private.h" @@ -441,43 +442,82 @@ cairo_status_t _cairo_path_append_to_context (const cairo_path_t *path, cairo_t *cr) { - int i; - cairo_path_data_t *p; + const cairo_path_data_t *p, *end; + cairo_fixed_t x1_fixed, y1_fixed; + cairo_fixed_t x2_fixed, y2_fixed; + cairo_fixed_t x3_fixed, y3_fixed; + cairo_matrix_t user_to_backend; cairo_status_t status; + double x, y; + + user_to_backend = cr->gstate->ctm; + cairo_matrix_multiply (&user_to_backend, + &cr->gstate->target->device_transform, + &user_to_backend); - for (i=0; i < path->num_data; i += path->data[i].header.length) { - p = &path->data[i]; + end = &path->data[path->num_data]; + for (p = &path->data[0]; p < end; p += p->header.length) { switch (p->header.type) { case CAIRO_PATH_MOVE_TO: - if (p->header.length < 2) + if (unlikely (p->header.length < 2)) return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - cairo_move_to (cr, - p[1].point.x, p[1].point.y); + + x = p[1].point.x, y = p[1].point.y; + cairo_matrix_transform_point (&user_to_backend, &x, &y); + x1_fixed = _cairo_fixed_from_double (x); + y1_fixed = _cairo_fixed_from_double (y); + + status = _cairo_path_fixed_move_to (cr->path, x1_fixed, y1_fixed); break; + case CAIRO_PATH_LINE_TO: - if (p->header.length < 2) + if (unlikely (p->header.length < 2)) return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - cairo_line_to (cr, - p[1].point.x, p[1].point.y); + + x = p[1].point.x, y = p[1].point.y; + cairo_matrix_transform_point (&user_to_backend, &x, &y); + x1_fixed = _cairo_fixed_from_double (x); + y1_fixed = _cairo_fixed_from_double (y); + + status = _cairo_path_fixed_line_to (cr->path, x1_fixed, y1_fixed); break; + case CAIRO_PATH_CURVE_TO: - if (p->header.length < 4) + if (unlikely (p->header.length < 4)) return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - cairo_curve_to (cr, - p[1].point.x, p[1].point.y, - p[2].point.x, p[2].point.y, - p[3].point.x, p[3].point.y); + + x = p[1].point.x, y = p[1].point.y; + cairo_matrix_transform_point (&user_to_backend, &x, &y); + x1_fixed = _cairo_fixed_from_double (x); + y1_fixed = _cairo_fixed_from_double (y); + + x = p[2].point.x, y = p[2].point.y; + cairo_matrix_transform_point (&user_to_backend, &x, &y); + x2_fixed = _cairo_fixed_from_double (x); + y2_fixed = _cairo_fixed_from_double (y); + + x = p[3].point.x, y = p[3].point.y; + cairo_matrix_transform_point (&user_to_backend, &x, &y); + x3_fixed = _cairo_fixed_from_double (x); + y3_fixed = _cairo_fixed_from_double (y); + + status = _cairo_path_fixed_curve_to (cr->path, + x1_fixed, y1_fixed, + x2_fixed, y2_fixed, + x3_fixed, y3_fixed); break; + case CAIRO_PATH_CLOSE_PATH: - if (p->header.length < 1) + if (unlikely (p->header.length < 1)) return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); - cairo_close_path (cr); + + status = _cairo_path_fixed_close_path (cr->path); break; + default: return _cairo_error (CAIRO_STATUS_INVALID_PATH_DATA); } - status = cairo_status (cr); if (unlikely (status)) return status; } -- cgit v1.2.3 From 187e3473512e40fa1d046783e797ec3a198b09b2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 13 Feb 2009 13:09:32 +0000 Subject: [test] Free ref_name in fallback-resolution. Trivial leak of a few thousand bytes. --- test/fallback-resolution.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/fallback-resolution.c b/test/fallback-resolution.c index 7b1d313b..eab79959 100644 --- a/test/fallback-resolution.c +++ b/test/fallback-resolution.c @@ -216,6 +216,7 @@ check_result (cairo_test_context_t *ctx, cairo_surface_destroy (test_image); free (png_name); free (diff_name); + free (ref_name); return FALSE; } @@ -247,6 +248,7 @@ check_result (cairo_test_context_t *ctx, cairo_surface_destroy (diff_image); free (png_name); free (diff_name); + free (ref_name); return ret; } -- cgit v1.2.3 From 1522fac5c71708fc9e98e03da9f51926c1e3769c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Feb 2009 17:18:53 +0000 Subject: [perf] Fix infinite loop in text The row would wrap-around with the character index, causing an infinite loop when trying to fill a window of size 512x512 and above. --- perf/text.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/perf/text.c b/perf/text.c index efe7d913..7aba1f91 100644 --- a/perf/text.c +++ b/perf/text.c @@ -31,21 +31,20 @@ do_text (cairo_t *cr, int width, int height) const char text[] = "the jay, pig, fox, zebra and my wolves quack"; int len = strlen (text); double x, y; - int i = 0; + int i = 0, j = 0; cairo_perf_timer_start (); cairo_set_font_size (cr, 9); do { - cairo_move_to (cr, 0, i * 10); + cairo_move_to (cr, 0, j++ * 10); cairo_show_text (cr, text + i); cairo_get_current_point (cr, &x, &y); while (x < width && cairo_status (cr) == CAIRO_STATUS_SUCCESS) { cairo_show_text (cr, text); cairo_get_current_point (cr, &x, &y); } - i++; - if (i >= len) + if (++i >= len) i = 0; } while (y < height && cairo_status (cr) == CAIRO_STATUS_SUCCESS); -- cgit v1.2.3 From 798581a1b5a8a56ce9d16c5b21eab82851061732 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 30 Jan 2009 22:12:49 +0000 Subject: [perf] Extend range of testing. Primarily to test longer glyph runs, but also test large upper bounds for strokes and fills. --- perf/cairo-perf.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index 6bb48f13..ad7da0af 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -444,11 +444,11 @@ main (int argc, char *argv[]) } const cairo_perf_case_t perf_cases[] = { - { paint, 256, 512}, - { paint_with_alpha, 256, 512}, - { fill, 64, 256}, - { stroke, 64, 256}, - { text, 64, 256}, + { paint, 64, 512}, + { paint_with_alpha, 64, 512}, + { fill, 64, 512}, + { stroke, 64, 512}, + { text, 64, 512}, { tessellate, 100, 100}, { subimage_copy, 16, 512}, { pattern_create_radial, 16, 16}, -- cgit v1.2.3 From 655f6987334b991763a5ab7746dbfd73c6b05f3e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 6 Feb 2009 20:11:17 +0000 Subject: [perf] Split can_run? into a separate precondition. Allow tests to skip unnecessary setup when pruning the list of perf cases. --- perf/box-outline.c | 3 +++ perf/cairo-perf.c | 24 ++++++++++++++++-------- perf/cairo-perf.h | 4 ++++ perf/composite-checker.c | 3 +++ perf/dragon.c | 3 +++ perf/fill.c | 3 +++ perf/intersections.c | 3 +++ perf/long-dashed-lines.c | 3 +++ perf/long-lines.c | 3 +++ perf/mosaic.c | 3 +++ perf/paint-with-alpha.c | 3 +++ perf/paint.c | 3 +++ perf/pattern_create_radial.c | 3 +++ perf/pythagoras-tree.c | 3 +++ perf/rectangles.c | 3 +++ perf/rounded-rectangles.c | 3 +++ perf/spiral.c | 3 +++ perf/stroke.c | 3 +++ perf/subimage_copy.c | 3 +++ perf/tessellate.c | 3 +++ perf/text.c | 3 +++ perf/twin.c | 3 +++ perf/unaligned-clip.c | 3 +++ perf/world-map.c | 3 +++ perf/zrusin.c | 3 +++ 25 files changed, 89 insertions(+), 8 deletions(-) diff --git a/perf/box-outline.c b/perf/box-outline.c index 74dd19ad..2d826e68 100644 --- a/perf/box-outline.c +++ b/perf/box-outline.c @@ -88,6 +88,9 @@ box_outline_fill (cairo_t *cr, int width, int height) void box_outline (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "box-outline")) + return; + cairo_perf_run (perf, "box-outline-stroke", box_outline_stroke); cairo_perf_run (perf, "box-outline-fill", box_outline_fill); } diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index ad7da0af..efe6e8d3 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -141,6 +141,22 @@ cairo_perf_has_similar (cairo_perf_t *perf) return TRUE; } +cairo_bool_t +cairo_perf_can_run (cairo_perf_t *perf, + const char *name) +{ + unsigned int i; + + if (perf->num_names == 0) + return TRUE; + + for (i = 0; i < perf->num_names; i++) + if (strstr (name, perf->names[i])) + return TRUE; + + return FALSE; +} + void cairo_perf_run (cairo_perf_t *perf, const char *name, @@ -152,14 +168,6 @@ cairo_perf_run (cairo_perf_t *perf, cairo_stats_t stats = {0.0, 0.0}; int low_std_dev_count; - if (perf->num_names) { - for (i = 0; i < perf->num_names; i++) - if (strstr (name, perf->names[i])) - goto NAME_FOUND; - return; - } - NAME_FOUND: - if (perf->list_only) { printf ("%s\n", name); return; diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h index 8c44c9ae..7e792ad8 100644 --- a/perf/cairo-perf.h +++ b/perf/cairo-perf.h @@ -89,6 +89,10 @@ typedef struct _cairo_perf { typedef cairo_perf_ticks_t (*cairo_perf_func_t) (cairo_t *cr, int width, int height); +cairo_bool_t +cairo_perf_can_run (cairo_perf_t *perf, + const char *name); + void cairo_perf_run (cairo_perf_t *perf, const char *name, diff --git a/perf/composite-checker.c b/perf/composite-checker.c index 69f48a08..e978990a 100644 --- a/perf/composite-checker.c +++ b/perf/composite-checker.c @@ -81,6 +81,9 @@ composite_checker (cairo_perf_t *perf, { cairo_surface_t *image; + if (! cairo_perf_can_run (perf, "composite-checker")) + return; + /* Create the checker pattern. We don't actually need to draw * anything on it since that wouldn't affect performance. */ diff --git a/perf/dragon.c b/perf/dragon.c index a6167cb3..1866c9ac 100644 --- a/perf/dragon.c +++ b/perf/dragon.c @@ -201,6 +201,9 @@ do_dragon_solid (cairo_t *cr, int width, int height) void dragon (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "dragon")) + return; + cairo_perf_run (perf, "dragon-solid", do_dragon_solid); cairo_perf_run (perf, "dragon", do_dragon); } diff --git a/perf/fill.c b/perf/fill.c index 2a413558..6ebe70ea 100644 --- a/perf/fill.c +++ b/perf/fill.c @@ -45,5 +45,8 @@ do_fill (cairo_t *cr, int width, int height) void fill (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "fill")) + return; + cairo_perf_cover_sources_and_operators (perf, "fill", do_fill); } diff --git a/perf/intersections.c b/perf/intersections.c index 5e410366..347c4a53 100644 --- a/perf/intersections.c +++ b/perf/intersections.c @@ -92,6 +92,9 @@ random_nz (cairo_t *cr, int width, int height) void intersections (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "intersections")) + return; + cairo_perf_run (perf, "intersections-nz-fill", random_nz); cairo_perf_run (perf, "intersections-eo-fill", random_eo); } diff --git a/perf/long-dashed-lines.c b/perf/long-dashed-lines.c index 31ddfe66..3520a197 100644 --- a/perf/long-dashed-lines.c +++ b/perf/long-dashed-lines.c @@ -63,5 +63,8 @@ do_long_dashed_lines (cairo_t *cr, int width, int height) void long_dashed_lines (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "long-dashed-lines")) + return; + cairo_perf_run (perf, "long-dashed-lines", do_long_dashed_lines); } diff --git a/perf/long-lines.c b/perf/long-lines.c index 62e8e16f..03592018 100644 --- a/perf/long-lines.c +++ b/perf/long-lines.c @@ -112,6 +112,9 @@ long_lines_cropped (cairo_t *cr, int width, int height) void long_lines (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "long-lines")) + return; + cairo_perf_run (perf, "long-lines-uncropped", long_lines_uncropped); cairo_perf_run (perf, "long-lines-cropped", long_lines_cropped); } diff --git a/perf/mosaic.c b/perf/mosaic.c index 7172a9d3..257a3626 100644 --- a/perf/mosaic.c +++ b/perf/mosaic.c @@ -161,6 +161,9 @@ mosaic_tessellate_curves (cairo_t *cr, int width, int height) void mosaic (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "mosaic")) + return; + cairo_perf_run (perf, "mosaic_fill_curves", mosaic_fill_curves); cairo_perf_run (perf, "mosaic_fill_lines", mosaic_fill_lines); cairo_perf_run (perf, "mosaic_tessellate_curves", mosaic_tessellate_curves); diff --git a/perf/paint-with-alpha.c b/perf/paint-with-alpha.c index d4d860ef..6ffe8bb1 100644 --- a/perf/paint-with-alpha.c +++ b/perf/paint-with-alpha.c @@ -40,6 +40,9 @@ do_paint_with_alpha (cairo_t *cr, int width, int height) void paint_with_alpha (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "paint-with-alpha")) + return; + cairo_perf_cover_sources_and_operators (perf, "paint-with-alpha", do_paint_with_alpha); } diff --git a/perf/paint.c b/perf/paint.c index 6f75016c..a60d132b 100644 --- a/perf/paint.c +++ b/perf/paint.c @@ -40,5 +40,8 @@ do_paint (cairo_t *cr, int width, int height) void paint (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "paint")) + return; + cairo_perf_cover_sources_and_operators (perf, "paint", do_paint); } diff --git a/perf/pattern_create_radial.c b/perf/pattern_create_radial.c index 09f15a82..8fa683b8 100644 --- a/perf/pattern_create_radial.c +++ b/perf/pattern_create_radial.c @@ -82,6 +82,9 @@ pattern_create_radial (cairo_perf_t *perf, cairo_t *cr, int width, int height) { int i; + if (! cairo_perf_can_run (perf, "pattern_create_radial")) + return; + srand (time (0)); for (i = 0; i < RADIALS_COUNT; i++) { diff --git a/perf/pythagoras-tree.c b/perf/pythagoras-tree.c index 5a78d8a7..750e83b2 100644 --- a/perf/pythagoras-tree.c +++ b/perf/pythagoras-tree.c @@ -82,5 +82,8 @@ do_pythagoras_tree (cairo_t *cr, int width, int height) void pythagoras_tree (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "pythagoras_tree")) + return; + cairo_perf_run (perf, "pythagoras_tree", do_pythagoras_tree); } diff --git a/perf/rectangles.c b/perf/rectangles.c index 374e3644..c224968f 100644 --- a/perf/rectangles.c +++ b/perf/rectangles.c @@ -96,6 +96,9 @@ rectangles (cairo_perf_t *perf, cairo_t *cr, int width, int height) { int i; + if (! cairo_perf_can_run (perf, "rectangles")) + return; + srand (8478232); for (i = 0; i < RECTANGLE_COUNT; i++) { diff --git a/perf/rounded-rectangles.c b/perf/rounded-rectangles.c index 7d20825d..25133f38 100644 --- a/perf/rounded-rectangles.c +++ b/perf/rounded-rectangles.c @@ -98,6 +98,9 @@ rounded_rectangles (cairo_perf_t *perf, cairo_t *cr, int width, int height) { int i; + if (! cairo_perf_can_run (perf, "rounded-rectangles")) + return; + srand (8478232); for (i = 0; i < RECTANGLE_COUNT; i++) { rects[i].x = rand () % width; diff --git a/perf/spiral.c b/perf/spiral.c index f26d0a2b..fb2af61d 100644 --- a/perf/spiral.c +++ b/perf/spiral.c @@ -189,6 +189,9 @@ draw_spiral_nz_na_di (cairo_t *cr, int width, int height) void spiral (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "spiral")) + return; + cairo_perf_run (perf, "spiral-diag-nonalign-evenodd-fill", draw_spiral_eo_na_di); cairo_perf_run (perf, "spiral-diag-nonalign-nonzero-fill", draw_spiral_nz_na_di); cairo_perf_run (perf, "spiral-diag-pixalign-evenodd-fill", draw_spiral_eo_pa_di); diff --git a/perf/stroke.c b/perf/stroke.c index 0b4ea8e6..7b3990d5 100644 --- a/perf/stroke.c +++ b/perf/stroke.c @@ -47,5 +47,8 @@ do_stroke (cairo_t *cr, int width, int height) void stroke (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "stroke")) + return; + cairo_perf_cover_sources_and_operators (perf, "stroke", do_stroke); } diff --git a/perf/subimage_copy.c b/perf/subimage_copy.c index 54f596f4..722705b4 100644 --- a/perf/subimage_copy.c +++ b/perf/subimage_copy.c @@ -55,6 +55,9 @@ subimage_copy (cairo_perf_t *perf, cairo_t *cr, int width, int height) cairo_surface_t *image; cairo_t *cr2; + if (! cairo_perf_can_run (perf, "subimage_copy")) + return; + cairo_set_source_rgb (cr, 0, 0, 1); /* blue */ cairo_paint (cr); diff --git a/perf/tessellate.c b/perf/tessellate.c index fc97db70..4af38411 100644 --- a/perf/tessellate.c +++ b/perf/tessellate.c @@ -143,6 +143,9 @@ tessellate_256 (cairo_t *cr, int width, int height) void tessellate (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "tessellate")) + return; + cairo_perf_run (perf, "tessellate-16", tessellate_16); cairo_perf_run (perf, "tessellate-64", tessellate_64); cairo_perf_run (perf, "tessellate-256", tessellate_256); diff --git a/perf/text.c b/perf/text.c index 7aba1f91..4448802a 100644 --- a/perf/text.c +++ b/perf/text.c @@ -56,5 +56,8 @@ do_text (cairo_t *cr, int width, int height) void text (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "text")) + return; + cairo_perf_cover_sources_and_operators (perf, "text", do_text); } diff --git a/perf/twin.c b/perf/twin.c index 84ac7598..f65cccf8 100644 --- a/perf/twin.c +++ b/perf/twin.c @@ -46,5 +46,8 @@ twin (cairo_perf_t *perf, int width, int height) { + if (! cairo_perf_can_run (perf, "twin")) + return; + cairo_perf_run (perf, "twin", do_twin); } diff --git a/perf/unaligned-clip.c b/perf/unaligned-clip.c index 6d2b1797..a757fa67 100644 --- a/perf/unaligned-clip.c +++ b/perf/unaligned-clip.c @@ -59,5 +59,8 @@ do_unaligned_clip (cairo_t *cr, int width, int height) void unaligned_clip (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "unaligned-clip")) + return; + cairo_perf_run (perf, "unaligned_clip", do_unaligned_clip); } diff --git a/perf/world-map.c b/perf/world-map.c index fe6d42d5..5b8be453 100644 --- a/perf/world-map.c +++ b/perf/world-map.c @@ -105,5 +105,8 @@ do_world_map (cairo_t *cr, int width, int height) void world_map (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "world_map")) + return; + cairo_perf_run (perf, "world_map", do_world_map); } diff --git a/perf/zrusin.c b/perf/zrusin.c index 68407751..21956159 100644 --- a/perf/zrusin.c +++ b/perf/zrusin.c @@ -85,6 +85,9 @@ zrusin_another_fill (cairo_t *cr, int width, int height) void zrusin (cairo_perf_t *perf, cairo_t *cr, int width, int height) { + if (! cairo_perf_can_run (perf, "zrusin")) + return; + cairo_perf_run (perf, "zrusin_another_tessellate", zrusin_another_tessellate); cairo_perf_run (perf, "zrusin_another_fill", zrusin_another_fill); } -- cgit v1.2.3 From aab9ed3432f0ea7b8b24990de4aa134bb599a3e5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 30 Jan 2009 10:22:47 +0000 Subject: [perf] Env variable to ignore similar targets whilst benchmarking. Use CAIRO_TEST_IGNORE_SIMILAR to skip similar targets. --- perf/cairo-perf.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index efe6e8d3..c66113f3 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -134,6 +134,9 @@ cairo_perf_has_similar (cairo_perf_t *perf) { cairo_surface_t *target = cairo_get_target (perf->cr); + if (getenv ("CAIRO_TEST_IGNORE_SIMILAR")) + return FALSE; + /* exclude the image backend */ if (cairo_surface_get_type (target) == CAIRO_SURFACE_TYPE_IMAGE) return FALSE; -- cgit v1.2.3 From fa66291c8862ed592fca469ceab0ac9b1d270835 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 28 Jan 2009 14:22:58 +0000 Subject: [perf] Test non-antialiased fill. Just because the i915 can special case such fills using a single-pass tessellation in the stencil buffer. --- perf/fill.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/perf/fill.c b/perf/fill.c index 6ebe70ea..f068561a 100644 --- a/perf/fill.c +++ b/perf/fill.c @@ -42,6 +42,26 @@ do_fill (cairo_t *cr, int width, int height) return cairo_perf_timer_elapsed (); } +static cairo_perf_ticks_t +do_fill_eo_noaa (cairo_t *cr, int width, int height) +{ + cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE); + cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); + + cairo_arc (cr, + width/2.0, height/2.0, + width/3.0, + 0, 2 * M_PI); + + cairo_perf_timer_start (); + + cairo_fill (cr); + + cairo_perf_timer_stop (); + + return cairo_perf_timer_elapsed (); +} + void fill (cairo_perf_t *perf, cairo_t *cr, int width, int height) { @@ -49,4 +69,5 @@ fill (cairo_perf_t *perf, cairo_t *cr, int width, int height) return; cairo_perf_cover_sources_and_operators (perf, "fill", do_fill); + cairo_perf_cover_sources_and_operators (perf, "fill-eo-noaa", do_fill_eo_noaa); } -- cgit v1.2.3 From b43e7aee98a8d69677f7e6d2584fe01f550f896b Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 13 Feb 2009 12:15:23 -0500 Subject: [wince] We don't need cairo_win32_tmpfile on Windows CE _cairo_win32_tmpfile() uses _open_osfhandle() which is not available on Windows CE. However, Windows CE doesn't have the permisions problems that necessitated _cairo_win32_tmpfile() in the first place so we can just use tmpfile() on Windows CE. --- src/cairo-misc.c | 5 ++++- src/cairoint.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cairo-misc.c b/src/cairo-misc.c index 0c9db901..ab30327b 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -610,10 +610,12 @@ _cairo_lround (double d) #include #include +#if !WINCE /* tmpfile() replacement for Windows. * * On Windows tmpfile() creates the file in the root directory. This - * may fail due to unsufficient privileges. + * may fail due to unsufficient privileges. However, this isn't a + * problem on Windows CE so we don't use it there. */ FILE * _cairo_win32_tmpfile (void) @@ -658,6 +660,7 @@ _cairo_win32_tmpfile (void) return fp; } +#endif /* !WINCE */ #endif /* _WIN32 */ diff --git a/src/cairoint.h b/src/cairoint.h index 1d6939f9..bfcaaa93 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -85,7 +85,7 @@ CAIRO_BEGIN_DECLS -#ifdef _WIN32 +#if _WIN32 && !WINCE // we don't have to worry about permissions on WINCE cairo_private FILE * _cairo_win32_tmpfile (void); #define tmpfile() _cairo_win32_tmpfile() -- cgit v1.2.3 From fcb13d262c5a09e56dc25c76103ef4ba623929ff Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Sun, 15 Feb 2009 15:59:10 -0500 Subject: Simplify region handling in xlib surface --- src/cairo-xlib-surface.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index a18fc034..c94004c2 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2294,7 +2294,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, XRectangle *rects = NULL; int n_boxes, i; cairo_rectangle_int_t rect; - cairo_region_t bound, bounded; + cairo_region_t bounded; rect.x = rect.y = 0; rect.width = surface->width; @@ -2304,11 +2304,9 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, * is necessary so we don't wrap around when we convert cairo's * 32 bit region into 16 bit rectangles. */ - _cairo_region_init_rect (&bound, &rect); - _cairo_region_init (&bounded); - status = _cairo_region_intersect (&bounded, &bound, region); + _cairo_region_init_rect (&bounded, &rect); + status = _cairo_region_intersect (&bounded, &bounded, region); if (unlikely (status)) { - _cairo_region_fini (&bound); _cairo_region_fini (&bounded); return status; } @@ -2317,7 +2315,6 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, boxes = (cairo_box_int_t *) surface->embedded_clip_rects; status = _cairo_region_get_boxes (&bounded, &n_boxes, &boxes); if (unlikely (status)) { - _cairo_region_fini (&bound); _cairo_region_fini (&bounded); return status; } @@ -2326,7 +2323,6 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle)); if (unlikely (rects == NULL)) { _cairo_region_boxes_fini (&bounded, boxes); - _cairo_region_fini (&bound); _cairo_region_fini (&bounded); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -2343,7 +2339,6 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, if (boxes != (cairo_box_int_t *) surface->embedded_clip_rects) _cairo_region_boxes_fini (&bounded, boxes); _cairo_region_fini (&bounded); - _cairo_region_fini (&bound); surface->have_clip_rects = TRUE; surface->clip_rects = rects; -- cgit v1.2.3 From f6daa664c1b2c894ba3baf2e7a72566bda1fd636 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Sun, 15 Feb 2009 18:55:17 -0500 Subject: Delete _cairo_region_get_boxes() in favor of _cairo_region_get_box() The _cairo_region_get_boxes() interface was difficult to use and often caused unnecessary memory allocation. With _cairo_region_get_box() it is possible to access the boxes of a region without allocating a big temporary array. --- src/cairo-clip.c | 21 ++++++++----------- src/cairo-directfb-surface.c | 21 ++++++++----------- src/cairo-paginated-surface.c | 19 ++++++++--------- src/cairo-region-private.h | 10 +++------ src/cairo-region.c | 39 +++++++++-------------------------- src/cairo-sdl-surface.c | 21 ++++++++----------- src/cairo-surface.c | 44 +++++++++++++++------------------------ src/cairo-win32-surface.c | 48 +++++++++++++++++++++---------------------- src/cairo-xcb-surface.c | 26 ++++++++++------------- src/cairo-xlib-surface.c | 31 ++++++++++++---------------- 10 files changed, 112 insertions(+), 168 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index a64d524f..9aac1154 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -884,38 +884,35 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) } if (clip->has_region) { - cairo_box_int_t *boxes; int i; - if (_cairo_region_get_boxes (&clip->region, &n_boxes, &boxes)) - return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; + n_boxes = _cairo_region_num_boxes (&clip->region); if (n_boxes) { rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t)); if (unlikely (rectangles == NULL)) { - _cairo_region_boxes_fini (&clip->region, boxes); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; } for (i = 0; i < n_boxes; ++i) { - cairo_rectangle_int_t clip_rect; + cairo_box_int_t box; + cairo_rectangle_int_t clip_rect; - clip_rect.x = boxes[i].p1.x; - clip_rect.y = boxes[i].p1.y; - clip_rect.width = boxes[i].p2.x - boxes[i].p1.x; - clip_rect.height = boxes[i].p2.y - boxes[i].p1.y; + _cairo_region_get_box (&clip->region, i, &box); + clip_rect.x = box.p1.x; + clip_rect.y = box.p1.y; + clip_rect.width = box.p2.x - box.p1.x; + clip_rect.height = box.p2.y - box.p1.y; + if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) { _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); - _cairo_region_boxes_fini (&clip->region, boxes); free (rectangles); return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable; } } } - - _cairo_region_boxes_fini (&clip->region, boxes); } else { cairo_rectangle_int_t extents; diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c index ecce1792..b902cca1 100644 --- a/src/cairo-directfb-surface.c +++ b/src/cairo-directfb-surface.c @@ -1299,17 +1299,13 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface, __FUNCTION__, surface, region); if (region) { - cairo_box_int_t *boxes; int n_boxes; cairo_status_t status; int i; surface->has_clip = TRUE; - n_boxes = 0; - status = _cairo_region_get_boxes (region, &n_boxes, &boxes); - if (status) - return status; + n_boxes = _cairo_region_num_boxes (region); if (n_boxes == 0) return CAIRO_STATUS_SUCCESS; @@ -1321,7 +1317,6 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface, surface->clips = _cairo_malloc_ab (n_boxes, sizeof (DFBRegion)); if (!surface->clips) { surface->n_clips = 0; - _cairo_region_boxes_fini (region, boxes); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -1329,13 +1324,15 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface, } for (i = 0; i < n_boxes; i++) { - surface->clips[i].x1 = boxes[i].p1.x; - surface->clips[i].y1 = boxes[i].p1.y; - surface->clips[i].x2 = boxes[i].p2.x - 1; - surface->clips[i].y2 = boxes[i].p2.y - 1; + cairo_box_int_t box; + + _cairo_region_get_box (region, i, &box); + + surface->clips[i].x1 = box.p1.x; + surface->clips[i].y1 = box.p1.y; + surface->clips[i].x2 = box.p2.x - 1; + surface->clips[i].y2 = box.p2.y - 1; } - - _cairo_region_boxes_fini (region, boxes); } else { surface->has_clip = FALSE; if (surface->clips) { diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index 5d4e08fa..8c62644a 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -381,7 +381,6 @@ _paint_page (cairo_paginated_surface_t *surface) if (has_finegrained_fallback) { cairo_region_t *region; - cairo_box_int_t *boxes; int num_boxes, i; surface->backend->set_paginated_mode (surface->target, @@ -398,19 +397,17 @@ _paint_page (cairo_paginated_surface_t *surface) region = _cairo_analysis_surface_get_unsupported (analysis); - num_boxes = 0; - status = _cairo_region_get_boxes (region, &num_boxes, &boxes); - if (unlikely (status)) - goto FAIL; - + num_boxes = _cairo_region_num_boxes (region); for (i = 0; i < num_boxes; i++) { - status = _paint_fallback_image (surface, &boxes[i]); - if (unlikely (status)) { - _cairo_region_boxes_fini (region, boxes); + cairo_box_int_t box; + + _cairo_region_get_box (region, i, &box); + + status = _paint_fallback_image (surface, &box); + + if (unlikely (status)) goto FAIL; - } } - _cairo_region_boxes_fini (region, boxes); } FAIL: diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index 588762e5..d969116a 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -72,14 +72,10 @@ _cairo_region_copy (cairo_region_t *dst, cairo_private int _cairo_region_num_boxes (cairo_region_t *region); -cairo_private cairo_int_status_t -_cairo_region_get_boxes (cairo_region_t *region, - int *num_boxes, - cairo_box_int_t **boxes); - cairo_private void -_cairo_region_boxes_fini (cairo_region_t *region, - cairo_box_int_t *boxes); +_cairo_region_get_box (cairo_region_t *region, + int nth_box, + cairo_box_int_t *box); cairo_private void _cairo_region_get_extents (cairo_region_t *region, diff --git a/src/cairo-region.c b/src/cairo-region.c index 53a359b3..a9efacc4 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -105,38 +105,19 @@ _cairo_region_num_boxes (cairo_region_t *region) return pixman_region32_n_rects (®ion->rgn); } -cairo_int_status_t -_cairo_region_get_boxes (cairo_region_t *region, int *num_boxes, cairo_box_int_t **boxes) +cairo_private void +_cairo_region_get_box (cairo_region_t *region, + int nth_box, + cairo_box_int_t *box) { - int nboxes; - pixman_box32_t *pboxes; - cairo_box_int_t *cboxes; - int i; - - pboxes = pixman_region32_rectangles (®ion->rgn, &nboxes); - if (nboxes == 0) { - *num_boxes = 0; - return CAIRO_STATUS_SUCCESS; - } + pixman_box32_t *pbox; - if (nboxes > *num_boxes) { - cboxes = _cairo_malloc_ab (nboxes, sizeof (cairo_box_int_t)); - if (unlikely (cboxes == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } else - cboxes = *boxes; - - for (i = 0; i < nboxes; i++) { - cboxes[i].p1.x = pboxes[i].x1; - cboxes[i].p1.y = pboxes[i].y1; - cboxes[i].p2.x = pboxes[i].x2; - cboxes[i].p2.y = pboxes[i].y2; - } + pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth_box; - *num_boxes = nboxes; - *boxes = cboxes; - - return CAIRO_STATUS_SUCCESS; + box->p1.x = pbox->x1; + box->p1.y = pbox->y1; + box->p2.x = pbox->x2; + box->p2.y = pbox->y2; } void diff --git a/src/cairo-sdl-surface.c b/src/cairo-sdl-surface.c index 1f97fb47..9ab82a56 100644 --- a/src/cairo-sdl-surface.c +++ b/src/cairo-sdl-surface.c @@ -318,27 +318,24 @@ static cairo_status_t _cairo_sdl_surface_flush (void *abstract_surface) { cairo_sdl_surface_t *surface = abstract_surface; - cairo_box_int_t *boxes; int n_boxes, i; - cairo_status_t status; - n_boxes = 0; - status = _cairo_region_get_boxes (&surface->update, &n_boxes, &boxes); - if (unlikely (status)) - return status; + n_boxes = _cairo_region_num_boxes (&surface->update); if (n_boxes == 0) return CAIRO_STATUS_SUCCESS; for (i = 0; i < n_boxes; i++) { + cairo_box_int_t box; + + _cairo_region_get_box (&surface->update, i, &box); + SDL_UpdateRect (surface->sdl, - boxes[i].p1.x, - boxes[i].p1.y, - boxes[i].p2.x - boxes[i].p1.x, - boxes[i].p2.y - boxes[i].p1.y); + box.p1.x, + box.p1.y, + box.p2.x - box.p1.x, + box.p2.y - box.p1.y); } - _cairo_region_boxes_fini (&surface->update, boxes); - _cairo_region_fini (&surface->update); _cairo_region_init (&surface->update); diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 7bb502b6..6f522fc4 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1579,7 +1579,6 @@ _cairo_surface_fill_region (cairo_surface_t *surface, { int num_boxes; cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; - cairo_box_int_t *boxes = (cairo_box_int_t *) stack_rects; cairo_rectangle_int_t *rects = stack_rects; cairo_status_t status; int i; @@ -1593,38 +1592,29 @@ _cairo_surface_fill_region (cairo_surface_t *surface, if (num_boxes == 0) return CAIRO_STATUS_SUCCESS; - /* handle the common case of a single box without allocation */ - if (num_boxes > 1) { - num_boxes = sizeof (stack_rects) / sizeof (cairo_box_int_t); - status = _cairo_region_get_boxes (region, &num_boxes, &boxes); - if (unlikely (status)) - return status; - - if (num_boxes > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (num_boxes, - sizeof (cairo_rectangle_int_t)); - if (rects == NULL) { - _cairo_region_boxes_fini (region, boxes); - return _cairo_surface_set_error (surface, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } + if (num_boxes > ARRAY_LENGTH (stack_rects)) { + rects = _cairo_malloc_ab (num_boxes, + sizeof (cairo_rectangle_int_t)); + if (rects == NULL) { + return _cairo_surface_set_error (surface, + _cairo_error (CAIRO_STATUS_NO_MEMORY)); } + } - for (i = 0; i < num_boxes; i++) { - rects[i].x = boxes[i].p1.x; - rects[i].y = boxes[i].p1.y; - rects[i].width = boxes[i].p2.x - rects[i].x; - rects[i].height = boxes[i].p2.y - rects[i].y; - } - } else - _cairo_region_get_extents (region, &rects[0]); + for (i = 0; i < num_boxes; i++) { + cairo_box_int_t box; + + _cairo_region_get_box (region, i, &box); + + rects[i].x = box.p1.x; + rects[i].y = box.p1.y; + rects[i].width = box.p2.x - rects[i].x; + rects[i].height = box.p2.y - rects[i].y; + } status = _cairo_surface_fill_rectangles (surface, op, color, rects, num_boxes); - if (boxes != (cairo_box_int_t *) stack_rects) - _cairo_region_boxes_fini (region, boxes); - if (rects != stack_rects) free (rects); diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index 03a8f61a..f0c7aa2c 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -1461,38 +1461,36 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, /* Then combine any new region with it */ if (region) { cairo_rectangle_int_t extents; - cairo_box_int_t *boxes; int num_boxes; RGNDATA *data; size_t data_size; RECT *rects; int i; HRGN gdi_region; + cairo_box_int_t box0; /* Create a GDI region for the cairo region */ _cairo_region_get_extents (region, &extents); - num_boxes = 0; - status = _cairo_region_get_boxes (region, &num_boxes, &boxes); - if (status) - return status; + num_boxes = _cairo_region_num_boxes (region); + if (num_boxes == 1) + _cairo_region_get_box (region, 0, &box0); + if (num_boxes == 1 && - boxes[0].p1.x == 0 && - boxes[0].p1.y == 0 && - boxes[0].p2.x == surface->extents.width && - boxes[0].p2.y == surface->extents.height) + box0.p1.x == 0 && + box0.p1.y == 0 && + box0.p2.x == surface->extents.width && + box0.p2.y == surface->extents.height) { gdi_region = NULL; - + SelectClipRgn (surface->dc, NULL); IntersectClipRect (surface->dc, - boxes[0].p1.x, - boxes[0].p1.y, - boxes[0].p2.x, - boxes[0].p2.y); - - _cairo_region_boxes_fini (region, boxes); + box0.p1.x, + box0.p1.y, + box0.p2.x, + box0.p2.y); } else { /* XXX see notes in _cairo_win32_save_initial_clip -- * this code will interact badly with a HDC which had an initial @@ -1503,10 +1501,8 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT); data = malloc (data_size); - if (!data) { - _cairo_region_boxes_fini (region, boxes); + if (!data) return _cairo_error(CAIRO_STATUS_NO_MEMORY); - } rects = (RECT *)data->Buffer; data->rdh.dwSize = sizeof (RGNDATAHEADER); @@ -1519,14 +1515,16 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, data->rdh.rcBound.bottom = extents.y + extents.height; for (i = 0; i < num_boxes; i++) { - rects[i].left = boxes[i].p1.x; - rects[i].top = boxes[i].p1.y; - rects[i].right = boxes[i].p2.x; - rects[i].bottom = boxes[i].p2.y; + cairo_box_int_t box; + + _cairo_region_get_box (region, i, &box); + + rects[i].left = box.p1.x; + rects[i].top = box.p1.y; + rects[i].right = box.p2.x; + rects[i].bottom = box.p2.y; } - _cairo_region_boxes_fini (region, boxes); - gdi_region = ExtCreateRegion (NULL, data_size, data); free (data); diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index 2ae7dcf3..17a09e3f 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -1555,35 +1555,31 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface, xcb_render_change_picture (surface->dpy, surface->dst_picture, XCB_RENDER_CP_CLIP_MASK, none); } else { - cairo_box_int_t *boxes; cairo_status_t status; xcb_rectangle_t *rects = NULL; int n_boxes, i; - n_boxes = 0; - status = _cairo_region_get_boxes (region, &n_boxes, &boxes); - if (status) - return status; + n_boxes = _cairo_region_num_boxes (region); if (n_boxes > 0) { rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t)); - if (rects == NULL) { - _cairo_region_boxes_fini (region, boxes); + if (rects == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } } else { rects = NULL; } for (i = 0; i < n_boxes; i++) { - rects[i].x = boxes[i].p1.x; - rects[i].y = boxes[i].p1.y; - rects[i].width = boxes[i].p2.x - boxes[i].p1.x; - rects[i].height = boxes[i].p2.y - boxes[i].p1.y; + cairo_box_int_t box; + + _cairo_region_get_box (region, i, &box); + + rects[i].x = box.p1.x; + rects[i].y = box.p1.y; + rects[i].width = box.p2.x - box.p1.x; + rects[i].height = box.p2.y - box.p1.y; } - - _cairo_region_boxes_fini (region, boxes); - + surface->have_clip_rects = TRUE; surface->clip_rects = rects; surface->num_clip_rects = n_boxes; diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index c94004c2..f86a133e 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2289,7 +2289,6 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, surface->num_clip_rects = 0; if (region != NULL) { - cairo_box_int_t *boxes; cairo_status_t status; XRectangle *rects = NULL; int n_boxes, i; @@ -2311,33 +2310,29 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, return status; } - n_boxes = sizeof (surface->embedded_clip_rects) / sizeof (cairo_box_int_t); - boxes = (cairo_box_int_t *) surface->embedded_clip_rects; - status = _cairo_region_get_boxes (&bounded, &n_boxes, &boxes); - if (unlikely (status)) { - _cairo_region_fini (&bounded); - return status; - } + n_boxes = _cairo_region_num_boxes (&bounded); if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) { rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle)); if (unlikely (rects == NULL)) { - _cairo_region_boxes_fini (&bounded, boxes); _cairo_region_fini (&bounded); return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - } else + } + } else { rects = surface->embedded_clip_rects; + } for (i = 0; i < n_boxes; i++) { - rects[i].x = boxes[i].p1.x; - rects[i].y = boxes[i].p1.y; - rects[i].width = boxes[i].p2.x - rects[i].x; - rects[i].height = boxes[i].p2.y - rects[i].y; - } + cairo_box_int_t box; - if (boxes != (cairo_box_int_t *) surface->embedded_clip_rects) - _cairo_region_boxes_fini (&bounded, boxes); + _cairo_region_get_box (&bounded, i, &box); + + rects[i].x = box.p1.x; + rects[i].y = box.p1.y; + rects[i].width = box.p2.x - rects[i].x; + rects[i].height = box.p2.y - rects[i].y; + } + _cairo_region_fini (&bounded); surface->have_clip_rects = TRUE; -- cgit v1.2.3 From 79a72e63585d7fce7898f2c8bd997c6d88f8895f Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Mon, 16 Feb 2009 05:44:15 -0500 Subject: Delete _cairo_region_boxes_fini() --- src/cairo-region.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index a9efacc4..d32805e8 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -120,12 +120,6 @@ _cairo_region_get_box (cairo_region_t *region, box->p2.y = pbox->y2; } -void -_cairo_region_boxes_fini (cairo_region_t *region, cairo_box_int_t *boxes) -{ - free (boxes); -} - /** * _cairo_region_get_extents: * @region: a #cairo_region_t -- cgit v1.2.3 From e380beae5382df547a1b538de94e90c0e2339141 Mon Sep 17 00:00:00 2001 From: M Joonas Pihlaja Date: Mon, 16 Feb 2009 14:01:43 +0200 Subject: [sdl] Remove new backend. The SDL backend makes invalid assumptions about SDL_Surface locking semantics and doesn't deal correctly with the unpremultiplied pixel format supported by SDL. Removed as per discussion on the mailing list. http://lists.cairographics.org/archives/cairo/2009-February/016595.html --- boilerplate/Makefile.sources | 3 - boilerplate/Makefile.win32.features | 10 - boilerplate/cairo-boilerplate-sdl-private.h | 56 ---- boilerplate/cairo-boilerplate-sdl.c | 69 ----- boilerplate/cairo-boilerplate.c | 15 - build/Makefile.win32.features | 1 - build/Makefile.win32.features-h | 3 - build/configure.ac.features | 1 - configure.ac | 8 - doc/public/tmpl/cairo-surface.sgml | 1 - perf/Makefile.am | 4 - perf/cairo-perf.c | 4 - src/Makefile.sources | 3 - src/Makefile.win32.features | 14 - src/cairo-sdl-surface.c | 418 ---------------------------- src/cairo-sdl.h | 54 ---- src/cairo.h | 2 - test/Makefile.am | 4 - test/cairo-test-runner.c | 4 - test/get-clip.c | 1 - 20 files changed, 675 deletions(-) delete mode 100644 boilerplate/cairo-boilerplate-sdl-private.h delete mode 100644 boilerplate/cairo-boilerplate-sdl.c delete mode 100644 src/cairo-sdl-surface.c delete mode 100644 src/cairo-sdl.h diff --git a/boilerplate/Makefile.sources b/boilerplate/Makefile.sources index b3cea817..1b82bbda 100644 --- a/boilerplate/Makefile.sources +++ b/boilerplate/Makefile.sources @@ -43,9 +43,6 @@ cairo_boilerplate_quartz_sources = cairo-boilerplate-quartz.c cairo_boilerplate_script_private = cairo-boilerplate-script-private.h cairo_boilerplate_script_sources = cairo-boilerplate-script.c -cairo_boilerplate_sdl_private = cairo-boilerplate-sdl-private.h -cairo_boilerplate_sdl_sources = cairo-boilerplate-sdl.c - cairo_boilerplate_svg_private = cairo-boilerplate-svg-private.h cairo_boilerplate_svg_sources = cairo-boilerplate-svg.c diff --git a/boilerplate/Makefile.win32.features b/boilerplate/Makefile.win32.features index 74f1ec1e..f5ee452f 100644 --- a/boilerplate/Makefile.win32.features +++ b/boilerplate/Makefile.win32.features @@ -119,16 +119,6 @@ enabled_cairo_boilerplate_private += $(cairo_boilerplate_beos_private) enabled_cairo_boilerplate_sources += $(cairo_boilerplate_beos_sources) endif -unsupported_cairo_boilerplate_headers += $(cairo_boilerplate_sdl_headers) -all_cairo_boilerplate_headers += $(cairo_boilerplate_sdl_headers) -all_cairo_boilerplate_private += $(cairo_boilerplate_sdl_private) -all_cairo_boilerplate_sources += $(cairo_boilerplate_sdl_sources) -ifeq ($(CAIRO_HAS_SDL_SURFACE),1) -enabled_cairo_boilerplate_headers += $(cairo_boilerplate_sdl_headers) -enabled_cairo_boilerplate_private += $(cairo_boilerplate_sdl_private) -enabled_cairo_boilerplate_sources += $(cairo_boilerplate_sdl_sources) -endif - supported_cairo_boilerplate_headers += $(cairo_boilerplate_png_headers) all_cairo_boilerplate_headers += $(cairo_boilerplate_png_headers) all_cairo_boilerplate_private += $(cairo_boilerplate_png_private) diff --git a/boilerplate/cairo-boilerplate-sdl-private.h b/boilerplate/cairo-boilerplate-sdl-private.h deleted file mode 100644 index 9b5bdf79..00000000 --- a/boilerplate/cairo-boilerplate-sdl-private.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Chris Wilson. - */ - -#ifndef CAIRO_BOILERPLATE_SDL_PRIVATE_H -#define CAIRO_BOILERPLATE_SDL_PRIVATE_H - -#include - -CAIRO_BEGIN_DECLS - -extern cairo_surface_t * -_cairo_boilerplate_sdl_create_surface (const char *name, - cairo_content_t content, - int width, - int height, - int max_width, - int max_height, - cairo_boilerplate_mode_t mode, - int id, - void **closure); - -extern void -_cairo_boilerplate_sdl_cleanup (void* closure); - -CAIRO_END_DECLS - -#endif /* CAIRO_BOILERPLATE_SDL_PRIVATE_H */ diff --git a/boilerplate/cairo-boilerplate-sdl.c b/boilerplate/cairo-boilerplate-sdl.c deleted file mode 100644 index 407c2ee4..00000000 --- a/boilerplate/cairo-boilerplate-sdl.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Chris Wilson. - */ - -#include "cairo-boilerplate.h" -#include "cairo-boilerplate-sdl-private.h" - -#include - -void -_cairo_boilerplate_sdl_cleanup (void *closure) -{ - SDL_Quit (); -} - -cairo_surface_t * -_cairo_boilerplate_sdl_create_surface (const char *name, - cairo_content_t content, - int width, - int height, - int max_width, - int max_height, - cairo_boilerplate_mode_t mode, - int id, - void **closure) -{ - SDL_Surface *screen; - cairo_surface_t *surface; - - if (SDL_Init (SDL_INIT_VIDEO) < 0) - return NULL; - - screen = SDL_SetVideoMode (width, height, 24, SDL_SWSURFACE); - if (screen == NULL) - return NULL; - - surface = cairo_sdl_surface_create (screen); - SDL_FreeSurface (screen); - - return surface; -} diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c index dd34110c..b6c2c80b 100644 --- a/boilerplate/cairo-boilerplate.c +++ b/boilerplate/cairo-boilerplate.c @@ -50,9 +50,6 @@ #if CAIRO_HAS_SCRIPT_SURFACE #include "cairo-boilerplate-script-private.h" #endif -#if CAIRO_HAS_SDL_SURFACE -#include "cairo-boilerplate-sdl-private.h" -#endif #if CAIRO_HAS_SVG_SURFACE #include "cairo-boilerplate-svg-private.h" #endif @@ -723,18 +720,6 @@ static cairo_boilerplate_target_t targets[] = _cairo_boilerplate_directfb_cleanup }, #endif - -#if CAIRO_HAS_SDL_SURFACE - { - "sdl", "sdl", NULL, - CAIRO_SURFACE_TYPE_SDL, CAIRO_CONTENT_COLOR, 0, - _cairo_boilerplate_sdl_create_surface, NULL, - NULL, - _cairo_boilerplate_get_image_surface, - cairo_surface_write_to_png, - _cairo_boilerplate_sdl_cleanup - }, -#endif }; cairo_boilerplate_target_t ** diff --git a/build/Makefile.win32.features b/build/Makefile.win32.features index aa7e56e1..f90a6ee8 100644 --- a/build/Makefile.win32.features +++ b/build/Makefile.win32.features @@ -10,7 +10,6 @@ CAIRO_HAS_WIN32_SURFACE=1 CAIRO_HAS_WIN32_FONT=1 CAIRO_HAS_OS2_SURFACE=0 CAIRO_HAS_BEOS_SURFACE=0 -CAIRO_HAS_SDL_SURFACE=0 CAIRO_HAS_PNG_FUNCTIONS=1 CAIRO_HAS_GLITZ_SURFACE=0 CAIRO_HAS_DIRECTFB_SURFACE=0 diff --git a/build/Makefile.win32.features-h b/build/Makefile.win32.features-h index 82f6121b..a468e307 100644 --- a/build/Makefile.win32.features-h +++ b/build/Makefile.win32.features-h @@ -35,9 +35,6 @@ endif ifeq ($(CAIRO_HAS_BEOS_SURFACE),1) @echo "#define CAIRO_HAS_BEOS_SURFACE 1" >> src/cairo-features.h endif -ifeq ($(CAIRO_HAS_SDL_SURFACE),1) - @echo "#define CAIRO_HAS_SDL_SURFACE 1" >> src/cairo-features.h -endif ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1) @echo "#define CAIRO_HAS_PNG_FUNCTIONS 1" >> src/cairo-features.h endif diff --git a/build/configure.ac.features b/build/configure.ac.features index a7311c18..26dbfb12 100644 --- a/build/configure.ac.features +++ b/build/configure.ac.features @@ -375,7 +375,6 @@ AC_DEFUN([CAIRO_REPORT], echo " glitz: $use_glitz" echo " BeOS: $use_beos" echo " DirectFB: $use_directfb" - echo " SDL: $use_sdl" echo "" echo "The following font backends:" echo " User: yes (always builtin)" diff --git a/configure.ac b/configure.ac index d3ed7031..229eb6aa 100644 --- a/configure.ac +++ b/configure.ac @@ -160,14 +160,6 @@ CAIRO_ENABLE_SURFACE_BACKEND(beos, BeOS/Zeta, no, [ dnl =========================================================================== -CAIRO_ENABLE_SURFACE_BACKEND(sdl, SDL, no, [ - sdl_REQUIRES="sdl >= 1.2" - PKG_CHECK_MODULES(sdl, $sdl_REQUIRES, , [AC_MSG_RESULT(no) - use_sdl="no (requires $sdl_REQUIRES http://www.libsdl.org)"]) -]) - -dnl =========================================================================== - CAIRO_ENABLE_FUNCTIONS(png, PNG, yes, [ use_png=no AC_ARG_VAR([png_REQUIRES], [module name for libpng to search for using pkg-config]) diff --git a/doc/public/tmpl/cairo-surface.sgml b/doc/public/tmpl/cairo-surface.sgml index f32dd49e..f7df8296 100644 --- a/doc/public/tmpl/cairo-surface.sgml +++ b/doc/public/tmpl/cairo-surface.sgml @@ -214,7 +214,6 @@ The Portable Network Graphics image file format (ISO/IEC 15948). Since 1.10 @CAIRO_SURFACE_TYPE_OS2: @CAIRO_SURFACE_TYPE_WIN32_PRINTING: @CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: -@CAIRO_SURFACE_TYPE_SDL: @CAIRO_SURFACE_TYPE_SCRIPT: diff --git a/perf/Makefile.am b/perf/Makefile.am index 59271999..f4feed05 100644 --- a/perf/Makefile.am +++ b/perf/Makefile.am @@ -61,10 +61,6 @@ endif endif cairo_perf_LDADD = $(LDADD) -if CAIRO_HAS_SDL_SURFACE -cairo_perf_LDADD += $(sdl_LIBS) -endif - libcairoperf_la_SOURCES = \ cairo-perf-report.c \ cairo-stats.c \ diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index c66113f3..d7a7e889 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -33,10 +33,6 @@ #include "cairo-boilerplate-getopt.h" -#if CAIRO_HAS_SDL_SURFACE -#include -#endif - /* For basename */ #ifdef HAVE_LIBGEN_H #include diff --git a/src/Makefile.sources b/src/Makefile.sources index 174bb993..7305995e 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -251,8 +251,5 @@ cairo_glitz_sources = cairo-glitz-surface.c cairo_directfb_headers = cairo-directfb.h cairo_directfb_sources = cairo-directfb-surface.c -cairo_sdl_headers = cairo-sdl.h -cairo_sdl_sources = cairo-sdl-surface.c - cairo_script_headers = cairo-script.h cairo_script_sources = cairo-script-surface.c diff --git a/src/Makefile.win32.features b/src/Makefile.win32.features index 921ab2d0..94815d30 100644 --- a/src/Makefile.win32.features +++ b/src/Makefile.win32.features @@ -161,20 +161,6 @@ ifeq ($(CAIRO_HAS_BEOS_SURFACE),1) enabled_cairo_pkgconf += cairo-beos.pc endif -unsupported_cairo_headers += $(cairo_sdl_headers) -all_cairo_headers += $(cairo_sdl_headers) -all_cairo_private += $(cairo_sdl_private) -all_cairo_sources += $(cairo_sdl_sources) -ifeq ($(CAIRO_HAS_SDL_SURFACE),1) -enabled_cairo_headers += $(cairo_sdl_headers) -enabled_cairo_private += $(cairo_sdl_private) -enabled_cairo_sources += $(cairo_sdl_sources) -endif -all_cairo_pkgconf += cairo-sdl.pc -ifeq ($(CAIRO_HAS_SDL_SURFACE),1) -enabled_cairo_pkgconf += cairo-sdl.pc -endif - supported_cairo_headers += $(cairo_png_headers) all_cairo_headers += $(cairo_png_headers) all_cairo_private += $(cairo_png_private) diff --git a/src/cairo-sdl-surface.c b/src/cairo-sdl-surface.c deleted file mode 100644 index 9ab82a56..00000000 --- a/src/cairo-sdl-surface.c +++ /dev/null @@ -1,418 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Chris Wilson. - */ - -#include "cairoint.h" - -#include "cairo-sdl.h" - -typedef struct _cairo_sdl_surface { - cairo_surface_t base; - - SDL_Surface *sdl; - cairo_image_surface_t *image; - - cairo_region_t update; -} cairo_sdl_surface_t; - -static const cairo_surface_backend_t _cairo_sdl_surface_backend; - -static cairo_surface_t * -_cairo_sdl_surface_create_internal (SDL_Surface *sdl, - cairo_surface_t *image) -{ - cairo_sdl_surface_t *surface; - - surface = malloc (sizeof (cairo_sdl_surface_t)); - if (unlikely (surface == NULL)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); - - _cairo_surface_init (&surface->base, - &_cairo_sdl_surface_backend, - image->content); - - surface->sdl = sdl; - sdl->refcount++; - surface->image = (cairo_image_surface_t *) cairo_surface_reference (image); - - _cairo_region_init (&surface->update); - - return &surface->base; -} - -static cairo_surface_t * -_cairo_sdl_surface_create_similar (void *abstract_src, - cairo_content_t content, - int width, - int height) -{ - return _cairo_image_surface_create_with_content (content, width, height); -} - -static cairo_status_t -_cairo_sdl_surface_finish (void *abstract_surface) -{ - cairo_sdl_surface_t *surface = abstract_surface; - - cairo_surface_destroy (&surface->image->base); - SDL_FreeSurface (surface->sdl); - - _cairo_region_fini (&surface->update); - - return CAIRO_STATUS_SUCCESS; -} - -static cairo_status_t -_cairo_sdl_surface_acquire_source_image (void *abstract_surface, - cairo_image_surface_t **image_out, - void **image_extra) -{ - cairo_sdl_surface_t *surface = abstract_surface; - - SDL_LockSurface (surface->sdl); - - *image_out = surface->image; - *image_extra = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_sdl_surface_release_source_image (void *abstract_surface, - cairo_image_surface_t *image, - void *image_extra) -{ - cairo_sdl_surface_t *surface = abstract_surface; - - SDL_UnlockSurface (surface->sdl); -} - -static cairo_status_t -_cairo_sdl_surface_acquire_dest_image (void *abstract_surface, - cairo_rectangle_int_t *interest_rect, - cairo_image_surface_t **image_out, - cairo_rectangle_int_t *image_rect_out, - void **image_extra) -{ - cairo_sdl_surface_t *surface = abstract_surface; - - SDL_LockSurface (surface->sdl); - - image_rect_out->x = 0; - image_rect_out->y = 0; - image_rect_out->width = surface->image->width; - image_rect_out->height = surface->image->height; - - *image_out = surface->image; - *image_extra = NULL; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_sdl_surface_release_dest_image (void *abstract_surface, - cairo_rectangle_int_t *interest_rect, - cairo_image_surface_t *image, - cairo_rectangle_int_t *image_rect, - void *image_extra) -{ - cairo_sdl_surface_t *surface = abstract_surface; - cairo_status_t status; - - SDL_UnlockSurface (surface->sdl); - - status = _cairo_region_union_rect (&surface->update, - &surface->update, - interest_rect); - status = _cairo_surface_set_error (&surface->base, status); -} - -static cairo_status_t -_cairo_sdl_surface_clone_similar (void *abstract_surface, - cairo_surface_t *src, - int src_x, - int src_y, - int width, - int height, - int *clone_offset_x, - int *clone_offset_y, - cairo_surface_t **clone_out) -{ - cairo_sdl_surface_t *surface = abstract_surface; - - if (src->backend == surface->base.backend) { - *clone_offset_x = *clone_offset_y = 0; - *clone_out = cairo_surface_reference (src); - - return CAIRO_STATUS_SUCCESS; - } else if (_cairo_surface_is_image (src)) { - cairo_image_surface_t *image = (cairo_image_surface_t *) src; - cairo_format_masks_t masks; - cairo_surface_t *clone; - SDL_Surface *sdl; - - _pixman_format_to_masks (image->pixman_format, &masks); - - sdl = SDL_CreateRGBSurfaceFrom (image->data, - image->width, - image->height, - masks.bpp, - image->stride, - masks.red_mask, - masks.green_mask, - masks.blue_mask, - masks.alpha_mask); - if (sdl == NULL) - return CAIRO_INT_STATUS_UNSUPPORTED; - - clone = _cairo_sdl_surface_create_internal (sdl, &image->base); - SDL_FreeSurface (sdl); - - if (clone->status) - return clone->status; - - *clone_offset_x = *clone_offset_y = 0; - *clone_out = clone; - return CAIRO_STATUS_SUCCESS; - } - - return CAIRO_INT_STATUS_UNSUPPORTED; -} - -static cairo_int_status_t -_cairo_sdl_surface_composite (cairo_operator_t op, - const cairo_pattern_t *src_pattern, - const cairo_pattern_t *mask_pattern, - void *abstract_dst, - int src_x, - int src_y, - int mask_x, - int mask_y, - int dst_x, - int dst_y, - unsigned int width, - unsigned int height) -{ - cairo_sdl_surface_t *dst = abstract_dst; - cairo_sdl_surface_t *src; - cairo_surface_attributes_t src_attr; - cairo_bool_t is_integer_translation; - int itx, ity; - cairo_int_status_t status; - - /* under a few conditions we can perform a (hardware) blit...*/ - if (op != CAIRO_OPERATOR_SOURCE) - return CAIRO_INT_STATUS_UNSUPPORTED; - if (mask_pattern) - return CAIRO_INT_STATUS_UNSUPPORTED; - if (dst->base.current_clip_serial != 0) - return CAIRO_INT_STATUS_UNSUPPORTED; - - status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, - src_x, src_y, width, height, - (cairo_surface_t **) &src, - &src_attr); - if (unlikely (status)) - return status; - - is_integer_translation = - _cairo_matrix_is_integer_translation (&src_attr.matrix, &itx, &ity); - - status = CAIRO_INT_STATUS_UNSUPPORTED; - if (is_integer_translation && - src_attr.extend == CAIRO_EXTEND_NONE && - src_attr.filter == CAIRO_FILTER_NEAREST) - { - SDL_Rect src_rect; - SDL_Rect dst_rect; - cairo_rectangle_int_t rect; - - src_rect.x = src_x + src_attr.x_offset + itx; - src_rect.y = src_y + src_attr.y_offset + ity; - src_rect.w = width; - src_rect.h = height; - - dst_rect.x = dst_x; - dst_rect.y = dst_y; - dst_rect.w = width; - dst_rect.h = height; - - SDL_BlitSurface (src->sdl, &src_rect, dst->sdl, &dst_rect); - - rect.x = dst_x; - rect.y = dst_y; - rect.width = width; - rect.height = height; - status = _cairo_region_union_rect (&dst->update, - &dst->update, - &rect); - } - - _cairo_pattern_release_surface (src_pattern, &src->base, &src_attr); - return status; -} - -static cairo_int_status_t -_cairo_sdl_surface_set_clip_region (void *abstract_surface, - cairo_region_t *region) -{ - cairo_sdl_surface_t *surface = abstract_surface; - - return _cairo_surface_set_clip_region (&surface->image->base, - region, - surface->base.current_clip_serial); -} - -static cairo_int_status_t -_cairo_sdl_surface_get_extents (void *abstract_surface, - cairo_rectangle_int_t *rectangle) -{ - cairo_sdl_surface_t *surface = abstract_surface; - - rectangle->x = 0; - rectangle->y = 0; - rectangle->width = surface->image->width; - rectangle->height = surface->image->height; - - return CAIRO_STATUS_SUCCESS; -} - -static void -_cairo_sdl_surface_get_font_options (void *abstract_surface, - cairo_font_options_t *options) -{ - cairo_sdl_surface_t *surface = abstract_surface; - - cairo_surface_get_font_options (&surface->image->base, options); -} - -static cairo_status_t -_cairo_sdl_surface_flush (void *abstract_surface) -{ - cairo_sdl_surface_t *surface = abstract_surface; - int n_boxes, i; - - n_boxes = _cairo_region_num_boxes (&surface->update); - if (n_boxes == 0) - return CAIRO_STATUS_SUCCESS; - - for (i = 0; i < n_boxes; i++) { - cairo_box_int_t box; - - _cairo_region_get_box (&surface->update, i, &box); - - SDL_UpdateRect (surface->sdl, - box.p1.x, - box.p1.y, - box.p2.x - box.p1.x, - box.p2.y - box.p1.y); - } - - _cairo_region_fini (&surface->update); - _cairo_region_init (&surface->update); - - return CAIRO_STATUS_SUCCESS; -} - -static const cairo_surface_backend_t _cairo_sdl_surface_backend = { - CAIRO_SURFACE_TYPE_SDL, - _cairo_sdl_surface_create_similar, - _cairo_sdl_surface_finish, - _cairo_sdl_surface_acquire_source_image, - _cairo_sdl_surface_release_source_image, - _cairo_sdl_surface_acquire_dest_image, - _cairo_sdl_surface_release_dest_image, - _cairo_sdl_surface_clone_similar, - _cairo_sdl_surface_composite, - NULL, /* fill rectangles */ - NULL, /* composite traps */ - NULL, /* create_span_renderer */ - NULL, /* check_span_renderer */ - NULL, /* copy_page */ - NULL, /* show_page */ - _cairo_sdl_surface_set_clip_region, - NULL, /* intersect_clip_path */ - _cairo_sdl_surface_get_extents, - NULL, /* old_show_glyphs */ - _cairo_sdl_surface_get_font_options, - _cairo_sdl_surface_flush, /* flush */ - NULL, /* mark_dirty_rectangle */ - NULL, /* font_fini */ - NULL, /* glyph_fini */ - - NULL, /* paint */ - NULL, /* mask */ - NULL, /* stroke */ - NULL, /* fill */ - NULL, /* show_glyphs */ - NULL, /* snapshot */ - NULL, /* is_similar */ - - NULL, /* reset */ -}; - -static cairo_surface_t * -_cairo_image_surface_create_for_sdl (SDL_Surface *surface) -{ - cairo_format_masks_t masks; - pixman_format_code_t format; - - masks.bpp = surface->format->BitsPerPixel; - masks.alpha_mask = surface->format->Amask; - masks.red_mask = surface->format->Rmask; - masks.green_mask = surface->format->Gmask; - masks.blue_mask = surface->format->Bmask; - - if (! _pixman_format_from_masks (&masks, &format)) - return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_FORMAT)); - - return _cairo_image_surface_create_with_pixman_format (surface->pixels, - format, - surface->w, - surface->h, - surface->pitch); -} - -cairo_surface_t * -cairo_sdl_surface_create (SDL_Surface *sdl) -{ - cairo_surface_t *image; - cairo_surface_t *surface; - - image = _cairo_image_surface_create_for_sdl (sdl); - if (image->status) - return image; - - surface = _cairo_sdl_surface_create_internal (sdl, image); - cairo_surface_destroy (image); - - return surface; -} diff --git a/src/cairo-sdl.h b/src/cairo-sdl.h deleted file mode 100644 index c5291a76..00000000 --- a/src/cairo-sdl.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2008 Chris Wilson - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Chris Wilson. - */ - -#ifndef CAIRO_SDL_H -#define CAIRO_SDL_H - -#include "cairo.h" - -#if CAIRO_HAS_SDL_SURFACE - -#include - -CAIRO_BEGIN_DECLS - -cairo_public cairo_surface_t * -cairo_sdl_surface_create (SDL_Surface *surface); - -CAIRO_END_DECLS - -#else /* CAIRO_HAS_SDL_SURFACE */ -# error Cairo was not compiled with support for the SDL backend -#endif /* CAIRO_HAS_SDL_SURFACE */ - -#endif /* CAIRO_SDL_H */ - diff --git a/src/cairo.h b/src/cairo.h index 856f7afc..6994b304 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -1877,7 +1877,6 @@ cairo_surface_status (cairo_surface_t *surface); * @CAIRO_SURFACE_TYPE_OS2: The surface is of type os2 * @CAIRO_SURFACE_TYPE_WIN32_PRINTING: The surface is a win32 printing surface * @CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: The surface is of type quartz_image - * @CAIRO_SURFACE_TYPE_SDL: The surface is of type SDL, since 1.10 * @CAIRO_SURFACE_TYPE_SCRIPT: The surface is of type script, since 1.10 * * #cairo_surface_type_t is used to describe the type of a given @@ -1918,7 +1917,6 @@ typedef enum _cairo_surface_type { CAIRO_SURFACE_TYPE_OS2, CAIRO_SURFACE_TYPE_WIN32_PRINTING, CAIRO_SURFACE_TYPE_QUARTZ_IMAGE, - CAIRO_SURFACE_TYPE_SDL, CAIRO_SURFACE_TYPE_SCRIPT } cairo_surface_type_t; diff --git a/test/Makefile.am b/test/Makefile.am index 9c670ed3..f737fddc 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -308,10 +308,6 @@ if HAVE_PTHREAD cairo_test_suite_LDADD += -lpthread endif -if CAIRO_HAS_SDL_SURFACE -cairo_test_suite_LDADD += $(sdl_LIBS) -endif - BUILT_SOURCES += cairo-test-constructors.c noinst_SCRIPTS = make-cairo-test-constructors.pl EXTRA_DIST += $(BUILT_SOURCES) $(noinst_SCRIPTS) COPYING diff --git a/test/cairo-test-runner.c b/test/cairo-test-runner.c index 1d79c7e3..0f437c4c 100644 --- a/test/cairo-test-runner.c +++ b/test/cairo-test-runner.c @@ -33,10 +33,6 @@ #undef CAIRO_VERSION_MICRO #include "../cairo-version.h" -#if CAIRO_HAS_SDL_SURFACE -#include -#endif - #include /* for version information */ /* Coregraphics doesn't seem to like being forked and reports: diff --git a/test/get-clip.c b/test/get-clip.c index e246671a..1a07f012 100644 --- a/test/get-clip.c +++ b/test/get-clip.c @@ -129,7 +129,6 @@ draw (cairo_t *cr, int width, int height) case CAIRO_SURFACE_TYPE_WIN32: case CAIRO_SURFACE_TYPE_BEOS: case CAIRO_SURFACE_TYPE_DIRECTFB: - case CAIRO_SURFACE_TYPE_SDL: uses_clip_rects = TRUE; break; case CAIRO_SURFACE_TYPE_QUARTZ: -- cgit v1.2.3 From f7b3c9df5885a1cd7981ee12b91962bdbfff47af Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Mon, 16 Feb 2009 22:28:32 -0500 Subject: Add test/Makefile.sources This lets test/Makefile.am and test/Makefile.win32 share a common list of sources. It also makes test/Makefile.win32 useful again. --- test/Makefile.am | 251 ++++---------------------------------------------- test/Makefile.sources | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/Makefile.win32 | 125 +++++-------------------- 3 files changed, 293 insertions(+), 334 deletions(-) create mode 100644 test/Makefile.sources diff --git a/test/Makefile.am b/test/Makefile.am index f737fddc..2a1d93bc 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,276 +1,63 @@ include $(top_srcdir)/build/Makefile.am.common +include $(top_srcdir)/test/Makefile.sources + SUBDIRS=pdiff . CLEANFILES += have-similar.* -test_sources = \ - a1-image-sample.c \ - a1-mask.c \ - a1-traps-sample.c \ - a8-mask.c \ - alpha-similar.c \ - big-line.c \ - big-trap.c \ - bilevel-image.c \ - caps.c \ - caps-joins.c \ - caps-joins-alpha.c \ - caps-joins-curve.c \ - caps-sub-paths.c \ - clip-all.c \ - clip-empty.c \ - clip-fill-rule.c \ - clip-fill-rule-pixel-aligned.c \ - clip-nesting.c \ - clip-operator.c \ - clip-push-group.c \ - clip-twice.c \ - clip-zero.c \ - clipped-group.c \ - clipped-surface.c \ - close-path.c \ - composite-integer-translate-source.c \ - composite-integer-translate-over.c \ - composite-integer-translate-over-repeat.c \ - copy-path.c \ - create-for-stream.c \ - create-from-png.c \ - create-from-png-stream.c \ - culled-glyphs.c \ - dash-caps-joins.c \ - dash-curve.c \ - dash-no-dash.c \ - dash-offset-negative.c \ - dash-scale.c \ - dash-state.c \ - dash-zero-length.c \ - degenerate-arc.c \ - degenerate-dash.c \ - degenerate-path.c \ - degenerate-pen.c \ - device-offset.c \ - device-offset-fractional.c \ - device-offset-positive.c \ - device-offset-scale.c \ - extend-pad.c \ - extend-pad-border.c \ - extend-pad-similar.c \ - extend-reflect.c \ - extend-reflect-similar.c \ - extend-repeat.c \ - extend-repeat-similar.c \ - fill-alpha.c \ - fill-alpha-pattern.c \ - fill-and-stroke.c \ - fill-and-stroke-alpha.c \ - fill-and-stroke-alpha-add.c \ - fill-degenerate-sort-order.c \ - fill-image.c \ - fill-missed-stop.c \ - fill-rule.c \ - filter-bilinear-extents.c \ - filter-nearest-offset.c \ - filter-nearest-transformed.c \ - finer-grained-fallbacks.c \ - font-face-get-type.c \ - font-matrix-translation.c \ - font-options.c \ - glyph-cache-pressure.c \ - get-and-set.c \ - get-clip.c \ - get-group-target.c \ - get-path-extents.c \ - gradient-alpha.c \ - gradient-constant-alpha.c \ - gradient-zero-stops.c \ - group-paint.c \ - huge-linear.c \ - huge-radial.c \ - image-surface-source.c \ - infinite-join.c \ - in-fill-empty-trapezoid.c \ - in-fill-trapezoid.c \ - invalid-matrix.c \ - joins.c \ - large-clip.c \ - large-font.c \ - large-source.c \ - large-source-roi.c \ - leaky-dash.c \ - leaky-dashed-rectangle.c \ - leaky-dashed-stroke.c \ - leaky-polygon.c \ - line-width.c \ - line-width-scale.c \ - line-width-zero.c \ - linear-gradient.c \ - linear-gradient-reflect.c \ - long-dashed-lines.c \ - long-lines.c \ - mask.c \ - mask-alpha.c \ - mask-ctm.c \ - mask-surface-ctm.c \ - mask-transformed-image.c \ - mask-transformed-similar.c \ - meta-surface-pattern.c \ - mime-data.c \ - miter-precision.c \ - move-to-show-surface.c \ - new-sub-path.c \ - nil-surface.c \ - operator.c \ - operator-alpha.c \ - operator-clear.c \ - operator-source.c \ - over-above-source.c \ - over-around-source.c \ - over-below-source.c \ - over-between-source.c \ - paint.c \ - paint-repeat.c \ - paint-source-alpha.c \ - paint-with-alpha.c \ - path-precision.c \ - pattern-get-type.c \ - pattern-getters.c \ - pixman-rotate.c \ - png.c \ - push-group.c \ - radial-gradient.c \ - random-intersections.c \ - rectangle-rounding-error.c \ - rectilinear-fill.c \ - rectilinear-miter-limit.c \ - rectilinear-dash.c \ - rectilinear-stroke.c \ - reflected-stroke.c \ - rel-path.c \ - rgb24-ignore-alpha.c \ - rotate-image-surface-paint.c \ - scale-down-source-surface-paint.c \ - scale-offset-image.c \ - scale-offset-similar.c \ - scale-source-surface-paint.c \ - scaled-font-zero-matrix.c \ - stroke-ctm-caps.c \ - stroke-image.c \ - select-font-face.c \ - select-font-no-show-text.c \ - self-copy.c \ - self-copy-overlap.c \ - self-intersecting.c \ - set-source.c \ - show-glyphs-many.c \ - show-text-current-point.c \ - skew-extreme.c \ - smask.c \ - smask-fill.c \ - smask-image-mask.c \ - smask-mask.c \ - smask-paint.c \ - smask-stroke.c \ - smask-text.c \ - solid-pattern-cache-stress.c \ - source-clip.c \ - source-clip-scale.c \ - source-surface-scale-paint.c \ - spline-decomposition.c \ - surface-finish-twice.c \ - surface-pattern.c \ - surface-pattern-big-scale-down.c \ - surface-pattern-scale-down.c \ - surface-pattern-scale-up.c \ - text-antialias-gray.c \ - text-antialias-none.c \ - text-antialias-subpixel.c \ - text-cache-crash.c \ - text-glyph-range.c \ - text-pattern.c \ - text-rotate.c \ - text-transform.c \ - text-zero-len.c \ - toy-font-face.c \ - transforms.c \ - translate-show-surface.c \ - trap-clip.c \ - truetype-tables.c \ - twin.c \ - unantialiased-shapes.c \ - unbounded-operator.c \ - user-data.c \ - user-font.c \ - user-font-mask.c \ - user-font-proxy.c \ - user-font-rescale.c \ - zero-alpha.c - # Then we have a collection of tests that are only run if certain # features are compiled into cairo if HAVE_PTHREAD -test_sources += pthread-show-text.c +test_sources += $(pthread_test_sources) endif if CAIRO_HAS_FT_FONT -test_sources += bitmap-font.c -test_sources += ft-font-create-for-ft-face.c -test_sources += ft-show-glyphs-positioning.c -test_sources += ft-show-glyphs-table.c -test_sources += ft-text-vertical-layout-type1.c -test_sources += ft-text-vertical-layout-type3.c -test_sources += ft-text-antialias-none.c +test_sources += $(ft_font_sources) endif # Need to add quartz-surface-source if CAIRO_HAS_QUARTZ_SURFACE -test_sources += quartz-surface-source.c +test_sources += $(quartz_surface_sources) endif if CAIRO_HAS_GLITZ_SURFACE -test_sources += glitz-surface-source.c +test_sources += $(glitz_surface_sources) endif if CAIRO_HAS_PDF_SURFACE -test_sources += pdf-features.c -test_sources += pdf-mime-data.c -test_sources += pdf-surface-source.c +test_sources += $(pdf_surface_test_sources) endif if CAIRO_HAS_PS_SURFACE -test_sources += ps-features.c -test_sources += ps-surface-source.c +test_sources += $(ps_surface_test_sources) endif if CAIRO_HAS_SVG_SURFACE -test_sources += svg-surface.c -test_sources += svg-clip.c -test_sources += svg-surface-source.c +test_sources += $(svg_surface_test_sources) endif if CAIRO_HAS_XLIB_SURFACE -test_sources += xlib-expose-event.c -test_sources += xlib-surface.c -test_sources += xlib-surface-source.c +test_sources += $(xlib_surface_test_sources) endif if CAIRO_HAS_XLIB_XRENDER_SURFACE -test_sources += get-xrender-format.c +test_sources += $(xlib_xrender_surface_test_sources) endif if CAIRO_HAS_MULTI_PAGE_SURFACES -test_sources += multi-page.c +test_sources += $(multi_page_surface_test_sources) endif # Include fallback-resolution (once!) if we have any of the vector surfaces if CAIRO_HAS_SVG_SURFACE -test = fallback-resolution.c +test = $(fallback_resolution_test_sources) endif if CAIRO_HAS_PDF_SURFACE -test = fallback-resolution.c +test = $(fallback_resolution_test_sources) endif if CAIRO_HAS_PS_SURFACE -test = fallback-resolution.c +test = $(fallback_resolution_test_sources) endif test_sources += $(test) @@ -280,12 +67,8 @@ cairo-test-constructors.c: Makefile $(test_sources) make-cairo-test-constructors @(cd $(srcdir) && ./make-cairo-test-constructors.pl $(test_sources)) > $@ cairo_test_suite_SOURCES = \ - buffer-diff.c \ - buffer-diff.h \ - cairo-test.c \ - cairo-test.h \ - cairo-test-private.h \ - cairo-test-runner.c \ + $(cairo_test_suite_sources) \ + $(cairo_test_suite_headers) \ $(test_sources) if CAIRO_HAS_CONSTRUCTOR_ATTRIBUTE else diff --git a/test/Makefile.sources b/test/Makefile.sources new file mode 100644 index 00000000..69c581b1 --- /dev/null +++ b/test/Makefile.sources @@ -0,0 +1,251 @@ +test_sources = \ + a1-image-sample.c \ + a1-mask.c \ + a1-traps-sample.c \ + a8-mask.c \ + alpha-similar.c \ + big-line.c \ + big-trap.c \ + bilevel-image.c \ + caps.c \ + caps-joins.c \ + caps-joins-alpha.c \ + caps-joins-curve.c \ + caps-sub-paths.c \ + clip-all.c \ + clip-empty.c \ + clip-fill-rule.c \ + clip-fill-rule-pixel-aligned.c \ + clip-nesting.c \ + clip-operator.c \ + clip-push-group.c \ + clip-twice.c \ + clip-zero.c \ + clipped-group.c \ + clipped-surface.c \ + close-path.c \ + composite-integer-translate-source.c \ + composite-integer-translate-over.c \ + composite-integer-translate-over-repeat.c \ + copy-path.c \ + create-for-stream.c \ + create-from-png.c \ + create-from-png-stream.c \ + culled-glyphs.c \ + dash-caps-joins.c \ + dash-curve.c \ + dash-no-dash.c \ + dash-offset-negative.c \ + dash-scale.c \ + dash-state.c \ + dash-zero-length.c \ + degenerate-arc.c \ + degenerate-dash.c \ + degenerate-path.c \ + degenerate-pen.c \ + device-offset.c \ + device-offset-fractional.c \ + device-offset-positive.c \ + device-offset-scale.c \ + extend-pad.c \ + extend-pad-border.c \ + extend-pad-similar.c \ + extend-reflect.c \ + extend-reflect-similar.c \ + extend-repeat.c \ + extend-repeat-similar.c \ + fill-alpha.c \ + fill-alpha-pattern.c \ + fill-and-stroke.c \ + fill-and-stroke-alpha.c \ + fill-and-stroke-alpha-add.c \ + fill-degenerate-sort-order.c \ + fill-image.c \ + fill-missed-stop.c \ + fill-rule.c \ + filter-bilinear-extents.c \ + filter-nearest-offset.c \ + filter-nearest-transformed.c \ + finer-grained-fallbacks.c \ + font-face-get-type.c \ + font-matrix-translation.c \ + font-options.c \ + glyph-cache-pressure.c \ + get-and-set.c \ + get-clip.c \ + get-group-target.c \ + get-path-extents.c \ + gradient-alpha.c \ + gradient-constant-alpha.c \ + gradient-zero-stops.c \ + group-paint.c \ + huge-linear.c \ + huge-radial.c \ + image-surface-source.c \ + infinite-join.c \ + in-fill-empty-trapezoid.c \ + in-fill-trapezoid.c \ + invalid-matrix.c \ + joins.c \ + large-clip.c \ + large-font.c \ + large-source.c \ + large-source-roi.c \ + leaky-dash.c \ + leaky-dashed-rectangle.c \ + leaky-dashed-stroke.c \ + leaky-polygon.c \ + line-width.c \ + line-width-scale.c \ + line-width-zero.c \ + linear-gradient.c \ + linear-gradient-reflect.c \ + long-dashed-lines.c \ + long-lines.c \ + mask.c \ + mask-alpha.c \ + mask-ctm.c \ + mask-surface-ctm.c \ + mask-transformed-image.c \ + mask-transformed-similar.c \ + meta-surface-pattern.c \ + mime-data.c \ + miter-precision.c \ + move-to-show-surface.c \ + new-sub-path.c \ + nil-surface.c \ + operator.c \ + operator-alpha.c \ + operator-clear.c \ + operator-source.c \ + over-above-source.c \ + over-around-source.c \ + over-below-source.c \ + over-between-source.c \ + paint.c \ + paint-repeat.c \ + paint-source-alpha.c \ + paint-with-alpha.c \ + path-precision.c \ + pattern-get-type.c \ + pattern-getters.c \ + pixman-rotate.c \ + png.c \ + push-group.c \ + radial-gradient.c \ + random-intersections.c \ + rectangle-rounding-error.c \ + rectilinear-fill.c \ + rectilinear-miter-limit.c \ + rectilinear-dash.c \ + rectilinear-stroke.c \ + reflected-stroke.c \ + rel-path.c \ + rgb24-ignore-alpha.c \ + rotate-image-surface-paint.c \ + scale-down-source-surface-paint.c \ + scale-offset-image.c \ + scale-offset-similar.c \ + scale-source-surface-paint.c \ + scaled-font-zero-matrix.c \ + stroke-ctm-caps.c \ + stroke-image.c \ + select-font-face.c \ + select-font-no-show-text.c \ + self-copy.c \ + self-copy-overlap.c \ + self-intersecting.c \ + set-source.c \ + show-glyphs-many.c \ + show-text-current-point.c \ + skew-extreme.c \ + smask.c \ + smask-fill.c \ + smask-image-mask.c \ + smask-mask.c \ + smask-paint.c \ + smask-stroke.c \ + smask-text.c \ + solid-pattern-cache-stress.c \ + source-clip.c \ + source-clip-scale.c \ + source-surface-scale-paint.c \ + spline-decomposition.c \ + surface-finish-twice.c \ + surface-pattern.c \ + surface-pattern-big-scale-down.c \ + surface-pattern-scale-down.c \ + surface-pattern-scale-up.c \ + text-antialias-gray.c \ + text-antialias-none.c \ + text-antialias-subpixel.c \ + text-cache-crash.c \ + text-glyph-range.c \ + text-pattern.c \ + text-rotate.c \ + text-transform.c \ + text-zero-len.c \ + toy-font-face.c \ + transforms.c \ + translate-show-surface.c \ + trap-clip.c \ + truetype-tables.c \ + twin.c \ + unantialiased-shapes.c \ + unbounded-operator.c \ + user-data.c \ + user-font.c \ + user-font-mask.c \ + user-font-proxy.c \ + user-font-rescale.c \ + zero-alpha.c + +pthread_test_sources = pthread-show-text.c + +ft_font_test_sources = \ + bitmap-font.c \ + ft-font-create-for-ft-face.c \ + ft-show-glyphs-positioning.c \ + ft-show-glyphs-table.c \ + ft-text-vertical-layout-type1.c \ + ft-text-vertical-layout-type3.c \ + ft-text-antialias-none.c + +quartz_surface_test_sources = quartz-surface-source.c + +glitz_surface_test_sources = glitz-surface-source.c + +pdf_surface_test_sources = \ + pdf-features.c \ + pdf-mime-data.c \ + pdf-surface-source.c + +ps_surface_test_sources = \ + ps-features.c \ + ps-surface-source.c + +svg_surface_test_sources = \ + svg-surface.c \ + svg-clip.c \ + svg-surface-source.c + +xlib_surface_test_sources = \ + xlib-expose-event.c \ + xlib-surface.c \ + xlib-surface-source.c + +xlib_xrender_surface_test_sources = get-xrender-format.c + +multi_page_surface_test_sources = multi-page.c + +fallback_resolution_test_sources = fallback-resolution.c + +cairo_test_suite_headers = \ + buffer-diff.h \ + cairo-test.h \ + cairo-test-private.h + +cairo_test_suite_sources = \ + buffer-diff.c \ + cairo-test.c \ + cairo-test-runner.c diff --git a/test/Makefile.win32 b/test/Makefile.win32 index 003d96a2..f4c12916 100644 --- a/test/Makefile.win32 +++ b/test/Makefile.win32 @@ -1,121 +1,46 @@ top_srcdir = .. include $(top_srcdir)/build/Makefile.win32.common +include $(top_srcdir)/test/Makefile.sources CFLAGS += -I../src -I../boilerplate -I./pdiff LDFLAGS += ./pdiff/pdiff.lib ../src/$(CFG)/cairo-static.lib $(PIXMAN_LIBS) ../boilerplate/$(CFG)/boiler.lib $(EXE_LDFLAGS) -TESTS = \ -a8-mask \ -caps-joins \ -caps-joins-alpha \ -caps-sub-paths \ -clip-all \ -clip-fill-rule \ -clip-fill-rule-pixel-aligned \ -clip-nesting \ -clip-operator \ -clip-twice \ -composite-integer-translate-source \ -composite-integer-translate-over \ -composite-integer-translate-over-repeat \ -create-for-stream \ -create-from-png \ -create-from-png-stream \ -dash-caps-joins \ -dash-no-dash \ -dash-offset-negative \ -dash-scale \ -dash-zero-length \ -degenerate-path \ -device-offset \ -device-offset-positive \ -extend-pad \ -extend-reflect \ -fill-and-stroke \ -fill-and-stroke-alpha \ -fill-and-stroke-alpha-add \ -fill-rule \ -filter-nearest-offset \ -font-face-get-type \ -font-matrix-translation \ -glyph-cache-pressure \ -get-and-set \ -get-clip \ -get-group-target \ -get-path-extents \ -gradient-alpha \ -leaky-dash \ -leaky-polygon \ -line-width \ -line-width-scale \ -linear-gradient \ -mask \ -mask-ctm \ -mask-surface-ctm \ -move-to-show-surface \ -new-sub-path \ -nil-surface \ -operator-clear \ -operator-source \ -paint \ -paint-source-alpha \ -paint-with-alpha \ -pattern-get-type \ -pattern-getters \ -pixman-rotate \ -rectangle-rounding-error \ -scale-source-surface-paint \ -select-font-face \ -select-font-no-show-text \ -self-copy \ -self-intersecting \ -set-source \ -show-text-current-point \ -source-clip \ -source-surface-scale-paint \ -surface-finish-twice \ -surface-pattern \ -text-antialias-gray \ -text-antialias-none \ -text-antialias-subpixel \ -text-cache-crash \ -text-pattern \ -text-rotate \ -transforms \ -translate-show-surface \ -trap-clip \ -unantialiased-shapes \ -unbounded-operator \ -user-data \ -rel-path \ -push-group \ -zero-alpha \ -$(NULL) TESTCORE_SOURCES = \ cairo-test.c \ buffer-diff.c \ $(NULL) -TEST_EXE = $(patsubst %, $(CFG)/%.exe, $(TESTS)) -# TEST_EXE = $(addsuffix .exe,$(TESTS)) +all: cairo-test-suite.exe -all: $(TEST_EXE) +cairo-test-constructors.c: $(test_sources) + ./make-cairo-test-constructors.pl $(test_sources) > $@ -$(CFG)/%.exe: %.c ./pdiff/pdiff.lib - @mkdir -p $(CFG) - @$(CC) $(CFLAGS) -Fe"$@" $< $(TESTCORE_SOURCES) -link $(LDFLAGS) +SOURCES = $(cairo_test_suite_sources) $(test_sources) cairo-test-constructors.c + +OBJECTS = $(patsubst %.c, $(CFG)/%.obj, $(SOURCES)) + +cairo-test-suite.exe: $(OBJECTS) + $(CC) $(OPT) $(MS_MDFLAGS) $(OBJECTS) -Fe"$@" -link $(LDFLAGS) /NODEFAULTLIB:library ./pdiff/pdiff.lib: (cd pdiff ; $(MAKE) -f Makefile.win32) -test: $(TEST_EXE) - @for exe in $(TEST_EXE) ; do \ - echo $$exe ; \ - ( ./$$exe || exit 0 ) ; \ - done +.PHONY: check test html + +check: cairo-test-suite.exe + ./cairo-test-suite.exe + +# define gen-html so that both 'test' and 'html' targets +# can generate html while having different dependencies +define gen-html +@echo Creating index.html... +@perl make-html.pl > index.html +endef + +test: check + $(gen-html) html: - @echo Creating index.html... - @perl make-html.pl > index.html + $(gen-html) -- cgit v1.2.3 From 06fa7a8386b267fdbd7635b952adc75a58f62584 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Wed, 18 Feb 2009 18:43:29 -0500 Subject: Fix a const warning in _cairo_user_data_array_foreach() _cairo_user_data_array_foreach() was taking a function with a void *key parameter instead of a const void *key to match cairo_user_data_slot_t. --- src/cairo-array.c | 2 +- src/cairo-surface.c | 2 +- src/cairoint.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cairo-array.c b/src/cairo-array.c index 70c16465..318fd07e 100644 --- a/src/cairo-array.c +++ b/src/cairo-array.c @@ -515,7 +515,7 @@ _cairo_user_data_array_copy (cairo_user_data_array_t *dst, void _cairo_user_data_array_foreach (cairo_user_data_array_t *array, - void (*func) (void *key, + void (*func) (const void *key, void *elt, void *closure), void *closure) diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 6f522fc4..456f8518 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -716,7 +716,7 @@ cairo_surface_set_mime_data (cairo_surface_t *surface, slim_hidden_def (cairo_surface_set_mime_data); static void -_cairo_mime_data_reference (void *key, void *elt, void *closure) +_cairo_mime_data_reference (const void *key, void *elt, void *closure) { cairo_mime_data_t *mime_data = elt; diff --git a/src/cairoint.h b/src/cairoint.h index bfcaaa93..b550f867 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -336,7 +336,7 @@ _cairo_user_data_array_copy (cairo_user_data_array_t *dst, cairo_private void _cairo_user_data_array_foreach (cairo_user_data_array_t *array, - void (*func) (void *key, + void (*func) (const void *key, void *elt, void *closure), void *closure); -- cgit v1.2.3 From d4227fc9126ffbb3a967aea1bc9795e7e64ee8e1 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 19 Feb 2009 11:45:14 -0500 Subject: [test] Fix assert on default font family in toy-font-face toy-font-face was checking that cairo_toy_font_face_get_family returned "" which is CAIRO_FONT_FAMILY_DEFAULT when the freetype font backend is the default. However, when other font backends are the default the returned family is different. Therefore, instead of checking for "", we check for the appropriate string depending on the backend. --- test/toy-font-face.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/test/toy-font-face.c b/test/toy-font-face.c index e26a19ca..147c43b7 100644 --- a/test/toy-font-face.c +++ b/test/toy-font-face.c @@ -34,6 +34,17 @@ #include #include +#if CAIRO_HAS_WIN32_FONT +#define CAIRO_FONT_FAMILY_DEFAULT "Arial" +#elif CAIRO_HAS_QUARTZ_FONT +#define CAIRO_FONT_FAMILY_DEFAULT "Helvetica" +#elif CAIRO_HAS_FT_FONT +#define CAIRO_FONT_FAMILY_DEFAULT "" +#else +#define CAIRO_FONT_FAMILY_DEFAULT "@cairo:" +#endif + + static cairo_test_status_t preamble (cairo_test_context_t *ctx) { @@ -79,7 +90,7 @@ preamble (cairo_test_context_t *ctx) CAIRO_FONT_SLANT_OBLIQUE, CAIRO_FONT_WEIGHT_BOLD); assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY); - assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), "")); + assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), CAIRO_FONT_FAMILY_DEFAULT)); assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL); assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL); assert (cairo_font_face_status(font_face) == CAIRO_STATUS_NULL_POINTER); @@ -89,7 +100,7 @@ preamble (cairo_test_context_t *ctx) CAIRO_FONT_SLANT_OBLIQUE, CAIRO_FONT_WEIGHT_BOLD); assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY); - assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), "")); + assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), CAIRO_FONT_FAMILY_DEFAULT)); assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL); assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL); assert (cairo_font_face_status(font_face) == CAIRO_STATUS_INVALID_STRING); @@ -99,7 +110,7 @@ preamble (cairo_test_context_t *ctx) -1, CAIRO_FONT_WEIGHT_BOLD); assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY); - assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), "")); + assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), CAIRO_FONT_FAMILY_DEFAULT)); assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL); assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL); assert (cairo_font_face_status(font_face) == CAIRO_STATUS_INVALID_SLANT); @@ -109,7 +120,7 @@ preamble (cairo_test_context_t *ctx) CAIRO_FONT_SLANT_OBLIQUE, -1); assert (cairo_font_face_get_type (font_face) == CAIRO_FONT_TYPE_TOY); - assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), "")); + assert (0 == (strcmp) (cairo_toy_font_face_get_family (font_face), CAIRO_FONT_FAMILY_DEFAULT)); assert (cairo_toy_font_face_get_slant (font_face) == CAIRO_FONT_SLANT_NORMAL); assert (cairo_toy_font_face_get_weight (font_face) == CAIRO_FONT_WEIGHT_NORMAL); assert (cairo_font_face_status(font_face) == CAIRO_STATUS_INVALID_WEIGHT); -- cgit v1.2.3 From 126824f5e6279f56dab0c040394b6c326b848cf7 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 19 Feb 2009 13:31:55 -0500 Subject: Add CAIRO_ENSURE_UNIQUE macro and use it in _cairo_error() When using MSVC, _cairo_error() can be folded into other identical functions. If that happens, _cairo_error isn't really useful anymore. Using the CAIRO_ENSURE_UNIQUE macro makes sure this doesn't happen. --- src/cairo-compiler-private.h | 24 ++++++++++++++++++++++++ src/cairo.c | 1 + 2 files changed, 25 insertions(+) diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h index bd7cccd9..236246e6 100644 --- a/src/cairo-compiler-private.h +++ b/src/cairo-compiler-private.h @@ -172,6 +172,30 @@ #define inline __inline #endif +#ifdef _MSC_VER +/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together. + The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and + will never be folded into another one. Something like this might eventually + be needed for GCC but it seems fine for now. */ +#define CAIRO_ENSURE_UNIQUE \ + do { \ + char func[] = __FUNCTION__; \ + char file[] = __FILE__; \ + __asm { \ + jmp __internal_skip_line_no; \ + _emit (__LINE__ & 0xff); \ + _emit ((__LINE__>>8) & 0xff); \ + _emit ((__LINE__>>16) & 0xff); \ + _emit ((__LINE__>>24) & 0xff); \ + lea eax, func; \ + lea eax, file; \ + __internal_skip_line_no: \ + }; \ + } while (0) +#else +#define CAIRO_ENSURE_UNIQUE do { } while (0) +#endif + #ifdef __STRICT_ANSI__ #undef inline #define inline __inline__ diff --git a/src/cairo.c b/src/cairo.c index 4aa52f69..ddc8d4a9 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -82,6 +82,7 @@ static const cairo_t _cairo_nil = { cairo_status_t _cairo_error (cairo_status_t status) { + CAIRO_ENSURE_UNIQUE; assert (_cairo_status_is_error (status)); return status; -- cgit v1.2.3 From 78de0e045ec0c10708052ed48df228e786839ddb Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 19 Feb 2009 15:45:11 -0500 Subject: Revert "Add CAIRO_ENSURE_UNIQUE macro and use it in _cairo_error()" This reverts commit 126824f5e6279f56dab0c040394b6c326b848cf7. It turns out MSVC doesn't handle line continuation characters in __asm{} blocks very well, so revert for now until I come up with something that works. --- src/cairo-compiler-private.h | 24 ------------------------ src/cairo.c | 1 - 2 files changed, 25 deletions(-) diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h index 236246e6..bd7cccd9 100644 --- a/src/cairo-compiler-private.h +++ b/src/cairo-compiler-private.h @@ -172,30 +172,6 @@ #define inline __inline #endif -#ifdef _MSC_VER -/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together. - The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and - will never be folded into another one. Something like this might eventually - be needed for GCC but it seems fine for now. */ -#define CAIRO_ENSURE_UNIQUE \ - do { \ - char func[] = __FUNCTION__; \ - char file[] = __FILE__; \ - __asm { \ - jmp __internal_skip_line_no; \ - _emit (__LINE__ & 0xff); \ - _emit ((__LINE__>>8) & 0xff); \ - _emit ((__LINE__>>16) & 0xff); \ - _emit ((__LINE__>>24) & 0xff); \ - lea eax, func; \ - lea eax, file; \ - __internal_skip_line_no: \ - }; \ - } while (0) -#else -#define CAIRO_ENSURE_UNIQUE do { } while (0) -#endif - #ifdef __STRICT_ANSI__ #undef inline #define inline __inline__ diff --git a/src/cairo.c b/src/cairo.c index ddc8d4a9..4aa52f69 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -82,7 +82,6 @@ static const cairo_t _cairo_nil = { cairo_status_t _cairo_error (cairo_status_t status) { - CAIRO_ENSURE_UNIQUE; assert (_cairo_status_is_error (status)); return status; -- cgit v1.2.3 From fe7d5323f5bc734e76179b74d68fcba9b924ba94 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 19 Feb 2009 16:00:17 -0500 Subject: Relanding: Add CAIRO_ENSURE_UNIQUE macro and use it in _cairo_error() When using MSVC, _cairo_error() can be folded into other identical functions. If that happens, _cairo_error isn't really useful anymore. Using the CAIRO_ENSURE_UNIQUE macro makes sure this doesn't happen. Use __asm to serve as a line delimiter. This allows us to use the __asm{} block in a macro. --- src/cairo-compiler-private.h | 24 ++++++++++++++++++++++++ src/cairo.c | 1 + 2 files changed, 25 insertions(+) diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h index bd7cccd9..f796e138 100644 --- a/src/cairo-compiler-private.h +++ b/src/cairo-compiler-private.h @@ -172,6 +172,30 @@ #define inline __inline #endif +#ifdef _MSC_VER +/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together. + The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and + will never be folded into another one. Something like this might eventually + be needed for GCC but it seems fine for now. */ +#define CAIRO_ENSURE_UNIQUE \ + do { \ + char func[] = __FUNCTION__; \ + char file[] = __FILE__; \ + __asm { \ + __asm jmp __internal_skip_line_no \ + __asm _emit (__LINE__ & 0xff) \ + __asm _emit ((__LINE__>>8) & 0xff) \ + __asm _emit ((__LINE__>>16) & 0xff) \ + __asm _emit ((__LINE__>>24) & 0xff) \ + __asm lea eax, func \ + __asm lea eax, file \ + __asm __internal_skip_line_no: \ + }; \ + } while (0) +#else +#define CAIRO_ENSURE_UNIQUE do { } while (0) +#endif + #ifdef __STRICT_ANSI__ #undef inline #define inline __inline__ diff --git a/src/cairo.c b/src/cairo.c index 4aa52f69..ddc8d4a9 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -82,6 +82,7 @@ static const cairo_t _cairo_nil = { cairo_status_t _cairo_error (cairo_status_t status) { + CAIRO_ENSURE_UNIQUE; assert (_cairo_status_is_error (status)); return status; -- cgit v1.2.3 From 6eb0a9d97ff7eaaee69ca10e4081cb950a543ce3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 15 Feb 2009 21:27:29 +0000 Subject: [scaled-font] Hold reference to original font face As noted by Carl during his LCA talk, caching of toy fonts was broken because we create the scaled font using the implementation font face and lose the reference to the containing font face that is cached by the toy font face create routines. So the toy fonts were not being preserved for the duration of the holdover scaled fonts and we recreated a new font face, new scaled font and new glyph caches every time we needed a font. --- src/cairo-ft-font.c | 2 +- src/cairo-scaled-font-private.h | 2 ++ src/cairo-scaled-font.c | 17 +++++++++++++---- src/cairo-toy-font-face.c | 1 + 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 4295d250..493a1e27 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -444,6 +444,7 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face, if (unlikely (status)) goto UNWIND_UNSCALED_MALLOC; + assert (unscaled->base.hash_entry.hash == key.base.hash_entry.hash); status = _cairo_hash_table_insert (font_map->hash_table, &unscaled->base.hash_entry); if (unlikely (status)) @@ -484,7 +485,6 @@ _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern) DONE: return _cairo_ft_unscaled_font_create_internal (font_face != NULL, filename, id, font_face); - } static cairo_ft_unscaled_font_t * diff --git a/src/cairo-scaled-font-private.h b/src/cairo-scaled-font-private.h index 13d89ebe..89820c8f 100644 --- a/src/cairo-scaled-font-private.h +++ b/src/cairo-scaled-font-private.h @@ -84,6 +84,8 @@ struct _cairo_scaled_font { cairo_reference_count_t ref_count; cairo_user_data_array_t user_data; + cairo_font_face_t *original_font_face; /* may be NULL */ + /* hash key members */ cairo_font_face_t *font_face; /* may be NULL */ cairo_matrix_t font_matrix; /* font space => user space */ diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 7096a01e..36e3d9cc 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -206,6 +206,7 @@ static const cairo_scaled_font_t _cairo_scaled_font_nil = { CAIRO_STATUS_NO_MEMORY, /* status */ CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ { 0, 0, 0, NULL }, /* user_data */ + NULL, /* original_font_face */ NULL, /* font_face */ { 1., 0., 0., 1., 0, 0}, /* font_matrix */ { 1., 0., 0., 1., 0, 0}, /* ctm */ @@ -706,14 +707,17 @@ _cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_ const cairo_scaled_font_t *key_a = abstract_key_a; const cairo_scaled_font_t *key_b = abstract_key_b; - return (key_a->font_face == key_b->font_face && + if (key_a->hash_entry.hash != key_b->hash_entry.hash) + return FALSE; + + return key_a->font_face == key_b->font_face && memcmp ((unsigned char *)(&key_a->font_matrix.xx), (unsigned char *)(&key_b->font_matrix.xx), sizeof(cairo_matrix_t)) == 0 && memcmp ((unsigned char *)(&key_a->ctm.xx), (unsigned char *)(&key_b->ctm.xx), sizeof(cairo_matrix_t)) == 0 && - cairo_font_options_equal (&key_a->options, &key_b->options)); + cairo_font_options_equal (&key_a->options, &key_b->options); } /* @@ -863,8 +867,8 @@ _cairo_scaled_font_fini_internal (cairo_scaled_font_t *scaled_font) _cairo_scaled_glyph_page_cache_remove_scaled_font (scaled_font); - if (scaled_font->font_face != NULL) - cairo_font_face_destroy (scaled_font->font_face); + cairo_font_face_destroy (scaled_font->font_face); + cairo_font_face_destroy (scaled_font->original_font_face); CAIRO_MUTEX_FINI (scaled_font->mutex); @@ -916,6 +920,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, { cairo_status_t status; cairo_scaled_font_map_t *font_map; + cairo_font_face_t *original_font_face = font_face; cairo_scaled_font_t key, *old = NULL, *scaled_font = NULL; double det; @@ -1051,6 +1056,10 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, return scaled_font; } + scaled_font->original_font_face = + cairo_font_face_reference (original_font_face); + + assert (scaled_font->hash_entry.hash == key.hash_entry.hash); status = _cairo_hash_table_insert (font_map->hash_table, &scaled_font->hash_entry); if (likely (status == CAIRO_STATUS_SUCCESS)) { diff --git a/src/cairo-toy-font-face.c b/src/cairo-toy-font-face.c index 05ad495d..b2d41af3 100644 --- a/src/cairo-toy-font-face.c +++ b/src/cairo-toy-font-face.c @@ -325,6 +325,7 @@ cairo_toy_font_face_create (const char *family, if (unlikely (status)) goto UNWIND_FONT_FACE_MALLOC; + assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash); status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry); if (unlikely (status)) goto UNWIND_FONT_FACE_INIT; -- cgit v1.2.3 From eb2a73ba6d290497cabb0f917c0375eea919178e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 24 Feb 2009 20:27:36 +0000 Subject: [ps] Check the status of _cairo_type3_glyph_surface_create() Doing so serves two purposes. The first is to do an early error check and the second is to clearly initialise the status variable. --- src/cairo-ps-surface.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 169a539a..346bb88c 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -505,6 +505,9 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, NULL, _cairo_ps_emit_imagemask, surface->font_subsets); + status = type3_surface->status; + if (unlikely (status)) + return status; for (i = 0; i < font_subset->num_glyphs; i++) { if (font_subset->glyph_names != NULL) { -- cgit v1.2.3 From 102ddd37bb329d41241f434ede0f9cba8424e71e Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Thu, 26 Feb 2009 16:04:49 -0500 Subject: [win32] Include $(OPT) flags when linking cairo.dll This will pass in -Zi which causes the /DEBUG flag to be passed to the linker keeping the debug information from being discarded during link. --- src/Makefile.win32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.win32 b/src/Makefile.win32 index ee589296..6fdc3956 100644 --- a/src/Makefile.win32 +++ b/src/Makefile.win32 @@ -13,7 +13,7 @@ static: inform $(CFG)/cairo-static.lib dynamic: inform $(CFG)/cairo.dll $(CFG)/cairo.dll: $(OBJECTS) - $(CC) $(MS_MDFLAGS) $(MS_LDFLAGS) -Fe$@ $(PIXMAN_LIBS) $(OBJECTS) -link $(CAIRO_LIBS) + $(CC) $(OPT) $(MS_MDFLAGS) $(MS_LDFLAGS) -Fe$@ $(PIXMAN_LIBS) $(OBJECTS) -link $(CAIRO_LIBS) $(CFG)/cairo-static.lib: $(OBJECTS_STATIC) lib -NOLOGO -OUT:$@ $(PIXMAN_LIBS) $(OBJECTS_STATIC) -- cgit v1.2.3 From e20f1a0c76f2185760ca3a7466e25de6beedeaac Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 27 Feb 2009 16:30:05 +0000 Subject: [in-fill] Close the path, cf fill() In order for in-fill treat the path equivalently to a fill, we need to close the path after interpretation. --- src/cairo-path-in-fill.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cairo-path-in-fill.c b/src/cairo-path-in-fill.c index 431f005b..21cd0bdb 100644 --- a/src/cairo-path-in-fill.c +++ b/src/cairo-path-in-fill.c @@ -244,6 +244,8 @@ _cairo_path_fixed_in_fill (cairo_path_fixed_t *path, &in_fill); assert (status == CAIRO_STATUS_SUCCESS); + _cairo_in_fill_close_path (&in_fill); + switch (fill_rule) { case CAIRO_FILL_RULE_EVEN_ODD: *is_inside = in_fill.winding & 1; -- cgit v1.2.3 From b30de64a8ca3de7632696f45bdb580217bd9f8a1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 1 Mar 2009 10:05:16 +0000 Subject: [test] Add regression test for 005436 Jeff Muizelaar found a regression in commit 005436 and submitted this little test to exercise it. The essence of the bug appears to be wrt to the product of the CTM and device transform matrices. --- test/Makefile.sources | 1 + test/path-append.c | 81 +++++++++++++++++++++++++++++++++ test/path-append.ps.ref.png | Bin 0 -> 4516 bytes test/path-append.ref.png | Bin 0 -> 6165 bytes test/path-append.test-fallback.ref.png | Bin 0 -> 6461 bytes test/path-append.xlib-fallback.ref.png | Bin 0 -> 6357 bytes test/path-append.xlib.ref.png | Bin 0 -> 6461 bytes 7 files changed, 82 insertions(+) create mode 100644 test/path-append.c create mode 100644 test/path-append.ps.ref.png create mode 100644 test/path-append.ref.png create mode 100644 test/path-append.test-fallback.ref.png create mode 100644 test/path-append.xlib-fallback.ref.png create mode 100644 test/path-append.xlib.ref.png diff --git a/test/Makefile.sources b/test/Makefile.sources index 69c581b1..eb118acc 100644 --- a/test/Makefile.sources +++ b/test/Makefile.sources @@ -126,6 +126,7 @@ test_sources = \ paint-repeat.c \ paint-source-alpha.c \ paint-with-alpha.c \ + path-append.c \ path-precision.c \ pattern-get-type.c \ pattern-getters.c \ diff --git a/test/path-append.c b/test/path-append.c new file mode 100644 index 00000000..bcd282db --- /dev/null +++ b/test/path-append.c @@ -0,0 +1,81 @@ +/* + * Copyright © 2009 Jeff Muizelaar + * Copyright © 2009 Chris Wilson + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include "cairo-test.h" + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_matrix_t m; + int xoffset = 50; + int yoffset = 50; + + cairo_surface_t *shadow; + cairo_t *shadow_cr; + cairo_path_t *path; + + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_paint (cr); + + cairo_translate (cr, 130, 130); + cairo_rotate (cr, .5);//2*M_PI*angle/360); + cairo_rectangle (cr, 0, 0, 50, 100); + cairo_get_matrix (cr, &m); + + shadow = cairo_surface_create_similar (cairo_get_target (cr), + CAIRO_CONTENT_COLOR_ALPHA, + 600 - xoffset, + 600 - yoffset); + cairo_surface_set_device_offset (shadow, xoffset, yoffset); + shadow_cr = cairo_create (shadow); + cairo_surface_destroy (shadow); + + cairo_set_source_rgb (shadow_cr, 0, 1, 0); + cairo_set_matrix (shadow_cr, &m); + + path = cairo_copy_path (cr); + cairo_new_path (shadow_cr); + cairo_append_path (shadow_cr, path); + cairo_fill (shadow_cr); + cairo_path_destroy (path); + + cairo_identity_matrix (cr); + cairo_translate (cr, 10, 50); + cairo_set_source_surface (cr, cairo_get_target (shadow_cr), 0, 0); + cairo_paint (cr); + cairo_set_matrix (cr, &m); + cairo_set_source_rgb (cr, 1, 0, 0); + cairo_fill (cr); + + cairo_destroy (shadow_cr); + + return CAIRO_TEST_SUCCESS; +} + +CAIRO_TEST (path_append, + "Test appending path to a context, in particular to exercise a regression in 005436", + "path", /* keywords */ + NULL, /* requirements */ + 600, 600, + NULL, draw) diff --git a/test/path-append.ps.ref.png b/test/path-append.ps.ref.png new file mode 100644 index 00000000..fd8026f7 Binary files /dev/null and b/test/path-append.ps.ref.png differ diff --git a/test/path-append.ref.png b/test/path-append.ref.png new file mode 100644 index 00000000..de9057c8 Binary files /dev/null and b/test/path-append.ref.png differ diff --git a/test/path-append.test-fallback.ref.png b/test/path-append.test-fallback.ref.png new file mode 100644 index 00000000..fa72ac06 Binary files /dev/null and b/test/path-append.test-fallback.ref.png differ diff --git a/test/path-append.xlib-fallback.ref.png b/test/path-append.xlib-fallback.ref.png new file mode 100644 index 00000000..08a33a26 Binary files /dev/null and b/test/path-append.xlib-fallback.ref.png differ diff --git a/test/path-append.xlib.ref.png b/test/path-append.xlib.ref.png new file mode 100644 index 00000000..fa72ac06 Binary files /dev/null and b/test/path-append.xlib.ref.png differ -- cgit v1.2.3 From 9304984f4e20beec7b4de6a4141e2fd489130006 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 1 Mar 2009 10:10:24 +0000 Subject: [path] Fix regression introduced with 005436 The order of the multiplication of the CTM and device_transform was reversed. --- src/cairo-path.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cairo-path.c b/src/cairo-path.c index d62843e7..05445054 100644 --- a/src/cairo-path.c +++ b/src/cairo-path.c @@ -452,8 +452,8 @@ _cairo_path_append_to_context (const cairo_path_t *path, user_to_backend = cr->gstate->ctm; cairo_matrix_multiply (&user_to_backend, - &cr->gstate->target->device_transform, - &user_to_backend); + &user_to_backend, + &cr->gstate->target->device_transform); end = &path->data[path->num_data]; for (p = &path->data[0]; p < end; p += p->header.length) { -- cgit v1.2.3 From 694f2eea9feecfdc437e6964d1e758fab7315af9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Mar 2009 10:24:25 +0000 Subject: [test/any2ppm] Add feature checks for daemon() Add the feature checks for the presence of the daemon() function call. --- test/any2ppm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/any2ppm.c b/test/any2ppm.c index 7b3dabb8..0149230c 100644 --- a/test/any2ppm.c +++ b/test/any2ppm.c @@ -77,7 +77,7 @@ #include #endif -#if HAVE_FCNTL_H && HAVE_SIGNAL_H && HAVE_SYS_STAT_H && HAVE_SYS_SOCKET_H && HAVE_SYS_POLL_H && HAVE_SYS_UN_H +#if HAVE_UNISTD_H && HAVE_FCNTL_H && HAVE_SIGNAL_H && HAVE_SYS_STAT_H && HAVE_SYS_SOCKET_H && HAVE_SYS_POLL_H && HAVE_SYS_UN_H #include #include #include @@ -89,7 +89,11 @@ #define SOCKET_PATH "./.any2ppm" #define TIMEOUT 60000 /* 60 seconds */ +#if _BSD_SOURCE || (_XOPEN_SOURCE && _XOPEN_SOURCE < 500) #define CAN_RUN_AS_DAEMON 1 +#else +#define CAN_RUN_AS_DAEMON 0 +#endif #endif #define ARRAY_LENGTH(A) (sizeof (A) / sizeof (A[0])) -- cgit v1.2.3 From f178f55e47013a92a47a24ac04b1041963b03976 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Mar 2009 10:25:05 +0000 Subject: [test/any2ppm] Update the cairo-script-interpreter callback. Reflect the current prototype which now specifies the content to use when creating the surface. --- test/any2ppm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/test/any2ppm.c b/test/any2ppm.c index 0149230c..13275814 100644 --- a/test/any2ppm.c +++ b/test/any2ppm.c @@ -239,6 +239,7 @@ write_ppm (cairo_surface_t *surface, int fd) static cairo_surface_t * _create_image (void *closure, + cairo_content_t content, double width, double height) //csi_object_t *dictionary) { -- cgit v1.2.3 From e4b1f871e9cbb04590df5dc6f6f7854642fa0340 Mon Sep 17 00:00:00 2001 From: Ginn Chen Date: Tue, 3 Mar 2009 10:27:11 +0000 Subject: [configure] Detect mkdir variant with non-gcc compilers. It doesn't work for non GCC compiler right now, as "-Werror -Wall" is an error to non GCC compiler. I swapped the sequence of build/configure.ac.system and build/ configure.ac.warnings, then WARN_CFLAGS can be used. --- build/configure.ac.system | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/configure.ac.system b/build/configure.ac.system index 4544a54f..d71d2d0c 100644 --- a/build/configure.ac.system +++ b/build/configure.ac.system @@ -81,7 +81,7 @@ AC_CHECK_FUNC(mkdir, [AC_MSG_CHECKING([mkdir variant]) mkdir_variant="unknown" save_CFLAGS="$CFLAGS" - CFLAGS="-Werror -Wall $CFLAGS" # non-gcc compilers? + CFLAGS=$WARN_CFLAGS AC_TRY_COMPILE([ #ifdef HAVE_SYS_STAT_H #include diff --git a/configure.ac b/configure.ac index 229eb6aa..48b61b25 100644 --- a/configure.ac +++ b/configure.ac @@ -19,9 +19,9 @@ dnl The order of the includes here is rather important dnl m4_include(build/configure.ac.version) dnl macros setting up various version declares m4_include(build/configure.ac.tools) dnl checks for tools we use -m4_include(build/configure.ac.system) dnl checks for system functions, headers, libs m4_include(build/configure.ac.features) dnl macros for backend/feature handling m4_include(build/configure.ac.warnings) dnl checks for compiler warning +m4_include(build/configure.ac.system) dnl checks for system functions, headers, libs m4_include(build/configure.ac.analysis) dnl checks for analysis tools (lcov, etc) m4_include(build/configure.ac.noversion) dnl disable builtin libtool versioning AC_CACHE_SAVE -- cgit v1.2.3 From a8158d443e6a4bafae28a46b883cbdcfd5789eec Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 3 Mar 2009 11:21:35 +0000 Subject: [truetype] Move the sizeof asserts to compile time. Eliminate the need for a runtime test on the sizeof the private structures by performing the check at compile time. This was provoked by Ginn Chenn noting that the test was including a private header. --- src/cairo-truetype-subset.c | 15 +++++++++++ test/Makefile.sources | 1 - test/truetype-tables.c | 63 --------------------------------------------- 3 files changed, 15 insertions(+), 64 deletions(-) delete mode 100644 test/truetype-tables.c diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c index d01b0895..31e39710 100644 --- a/src/cairo-truetype-subset.c +++ b/src/cairo-truetype-subset.c @@ -94,6 +94,21 @@ struct _cairo_truetype_font { }; +/* + * Test that the structs we define for TrueType tables have the + * correct size, ie. they are not padded. + */ +#define check(T, S) COMPILE_TIME_ASSERT (sizeof (T) == (S)) +check (tt_head_t, 54); +check (tt_hhea_t, 36); +check (tt_maxp_t, 32); +check (tt_name_record_t, 12); +check (tt_name_t, 18); +check (tt_name_t, 18); +check (tt_composite_glyph_t, 18); +check (tt_glyph_data_t, 28); +#undef check + static cairo_status_t cairo_truetype_font_use_glyph (cairo_truetype_font_t *font, unsigned short glyph, diff --git a/test/Makefile.sources b/test/Makefile.sources index eb118acc..f8c19fd3 100644 --- a/test/Makefile.sources +++ b/test/Makefile.sources @@ -190,7 +190,6 @@ test_sources = \ transforms.c \ translate-show-surface.c \ trap-clip.c \ - truetype-tables.c \ twin.c \ unantialiased-shapes.c \ unbounded-operator.c \ diff --git a/test/truetype-tables.c b/test/truetype-tables.c deleted file mode 100644 index bab119f7..00000000 --- a/test/truetype-tables.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright © 2006 Red Hat, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software - * and its documentation for any purpose is hereby granted without - * fee, provided that the above copyright notice appear in all copies - * and that both that copyright notice and this permission notice - * appear in supporting documentation, and that the name of - * Red Hat, Inc. not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. Red Hat, Inc. makes no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR - * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: Behdad Esfahbod - */ -/* - * Test that the structs we define for TrueType tables have the - * correct size, ie. they are not padded. - */ - -#include "cairo-test.h" - -#include - -static cairo_test_status_t -preamble (cairo_test_context_t *ctx) -{ - cairo_test_status_t ret = CAIRO_TEST_SUCCESS; - -#define check(st, sz) \ - if (sizeof (st) != (sz)) { \ - cairo_test_log (ctx, "sizeof (%s): got %d, expected %d", #st, (int)sizeof (st), sz); \ - ret = CAIRO_TEST_FAILURE; \ - } -#if CAIRO_HAS_FONT_SUBSET - check (tt_head_t, 54); - check (tt_hhea_t, 36); - check (tt_maxp_t, 32); - check (tt_name_record_t, 12); - check (tt_name_t, 18); - check (tt_name_t, 18); - check (tt_composite_glyph_t, 18); - check (tt_glyph_data_t, 28); -#endif - - return ret; -} - -CAIRO_TEST (truetype_tables, - "Test that the size of TrueType table structs is correct", - "ft, api", /* keywords */ - NULL, /* requirements */ - 0, 0, - preamble, NULL) -- cgit v1.2.3 From addeb32c751ac080fe634ea6f83076d018944e4a Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 3 Mar 2009 12:20:47 -0500 Subject: [pdf] Intialize 'interpolate' Intialize 'interpolate' to prevent a gcc warning. Do this instead of adding a 'default' case to the switch statement so that we still get warnings if new filter types are added. --- src/cairo-pdf-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index a9012744..f562e3fd 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1543,7 +1543,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, int i, x, y; cairo_pdf_resource_t smask = {0}; /* squelch bogus compiler warning */ cairo_bool_t need_smask; - const char *interpolate; + const char *interpolate = "true"; /* These are the only image formats we currently support, (which * makes things a lot simpler here). This is enforced through -- cgit v1.2.3 From 9099c7e7307a39bc630919faa65bba089fd15104 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 4 Mar 2009 09:26:17 +0000 Subject: [trace] Disable mark dirty tracing. Applications like firefox have a very conservative approach and mark surfaces dirty before every render. As we record the image data every time, firefox traces can grow very large with redundant data - so allow the user to disable mark dirty tracing. --- util/cairo-trace/cairo-trace.in | 19 +++++++++++++++---- util/cairo-trace/trace.c | 27 ++++++++++++++++++++------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/util/cairo-trace/cairo-trace.in b/util/cairo-trace/cairo-trace.in index 40c9d193..6660ff80 100644 --- a/util/cairo-trace/cairo-trace.in +++ b/util/cairo-trace/cairo-trace.in @@ -6,6 +6,7 @@ exec_prefix=@exec_prefix@ nofile= flush= nocallers= +nomarkdirty= usage() { cat << EOF @@ -14,10 +15,11 @@ cairo-trace will generate a log of all calls made by command to cairo. This log will be stored in a file in the local directory called command.pid.trace. Whatever else happens is driven by its argument: - --flush - Flush the output trace after every call. - --no-file - Disable the creation of an output file. Outputs to the - terminal instead. - --no-callers - Do not lookup the caller address/symbol/line whilst tracing. + --flush - Flush the output trace after every call. + --no-file - Disable the creation of an output file. Outputs to the + terminal instead. + --no-callers - Do not lookup the caller address/symbol/line whilst tracing. + --no-mark-dirty - Do not record image data for cairo_mark_dirty() Enviroment variables understood by cairo-trace: CAIRO_TRACE_FLUSH - flush the output after every function call. @@ -42,6 +44,10 @@ while test $skip -eq 1; do skip=1 nocallers=1 ;; + --no-mark-dirty) + skip=1 + nomarkdirty=1 + ;; --version) echo "cairo-trace, version @CAIRO_VERSION_MAJOR@.@CAIRO_VERSION_MINOR@.@CAIRO_VERSION_MICRO@." exit @@ -69,6 +75,11 @@ if test -n "$nocallers"; then export CAIRO_TRACE_LINE_INFO fi +if test -n "$nomarkdirty"; then + CAIRO_TRACE_MARK_DIRTY=0 + export CAIRO_TRACE_MARK_DIRTY +fi + if test -n "$flush"; then CAIRO_TRACE_FLUSH=1 export CAIRO_TRACE_FLUSH diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c index 029a7200..4a7096db 100644 --- a/util/cairo-trace/trace.c +++ b/util/cairo-trace/trace.c @@ -166,6 +166,7 @@ static FILE *logfile; static bool _flush; static bool _error; static bool _line_info; +static bool _mark_dirty; static const cairo_user_data_key_t destroy_key; #if __GNUC__ >= 3 @@ -692,6 +693,11 @@ _init_logfile (void) if (env != NULL) _line_info = atoi (env); + _mark_dirty = true; + env = getenv ("CAIRO_TRACE_MARK_DIRTY"); + if (env != NULL) + _mark_dirty = atoi (env); + filename = getenv ("CAIRO_TRACE_FD"); if (filename != NULL) { int fd = atoi (filename); @@ -3115,9 +3121,12 @@ cairo_surface_mark_dirty (cairo_surface_t *surface) { _emit_line_info (); if (surface != NULL && _write_lock ()) { - _emit_surface (surface); - _trace_printf ("%% mark-dirty\n"); - _emit_source_image (surface); + if (_mark_dirty) { + _emit_surface (surface); + _trace_printf ("%% mark-dirty\n"); + _emit_source_image (surface); + } else + _trace_printf ("%% s%ld mark-dirty\n", _get_surface_id (surface)); _write_unlock (); } @@ -3130,10 +3139,14 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, { _emit_line_info (); if (surface != NULL && _write_lock ()) { - _emit_surface (surface); - _trace_printf ("%% %d %d %d %d mark-dirty-rectangle\n", - x, y, width, height); - _emit_source_image_rectangle (surface, x,y, width, height); + if (_mark_dirty) { + _emit_surface (surface); + _trace_printf ("%% %d %d %d %d mark-dirty-rectangle\n", + x, y, width, height); + _emit_source_image_rectangle (surface, x,y, width, height); + } else + _trace_printf ("%% s%ld %d %d %d %d mark-dirty-rectangle\n", + _get_surface_id (surface), x, y, width, height); _write_unlock (); } -- cgit v1.2.3 From 121d4bb656755b7ca89065bf87e3e4e47c49c89d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Mar 2009 19:42:47 +0000 Subject: [scaled-font] Initialise original_font_face Eek, attempting to use+free an uninitialised pointer! --- src/cairo-scaled-font.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 36e3d9cc..58733a79 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -777,6 +777,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, _cairo_user_data_array_init (&scaled_font->user_data); cairo_font_face_reference (font_face); + scaled_font->original_font_face = NULL; CAIRO_MUTEX_INIT (scaled_font->mutex); -- cgit v1.2.3 From 9c80392ac415e7f07c71261d280ac4376d3c8471 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Mar 2009 19:31:38 +0000 Subject: [scaled-font] Lean and mean global glyph cache. Jeff Muizelaar pointed out that the severe overallocation implicit in the current version of the glyph cache is obnoxious and prevents him from accepting the trunk into Mozilla. Jeff captured a trace of scaled font and glyph usage during a tp run and presented his analysis in http://lists.cairographics.org/archives/cairo/2009-March/016706.html Using that data, the design was changed to allocate pages of glyphs from a capped global pool but with per-font hash tables. This should allow the glyph cache to have tight memory bounds with fair allocation according to usage. Note that both the old design and the 1.8 glyph cache had essentially unbounded memory constraints, since each scaled font could cache up to 256 glyphs (1.8) or had a reserved page (old), with no limit on the number of active fonts. Currently the eviction policy is a simple random strategy, this gives a 'fair' allotment of the cache, but a LRU variant might perform better. On a sample run of firefox-3.0.7 perusing BBC news in 32 languages: 1.8: cache allocation 8190x, ~1.2 MiB; elapsed 88.2s old: cache allocation 771x, ~13.8 MiB; elapsed 81.7s lean: cache allocation 433x, ~1.8 MiB; elapsed 82.4s --- src/cairo-cache-private.h | 5 +- src/cairo-cache.c | 39 ++-- src/cairo-ft-font.c | 4 +- src/cairo-hash-private.h | 6 +- src/cairo-hash.c | 55 ------ src/cairo-scaled-font-private.h | 6 +- src/cairo-scaled-font.c | 396 ++++++++++++++++++++-------------------- src/cairo-types-private.h | 3 + src/cairoint.h | 7 +- 9 files changed, 232 insertions(+), 289 deletions(-) diff --git a/src/cairo-cache-private.h b/src/cairo-cache-private.h index 8ad0c774..25858e54 100644 --- a/src/cairo-cache-private.h +++ b/src/cairo-cache-private.h @@ -97,6 +97,7 @@ typedef void cairo_private cairo_cache_t * _cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal, + cairo_cache_predicate_func_t predicate, cairo_destroy_func_t entry_destroy, unsigned long max_size); @@ -113,10 +114,6 @@ cairo_private void * _cairo_cache_lookup (cairo_cache_t *cache, cairo_cache_entry_t *key); -cairo_private void * -_cairo_cache_steal (cairo_cache_t *cache, - cairo_cache_entry_t *key); - cairo_private cairo_status_t _cairo_cache_insert (cairo_cache_t *cache, cairo_cache_entry_t *entry); diff --git a/src/cairo-cache.c b/src/cairo-cache.c index cab6e1e9..7542242d 100644 --- a/src/cairo-cache.c +++ b/src/cairo-cache.c @@ -42,9 +42,16 @@ static void _cairo_cache_shrink_to_accommodate (cairo_cache_t *cache, unsigned long additional); +static cairo_bool_t +_cairo_cache_entry_is_non_zero (const void *entry) +{ + return ((const cairo_cache_entry_t *) entry)->size; +} + static cairo_status_t _cairo_cache_init (cairo_cache_t *cache, cairo_cache_keys_equal_func_t keys_equal, + cairo_cache_predicate_func_t predicate, cairo_destroy_func_t entry_destroy, unsigned long max_size) { @@ -52,6 +59,9 @@ _cairo_cache_init (cairo_cache_t *cache, if (unlikely (cache->hash_table == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (predicate == NULL) + predicate = _cairo_cache_entry_is_non_zero; + cache->predicate = predicate; cache->entry_destroy = entry_destroy; cache->max_size = max_size; @@ -114,6 +124,7 @@ _cairo_cache_fini (cairo_cache_t *cache) **/ cairo_cache_t * _cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal, + cairo_cache_predicate_func_t predicate, cairo_destroy_func_t entry_destroy, unsigned long max_size) { @@ -126,7 +137,11 @@ _cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal, return NULL; } - status = _cairo_cache_init (cache, keys_equal, entry_destroy, max_size); + status = _cairo_cache_init (cache, + keys_equal, + predicate, + entry_destroy, + max_size); if (unlikely (status)) { free (cache); return NULL; @@ -221,26 +236,6 @@ _cairo_cache_lookup (cairo_cache_t *cache, (cairo_hash_entry_t *) key); } -void * -_cairo_cache_steal (cairo_cache_t *cache, - cairo_cache_entry_t *key) -{ - cairo_cache_entry_t *entry; - - entry = _cairo_hash_table_steal (cache->hash_table, - (cairo_hash_entry_t *) key); - if (entry != NULL) - cache->size -= entry->size; - - return entry; -} - -static cairo_bool_t -_cairo_cache_entry_is_non_zero (void *entry) -{ - return ((cairo_cache_entry_t *)entry)->size; -} - /** * _cairo_cache_remove_random: * @cache: a cache @@ -256,7 +251,7 @@ _cairo_cache_remove_random (cairo_cache_t *cache) cairo_cache_entry_t *entry; entry = _cairo_hash_table_random_entry (cache->hash_table, - _cairo_cache_entry_is_non_zero); + cache->predicate); if (unlikely (entry == NULL)) return FALSE; diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 493a1e27..ec6041a2 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -532,9 +532,9 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font) } static cairo_bool_t -_has_unlocked_face (void *entry) +_has_unlocked_face (const void *entry) { - cairo_ft_unscaled_font_t *unscaled = entry; + const cairo_ft_unscaled_font_t *unscaled = entry; return (!unscaled->from_face && unscaled->lock_count == 0 && unscaled->face); } diff --git a/src/cairo-hash-private.h b/src/cairo-hash-private.h index 8ab08582..32078bd2 100644 --- a/src/cairo-hash-private.h +++ b/src/cairo-hash-private.h @@ -51,7 +51,7 @@ typedef cairo_bool_t (*cairo_hash_keys_equal_func_t) (const void *key_a, const void *key_b); typedef cairo_bool_t -(*cairo_hash_predicate_func_t) (void *entry); +(*cairo_hash_predicate_func_t) (const void *entry); typedef void (*cairo_hash_callback_func_t) (void *entry, @@ -67,10 +67,6 @@ cairo_private void * _cairo_hash_table_lookup (cairo_hash_table_t *hash_table, cairo_hash_entry_t *key); -cairo_private void * -_cairo_hash_table_steal (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key); - cairo_private void * _cairo_hash_table_random_entry (cairo_hash_table_t *hash_table, cairo_hash_predicate_func_t predicate); diff --git a/src/cairo-hash.c b/src/cairo-hash.c index c0c9f7d8..51303f5a 100644 --- a/src/cairo-hash.c +++ b/src/cairo-hash.c @@ -345,61 +345,6 @@ _cairo_hash_table_lookup (cairo_hash_table_t *hash_table, return NULL; } -/** - * _cairo_hash_table_steal: - * @hash_table: a hash table - * @key: the key of interest - * - * Performs a lookup in @hash_table looking for an entry which has a - * key that matches @key, (as determined by the keys_equal() function - * passed to _cairo_hash_table_create) and removes that entry from the - * hash table. - * - * Return value: the matching entry, of %NULL if no match was found. - **/ -void * -_cairo_hash_table_steal (cairo_hash_table_t *hash_table, - cairo_hash_entry_t *key) -{ - cairo_hash_entry_t *entry; - unsigned long table_size, i, idx, step; - - table_size = hash_table->arrangement->size; - idx = key->hash % table_size; - - entry = hash_table->entries[idx]; - if (ENTRY_IS_LIVE (entry)) { - if (hash_table->keys_equal (key, entry)) { - hash_table->entries[idx] = DEAD_ENTRY; - hash_table->live_entries--; - return entry; - } - } else if (ENTRY_IS_FREE (entry)) - return NULL; - - i = 1; - step = key->hash % hash_table->arrangement->rehash; - if (step == 0) - step = 1; - do { - idx += step; - if (idx >= table_size) - idx -= table_size; - - entry = hash_table->entries[idx]; - if (ENTRY_IS_LIVE (entry)) { - if (hash_table->keys_equal (key, entry)) { - hash_table->entries[idx] = DEAD_ENTRY; - hash_table->live_entries--; - return entry; - } - } else if (ENTRY_IS_FREE (entry)) - return NULL; - } while (++i < table_size); - - return NULL; -} - /** * _cairo_hash_table_random_entry: * @hash_table: a hash table diff --git a/src/cairo-scaled-font-private.h b/src/cairo-scaled-font-private.h index 89820c8f..f6c97488 100644 --- a/src/cairo-scaled-font-private.h +++ b/src/cairo-scaled-font-private.h @@ -106,8 +106,10 @@ struct _cairo_scaled_font { /* The mutex protects modification to all subsequent fields. */ cairo_mutex_t mutex; - int cache_frozen; - cairo_scaled_glyph_page_t *mru_page; + cairo_hash_table_t *glyphs; + cairo_scaled_glyph_page_t *glyph_pages; + cairo_bool_t cache_frozen; + cairo_bool_t global_cache_frozen; /* * One surface backend may store data in each glyph. diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 58733a79..e14aa2e9 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -49,21 +49,30 @@ #define ISFINITE(x) ((x) * (x) >= 0.) /* check for NaNs */ #endif -#define CAIRO_SCALED_GLYPH_PAGE_SHIFT 7 -#define CAIRO_SCALED_GLYPH_PAGE_SIZE (1 << CAIRO_SCALED_GLYPH_PAGE_SHIFT) -#define CAIRO_SCALED_GLYPH_PAGE_INDEX(I) \ - ((I) & (CAIRO_SCALED_GLYPH_PAGE_SIZE - 1)) -#define CAIRO_SCALED_GLYPH_PAGE_BASE_INDEX(I) ((I) & -CAIRO_SCALED_GLYPH_PAGE_SIZE) -#define CAIRO_SCALED_GLYPH_PAGE_HAS_INDEX(P, I) \ - ((I) - (P)->base_index < CAIRO_SCALED_GLYPH_PAGE_SIZE) -typedef struct _cairo_scaled_glyph_page_key { - cairo_cache_entry_t cache_entry; - cairo_scaled_font_t *scaled_font; -} cairo_scaled_glyph_page_key_t; +/* Global Glyph Cache + * + * We maintain a global pool of glyphs split between all open fonts. This + * allows a heavily used individual font to cache more glyphs than we could + * manage if we used per-font glyph caches, but at the same time maintains + * fairness across all fonts and provides a cap on the maximum number of + * global glyphs. + * + * The glyphs are allocated in pages, which are cached in the global pool. + * Using pages means we can reduce the frequency at which we have to probe the + * global cache and ameliorates the memory allocation pressure. + */ + +/* XXX: This number is arbitrary---we've never done any measurement of this. */ +#define MAX_GLYPH_PAGES_CACHED 512 +static cairo_cache_t *cairo_scaled_glyph_page_cache; +#define CAIRO_SCALED_GLYPH_PAGE_SIZE 32 struct _cairo_scaled_glyph_page { - cairo_scaled_glyph_page_key_t key; - unsigned long base_index; + cairo_cache_entry_t cache_entry; + + struct _cairo_scaled_glyph_page *prev, *next; + + unsigned int num_glyphs; cairo_scaled_glyph_t glyphs[CAIRO_SCALED_GLYPH_PAGE_SIZE]; }; @@ -176,13 +185,9 @@ static void _cairo_scaled_font_fini_internal (cairo_scaled_font_t *scaled_font); static void -_cairo_scaled_glyph_page_cache_remove_scaled_font (cairo_scaled_font_t - *scaled_font); - -static void -_cairo_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph) +_cairo_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, + cairo_scaled_glyph_t *scaled_glyph) { - cairo_scaled_font_t *scaled_font = scaled_glyph->scaled_font; const cairo_surface_backend_t *surface_backend = scaled_font->surface_backend; if (surface_backend != NULL && surface_backend->scaled_glyph_fini != NULL) @@ -196,8 +201,6 @@ _cairo_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph) if (scaled_glyph->meta_surface != NULL) cairo_surface_destroy (scaled_glyph->meta_surface); - - scaled_glyph->scaled_font = NULL; } #define ZOMBIE 0 @@ -222,8 +225,10 @@ static const cairo_scaled_font_t _cairo_scaled_font_nil = { { 0., 0., 0., 0., 0. }, /* extents */ { 0., 0., 0., 0., 0. }, /* fs_extents */ CAIRO_MUTEX_NIL_INITIALIZER,/* mutex */ + NULL, /* glyphs */ + NULL, /* pages */ FALSE, /* cache_frozen */ - NULL, /* mru_page */ + FALSE, /* global_cache_frozen */ NULL, /* surface_backend */ NULL, /* surface_private */ NULL /* backend */ @@ -419,112 +424,29 @@ _cairo_scaled_font_map_destroy (void) CLEANUP_MUTEX_LOCK: CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); } - -/* Global Glyph Cache - * - * We maintain a global pool of glyphs split between all open fonts. This - * allows a heavily used individual font to cache more glyphs than we could - * manage if we used per-font glyph caches, but at the same time maintains - * fairness across all fonts and provides a cap on the maximum number of - * global glyphs. - * - * The glyphs are allocated in pages, which are cached in the global pool. - * Using pages means we can exploit spatial locality within the font (nearby - * indices are typically used in clusters) to reduce frequency of small - * allocations and allow the scaled font to reserve a single MRU page of - * glyphs. - */ - -/* XXX: This number is arbitrary---we've never done any measurement of this. */ -#define MAX_GLYPH_PAGES_CACHED 512 - -static cairo_cache_t *cairo_scaled_glyph_page_cache; - -static cairo_bool_t -_cairo_scaled_glyph_pages_equal (const void *key_a, const void *key_b) -{ - const cairo_scaled_glyph_page_key_t *a = key_a; - const cairo_scaled_glyph_page_key_t *b = key_b; - - return - a->cache_entry.hash == b->cache_entry.hash && - a->scaled_font == b->scaled_font; -} - static void _cairo_scaled_glyph_page_destroy (void *closure) { cairo_scaled_glyph_page_t *page = closure; - int n; - - for (n = 0; n < CAIRO_SCALED_GLYPH_PAGE_SIZE; n++) { - if (page->glyphs[n].scaled_font != NULL) - _cairo_scaled_glyph_fini (&page->glyphs[n]); - } - - free (page); -} - -static cairo_scaled_glyph_page_t * -_cairo_scaled_glyph_page_cache_lookup (cairo_scaled_font_t *scaled_font, - unsigned long index) -{ - cairo_scaled_glyph_page_key_t key; - cairo_scaled_glyph_page_t *page; - - key.cache_entry.hash = - (index >> CAIRO_SCALED_GLYPH_PAGE_SHIFT) ^ - (unsigned long) scaled_font; - key.scaled_font = scaled_font; + cairo_scaled_font_t *scaled_font; + unsigned int n; - if (scaled_font->cache_frozen) { - CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); - page = _cairo_cache_steal (cairo_scaled_glyph_page_cache, - &key.cache_entry); - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); - } else - page = NULL; - - if (page == NULL) { - /* On miss, create glyph page and insert into cache */ - page = malloc (sizeof (cairo_scaled_glyph_page_t)); - if (unlikely (page == NULL)) - return NULL; - - page->key.cache_entry.hash = key.cache_entry.hash; - /* We currently don't differentiate on glyph size at all */ - page->key.cache_entry.size = 1; - page->key.scaled_font = scaled_font; - page->base_index = CAIRO_SCALED_GLYPH_PAGE_BASE_INDEX (index); - - memset (page->glyphs, 0, sizeof (page->glyphs)); + scaled_font = (cairo_scaled_font_t *) page->cache_entry.hash; + for (n = 0; n < page->num_glyphs; n++) { + _cairo_hash_table_remove (scaled_font->glyphs, + &page->glyphs[n].hash_entry); + _cairo_scaled_glyph_fini (scaled_font, &page->glyphs[n]); } - return page; -} - -static void -_cairo_scaled_glyph_page_cache_remove_scaled_font_cb (void *entry, - void *closure) -{ - cairo_scaled_glyph_page_key_t *key = entry; - - if (key->scaled_font == closure) - _cairo_cache_remove (cairo_scaled_glyph_page_cache, entry); -} - -static void -_cairo_scaled_glyph_page_cache_remove_scaled_font (cairo_scaled_font_t *scaled_font) -{ - CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); + if (page->prev != NULL) + page->prev->next = page->next; + else + scaled_font->glyph_pages = page->next; - if (cairo_scaled_glyph_page_cache != NULL) { - _cairo_cache_foreach (cairo_scaled_glyph_page_cache, - _cairo_scaled_glyph_page_cache_remove_scaled_font_cb, - scaled_font); - } + if (page->next != NULL) + page->next->prev = page->prev; - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); + free (page); } /* If a scaled font wants to unlock the font map while still being @@ -702,7 +624,8 @@ _cairo_scaled_font_init_key (cairo_scaled_font_t *scaled_font, } static cairo_bool_t -_cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_key_b) +_cairo_scaled_font_keys_equal (const void *abstract_key_a, + const void *abstract_key_b) { const cairo_scaled_font_t *key_a = abstract_key_a; const cairo_scaled_font_t *key_b = abstract_key_b; @@ -720,6 +643,15 @@ _cairo_scaled_font_keys_equal (const void *abstract_key_a, const void *abstract_ cairo_font_options_equal (&key_a->options, &key_b->options); } +static cairo_bool_t +_cairo_scaled_glyphs_equal (const void *abstract_a, const void *abstract_b) +{ + const cairo_scaled_glyph_t *a = abstract_a; + const cairo_scaled_glyph_t *b = abstract_b; + + return a->hash_entry.hash == b->hash_entry.hash; +} + /* * Basic #cairo_scaled_font_t object management */ @@ -769,8 +701,15 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, return status; } - scaled_font->finished = FALSE; + scaled_font->glyphs = _cairo_hash_table_create (_cairo_scaled_glyphs_equal); + if (unlikely (scaled_font->glyphs == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + scaled_font->glyph_pages = NULL; scaled_font->cache_frozen = FALSE; + scaled_font->global_cache_frozen = FALSE; + + scaled_font->finished = FALSE; CAIRO_REFERENCE_COUNT_INIT (&scaled_font->ref_count, 1); @@ -781,8 +720,6 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, CAIRO_MUTEX_INIT (scaled_font->mutex); - scaled_font->mru_page = NULL; - scaled_font->surface_backend = NULL; scaled_font->surface_private = NULL; @@ -798,17 +735,20 @@ _cairo_scaled_font_freeze_cache (cairo_scaled_font_t *scaled_font) assert (scaled_font->status == CAIRO_STATUS_SUCCESS); CAIRO_MUTEX_LOCK (scaled_font->mutex); + scaled_font->cache_frozen = TRUE; } void _cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font) { - if (scaled_font->cache_frozen) { + scaled_font->cache_frozen = FALSE; + + if (scaled_font->global_cache_frozen) { CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); _cairo_cache_thaw (cairo_scaled_glyph_page_cache); CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); - scaled_font->cache_frozen = FALSE; + scaled_font->global_cache_frozen = FALSE; } CAIRO_MUTEX_UNLOCK (scaled_font->mutex); @@ -817,14 +757,14 @@ _cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font) void _cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font) { - assert (CAIRO_MUTEX_IS_LOCKED (scaled_font->mutex)); + assert (! scaled_font->cache_frozen); - if (scaled_font->mru_page != NULL) { - _cairo_scaled_glyph_page_destroy (scaled_font->mru_page); - scaled_font->mru_page = NULL; + CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); + while (scaled_font->glyph_pages != NULL) { + _cairo_cache_remove (cairo_scaled_glyph_page_cache, + &scaled_font->glyph_pages->cache_entry); } - - _cairo_scaled_glyph_page_cache_remove_scaled_font (scaled_font); + CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); } cairo_status_t @@ -861,12 +801,8 @@ _cairo_scaled_font_fini_internal (cairo_scaled_font_t *scaled_font) { scaled_font->finished = TRUE; - if (scaled_font->mru_page != NULL) { - _cairo_scaled_glyph_page_destroy (scaled_font->mru_page); - scaled_font->mru_page = NULL; - } - - _cairo_scaled_glyph_page_cache_remove_scaled_font (scaled_font); + _cairo_scaled_font_reset_cache (scaled_font); + _cairo_hash_table_destroy (scaled_font->glyphs); cairo_font_face_destroy (scaled_font->font_face); cairo_font_face_destroy (scaled_font->original_font_face); @@ -2496,6 +2432,92 @@ _cairo_scaled_glyph_set_meta_surface (cairo_scaled_glyph_t *scaled_glyph, scaled_glyph->meta_surface = meta_surface; } +static cairo_bool_t +_cairo_scaled_glyph_page_can_remove (const void *closure) +{ + const cairo_scaled_glyph_page_t *page = closure; + const cairo_scaled_font_t *scaled_font; + + scaled_font = (cairo_scaled_font_t *) page->cache_entry.hash; + return scaled_font->cache_frozen == 0; +} + +static cairo_status_t +_cairo_scaled_font_allocate_glyph (cairo_scaled_font_t *scaled_font, + cairo_scaled_glyph_t **scaled_glyph) +{ + cairo_scaled_glyph_page_t *page; + cairo_status_t status; + + /* only the first page in the list may contain available slots */ + page = scaled_font->glyph_pages; + if (page != NULL && page->num_glyphs < CAIRO_SCALED_GLYPH_PAGE_SIZE) { + *scaled_glyph = &page->glyphs[page->num_glyphs++]; + return CAIRO_STATUS_SUCCESS; + } + + page = malloc (sizeof (cairo_scaled_glyph_page_t)); + if (unlikely (page == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + page->cache_entry.hash = (unsigned long) scaled_font; + page->cache_entry.size = 1; /* XXX occupancy weighting? */ + page->num_glyphs = 0; + + CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); + if (scaled_font->global_cache_frozen == FALSE) { + if (unlikely (cairo_scaled_glyph_page_cache == NULL)) { + cairo_scaled_glyph_page_cache = + _cairo_cache_create (NULL, + _cairo_scaled_glyph_page_can_remove, + _cairo_scaled_glyph_page_destroy, + MAX_GLYPH_PAGES_CACHED); + if (unlikely (cairo_scaled_glyph_page_cache == NULL)) { + CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); + free (page); + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } + } + + _cairo_cache_freeze (cairo_scaled_glyph_page_cache); + scaled_font->global_cache_frozen = TRUE; + } + + status = _cairo_cache_insert (cairo_scaled_glyph_page_cache, + &page->cache_entry); + CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); + if (unlikely (status)) { + free (page); + return status; + } + + page->next = scaled_font->glyph_pages; + page->prev = NULL; + if (scaled_font->glyph_pages != NULL) + scaled_font->glyph_pages->prev = page; + scaled_font->glyph_pages = page; + + *scaled_glyph = &page->glyphs[page->num_glyphs++]; + return CAIRO_STATUS_SUCCESS; +} + +static void +_cairo_scaled_font_free_last_glyph (cairo_scaled_font_t *scaled_font, + cairo_scaled_glyph_t *scaled_glyph) +{ + cairo_scaled_glyph_page_t *page; + + page = scaled_font->glyph_pages; + assert (page != NULL && scaled_glyph == &page->glyphs[page->num_glyphs-1]); + + _cairo_scaled_glyph_fini (scaled_font, scaled_glyph); + + if (--page->num_glyphs == 0) { + _cairo_cache_remove (cairo_scaled_glyph_page_cache, &page->cache_entry); + assert (scaled_font->glyph_pages != page); + } +} + /** * _cairo_scaled_glyph_lookup: * @scaled_font: a #cairo_scaled_font_t @@ -2529,66 +2551,40 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, cairo_scaled_glyph_info_t info, cairo_scaled_glyph_t **scaled_glyph_ret) { - cairo_status_t status = CAIRO_STATUS_SUCCESS; - cairo_scaled_glyph_page_t *page; + cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_scaled_glyph_t *scaled_glyph; - cairo_scaled_glyph_info_t need_info; + cairo_scaled_glyph_info_t need_info; if (unlikely (scaled_font->status)) return scaled_font->status; - page = scaled_font->mru_page; - if (page != NULL && ! CAIRO_SCALED_GLYPH_PAGE_HAS_INDEX (page, index)) { - CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex); - if (! scaled_font->cache_frozen) { - if (cairo_scaled_glyph_page_cache == NULL) { - cairo_scaled_glyph_page_cache = - _cairo_cache_create (_cairo_scaled_glyph_pages_equal, - _cairo_scaled_glyph_page_destroy, - MAX_GLYPH_PAGES_CACHED); - if (unlikely (cairo_scaled_glyph_page_cache == NULL)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL; - } - } - - _cairo_cache_freeze (cairo_scaled_glyph_page_cache); - scaled_font->cache_frozen = TRUE; - } - status = _cairo_cache_insert (cairo_scaled_glyph_page_cache, - &page->key.cache_entry); - BAIL: - CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex); - if (unlikely (status)) - return _cairo_scaled_font_set_error (scaled_font, status); - - page = scaled_font->mru_page = NULL; - } - - if (page == NULL) { - page = _cairo_scaled_glyph_page_cache_lookup (scaled_font, index); - if (unlikely (page == NULL)) { - return _cairo_scaled_font_set_error (scaled_font, - _cairo_error (CAIRO_STATUS_NO_MEMORY)); - } - } - - scaled_font->mru_page = page; - /* * Check cache for glyph */ - info |= CAIRO_SCALED_GLYPH_INFO_METRICS; - scaled_glyph = &page->glyphs[CAIRO_SCALED_GLYPH_PAGE_INDEX (index)]; - if (scaled_glyph->scaled_font == NULL) { - scaled_glyph->index = index; - scaled_glyph->scaled_font = scaled_font; + scaled_glyph = _cairo_hash_table_lookup (scaled_font->glyphs, + (cairo_hash_entry_t *) &index); + if (scaled_glyph == NULL) { + status = _cairo_scaled_font_allocate_glyph (scaled_font, &scaled_glyph); + if (unlikely (status)) + goto CLEANUP; + + memset (scaled_glyph, 0, sizeof (cairo_scaled_glyph_t)); + _cairo_scaled_glyph_set_index (scaled_glyph, index); /* ask backend to initialize metrics and shape fields */ - status = (*scaled_font->backend-> - scaled_glyph_init) (scaled_font, scaled_glyph, info); + status = + scaled_font->backend->scaled_glyph_init (scaled_font, + scaled_glyph, + info | CAIRO_SCALED_GLYPH_INFO_METRICS); + if (unlikely (status)) { + _cairo_scaled_font_free_last_glyph (scaled_font, scaled_glyph); + goto CLEANUP; + } + + status = _cairo_hash_table_insert (scaled_font->glyphs, + &scaled_glyph->hash_entry); if (unlikely (status)) { - _cairo_scaled_glyph_fini (scaled_glyph); + _cairo_scaled_font_free_last_glyph (scaled_font, scaled_glyph); goto CLEANUP; } } @@ -2600,19 +2596,26 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, need_info = 0; if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0 && scaled_glyph->surface == NULL) + { need_info |= CAIRO_SCALED_GLYPH_INFO_SURFACE; + } - if (((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 && - scaled_glyph->path == NULL)) + if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 && + scaled_glyph->path == NULL) + { need_info |= CAIRO_SCALED_GLYPH_INFO_PATH; + } - if (((info & CAIRO_SCALED_GLYPH_INFO_META_SURFACE) != 0 && - scaled_glyph->meta_surface == NULL)) + if ((info & CAIRO_SCALED_GLYPH_INFO_META_SURFACE) != 0 && + scaled_glyph->meta_surface == NULL) + { need_info |= CAIRO_SCALED_GLYPH_INFO_META_SURFACE; + } if (need_info) { - status = (*scaled_font->backend-> - scaled_glyph_init) (scaled_font, scaled_glyph, need_info); + status = scaled_font->backend->scaled_glyph_init (scaled_font, + scaled_glyph, + need_info); if (unlikely (status)) goto CLEANUP; @@ -2622,19 +2625,22 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, * glyph info. */ if ((info & CAIRO_SCALED_GLYPH_INFO_SURFACE) != 0 && - scaled_glyph->surface == NULL) { + scaled_glyph->surface == NULL) + { status = CAIRO_INT_STATUS_UNSUPPORTED; goto CLEANUP; } if ((info & CAIRO_SCALED_GLYPH_INFO_PATH) != 0 && - scaled_glyph->path == NULL) { + scaled_glyph->path == NULL) + { status = CAIRO_INT_STATUS_UNSUPPORTED; goto CLEANUP; } if ((info & CAIRO_SCALED_GLYPH_INFO_META_SURFACE) != 0 && - scaled_glyph->meta_surface == NULL) { + scaled_glyph->meta_surface == NULL) + { status = CAIRO_INT_STATUS_UNSUPPORTED; goto CLEANUP; } diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index 149d894e..0a3ec2e4 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -123,9 +123,12 @@ struct _cairo_font_options { cairo_hint_metrics_t hint_metrics; }; +typedef cairo_bool_t (*cairo_cache_predicate_func_t) (const void *entry); + struct _cairo_cache { cairo_hash_table_t *hash_table; + cairo_cache_predicate_func_t predicate; cairo_destroy_func_t entry_destroy; unsigned long max_size; diff --git a/src/cairoint.h b/src/cairoint.h index b550f867..b93c4a44 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -362,8 +362,7 @@ typedef struct _cairo_unscaled_font { } cairo_unscaled_font_t; typedef struct _cairo_scaled_glyph { - unsigned long index; - cairo_scaled_font_t *scaled_font; /* font the glyph lives in */ + cairo_hash_entry_t hash_entry; cairo_text_extents_t metrics; /* user-space metrics */ cairo_text_extents_t fs_metrics; /* font-space metrics */ @@ -378,8 +377,8 @@ typedef struct _cairo_scaled_glyph { void *surface_private; /* for the surface backend */ } cairo_scaled_glyph_t; -#define _cairo_scaled_glyph_index(g) ((g)->index) -#define _cairo_scaled_glyph_set_index(g, i) ((g)->index = (i)) +#define _cairo_scaled_glyph_index(g) ((g)->hash_entry.hash) +#define _cairo_scaled_glyph_set_index(g, i) ((g)->hash_entry.hash = (i)) #include "cairo-scaled-font-private.h" -- cgit v1.2.3 From 0e7bcb5e3793771d50f7d391d7b1e538ef220a80 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Mar 2009 21:32:44 +0000 Subject: [scaled-font] Improve comments. Grr. I thought I had merged this in with the previous commit... --- src/cairo-scaled-font.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index e14aa2e9..9acfc43b 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -51,15 +51,15 @@ /* Global Glyph Cache * - * We maintain a global pool of glyphs split between all open fonts. This + * We maintain a global pool of glyphs split between all active fonts. This * allows a heavily used individual font to cache more glyphs than we could * manage if we used per-font glyph caches, but at the same time maintains * fairness across all fonts and provides a cap on the maximum number of * global glyphs. * - * The glyphs are allocated in pages, which are cached in the global pool. + * The glyphs are allocated in pages, which are capped in the global pool. * Using pages means we can reduce the frequency at which we have to probe the - * global cache and ameliorates the memory allocation pressure. + * global pool and ameliorates the memory allocation pressure. */ /* XXX: This number is arbitrary---we've never done any measurement of this. */ -- cgit v1.2.3 From 3ec94f9b5917b8f71304c982bd153e5a810f3b12 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 17 Mar 2009 00:53:30 -0400 Subject: Support compiling without fontconfig Adds a new, fake, fontconfig font backend. Fontconfig can be disabled using --disable-fc, in which case the toy text API wont find fonts and the internal font will always be used. Also defines the feature macro CAIRO_HAS_FC_FONT. The two fontconfig-specific functions in cairo-ft.h depend on that macro now. --- boilerplate/Makefile.win32.features | 10 +++++++++ build/Makefile.win32.features | 1 + build/Makefile.win32.features-h | 3 +++ build/configure.ac.features | 1 + configure.ac | 26 ++++++++++++++-------- doc/public/cairo-sections.txt | 1 + doc/public/tmpl/cairo-ft.sgml | 9 ++++++++ doc/public/tmpl/cairo-status.sgml | 2 +- src/Makefile.win32.features | 14 ++++++++++++ src/cairo-ft-font.c | 43 +++++++++++++++++++++++++++++++------ src/cairo-ft.h | 23 +++++++++++++------- src/cairo-os2-surface.c | 6 ++++-- src/cairo-path-fixed.c | 2 +- src/cairo-scaled-font.c | 4 ++-- src/cairo-xlib-display.c | 2 -- src/cairo-xlib-screen.c | 23 +++++++++----------- 16 files changed, 125 insertions(+), 45 deletions(-) diff --git a/boilerplate/Makefile.win32.features b/boilerplate/Makefile.win32.features index f5ee452f..d6d50650 100644 --- a/boilerplate/Makefile.win32.features +++ b/boilerplate/Makefile.win32.features @@ -169,6 +169,16 @@ enabled_cairo_boilerplate_private += $(cairo_boilerplate_ft_private) enabled_cairo_boilerplate_sources += $(cairo_boilerplate_ft_sources) endif +supported_cairo_boilerplate_headers += $(cairo_boilerplate_fc_headers) +all_cairo_boilerplate_headers += $(cairo_boilerplate_fc_headers) +all_cairo_boilerplate_private += $(cairo_boilerplate_fc_private) +all_cairo_boilerplate_sources += $(cairo_boilerplate_fc_sources) +ifeq ($(CAIRO_HAS_FC_FONT),1) +enabled_cairo_boilerplate_headers += $(cairo_boilerplate_fc_headers) +enabled_cairo_boilerplate_private += $(cairo_boilerplate_fc_private) +enabled_cairo_boilerplate_sources += $(cairo_boilerplate_fc_sources) +endif + supported_cairo_boilerplate_headers += $(cairo_boilerplate_ps_headers) all_cairo_boilerplate_headers += $(cairo_boilerplate_ps_headers) all_cairo_boilerplate_private += $(cairo_boilerplate_ps_private) diff --git a/build/Makefile.win32.features b/build/Makefile.win32.features index f90a6ee8..764639ce 100644 --- a/build/Makefile.win32.features +++ b/build/Makefile.win32.features @@ -15,6 +15,7 @@ CAIRO_HAS_GLITZ_SURFACE=0 CAIRO_HAS_DIRECTFB_SURFACE=0 CAIRO_HAS_SCRIPT_SURFACE=0 CAIRO_HAS_FT_FONT=0 +CAIRO_HAS_FC_FONT=0 CAIRO_HAS_PS_SURFACE=1 CAIRO_HAS_PDF_SURFACE=1 CAIRO_HAS_SVG_SURFACE=1 diff --git a/build/Makefile.win32.features-h b/build/Makefile.win32.features-h index a468e307..dcefdbc0 100644 --- a/build/Makefile.win32.features-h +++ b/build/Makefile.win32.features-h @@ -50,6 +50,9 @@ endif ifeq ($(CAIRO_HAS_FT_FONT),1) @echo "#define CAIRO_HAS_FT_FONT 1" >> src/cairo-features.h endif +ifeq ($(CAIRO_HAS_FC_FONT),1) + @echo "#define CAIRO_HAS_FC_FONT 1" >> src/cairo-features.h +endif ifeq ($(CAIRO_HAS_PS_SURFACE),1) @echo "#define CAIRO_HAS_PS_SURFACE 1" >> src/cairo-features.h endif diff --git a/build/configure.ac.features b/build/configure.ac.features index 26dbfb12..2d5fb8a5 100644 --- a/build/configure.ac.features +++ b/build/configure.ac.features @@ -379,6 +379,7 @@ AC_DEFUN([CAIRO_REPORT], echo "The following font backends:" echo " User: yes (always builtin)" echo " FreeType: $use_ft" + echo " Fontconfig: $use_fc" echo " Win32: $use_win32_font" echo " Quartz: $use_quartz_font" echo "" diff --git a/configure.ac b/configure.ac index 48b61b25..d0b69269 100644 --- a/configure.ac +++ b/configure.ac @@ -259,13 +259,6 @@ FREETYPE_MIN_RELEASE=2.1.9 FREETYPE_MIN_VERSION=9.7.3 CAIRO_ENABLE_FONT_BACKEND(ft, FreeType, auto, [ - ft_REQUIRES="fontconfig" - PKG_CHECK_MODULES(FONTCONFIG, $ft_REQUIRES,, - [AC_MSG_RESULT(no); use_ft="no (requires $ft_REQUIRES)"]) - - if test "x$use_ft" = "xyes"; then - - CAIRO_CHECK_FUNCS_WITH_FLAGS(FcFini, [$FONTCONFIG_CFLAGS], [$FONTCONFIG_LIBS]) PKG_CHECK_MODULES(FREETYPE, freetype2 >= $FREETYPE_MIN_VERSION, [freetype_pkgconfig=yes], @@ -293,9 +286,20 @@ CAIRO_ENABLE_FONT_BACKEND(ft, FreeType, auto, [ use_ft="no ($FREETYPE_VERSION found; version $FREETYPE_MIN_VERSION from release $FREETYPE_MIN_RELEASE required)"]) fi fi + + ft_CFLAGS="$FREETYPE_CFLAGS" + ft_LIBS="$FREETYPE_LIBS" +]) + +CAIRO_ENABLE_FONT_BACKEND(fc, Fontconfig, auto, [ + use_fc=$use_ft + if test "x$use_fc" = "xyes"; then + fc_REQUIRES="fontconfig" + PKG_CHECK_MODULES(FONTCONFIG, $fc_REQUIRES,, + [AC_MSG_RESULT(no); use_fc="no (requires $fc_REQUIRES)"]) fi - ft_CFLAGS="$FREETYPE_CFLAGS $FONTCONFIG_CFLAGS" - ft_LIBS="$FREETYPE_LIBS $FONTCONFIG_LIBS" + fc_CFLAGS="$FONTCONFIG_CFLAGS" + fc_LIBS="$FONTCONFIG_LIBS" ]) if test "x$use_ft" = "xyes"; then @@ -317,6 +321,10 @@ if test "x$use_ft" = "xyes"; then CFLAGS="$_save_cflags" fi +if test "x$use_fc" = "xyes"; then + CAIRO_CHECK_FUNCS_WITH_FLAGS(FcFini, [$FONTCONFIG_CFLAGS], [$FONTCONFIG_LIBS]) +fi + dnl =========================================================================== AC_ARG_ENABLE(pthread, diff --git a/doc/public/cairo-sections.txt b/doc/public/cairo-sections.txt index bb64cd68..ff89db71 100644 --- a/doc/public/cairo-sections.txt +++ b/doc/public/cairo-sections.txt @@ -2,6 +2,7 @@ cairo-ft ft-font CAIRO_HAS_FT_FONT +CAIRO_HAS_FC_FONT cairo_ft_font_face_create_for_ft_face cairo_ft_font_face_create_for_pattern cairo_ft_font_options_substitute diff --git a/doc/public/tmpl/cairo-ft.sgml b/doc/public/tmpl/cairo-ft.sgml index 68a3fd43..307d632f 100644 --- a/doc/public/tmpl/cairo-ft.sgml +++ b/doc/public/tmpl/cairo-ft.sgml @@ -28,6 +28,15 @@ This macro can be used to conditionally compile backend-specific code. + + +Defined if the Fontconfig-specific functions of the FreeType font backend +are available. +This macro can be used to conditionally compile backend-specific code. + + + + diff --git a/doc/public/tmpl/cairo-status.sgml b/doc/public/tmpl/cairo-status.sgml index 16b67d25..d2636c65 100644 --- a/doc/public/tmpl/cairo-status.sgml +++ b/doc/public/tmpl/cairo-status.sgml @@ -70,7 +70,7 @@ code is required before or after each individual cairo function call. @CAIRO_STATUS_INVALID_CLUSTERS: @CAIRO_STATUS_INVALID_SLANT: @CAIRO_STATUS_INVALID_WEIGHT: -@CAIRO_STATUS_INVALID_SIZE: +@CAIRO_STATUS_INVALID_SIZE: diff --git a/src/Makefile.win32.features b/src/Makefile.win32.features index 94815d30..bed181fd 100644 --- a/src/Makefile.win32.features +++ b/src/Makefile.win32.features @@ -231,6 +231,20 @@ ifeq ($(CAIRO_HAS_FT_FONT),1) enabled_cairo_pkgconf += cairo-ft.pc endif +supported_cairo_headers += $(cairo_fc_headers) +all_cairo_headers += $(cairo_fc_headers) +all_cairo_private += $(cairo_fc_private) +all_cairo_sources += $(cairo_fc_sources) +ifeq ($(CAIRO_HAS_FC_FONT),1) +enabled_cairo_headers += $(cairo_fc_headers) +enabled_cairo_private += $(cairo_fc_private) +enabled_cairo_sources += $(cairo_fc_sources) +endif +all_cairo_pkgconf += cairo-fc.pc +ifeq ($(CAIRO_HAS_FC_FONT),1) +enabled_cairo_pkgconf += cairo-fc.pc +endif + supported_cairo_headers += $(cairo_ps_headers) all_cairo_headers += $(cairo_ps_headers) all_cairo_private += $(cairo_ps_private) diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index ec6041a2..3cfe344a 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -45,8 +45,10 @@ #include +#if CAIRO_HAS_FC_FONT #include #include +#endif #include #include FT_FREETYPE_H @@ -117,10 +119,6 @@ _cairo_ft_unscaled_font_keys_equal (const void *key_a, static void _cairo_ft_unscaled_font_fini (cairo_ft_unscaled_font_t *unscaled); -static cairo_status_t -_cairo_ft_font_options_substitute (const cairo_font_options_t *options, - FcPattern *pattern); - typedef enum _cairo_ft_extra_flags { CAIRO_FT_OPTIONS_HINT_METRICS = (1 << 0), CAIRO_FT_OPTIONS_EMBOLDEN = (1 << 1) @@ -139,11 +137,18 @@ struct _cairo_ft_font_face { cairo_ft_options_t ft_options; cairo_ft_font_face_t *next; +#if CAIRO_HAS_FC_FONT FcPattern *pattern; /* if pattern is set, the above fields will be NULL */ +#endif }; static const cairo_unscaled_font_backend_t cairo_ft_unscaled_font_backend; +#if CAIRO_HAS_FC_FONT +static cairo_status_t +_cairo_ft_font_options_substitute (const cairo_font_options_t *options, + FcPattern *pattern); + static cairo_status_t _cairo_ft_resolve_pattern (FcPattern *pattern, const cairo_matrix_t *font_matrix, @@ -152,6 +157,7 @@ _cairo_ft_resolve_pattern (FcPattern *pattern, cairo_ft_unscaled_font_t **unscaled, cairo_ft_options_t *ft_options); +#endif /* * We maintain a hash table to map file/id => #cairo_ft_unscaled_font_t. @@ -465,6 +471,7 @@ UNWIND: } +#if CAIRO_HAS_FC_FONT static cairo_ft_unscaled_font_t * _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern) { @@ -486,6 +493,7 @@ _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern) DONE: return _cairo_ft_unscaled_font_create_internal (font_face != NULL, filename, id, font_face); } +#endif static cairo_ft_unscaled_font_t * _cairo_ft_unscaled_font_create_from_face (FT_Face face) @@ -1291,6 +1299,7 @@ typedef struct _cairo_ft_scaled_font { static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend; +#if CAIRO_HAS_FC_FONT /* The load flags passed to FT_Load_Glyph control aspects like hinting and * antialiasing. Here we compute them from the fields of a FcPattern. */ @@ -1426,6 +1435,7 @@ _get_pattern_ft_options (FcPattern *pattern, cairo_ft_options_t *ret) *ret = ft_options; } +#endif static void _cairo_ft_options_merge (cairo_ft_options_t *options, @@ -2044,9 +2054,11 @@ _cairo_ft_ucs4_to_index (void *abstract_font, if (!face) return 0; - /* If making this compile without fontconfig, use: - * index = FT_Get_Char_Index (face, ucs4); */ +#if CAIRO_HAS_FC_FONT index = FcFreeTypeCharIndex (face, ucs4); +#else + index = FT_Get_Char_Index (face, ucs4); +#endif _cairo_ft_unscaled_font_unlock_face (unscaled); return index; @@ -2125,6 +2137,7 @@ static const cairo_scaled_font_backend_t _cairo_ft_scaled_font_backend = { /* #cairo_ft_font_face_t */ +#if CAIRO_HAS_FC_FONT static cairo_status_t _cairo_ft_font_face_create_for_pattern (FcPattern *pattern, cairo_font_face_t **out); @@ -2191,6 +2204,7 @@ _cairo_ft_font_face_create_for_toy (cairo_toy_font_face_t *toy_face, return status; } +#endif static void _cairo_ft_font_face_destroy (void *abstract_face) @@ -2249,8 +2263,10 @@ _cairo_ft_font_face_destroy (void *abstract_face) font_face->unscaled = NULL; } +#if CAIRO_HAS_FC_FONT if (font_face->pattern) FcPatternDestroy (font_face->pattern); +#endif } static cairo_status_t @@ -2274,6 +2290,7 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face, * flags and ignore the options. */ +#if CAIRO_HAS_FC_FONT /* If we have an unresolved pattern, resolve it and create * unscaled font. Otherwise, use the ones stored in font_face. */ @@ -2295,7 +2312,9 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face, return CAIRO_STATUS_SUCCESS; } - } else { + } else +#endif + { unscaled = font_face->unscaled; ft_options = font_face->ft_options; } @@ -2309,11 +2328,16 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face, const cairo_font_face_backend_t _cairo_ft_font_face_backend = { CAIRO_FONT_TYPE_FT, +#if CAIRO_HAS_FC_FONT _cairo_ft_font_face_create_for_toy, +#else + NULL, +#endif _cairo_ft_font_face_destroy, _cairo_ft_font_face_scaled_font_create }; +#if CAIRO_HAS_FC_FONT static cairo_status_t _cairo_ft_font_face_create_for_pattern (FcPattern *pattern, cairo_font_face_t **out) @@ -2338,6 +2362,7 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern, *out = &font_face->base; return CAIRO_STATUS_SUCCESS; } +#endif static cairo_font_face_t * _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, @@ -2378,7 +2403,9 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, font_face->next = unscaled->faces; unscaled->faces = font_face; +#if CAIRO_HAS_FC_FONT font_face->pattern = NULL; +#endif _cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend); @@ -2387,6 +2414,7 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, /* implement the platform-specific interface */ +#if CAIRO_HAS_FC_FONT static cairo_status_t _cairo_ft_font_options_substitute (const cairo_font_options_t *options, FcPattern *pattern) @@ -2633,6 +2661,7 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern) return font_face; } +#endif /** * cairo_ft_font_face_create_for_ft_face: diff --git a/src/cairo-ft.h b/src/cairo-ft.h index 91e2db89..b7178d35 100644 --- a/src/cairo-ft.h +++ b/src/cairo-ft.h @@ -43,18 +43,14 @@ /* Fontconfig/Freetype platform-specific font interface */ -#include #include #include FT_FREETYPE_H -CAIRO_BEGIN_DECLS - -cairo_public cairo_font_face_t * -cairo_ft_font_face_create_for_pattern (FcPattern *pattern); +#if CAIRO_HAS_FC_FONT +#include +#endif -cairo_public void -cairo_ft_font_options_substitute (const cairo_font_options_t *options, - FcPattern *pattern); +CAIRO_BEGIN_DECLS cairo_public cairo_font_face_t * cairo_ft_font_face_create_for_ft_face (FT_Face face, @@ -66,6 +62,17 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *scaled_font); cairo_public void cairo_ft_scaled_font_unlock_face (cairo_scaled_font_t *scaled_font); +#if CAIRO_HAS_FC_FONT + +cairo_public cairo_font_face_t * +cairo_ft_font_face_create_for_pattern (FcPattern *pattern); + +cairo_public void +cairo_ft_font_options_substitute (const cairo_font_options_t *options, + FcPattern *pattern); + +#endif + CAIRO_END_DECLS #else /* CAIRO_HAS_FT_FONT */ diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c index fa678bd2..82bab3be 100644 --- a/src/cairo-os2-surface.c +++ b/src/cairo-os2-surface.c @@ -39,7 +39,9 @@ #include "cairo-os2-private.h" +#if CAIRO_HAS_FC_FONT #include +#endif #include #ifdef BUILD_CAIRO_DLL @@ -101,7 +103,7 @@ cairo_os2_init (void) DisableFPUException (); -#if CAIRO_HAS_FT_FONT +#if CAIRO_HAS_FC_FONT /* Initialize FontConfig */ FcInit (); #endif @@ -132,7 +134,7 @@ cairo_os2_fini (void) cairo_debug_reset_static_data (); -#if CAIRO_HAS_FT_FONT +#if CAIRO_HAS_FC_FONT # if HAVE_FCFINI /* Uninitialize FontConfig */ FcFini (); diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c index 41096f12..a90c317d 100644 --- a/src/cairo-path-fixed.c +++ b/src/cairo-path-fixed.c @@ -1240,7 +1240,7 @@ _cprt_move_to (void *closure, return CAIRO_INT_STATUS_UNSUPPORTED; } -/** +/* * Check whether the given path is representable as a region. * That is, if the path contains only axis aligned lines between * integer coordinates in device space. diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 9acfc43b..249ab6c2 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -2719,8 +2719,8 @@ slim_hidden_def (cairo_scaled_font_get_font_matrix); * * Stores the CTM with which @scaled_font was created into @ctm. * Note that the translation offsets (x0, y0) of the CTM are ignored - * by cairo_scaled_font_create(). So, the matrix this function - * returns always has 0,0 as x0,y0. + * by cairo_scaled_font_create(). So, the matrix this + * function returns always has 0,0 as x0,y0. * * Since: 1.2 **/ diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c index e85174b7..af244abe 100644 --- a/src/cairo-xlib-display.c +++ b/src/cairo-xlib-display.c @@ -38,8 +38,6 @@ #include "cairo-xlib-private.h" #include "cairo-xlib-xrender-private.h" -#include - #include /* For XESetCloseDisplay */ typedef int (*cairo_xlib_error_func_t) (Display *display, diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c index 3b1ae2e1..8f1e9497 100644 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@ -112,7 +112,7 @@ get_integer_default (Display *dpy, v = XGetDefault (dpy, "Xft", option); if (v) { -#if CAIRO_HAS_FT_FONT +#if CAIRO_HAS_FC_FONT if (FcNameConstant ((FcChar8 *) v, value)) return TRUE; #endif @@ -125,7 +125,15 @@ get_integer_default (Display *dpy, return FALSE; } -/* Old versions of fontconfig didn't have these options */ +#ifndef FC_RGBA_UNKNOWN +#define FC_RGBA_UNKNOWN 0 +#define FC_RGBA_RGB 1 +#define FC_RGBA_BGR 2 +#define FC_RGBA_VRGB 3 +#define FC_RGBA_VBGR 4 +#define FC_RGBA_NONE 5 +#endif + #ifndef FC_HINT_NONE #define FC_HINT_NONE 0 #define FC_HINT_SLIGHT 1 @@ -133,17 +141,6 @@ get_integer_default (Display *dpy, #define FC_HINT_FULL 3 #endif -/* Fontconfig version older than 2.6 didn't have these options */ -#ifndef FC_LCD_FILTER -#define FC_LCD_FILTER "lcdfilter" -#endif -/* Some Ubuntu versions defined FC_LCD_FILTER without defining the following */ -#ifndef FC_LCD_NONE -#define FC_LCD_NONE 0 -#define FC_LCD_DEFAULT 1 -#define FC_LCD_LIGHT 2 -#define FC_LCD_LEGACY 3 -#endif static void _cairo_xlib_init_screen_font_options (Display *dpy, -- cgit v1.2.3 From 2b4044a36f8b156ca0e58b72614659324a9b022e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 17 Mar 2009 18:52:16 -0400 Subject: [twin] Update parsed weights and stretches from Pango --- src/cairo-font-face-twin.c | 64 ++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c index 3ced9b02..ca847ce6 100644 --- a/src/cairo-font-face-twin.c +++ b/src/cairo-font-face-twin.c @@ -59,14 +59,17 @@ static cairo_user_data_key_t twin_properties_key; /* CSS weight */ typedef enum { + TWIN_WEIGHT_THIN = 100, TWIN_WEIGHT_ULTRALIGHT = 200, TWIN_WEIGHT_LIGHT = 300, + TWIN_WEIGHT_BOOK = 380, TWIN_WEIGHT_NORMAL = 400, TWIN_WEIGHT_MEDIUM = 500, TWIN_WEIGHT_SEMIBOLD = 600, TWIN_WEIGHT_BOLD = 700, TWIN_WEIGHT_ULTRABOLD = 800, - TWIN_WEIGHT_HEAVY = 900 + TWIN_WEIGHT_HEAVY = 900, + TWIN_WEIGHT_ULTRAHEAVY = 1000 } twin_face_weight_t; /* CSS stretch */ @@ -132,30 +135,41 @@ parse_field (twin_face_properties_t *props, if (0) ; - else MATCH ("oblique", props->slant, CAIRO_FONT_SLANT_OBLIQUE); - else MATCH ("italic", props->slant, CAIRO_FONT_SLANT_ITALIC); - - else MATCH ("ultra-light", props->weight, TWIN_WEIGHT_ULTRALIGHT); - else MATCH ("light", props->weight, TWIN_WEIGHT_LIGHT); - else MATCH ("medium", props->weight, TWIN_WEIGHT_NORMAL); - else MATCH ("semi-bold", props->weight, TWIN_WEIGHT_SEMIBOLD); - else MATCH ("bold", props->weight, TWIN_WEIGHT_BOLD); - else MATCH ("ultra-bold", props->weight, TWIN_WEIGHT_ULTRABOLD); - else MATCH ("heavy", props->weight, TWIN_WEIGHT_HEAVY); - - else MATCH ("ultra-condensed", props->stretch, TWIN_STRETCH_ULTRA_CONDENSED); - else MATCH ("extra-condensed", props->stretch, TWIN_STRETCH_EXTRA_CONDENSED); - else MATCH ("condensed", props->stretch, TWIN_STRETCH_CONDENSED); - else MATCH ("semi-condensed", props->stretch, TWIN_STRETCH_SEMI_CONDENSED); - else MATCH ("semi-expanded", props->stretch, TWIN_STRETCH_SEMI_EXPANDED); - else MATCH ("expanded", props->stretch, TWIN_STRETCH_EXPANDED); - else MATCH ("extra-expanded", props->stretch, TWIN_STRETCH_EXTRA_EXPANDED); - else MATCH ("ultra-expanded", props->stretch, TWIN_STRETCH_ULTRA_EXPANDED); - - else MATCH ("mono", props->monospace, TRUE); - else MATCH ("monospace", props->monospace, TRUE); - - else MATCH ("small-caps", props->smallcaps, TRUE); + else MATCH ("Oblique", props->slant, CAIRO_FONT_SLANT_OBLIQUE); + else MATCH ("Italic", props->slant, CAIRO_FONT_SLANT_ITALIC); + + else MATCH ("Thin", props->weight, TWIN_WEIGHT_THIN); + else MATCH ("Ultra-Light", props->weight, TWIN_WEIGHT_ULTRALIGHT); + else MATCH ("Extra-Light", props->weight, TWIN_WEIGHT_ULTRALIGHT); + else MATCH ("Light", props->weight, TWIN_WEIGHT_LIGHT); + else MATCH ("Book", props->weight, TWIN_WEIGHT_BOOK); + else MATCH ("Regular", props->weight, TWIN_WEIGHT_NORMAL); + else MATCH ("Medium", props->weight, TWIN_WEIGHT_MEDIUM); + else MATCH ("Semi-Bold", props->weight, TWIN_WEIGHT_SEMIBOLD); + else MATCH ("Demi-Bold", props->weight, TWIN_WEIGHT_SEMIBOLD); + else MATCH ("Bold", props->weight, TWIN_WEIGHT_BOLD); + else MATCH ("Ultra-Bold", props->weight, TWIN_WEIGHT_ULTRABOLD); + else MATCH ("Extra-Bold", props->weight, TWIN_WEIGHT_ULTRABOLD); + else MATCH ("Heavy", props->weight, TWIN_WEIGHT_HEAVY); + else MATCH ("Black", props->weight, TWIN_WEIGHT_HEAVY); + else MATCH ("Ultra-Heavy", props->weight, TWIN_WEIGHT_ULTRAHEAVY); + else MATCH ("Extra-Heavy", props->weight, TWIN_WEIGHT_ULTRAHEAVY); + else MATCH ("Ultra-Black", props->weight, TWIN_WEIGHT_ULTRAHEAVY); + else MATCH ("Extra-Black", props->weight, TWIN_WEIGHT_ULTRAHEAVY); + + else MATCH ("Ultra-Condensed", props->stretch, TWIN_STRETCH_ULTRA_CONDENSED); + else MATCH ("Extra-Condensed", props->stretch, TWIN_STRETCH_EXTRA_CONDENSED); + else MATCH ("Condensed", props->stretch, TWIN_STRETCH_CONDENSED); + else MATCH ("Semi-Condensed", props->stretch, TWIN_STRETCH_SEMI_CONDENSED); + else MATCH ("Semi-Expanded", props->stretch, TWIN_STRETCH_SEMI_EXPANDED); + else MATCH ("Expanded", props->stretch, TWIN_STRETCH_EXPANDED); + else MATCH ("Extra-Expanded", props->stretch, TWIN_STRETCH_EXTRA_EXPANDED); + else MATCH ("Ultra-Expanded", props->stretch, TWIN_STRETCH_ULTRA_EXPANDED); + + else MATCH ("Mono", props->monospace, TRUE); + else MATCH ("Monospace", props->monospace, TRUE); + + else MATCH ("Small-Caps", props->smallcaps, TRUE); } static void -- cgit v1.2.3 From 922c108365b940dbabf23358189bbaa8602446c9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 17 Mar 2009 19:22:31 -0400 Subject: [twin] Reorganize matching code to better reflect the code in Pango Makes it easier to update later. --- src/cairo-font-face-twin.c | 179 +++++++++++++++++++++++++++++++++------------ src/cairoint.h | 4 + 2 files changed, 138 insertions(+), 45 deletions(-) diff --git a/src/cairo-font-face-twin.c b/src/cairo-font-face-twin.c index ca847ce6..712ca0dc 100644 --- a/src/cairo-font-face-twin.c +++ b/src/cairo-font-face-twin.c @@ -57,6 +57,8 @@ static cairo_user_data_key_t twin_properties_key; /* We synthesize multiple faces from the twin data. Here is the parameters. */ +/* The following tables and matching code are copied from Pango */ + /* CSS weight */ typedef enum { TWIN_WEIGHT_THIN = 100, @@ -85,6 +87,64 @@ typedef enum { TWIN_STRETCH_ULTRA_EXPANDED } twin_face_stretch_t; +typedef struct +{ + int value; + const char str[16]; +} FieldMap; + +static const FieldMap slant_map[] = { + { CAIRO_FONT_SLANT_NORMAL, "" }, + { CAIRO_FONT_SLANT_NORMAL, "Roman" }, + { CAIRO_FONT_SLANT_OBLIQUE, "Oblique" }, + { CAIRO_FONT_SLANT_ITALIC, "Italic" } +}; + +static const FieldMap smallcaps_map[] = { + { FALSE, "" }, + { TRUE, "Small-Caps" } +}; + +static const FieldMap weight_map[] = { + { TWIN_WEIGHT_THIN, "Thin" }, + { TWIN_WEIGHT_ULTRALIGHT, "Ultra-Light" }, + { TWIN_WEIGHT_ULTRALIGHT, "Extra-Light" }, + { TWIN_WEIGHT_LIGHT, "Light" }, + { TWIN_WEIGHT_BOOK, "Book" }, + { TWIN_WEIGHT_NORMAL, "" }, + { TWIN_WEIGHT_NORMAL, "Regular" }, + { TWIN_WEIGHT_MEDIUM, "Medium" }, + { TWIN_WEIGHT_SEMIBOLD, "Semi-Bold" }, + { TWIN_WEIGHT_SEMIBOLD, "Demi-Bold" }, + { TWIN_WEIGHT_BOLD, "Bold" }, + { TWIN_WEIGHT_ULTRABOLD, "Ultra-Bold" }, + { TWIN_WEIGHT_ULTRABOLD, "Extra-Bold" }, + { TWIN_WEIGHT_HEAVY, "Heavy" }, + { TWIN_WEIGHT_HEAVY, "Black" }, + { TWIN_WEIGHT_ULTRAHEAVY, "Ultra-Heavy" }, + { TWIN_WEIGHT_ULTRAHEAVY, "Extra-Heavy" }, + { TWIN_WEIGHT_ULTRAHEAVY, "Ultra-Black" }, + { TWIN_WEIGHT_ULTRAHEAVY, "Extra-Black" } +}; + +static const FieldMap stretch_map[] = { + { TWIN_STRETCH_ULTRA_CONDENSED, "Ultra-Condensed" }, + { TWIN_STRETCH_EXTRA_CONDENSED, "Extra-Condensed" }, + { TWIN_STRETCH_CONDENSED, "Condensed" }, + { TWIN_STRETCH_SEMI_CONDENSED, "Semi-Condensed" }, + { TWIN_STRETCH_NORMAL, "" }, + { TWIN_STRETCH_SEMI_EXPANDED, "Semi-Expanded" }, + { TWIN_STRETCH_EXPANDED, "Expanded" }, + { TWIN_STRETCH_EXTRA_EXPANDED, "Extra-Expanded" }, + { TWIN_STRETCH_ULTRA_EXPANDED, "Ultra-Expanded" } +}; + +static const FieldMap monospace_map[] = { + { FALSE, "" }, + { TRUE, "Mono" }, + { TRUE, "Monospace" } +}; + typedef struct _twin_face_properties { cairo_font_slant_t slant; @@ -124,52 +184,84 @@ field_matches (const char *s1, return len == 0 && *s1 == '\0'; } +static cairo_bool_t +parse_int (const char *word, + size_t wordlen, + int *out) +{ + char *end; + long val = strtol (word, &end, 10); + int i = val; + + if (end != word && (end == word + wordlen) && val >= 0 && val == i) + { + if (out) + *out = i; + + return TRUE; + } + + return FALSE; +} + +static cairo_bool_t +find_field (const char *what, + const FieldMap *map, + int n_elements, + const char *str, + int len, + int *val) +{ + int i; + cairo_bool_t had_prefix = FALSE; + + if (what) + { + i = strlen (what); + if (len > i && 0 == strncmp (what, str, i) && str[i] == '=') + { + str += i + 1; + len -= i + 1; + had_prefix = TRUE; + } + } + + for (i=0; islant, CAIRO_FONT_SLANT_OBLIQUE); - else MATCH ("Italic", props->slant, CAIRO_FONT_SLANT_ITALIC); - - else MATCH ("Thin", props->weight, TWIN_WEIGHT_THIN); - else MATCH ("Ultra-Light", props->weight, TWIN_WEIGHT_ULTRALIGHT); - else MATCH ("Extra-Light", props->weight, TWIN_WEIGHT_ULTRALIGHT); - else MATCH ("Light", props->weight, TWIN_WEIGHT_LIGHT); - else MATCH ("Book", props->weight, TWIN_WEIGHT_BOOK); - else MATCH ("Regular", props->weight, TWIN_WEIGHT_NORMAL); - else MATCH ("Medium", props->weight, TWIN_WEIGHT_MEDIUM); - else MATCH ("Semi-Bold", props->weight, TWIN_WEIGHT_SEMIBOLD); - else MATCH ("Demi-Bold", props->weight, TWIN_WEIGHT_SEMIBOLD); - else MATCH ("Bold", props->weight, TWIN_WEIGHT_BOLD); - else MATCH ("Ultra-Bold", props->weight, TWIN_WEIGHT_ULTRABOLD); - else MATCH ("Extra-Bold", props->weight, TWIN_WEIGHT_ULTRABOLD); - else MATCH ("Heavy", props->weight, TWIN_WEIGHT_HEAVY); - else MATCH ("Black", props->weight, TWIN_WEIGHT_HEAVY); - else MATCH ("Ultra-Heavy", props->weight, TWIN_WEIGHT_ULTRAHEAVY); - else MATCH ("Extra-Heavy", props->weight, TWIN_WEIGHT_ULTRAHEAVY); - else MATCH ("Ultra-Black", props->weight, TWIN_WEIGHT_ULTRAHEAVY); - else MATCH ("Extra-Black", props->weight, TWIN_WEIGHT_ULTRAHEAVY); - - else MATCH ("Ultra-Condensed", props->stretch, TWIN_STRETCH_ULTRA_CONDENSED); - else MATCH ("Extra-Condensed", props->stretch, TWIN_STRETCH_EXTRA_CONDENSED); - else MATCH ("Condensed", props->stretch, TWIN_STRETCH_CONDENSED); - else MATCH ("Semi-Condensed", props->stretch, TWIN_STRETCH_SEMI_CONDENSED); - else MATCH ("Semi-Expanded", props->stretch, TWIN_STRETCH_SEMI_EXPANDED); - else MATCH ("Expanded", props->stretch, TWIN_STRETCH_EXPANDED); - else MATCH ("Extra-Expanded", props->stretch, TWIN_STRETCH_EXTRA_EXPANDED); - else MATCH ("Ultra-Expanded", props->stretch, TWIN_STRETCH_ULTRA_EXPANDED); - - else MATCH ("Mono", props->monospace, TRUE); - else MATCH ("Monospace", props->monospace, TRUE); - - else MATCH ("Small-Caps", props->smallcaps, TRUE); + if (field_matches ("Normal", str, len)) + return; + +#define FIELD(NAME) \ + if (find_field (STRINGIFY (NAME), NAME##_map, ARRAY_LENGTH (NAME##_map), str, len, \ + (int *)(void *)&props->NAME)) \ + return; \ + + FIELD (weight); + FIELD (slant); + FIELD (stretch); + FIELD (smallcaps); + FIELD (monospace); + +#undef FIELD } static void @@ -178,11 +270,8 @@ face_props_parse (twin_face_properties_t *props, { const char *start, *end; -#define ISALPHA(c) \ - (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) - for (start = end = s; *end; end++) { - if (ISALPHA (*end) || *end == '-') + if (*end != ' ' && *end != ':') continue; if (start < end) diff --git a/src/cairoint.h b/src/cairoint.h index b93c4a44..5c4626a6 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -120,6 +120,10 @@ _cairo_win32_tmpfile (void); #undef ARRAY_LENGTH #define ARRAY_LENGTH(__array) ((int) (sizeof (__array) / sizeof (__array[0]))) +#undef STRINGIFY +#undef STRINGIFY_ARG +#define STRINGIFY(macro_or_string) STRINGIFY_ARG (macro_or_string) +#define STRINGIFY_ARG(contents) #contents /* This has to be updated whenever #cairo_status_t is extended. That's * a bit of a pain, but it should be easy to always catch as long as -- cgit v1.2.3 From 496bbcf58233ceecfffc52ae5b1a3a1f07516c67 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 17 Mar 2009 19:46:25 -0400 Subject: Make CAIRO_STATUS_LAST_STATUS public --- doc/public/tmpl/cairo-status.sgml | 1 + src/cairo.h | 12 ++++++++++-- src/cairoint.h | 6 ------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/doc/public/tmpl/cairo-status.sgml b/doc/public/tmpl/cairo-status.sgml index d2636c65..b74856f7 100644 --- a/doc/public/tmpl/cairo-status.sgml +++ b/doc/public/tmpl/cairo-status.sgml @@ -71,6 +71,7 @@ code is required before or after each individual cairo function call. @CAIRO_STATUS_INVALID_SLANT: @CAIRO_STATUS_INVALID_WEIGHT: @CAIRO_STATUS_INVALID_SIZE: +@_CAIRO_STATUS_LAST_STATUS: diff --git a/src/cairo.h b/src/cairo.h index 6994b304..206861da 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -208,6 +208,7 @@ typedef struct _cairo_user_data_key { /** * cairo_status_t: * @CAIRO_STATUS_SUCCESS: no error has occurred + * * @CAIRO_STATUS_NO_MEMORY: out of memory * @CAIRO_STATUS_INVALID_RESTORE: cairo_restore() called without matching cairo_save() * @CAIRO_STATUS_INVALID_POP_GROUP: no saved group to pop @@ -241,6 +242,11 @@ typedef struct _cairo_user_data_key { * @CAIRO_STATUS_INVALID_WEIGHT: invalid value for an input #cairo_font_weight_t (Since 1.8) * @CAIRO_STATUS_INVALID_SIZE: invalid value (typically too big) for a size (Since 1.10) * + * @CAIRO_STATUS_LAST_STATUS: this is a special value indicating the number of + * status values defined in this enumeration. When using this value, note + * that the version of cairo at run-time may have additional status values + * defined than the value of this symbol at compile-time. (Since 1.10) + * * #cairo_status_t is used to indicate errors that can occur when * using Cairo. In some cases it is returned directly by functions. * but when using #cairo_t, the last error, if any, is stored in @@ -251,6 +257,7 @@ typedef struct _cairo_user_data_key { **/ typedef enum _cairo_status { CAIRO_STATUS_SUCCESS = 0, + CAIRO_STATUS_NO_MEMORY, CAIRO_STATUS_INVALID_RESTORE, CAIRO_STATUS_INVALID_POP_GROUP, @@ -282,8 +289,9 @@ typedef enum _cairo_status { CAIRO_STATUS_INVALID_CLUSTERS, CAIRO_STATUS_INVALID_SLANT, CAIRO_STATUS_INVALID_WEIGHT, - CAIRO_STATUS_INVALID_SIZE - /* after adding a new error: update CAIRO_STATUS_LAST_STATUS in cairoint.h. */ + CAIRO_STATUS_INVALID_SIZE, + + CAIRO_STATUS_LAST_STATUS } cairo_status_t; /** diff --git a/src/cairoint.h b/src/cairoint.h index 5c4626a6..035de287 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -125,12 +125,6 @@ _cairo_win32_tmpfile (void); #define STRINGIFY(macro_or_string) STRINGIFY_ARG (macro_or_string) #define STRINGIFY_ARG(contents) #contents -/* This has to be updated whenever #cairo_status_t is extended. That's - * a bit of a pain, but it should be easy to always catch as long as - * one adds a new test case to test a trigger of the new status value. - */ -#define CAIRO_STATUS_LAST_STATUS CAIRO_STATUS_INVALID_SIZE - #ifdef __GNUC__ #define cairo_container_of(ptr, type, member) ({ \ const typeof(((type *) 0)->member) *mptr__ = (ptr); \ -- cgit v1.2.3 From a4b44ca89eb9975e6af2913e50ec3c3eb566cfdd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Mar 2009 14:56:42 +0000 Subject: [pattern] Report the true error status from getters. As the getters actually return an error status, use it to report any pre-existing error status on the pattern. --- src/cairo-pattern.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index e8b1b23f..bd7e07af 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -2597,6 +2597,9 @@ cairo_pattern_get_rgba (cairo_pattern_t *pattern, cairo_solid_pattern_t *solid = (cairo_solid_pattern_t*) pattern; double r0, g0, b0, a0; + if (pattern->status) + return pattern->status; + if (pattern->type != CAIRO_PATTERN_TYPE_SOLID) return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); @@ -2635,6 +2638,9 @@ cairo_pattern_get_surface (cairo_pattern_t *pattern, { cairo_surface_pattern_t *spat = (cairo_surface_pattern_t*) pattern; + if (pattern->status) + return pattern->status; + if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE) return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); @@ -2673,6 +2679,9 @@ cairo_pattern_get_color_stop_rgba (cairo_pattern_t *pattern, { cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern; + if (pattern->status) + return pattern->status; + if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR && pattern->type != CAIRO_PATTERN_TYPE_RADIAL) return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); @@ -2714,6 +2723,9 @@ cairo_pattern_get_color_stop_count (cairo_pattern_t *pattern, { cairo_gradient_pattern_t *gradient = (cairo_gradient_pattern_t*) pattern; + if (pattern->status) + return pattern->status; + if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR && pattern->type != CAIRO_PATTERN_TYPE_RADIAL) return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); @@ -2747,6 +2759,9 @@ cairo_pattern_get_linear_points (cairo_pattern_t *pattern, { cairo_linear_pattern_t *linear = (cairo_linear_pattern_t*) pattern; + if (pattern->status) + return pattern->status; + if (pattern->type != CAIRO_PATTERN_TYPE_LINEAR) return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); @@ -2788,6 +2803,9 @@ cairo_pattern_get_radial_circles (cairo_pattern_t *pattern, { cairo_radial_pattern_t *radial = (cairo_radial_pattern_t*) pattern; + if (pattern->status) + return pattern->status; + if (pattern->type != CAIRO_PATTERN_TYPE_RADIAL) return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); -- cgit v1.2.3 From dc176d88ac03ae71fc32abb27329a35650801d99 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Mar 2009 10:42:37 +0000 Subject: [test] Trivial leak on error in show-glyphs-many. Free the allocated glyph array after failure. --- test/show-glyphs-many.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/show-glyphs-many.c b/test/show-glyphs-many.c index 497db584..9657e283 100644 --- a/test/show-glyphs-many.c +++ b/test/show-glyphs-many.c @@ -130,7 +130,7 @@ draw (cairo_t *cr, int width, int height) for (utf8 = characters; *utf8 != NULL; utf8++) { status = get_glyph (cr, *utf8, &glyphs[0]); if (status) - return status; + goto BAIL; if (glyphs[0].index) { glyphs[0].x = 1.0; @@ -145,21 +145,22 @@ draw (cairo_t *cr, int width, int height) /* we can pack ~21k 1-byte glyphs into a single XRenderCompositeGlyphs8 */ status = get_glyph (cr, "m", &glyphs[0]); if (status) - return status; + goto BAIL; for (i=1; i < 21500; i++) glyphs[i] = glyphs[0]; /* so check expanding the current 1-byte request for 2-byte glyphs */ status = get_glyph (cr, "μ", &glyphs[i]); if (status) - return status; + goto BAIL; for (j=i+1; j < NUM_GLYPHS; j++) glyphs[j] = glyphs[i]; cairo_show_glyphs (cr, glyphs, NUM_GLYPHS); - + + BAIL: free(glyphs); - return CAIRO_TEST_SUCCESS; + return status; } CAIRO_TEST (show_glyphs_many, -- cgit v1.2.3 From 7db55b37d4aef188e04771b45076f6735507c209 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Mar 2009 11:58:16 +0000 Subject: [test] Destroy pattern on error paths. Destroy the pattern after encountering an error in pattern-getters test. --- test/pattern-getters.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/test/pattern-getters.c b/test/pattern-getters.c index 0b9c86b1..657159c2 100644 --- a/test/pattern-getters.c +++ b/test/pattern-getters.c @@ -27,7 +27,12 @@ #include #include "cairo-test.h" -#define CHECK_SUCCESS do { if (status) return CAIRO_TEST_FAILURE; } while (0) +#define CHECK_SUCCESS do { \ + if (status) { \ + cairo_pattern_destroy (pat); \ + return cairo_test_status_from_status (ctx, status); \ + } \ +} while (0) static int double_buf_equal (const cairo_test_context_t *ctx, double *a, double *b, int nc) @@ -64,6 +69,7 @@ draw (cairo_t *cr, int width, int height) !CAIRO_TEST_DOUBLE_EQUALS(a,0.5)) { cairo_test_log (ctx, "Error: cairo_pattern_get_rgba returned unexepcted results: %g, %g, %g, %g\n", r, g, b, a); + cairo_pattern_destroy (pat); return CAIRO_TEST_FAILURE; } @@ -81,6 +87,7 @@ draw (cairo_t *cr, int width, int height) if (surf != cairo_get_target (cr)) { cairo_test_log (ctx, "Error: cairo_pattern_get_resurface returned wrong surface\n"); + cairo_pattern_destroy (pat); return CAIRO_TEST_FAILURE; } @@ -114,13 +121,18 @@ draw (cairo_t *cr, int width, int height) !CAIRO_TEST_DOUBLE_EQUALS(y0,2.0) || !CAIRO_TEST_DOUBLE_EQUALS(x1,3.0) || !CAIRO_TEST_DOUBLE_EQUALS(y1,4.0)) + { + cairo_pattern_destroy (pat); return CAIRO_TEST_FAILURE; + } status = cairo_pattern_get_color_stop_count (pat, &i); CHECK_SUCCESS; - if (i != 3) + if (i != 3) { + cairo_pattern_destroy (pat); return CAIRO_TEST_FAILURE; + } for (i = 0; i < 3; i++) { status = cairo_pattern_get_color_stop_rgba (pat, i, @@ -133,11 +145,17 @@ draw (cairo_t *cr, int width, int height) } status = cairo_pattern_get_color_stop_rgba (pat, 5, NULL, NULL, NULL, NULL, NULL); - if (status != CAIRO_STATUS_INVALID_INDEX) + if (status != CAIRO_STATUS_INVALID_INDEX) { + cairo_pattern_destroy (pat); return CAIRO_TEST_FAILURE; + } - if (!double_buf_equal (ctx, new_buf, expected_values, sizeof(expected_values)/sizeof(double)) != 0) + if (!double_buf_equal (ctx, new_buf, expected_values, + sizeof(expected_values)/sizeof(double)) != 0) + { + cairo_pattern_destroy (pat); return CAIRO_TEST_FAILURE; + } cairo_pattern_destroy (pat); } @@ -157,7 +175,10 @@ draw (cairo_t *cr, int width, int height) !CAIRO_TEST_DOUBLE_EQUALS(d,4.0) || !CAIRO_TEST_DOUBLE_EQUALS(e,5.0) || !CAIRO_TEST_DOUBLE_EQUALS(f,6.0)) + { + cairo_pattern_destroy (pat); return CAIRO_TEST_FAILURE; + } cairo_pattern_destroy (pat); } -- cgit v1.2.3 From c932a809d6484503d7ee267d934bbc87c8d44092 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Mar 2009 12:01:13 +0000 Subject: [test] Propagate allocation failure. Check for memfaults during rel-path test. --- test/rel-path.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/test/rel-path.c b/test/rel-path.c index 15440013..d1ef2592 100644 --- a/test/rel-path.c +++ b/test/rel-path.c @@ -74,24 +74,37 @@ draw (cairo_t *cr, int width, int height) { const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_status_t status; + cairo_test_status_t result; /* first test that a relative move without a current point fails... */ status = invalid_rel_move_to (cairo_get_target (cr)); if (status != CAIRO_STATUS_NO_CURRENT_POINT) { + result = cairo_test_status_from_status (ctx, status); + if (result == CAIRO_TEST_NO_MEMORY) + return result; + cairo_test_log (ctx, "Error: invalid cairo_rel_move_to() did not raise NO_CURRENT_POINT\n"); - return CAIRO_TEST_FAILURE; + return result; } status = invalid_rel_line_to (cairo_get_target (cr)); if (status != CAIRO_STATUS_NO_CURRENT_POINT) { + result = cairo_test_status_from_status (ctx, status); + if (result == CAIRO_TEST_NO_MEMORY) + return result; + cairo_test_log (ctx, "Error: invalid cairo_rel_line_to() did not raise NO_CURRENT_POINT\n"); - return CAIRO_TEST_FAILURE; + return result; } status = invalid_rel_curve_to (cairo_get_target (cr)); if (status != CAIRO_STATUS_NO_CURRENT_POINT) { + result = cairo_test_status_from_status (ctx, status); + if (result == CAIRO_TEST_NO_MEMORY) + return result; + cairo_test_log (ctx, "Error: invalid cairo_rel_curve_to() did not raise NO_CURRENT_POINT\n"); - return CAIRO_TEST_FAILURE; + return result; } cairo_set_source_rgb (cr, 1, 1, 1); -- cgit v1.2.3 From 86a935de42318c4be92a657ce8e8c452693d4414 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 20 Mar 2009 17:14:08 -0400 Subject: [msvc] Fix definition of CAIRO_ENSURE_UNIQUE for non-x86 The current definition of CAIRO_ENSURE_UNIQUE uses x86 assembly so make sure we only compile it when targeting x86. --- src/cairo-compiler-private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h index f796e138..445ef76b 100644 --- a/src/cairo-compiler-private.h +++ b/src/cairo-compiler-private.h @@ -172,7 +172,7 @@ #define inline __inline #endif -#ifdef _MSC_VER +#if defined(_MSC_VER) && defined(_M_IX86) /* When compiling with /Gy and /OPT:ICF identical functions will be folded in together. The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and will never be folded into another one. Something like this might eventually -- cgit v1.2.3 From 895fce1632069ddfb8c581d2b23b1b3552e35104 Mon Sep 17 00:00:00 2001 From: Stefan Klug Date: Fri, 20 Mar 2009 17:20:22 -0400 Subject: [wince] Use the official _WIN32_WCE define instead of WINCE --- src/cairo-misc.c | 4 ++-- src/cairoint.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cairo-misc.c b/src/cairo-misc.c index ab30327b..a6d4ffae 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -610,7 +610,7 @@ _cairo_lround (double d) #include #include -#if !WINCE +#if !_WIN32_WCE /* tmpfile() replacement for Windows. * * On Windows tmpfile() creates the file in the root directory. This @@ -660,7 +660,7 @@ _cairo_win32_tmpfile (void) return fp; } -#endif /* !WINCE */ +#endif /* !_WIN32_WCE */ #endif /* _WIN32 */ diff --git a/src/cairoint.h b/src/cairoint.h index 035de287..66a9726e 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -85,7 +85,7 @@ CAIRO_BEGIN_DECLS -#if _WIN32 && !WINCE // we don't have to worry about permissions on WINCE +#if _WIN32 && !_WIN32_WCE // we don't have to worry about permissions on WinCE cairo_private FILE * _cairo_win32_tmpfile (void); #define tmpfile() _cairo_win32_tmpfile() -- cgit v1.2.3 From 3b545330887209c68128fca0d1bb40bf4927c2a6 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Sat, 21 Mar 2009 11:56:18 -0700 Subject: [win32] Use _hypot instead of hypot The hypot symbol is deprecated on Win32, and nonexistent on Windows CE --- src/cairo-compiler-private.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cairo-compiler-private.h b/src/cairo-compiler-private.h index 445ef76b..403c3f7a 100644 --- a/src/cairo-compiler-private.h +++ b/src/cairo-compiler-private.h @@ -165,6 +165,7 @@ #define snprintf _snprintf #define popen _popen #define pclose _pclose +#define hypot _hypot #endif #ifdef _MSC_VER -- cgit v1.2.3 From 1a7b94f934f8c9a25e60d9466651b0b7fb919656 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 20 Mar 2009 11:06:29 +0000 Subject: [test] Check for errors during get-path-extents. Need to check that an error was not raised on the context before checking whether the extents match expectations. --- test/get-path-extents.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/get-path-extents.c b/test/get-path-extents.c index ce1bc7c6..96fdfccd 100644 --- a/test/get-path-extents.c +++ b/test/get-path-extents.c @@ -57,6 +57,10 @@ check_extents (const cairo_test_context_t *ctx, break; } + /* ignore results after an error occurs */ + if (cairo_status (cr)) + return 1; + /* let empty rects match */ if ((ext_x1 == ext_x2 || ext_y1 == ext_y2) && (width == 0 || height == 0)) return 1; @@ -106,6 +110,7 @@ draw (cairo_t *cr, int width, int height) const char *phase; const char string[] = "The quick brown fox jumps over the lazy dog."; cairo_text_extents_t extents, scaled_font_extents; + cairo_status_t status; int errors = 0; surface = cairo_surface_create_similar (cairo_get_group_target (cr), @@ -365,8 +370,12 @@ draw (cairo_t *cr, int width, int height) cairo_new_path (cr2); cairo_restore (cr2); + status = cairo_status (cr2); cairo_destroy (cr2); + if (status) + return cairo_test_status_from_status (ctx, status); + return errors == 0 ? CAIRO_TEST_SUCCESS : CAIRO_TEST_FAILURE; } -- cgit v1.2.3 From b5a4a2c4b1b1bab25e2ff0842e3c27205ec73d51 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 22 Mar 2009 19:00:04 +0000 Subject: [test] Early test for memfault. Check the error status within after each iteration in solid-pattern-cache-stress. --- test/solid-pattern-cache-stress.c | 41 ++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/test/solid-pattern-cache-stress.c b/test/solid-pattern-cache-stress.c index ec183fde..285275e1 100644 --- a/test/solid-pattern-cache-stress.c +++ b/test/solid-pattern-cache-stress.c @@ -108,6 +108,9 @@ use_similar (cairo_t *cr, { cairo_t *cr2; + if (cairo_status (cr)) + return; + cr2 = _cairo_create_similar (cr, 1, 1); _draw (cr2, red, green, blue); @@ -125,6 +128,9 @@ use_image (cairo_t *cr, { cairo_t *cr2; + if (cairo_status (cr)) + return; + cr2 = _cairo_create_image (cr, format, 1, 1); _draw (cr2, red, green, blue); @@ -153,23 +159,36 @@ use_solid (cairo_t *cr, static cairo_test_status_t draw (cairo_t *cr, int width, int height) { - int loop; - int i; + const cairo_test_context_t *ctx = cairo_test_get_context (cr); + cairo_status_t status; + const double colors[8][3] = { + { 1.0, 0.0, 0.0 }, /* red */ + { 0.0, 1.0, 0.0 }, /* green */ + { 1.0, 1.0, 0.0 }, /* yellow */ + { 0.0, 0.0, 1.0 }, /* blue */ + { 1.0, 0.0, 1.0 }, /* magenta */ + { 0.0, 1.0, 1.0 }, /* cyan */ + { 1.0, 1.0, 1.0 }, /* white */ + { 0.0, 0.0, 0.0 }, /* black */ + }; + int i, j, loop; for (loop = 0; loop < LOOPS; loop++) { for (i = 0; i < LOOPS; i++) { - use_solid (cr, 0.0, 0.0, 0.0); /* black */ - use_solid (cr, 1.0, 0.0, 0.0); /* red */ - use_solid (cr, 0.0, 1.0, 0.0); /* green */ - use_solid (cr, 1.0, 1.0, 0.0); /* yellow */ - use_solid (cr, 0.0, 0.0, 1.0); /* blue */ - use_solid (cr, 1.0, 0.0, 1.0); /* magenta */ - use_solid (cr, 0.0, 1.0, 1.0); /* cyan */ - use_solid (cr, 1.0, 1.0, 1.0); /* white */ + for (j = 0; j < 8; j++) { + use_solid (cr, colors[j][0], colors[j][1], colors[j][2]); + status = cairo_status (cr); + if (status) + return cairo_test_status_from_status (ctx, status); + } } - for (i = 0; i < NRAND; i++) + for (i = 0; i < NRAND; i++) { use_solid (cr, drand48 (), drand48 (), drand48 ()); + status = cairo_status (cr); + if (status) + return cairo_test_status_from_status (ctx, status); + } } /* stress test only, so clear the surface before comparing */ -- cgit v1.2.3 From ac30ced6135c5cf0fb34a67fe8f863030c1fbeb9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 22 Mar 2009 19:02:27 +0000 Subject: [test] Check for surface create failure. If the image surface creation fails, the data pointer will be NULL leading to a segfault -- so check! --- test/user-font-mask.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/user-font-mask.c b/test/user-font-mask.c index 149f8ee9..6fd40c87 100644 --- a/test/user-font-mask.c +++ b/test/user-font-mask.c @@ -117,6 +117,9 @@ test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, metrics->x_advance = (glyphs[glyph].width + 1) / 8.0; image = cairo_image_surface_create (CAIRO_FORMAT_A1, glyphs[glyph].width, 8); + if (cairo_surface_status (image)) + return cairo_surface_status (image); + data = cairo_image_surface_get_data (image); for (i = 0; i < 8; i++) { byte = glyphs[glyph].data[i]; @@ -125,15 +128,17 @@ test_scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, } pattern = cairo_pattern_create_for_surface (image); + cairo_surface_destroy (image); + cairo_matrix_init_identity (&matrix); cairo_matrix_scale (&matrix, 1.0/8.0, 1.0/8.0); cairo_matrix_translate (&matrix, 0, -8); cairo_matrix_invert (&matrix); cairo_pattern_set_matrix (pattern, &matrix); + cairo_set_source (cr, pattern); cairo_mask (cr, pattern); cairo_pattern_destroy (pattern); - cairo_surface_destroy (image); return CAIRO_STATUS_SUCCESS; } -- cgit v1.2.3 From 578b06a978d51dc3d1d844ee7eea9ddd8329cc8d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 23 Mar 2009 10:56:43 +0000 Subject: [perf] Use CAIRO_LDFLAGS Use CAIRO_LDFLAGS in order to pull in additional link options, such as --coverage. --- perf/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/perf/Makefile.am b/perf/Makefile.am index f4feed05..08f9cc00 100644 --- a/perf/Makefile.am +++ b/perf/Makefile.am @@ -7,6 +7,8 @@ AM_CPPFLAGS = \ -I$(top_builddir)/src \ $(CAIRO_CFLAGS) +AM_LDFLAGS = $(CAIRO_LDFLAGS) + EXTRA_PROGRAMS += cairo-perf \ cairo-perf-diff-files \ cairo-perf-compare-backends \ -- cgit v1.2.3 From 53107de63a954105f8820e5b96e2a1956cb7af8c Mon Sep 17 00:00:00 2001 From: Bertram Felgenhauer Date: Thu, 26 Mar 2009 04:56:27 +0100 Subject: [in_fill] Correctly track current point in curve_to. When discarding a bezier path segment, we still need to update the current point. --- src/cairo-path-in-fill.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cairo-path-in-fill.c b/src/cairo-path-in-fill.c index 21cd0bdb..d43b1caa 100644 --- a/src/cairo-path-in-fill.c +++ b/src/cairo-path-in-fill.c @@ -184,15 +184,19 @@ _cairo_in_fill_curve_to (void *closure, if (c->y > bot) bot = c->y; if (d->y < top) top = d->y; if (d->y > bot) bot = d->y; - if (bot < in_fill->y || top > in_fill->y) + if (bot < in_fill->y || top > in_fill->y) { + in_fill->current_point = *d; return CAIRO_STATUS_SUCCESS; + } left = in_fill->current_point.x; if (b->x < left) left = b->x; if (c->x < left) left = c->x; if (d->x < left) left = d->x; - if (left > in_fill->x) + if (left > in_fill->x) { + in_fill->current_point = *d; return CAIRO_STATUS_SUCCESS; + } /* XXX Investigate direct inspection of the inflections? */ if (! _cairo_spline_init (&spline, -- cgit v1.2.3 From fe10cd6467f2ec58532dc7c713bb6d08dab08442 Mon Sep 17 00:00:00 2001 From: Bertram Felgenhauer Date: Fri, 27 Mar 2009 07:10:21 +0100 Subject: [spline] fix wrong sign in _cairo_spline_bound. --- src/cairo-spline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-spline.c b/src/cairo-spline.c index 948516e1..45eedbd6 100644 --- a/src/cairo-spline.c +++ b/src/cairo-spline.c @@ -289,7 +289,7 @@ _cairo_spline_bound (cairo_spline_add_point_func_t add_point_func, * 0 < (-b±√delta)/a < 1 \ */ \ if (_2ab >= 0) \ - feasible = delta > b2 && delta < a*a + b2 - _2ab; \ + feasible = delta > b2 && delta < a*a + b2 + _2ab; \ else if (-b / a >= 1) \ feasible = delta < b2 && delta > a*a + b2 + _2ab; \ else \ -- cgit v1.2.3 From c2c637cf1d89fc8fdcced4467d602a55ef0b14e0 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Sat, 28 Mar 2009 04:26:10 -0400 Subject: Simplify _cairo_clip_intersect_region() The intermediate intersection region is not necessary because if the operation fails, clip->region will end up as a pixman error region. --- src/cairo-clip.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 9aac1154..9455c288 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -357,23 +357,14 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, if (status) return status; - if (!clip->has_region) { + if (clip->has_region) { + status = _cairo_region_intersect (&clip->region, + &clip->region, + ®ion); + } else { status = _cairo_region_copy (&clip->region, ®ion); if (status == CAIRO_STATUS_SUCCESS) clip->has_region = TRUE; - } else { - cairo_region_t intersection; - - _cairo_region_init (&intersection); - - status = _cairo_region_intersect (&intersection, - &clip->region, - ®ion); - - if (status == CAIRO_STATUS_SUCCESS) - status = _cairo_region_copy (&clip->region, &intersection); - - _cairo_region_fini (&intersection); } clip->serial = _cairo_surface_allocate_clip_serial (target); -- cgit v1.2.3 From e3e1b35eb9eb3cf90d882a7452580f9efe00b89a Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Thu, 11 Dec 2008 15:29:23 -0500 Subject: [region] Make cairo_region_t a malloced object. --- src/cairo-analysis-surface.c | 26 ++++--- src/cairo-clip-private.h | 2 +- src/cairo-clip.c | 99 +++++++++++++------------ src/cairo-region-private.h | 42 +++++------ src/cairo-region.c | 168 ++++++++++++++++++++++++++++++++++--------- src/cairo-surface-fallback.c | 65 ++++++++--------- src/cairo-surface.c | 29 ++++---- src/cairo-traps.c | 14 ++-- src/cairo-xlib-surface.c | 16 ++--- src/cairoint.h | 2 +- 10 files changed, 280 insertions(+), 183 deletions(-) diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index 1be592e9..9c97c111 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -52,8 +52,8 @@ typedef struct { cairo_bool_t has_supported; cairo_bool_t has_unsupported; - cairo_region_t supported_region; - cairo_region_t fallback_region; + cairo_region_t *supported_region; + cairo_region_t *fallback_region; cairo_rectangle_int_t current_clip; cairo_box_t page_bbox; @@ -215,7 +215,7 @@ _add_operation (cairo_analysis_surface_t *surface, * region there is no benefit in emitting a native operation as * the fallback image will be painted on top. */ - if (_cairo_region_contains_rectangle (&surface->fallback_region, rect) == PIXMAN_REGION_IN) + if (_cairo_region_contains_rectangle (surface->fallback_region, rect) == PIXMAN_REGION_IN) return CAIRO_INT_STATUS_IMAGE_FALLBACK; if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) { @@ -226,7 +226,7 @@ _add_operation (cairo_analysis_surface_t *surface, * natively supported and the backend will blend the * transparency into the white background. */ - if (_cairo_region_contains_rectangle (&surface->supported_region, rect) == PIXMAN_REGION_OUT) + if (_cairo_region_contains_rectangle (surface->supported_region, rect) == PIXMAN_REGION_OUT) backend_status = CAIRO_STATUS_SUCCESS; } @@ -235,8 +235,7 @@ _add_operation (cairo_analysis_surface_t *surface, * this region will be emitted as native operations. */ surface->has_supported = TRUE; - status = _cairo_region_union_rect (&surface->supported_region, - &surface->supported_region, + status = _cairo_region_union_rect (surface->supported_region, rect); return status; } @@ -246,8 +245,7 @@ _add_operation (cairo_analysis_surface_t *surface, * emitted. */ surface->has_unsupported = TRUE; - status = _cairo_region_union_rect (&surface->fallback_region, - &surface->fallback_region, + status = _cairo_region_union_rect (surface->fallback_region, rect); /* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate @@ -267,8 +265,8 @@ _cairo_analysis_surface_finish (void *abstract_surface) { cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - _cairo_region_fini (&surface->supported_region); - _cairo_region_fini (&surface->fallback_region); + _cairo_region_destroy (surface->supported_region); + _cairo_region_destroy (surface->fallback_region); cairo_surface_destroy (surface->target); @@ -783,8 +781,8 @@ _cairo_analysis_surface_create (cairo_surface_t *target, surface->page_bbox.p2.x = 0; surface->page_bbox.p2.y = 0; - _cairo_region_init (&surface->supported_region); - _cairo_region_init (&surface->fallback_region); + surface->supported_region = _cairo_region_create (); + surface->fallback_region = _cairo_region_create (); if (width == -1 && height == -1) { surface->current_clip.x = CAIRO_RECT_INT_MIN; @@ -831,7 +829,7 @@ _cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface) { cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - return &surface->supported_region; + return surface->supported_region; } cairo_region_t * @@ -839,7 +837,7 @@ _cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface) { cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - return &surface->fallback_region; + return surface->fallback_region; } cairo_bool_t diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h index 36c0fbdc..517c28cf 100644 --- a/src/cairo-clip-private.h +++ b/src/cairo-clip-private.h @@ -78,7 +78,7 @@ struct _cairo_clip { /* * A clip region that can be placed in the surface */ - cairo_region_t region; + cairo_region_t *region; cairo_bool_t has_region; /* * If the surface supports path clipping, we store the list of diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 9455c288..095af10b 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -64,8 +64,7 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target) clip->serial = 0; - _cairo_region_init (&clip->region); - clip->has_region = FALSE; + clip->region = NULL; clip->path = NULL; } @@ -73,6 +72,8 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target) cairo_status_t _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) { + cairo_status_t status; + clip->mode = other->mode; clip->all_clipped = other->all_clipped; @@ -82,22 +83,25 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) clip->serial = other->serial; - _cairo_region_init (&clip->region); - if (other->has_region) { - cairo_status_t status; - - status = _cairo_region_copy (&clip->region, &other->region); - if (unlikely (status)) { - _cairo_region_fini (&clip->region); - cairo_surface_destroy (clip->surface); - return status; - } clip->has_region = TRUE; + + clip->region = _cairo_region_copy (other->region); } else { clip->has_region = FALSE; + + clip->region = _cairo_region_create (); } + status = _cairo_region_status (clip->region); + if (unlikely (status)) { + cairo_surface_destroy (clip->surface); + _cairo_region_destroy (clip->region); + clip->region = NULL; + + return status; + } + clip->path = _cairo_clip_path_reference (other->path); return CAIRO_STATUS_SUCCESS; @@ -115,11 +119,7 @@ _cairo_clip_reset (cairo_clip_t *clip) clip->serial = 0; if (clip->has_region) { - /* _cairo_region_fini just releases the resources used but - * doesn't bother with leaving the region in a valid state. - * So _cairo_region_init has to be called afterwards. */ - _cairo_region_fini (&clip->region); - _cairo_region_init (&clip->region); + _cairo_region_clear (clip->region); clip->has_region = FALSE; } @@ -178,10 +178,10 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, return status; } - if (clip->has_region) { + if (clip->region) { cairo_rectangle_int_t extents; - _cairo_region_get_extents (&clip->region, &extents); + _cairo_region_get_extents (clip->region, &extents); is_empty = _cairo_rectangle_intersect (rectangle, &extents); if (is_empty) return CAIRO_STATUS_SUCCESS; @@ -194,7 +194,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, } cairo_status_t -_cairo_clip_intersect_to_region (cairo_clip_t *clip, +_cairo_clip_intersect_to_region (cairo_clip_t *clip, cairo_region_t *region) { cairo_status_t status; @@ -203,13 +203,13 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, return CAIRO_STATUS_SUCCESS; if (clip->all_clipped) { - cairo_region_t clip_rect; + cairo_region_t *clip_rect; - _cairo_region_init_rect (&clip_rect, &clip->surface_rect); + clip_rect = _cairo_region_create_rect (&clip->surface_rect); - status = _cairo_region_intersect (region, &clip_rect, region); + status = _cairo_region_intersect (region, clip_rect); - _cairo_region_fini (&clip_rect); + _cairo_region_destroy (clip_rect); return status; } @@ -218,20 +218,20 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, /* Intersect clip path into region. */ } - if (clip->has_region) { - status = _cairo_region_intersect (region, &clip->region, region); + if (clip->region) { + status = _cairo_region_intersect (region, clip->region); if (unlikely (status)) return status; } if (clip->surface) { - cairo_region_t clip_rect; + cairo_region_t *clip_rect; - _cairo_region_init_rect (&clip_rect, &clip->surface_rect); + clip_rect = _cairo_region_create_rect (&clip->surface_rect); - status = _cairo_region_intersect (region, &clip_rect, region); + status = _cairo_region_intersect (region, clip_rect); - _cairo_region_fini (&clip_rect); + _cairo_region_destroy (clip_rect); if (unlikely (status)) return status; @@ -344,7 +344,7 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, cairo_traps_t *traps, cairo_surface_t *target) { - cairo_region_t region; + cairo_region_t *region; cairo_int_status_t status; if (clip->all_clipped) @@ -357,20 +357,19 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, if (status) return status; - if (clip->has_region) { - status = _cairo_region_intersect (&clip->region, - &clip->region, - ®ion); + if (clip->region) { + status = _cairo_region_intersect (clip->region, region); } else { - status = _cairo_region_copy (&clip->region, ®ion); - if (status == CAIRO_STATUS_SUCCESS) - clip->has_region = TRUE; + clip->region = _cairo_region_copy (region); + + if ((status = _cairo_region_status (clip->region))) + clip->region = NULL; } clip->serial = _cairo_surface_allocate_clip_serial (target); - _cairo_region_fini (®ion); + _cairo_region_destroy (region); - if (! _cairo_region_not_empty (&clip->region)) + if (!clip->region || ! _cairo_region_not_empty (clip->region)) _cairo_clip_set_all_clipped (clip, target); return status; @@ -727,8 +726,8 @@ _cairo_clip_translate (cairo_clip_t *clip, if (clip->all_clipped) return; - if (clip->has_region) { - _cairo_region_translate (&clip->region, + if (clip->region) { + _cairo_region_translate (clip->region, _cairo_fixed_integer_part (tx), _cairo_fixed_integer_part (ty)); } @@ -785,9 +784,9 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, /* We should reapply the original clip path in this case, and let * whatever the right handling is happen */ } else { - if (other->has_region) { - status = _cairo_region_copy (&clip->region, &other->region); - if (unlikely (status)) + if (other->region) { + clip->region = _cairo_region_copy (other->region); + if (unlikely ((status = _cairo_region_status (clip->region)))) goto BAIL; clip->has_region = TRUE; @@ -822,8 +821,8 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, return CAIRO_STATUS_SUCCESS; BAIL: - if (clip->has_region) - _cairo_region_fini (&clip->region); + if (clip->region) + _cairo_region_destroy (clip->region); if (clip->surface) cairo_surface_destroy (clip->surface); @@ -874,10 +873,10 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable; } - if (clip->has_region) { + if (clip->region) { int i; - n_boxes = _cairo_region_num_boxes (&clip->region); + n_boxes = _cairo_region_num_boxes (clip->region); if (n_boxes) { rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t)); @@ -890,7 +889,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) cairo_box_int_t box; cairo_rectangle_int_t clip_rect; - _cairo_region_get_box (&clip->region, i, &box); + _cairo_region_get_box (clip->region, i, &box); clip_rect.x = box.p1.x; clip_rect.y = box.p1.y; diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index d969116a..f762fea7 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -47,27 +47,32 @@ CAIRO_BEGIN_DECLS /* #cairo_region_t is defined in cairoint.h */ struct _cairo_region { + cairo_status_t status; + pixman_region32_t rgn; }; -cairo_private void -_cairo_region_init (cairo_region_t *region); +cairo_private cairo_region_t * +_cairo_region_create (void); + +cairo_private cairo_region_t * +_cairo_region_create_rect (cairo_rectangle_int_t *rect); + +cairo_private cairo_status_t +_cairo_region_status (cairo_region_t *region); cairo_private void -_cairo_region_init_rect (cairo_region_t *region, - cairo_rectangle_int_t *rect); +_cairo_region_clear (cairo_region_t *region); -cairo_private cairo_int_status_t -_cairo_region_init_boxes (cairo_region_t *region, - cairo_box_int_t *boxes, - int count); +cairo_private cairo_region_t * +_cairo_region_create_boxes (cairo_box_int_t *boxes, + int count); cairo_private void -_cairo_region_fini (cairo_region_t *region); +_cairo_region_destroy (cairo_region_t *region); -cairo_private cairo_int_status_t -_cairo_region_copy (cairo_region_t *dst, - cairo_region_t *src); +cairo_private cairo_region_t * +_cairo_region_copy (cairo_region_t *original); cairo_private int _cairo_region_num_boxes (cairo_region_t *region); @@ -81,19 +86,16 @@ cairo_private void _cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents); -cairo_private cairo_int_status_t +cairo_private cairo_status_t _cairo_region_subtract (cairo_region_t *dst, - cairo_region_t *a, - cairo_region_t *b); + cairo_region_t *other); -cairo_private cairo_int_status_t +cairo_private cairo_status_t _cairo_region_intersect (cairo_region_t *dst, - cairo_region_t *a, - cairo_region_t *b); + cairo_region_t *other); -cairo_private cairo_int_status_t +cairo_private cairo_status_t _cairo_region_union_rect (cairo_region_t *dst, - cairo_region_t *src, cairo_rectangle_int_t *rect); cairo_private cairo_bool_t diff --git a/src/cairo-region.c b/src/cairo-region.c index d32805e8..804c64d7 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -33,39 +33,68 @@ * Contributor(s): * Owen Taylor * Vladimir Vukicevic + * Søren Sandmann */ #include "cairoint.h" -void -_cairo_region_init (cairo_region_t *region) +const cairo_region_t _cairo_region_nil = { + CAIRO_STATUS_NO_MEMORY, /* status */ +}; + +cairo_region_t * +_cairo_region_create (void) { + cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t)); + + if (!region) + return (cairo_region_t *)&_cairo_region_nil; + + region->status = CAIRO_STATUS_SUCCESS; + pixman_region32_init (®ion->rgn); + + return region; } -void -_cairo_region_init_rect (cairo_region_t *region, - cairo_rectangle_int_t *rect) +cairo_region_t * +_cairo_region_create_rect (cairo_rectangle_int_t *rect) { + cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t)); + + if (!region) + return (cairo_region_t *)&_cairo_region_nil; + + region->status = CAIRO_STATUS_SUCCESS; + pixman_region32_init_rect (®ion->rgn, - rect->x, rect->y, - rect->width, rect->height); + rect->x, rect->y, + rect->width, rect->height); + + return region; } -cairo_int_status_t -_cairo_region_init_boxes (cairo_region_t *region, - cairo_box_int_t *boxes, - int count) +cairo_region_t * +_cairo_region_create_boxes (cairo_box_int_t *boxes, + int count) { pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)]; pixman_box32_t *pboxes = stack_pboxes; - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; + cairo_region_t *region; int i; + region = _cairo_malloc (sizeof (cairo_region_t)); + + if (!region) + return (cairo_region_t *)&_cairo_region_nil; + if (count > ARRAY_LENGTH (stack_pboxes)) { pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t)); - if (unlikely (pboxes == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + if (unlikely (pboxes == NULL)) { + free (region); + return (cairo_region_t *)&_cairo_region_nil; + } } for (i = 0; i < count; i++) { @@ -75,26 +104,45 @@ _cairo_region_init_boxes (cairo_region_t *region, pboxes[i].y2 = boxes[i].p2.y; } - if (! pixman_region32_init_rects (®ion->rgn, pboxes, count)) - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (! pixman_region32_init_rects (®ion->rgn, pboxes, count)) { + free (region); + region = (cairo_region_t *)&_cairo_region_nil; + } + if (pboxes != stack_pboxes) free (pboxes); - return status; + return region; } void -_cairo_region_fini (cairo_region_t *region) +_cairo_region_destroy (cairo_region_t *region) { + if (region->status) + return; + pixman_region32_fini (®ion->rgn); + free (region); } -cairo_int_status_t -_cairo_region_copy (cairo_region_t *dst, cairo_region_t *src) +cairo_region_t * +_cairo_region_copy (cairo_region_t *original) { - if (!pixman_region32_copy (&dst->rgn, &src->rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + cairo_region_t *copy; + + if (original->status) + return (cairo_region_t *)&_cairo_region_nil; + + copy = _cairo_region_create (); + if (!copy) + return (cairo_region_t *)&_cairo_region_nil; + + if (!pixman_region32_copy (©->rgn, &original->rgn)) { + _cairo_region_destroy (copy); + + return (cairo_region_t *)&_cairo_region_nil; + } return CAIRO_STATUS_SUCCESS; } @@ -102,6 +150,9 @@ _cairo_region_copy (cairo_region_t *dst, cairo_region_t *src) int _cairo_region_num_boxes (cairo_region_t *region) { + if (region->status) + return 0; + return pixman_region32_n_rects (®ion->rgn); } @@ -112,6 +163,9 @@ _cairo_region_get_box (cairo_region_t *region, { pixman_box32_t *pbox; + if (region->status) + return; + pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth_box; box->p1.x = pbox->x1; @@ -128,9 +182,15 @@ _cairo_region_get_box (cairo_region_t *region, * Gets the bounding box of a region as a #cairo_rectangle_int_t **/ void -_cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents) +_cairo_region_get_extents (cairo_region_t *region, + cairo_rectangle_int_t *extents) { - pixman_box32_t *pextents = pixman_region32_extents (®ion->rgn); + pixman_box32_t *pextents; + + if (region->status || !extents) + return; + + pextents = pixman_region32_extents (®ion->rgn); extents->x = pextents->x1; extents->y = pextents->y1; @@ -138,33 +198,62 @@ _cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extent extents->height = pextents->y2 - pextents->y1; } -cairo_int_status_t -_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b) +cairo_status_t +_cairo_region_status (cairo_region_t *region) +{ + return region->status; +} + +void +_cairo_region_clear (cairo_region_t *region) +{ + if (region->status) + return; + + pixman_region32_fini (®ion->rgn); + pixman_region32_init (®ion->rgn); +} + +cairo_status_t +_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) { - if (!pixman_region32_subtract (&dst->rgn, &a->rgn, &b->rgn)) + if (dst->status) + return dst->status; + + if (other->status) + return other->status; + + if (!pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } -cairo_int_status_t -_cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b) +cairo_status_t +_cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) { - if (!pixman_region32_intersect (&dst->rgn, &a->rgn, &b->rgn)) + if (dst->status) + return dst->status; + + if (other->status) + return other->status; + + if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, &other->rgn)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } -cairo_int_status_t +cairo_status_t _cairo_region_union_rect (cairo_region_t *dst, - cairo_region_t *src, cairo_rectangle_int_t *rect) { - if (!pixman_region32_union_rect (&dst->rgn, &src->rgn, - rect->x, rect->y, - rect->width, rect->height)) + if (!pixman_region32_union_rect (&dst->rgn, &dst->rgn, + rect->x, rect->y, + rect->width, rect->height)) + { return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } return CAIRO_STATUS_SUCCESS; } @@ -172,6 +261,9 @@ _cairo_region_union_rect (cairo_region_t *dst, cairo_bool_t _cairo_region_not_empty (cairo_region_t *region) { + if (region->status) + return FALSE; + return (cairo_bool_t) pixman_region32_not_empty (®ion->rgn); } @@ -179,6 +271,9 @@ void _cairo_region_translate (cairo_region_t *region, int x, int y) { + if (region->status) + return; + pixman_region32_translate (®ion->rgn, x, y); } @@ -188,6 +283,9 @@ _cairo_region_contains_rectangle (cairo_region_t *region, { pixman_box32_t pbox; + if (region->status) + return PIXMAN_REGION_OUT; + pbox.x1 = rect->x; pbox.y1 = rect->y; pbox.x2 = rect->x + rect->width; diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 7c38cbdf..da2f9438 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -520,10 +520,8 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, cairo_antialias_t antialias) { cairo_status_t status; - cairo_region_t trap_region; - cairo_region_t clear_region; - cairo_bool_t has_trap_region = FALSE; - cairo_bool_t has_clear_region = FALSE; + cairo_region_t *trap_region = NULL; + cairo_region_t *clear_region = NULL; cairo_rectangle_int_t extents; cairo_composite_traps_info_t traps_info; @@ -535,23 +533,18 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, return status; status = _cairo_traps_extract_region (traps, &trap_region); - if (CAIRO_INT_STATUS_UNSUPPORTED == status) { - has_trap_region = FALSE; - } else if (status) { - return status; - } else { - has_trap_region = TRUE; - } + if (status && status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; if (_cairo_operator_bounded_by_mask (op)) { cairo_rectangle_int_t trap_extents; - if (has_trap_region) { - status = _cairo_clip_intersect_to_region (clip, &trap_region); + if (trap_region) { + status = _cairo_clip_intersect_to_region (clip, trap_region); if (unlikely (status)) goto out; - _cairo_region_get_extents (&trap_region, &trap_extents); + _cairo_region_get_extents (trap_region, &trap_extents); } else { cairo_box_t trap_box; _cairo_traps_extents (traps, &trap_box); @@ -569,27 +562,30 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, } else { cairo_surface_t *clip_surface = clip ? clip->surface : NULL; - if (has_trap_region && !clip_surface) { + if (trap_region && !clip_surface) { /* If we optimize drawing with an unbounded operator to * _cairo_surface_fill_rectangles() or to drawing with a * clip region, then we have an additional region to clear. */ - _cairo_region_init_rect (&clear_region, &extents); + clear_region = _cairo_region_create_rect (&extents); + + status = _cairo_region_status (clear_region); + if (unlikely (status)) + goto out; - has_clear_region = TRUE; - status = _cairo_clip_intersect_to_region (clip, &clear_region); + status = _cairo_clip_intersect_to_region (clip, clear_region); if (unlikely (status)) goto out; - _cairo_region_get_extents (&clear_region, &extents); + _cairo_region_get_extents (clear_region, &extents); - status = _cairo_region_subtract (&clear_region, &clear_region, &trap_region); + status = _cairo_region_subtract (clear_region, trap_region); if (unlikely (status)) goto out; - if (!_cairo_region_not_empty (&clear_region)) { - _cairo_region_fini (&clear_region); - has_clear_region = FALSE; + if (!_cairo_region_not_empty (clear_region)) { + _cairo_region_destroy (clear_region); + clear_region = NULL; } } else { status = _cairo_clip_intersect_to_rectangle (clip, &extents); @@ -599,7 +595,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, if (unlikely (status)) goto out; - if (has_trap_region) { + if (trap_region) { cairo_surface_t *clip_surface = clip ? clip->surface : NULL; if ((src->type == CAIRO_PATTERN_TYPE_SOLID || @@ -613,12 +609,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, } /* Solid rectangles special case */ - status = _cairo_surface_fill_region (dst, op, color, &trap_region); + status = _cairo_surface_fill_region (dst, op, color, trap_region); - if (!status && has_clear_region) + if (!status && clear_region) { status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, CAIRO_COLOR_TRANSPARENT, - &clear_region); + clear_region); + } goto out; } @@ -641,13 +638,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, * regions. In that case, we fall through. */ status = _composite_trap_region (clip, src, op, dst, - &trap_region, &extents); + trap_region, &extents); if (status != CAIRO_INT_STATUS_UNSUPPORTED) { - if (!status && has_clear_region) + if (!status && clear_region) status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR, CAIRO_COLOR_TRANSPARENT, - &clear_region); + clear_region); goto out; } } @@ -661,10 +658,10 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, &traps_info, dst, &extents); out: - if (has_trap_region) - _cairo_region_fini (&trap_region); - if (has_clear_region) - _cairo_region_fini (&clear_region); + if (trap_region) + _cairo_region_destroy (trap_region); + if (clear_region) + _cairo_region_destroy (clear_region); return status; } diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 456f8518..22e67f71 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2201,10 +2201,10 @@ _cairo_surface_reset_clip (cairo_surface_t *surface) cairo_status_t _cairo_surface_set_clip_region (cairo_surface_t *surface, cairo_region_t *region, - unsigned int serial) + unsigned int serial) { cairo_status_t status; - + if (surface->status) return surface->status; @@ -2381,7 +2381,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip) if (surface->backend->set_clip_region != NULL) return _cairo_surface_set_clip_region (surface, - &clip->region, + clip->region, clip->serial); } else { if (clip->path) @@ -2391,7 +2391,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip) if (clip->has_region) return _cairo_surface_set_clip_region (surface, - &clip->region, + clip->region, clip->serial); } } @@ -2689,8 +2689,8 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, cairo_rectangle_int_t dst_rectangle; cairo_rectangle_int_t drawn_rectangle; cairo_bool_t has_drawn_region = FALSE; - cairo_region_t drawn_region; - cairo_region_t clear_region; + cairo_region_t *drawn_region = NULL; + cairo_region_t *clear_region = NULL; cairo_status_t status; /* The area that was drawn is the area in the destination rectangle but not within @@ -2700,7 +2700,8 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, dst_rectangle.y = dst_y; dst_rectangle.width = width; dst_rectangle.height = height; - _cairo_region_init_rect (&clear_region, &dst_rectangle); + + clear_region = _cairo_region_create_rect (&dst_rectangle); drawn_rectangle = dst_rectangle; @@ -2716,24 +2717,22 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, /* Now compute the area that is in dst_rectangle but not in drawn_rectangle */ - _cairo_region_init_rect (&drawn_region, &drawn_rectangle); + drawn_region = _cairo_region_create_rect (&drawn_rectangle); has_drawn_region = TRUE; - status = _cairo_region_subtract (&clear_region, - &clear_region, - &drawn_region); + status = _cairo_region_subtract (clear_region, drawn_region); if (unlikely (status)) goto CLEANUP_REGIONS; EMPTY: status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE, CAIRO_COLOR_TRANSPARENT, - &clear_region); + clear_region); CLEANUP_REGIONS: - if (has_drawn_region) - _cairo_region_fini (&drawn_region); - _cairo_region_fini (&clear_region); + if (drawn_region) + _cairo_region_destroy (drawn_region); + _cairo_region_destroy (clear_region); return _cairo_surface_set_error (dst, status); } diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 0afdce23..3b6dedf7 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -608,7 +608,7 @@ _cairo_traps_extents (const cairo_traps_t *traps, **/ cairo_int_status_t _cairo_traps_extract_region (const cairo_traps_t *traps, - cairo_region_t *region) + cairo_region_t **region) { cairo_box_int_t stack_boxes[CAIRO_STACK_ARRAY_LENGTH (cairo_box_int_t)]; cairo_box_int_t *boxes = stack_boxes; @@ -616,7 +616,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, cairo_int_status_t status; if (traps->num_traps == 0) { - _cairo_region_init (region); + *region = _cairo_region_create (); return CAIRO_STATUS_SUCCESS; } @@ -661,13 +661,17 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, box_count++; } - status = _cairo_region_init_boxes (region, boxes, box_count); - + *region = _cairo_region_create_boxes (boxes, box_count); + status = _cairo_region_status (*region); + if (boxes != stack_boxes) free (boxes); if (unlikely (status)) - _cairo_region_fini (region); + { + _cairo_region_destroy (*region); + *region = NULL; + } return status; } diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index f86a133e..e3a1417a 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2293,7 +2293,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, XRectangle *rects = NULL; int n_boxes, i; cairo_rectangle_int_t rect; - cairo_region_t bounded; + cairo_region_t *bounded; rect.x = rect.y = 0; rect.width = surface->width; @@ -2303,19 +2303,19 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, * is necessary so we don't wrap around when we convert cairo's * 32 bit region into 16 bit rectangles. */ - _cairo_region_init_rect (&bounded, &rect); - status = _cairo_region_intersect (&bounded, &bounded, region); + bounded = _cairo_region_create_rect (&rect); + status = _cairo_region_intersect (bounded, region); if (unlikely (status)) { - _cairo_region_fini (&bounded); + _cairo_region_destroy (bounded); return status; } - n_boxes = _cairo_region_num_boxes (&bounded); + n_boxes = _cairo_region_num_boxes (bounded); if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) { rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle)); if (unlikely (rects == NULL)) { - _cairo_region_fini (&bounded); + _cairo_region_destroy (bounded); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } } else { @@ -2325,7 +2325,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, for (i = 0; i < n_boxes; i++) { cairo_box_int_t box; - _cairo_region_get_box (&bounded, i, &box); + _cairo_region_get_box (bounded, i, &box); rects[i].x = box.p1.x; rects[i].y = box.p1.y; @@ -2333,7 +2333,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, rects[i].height = box.p2.y - rects[i].y; } - _cairo_region_fini (&bounded); + _cairo_region_destroy (bounded); surface->have_clip_rects = TRUE; surface->clip_rects = rects; diff --git a/src/cairoint.h b/src/cairoint.h index 66a9726e..30273c22 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2408,7 +2408,7 @@ _cairo_traps_extents (const cairo_traps_t *traps, cairo_private cairo_int_status_t _cairo_traps_extract_region (const cairo_traps_t *tr, - cairo_region_t *region); + cairo_region_t **region); cairo_private cairo_status_t _cairo_traps_path (const cairo_traps_t *traps, -- cgit v1.2.3 From 93b285dc2c9c9ec486e0096933c3611f73374fcb Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Thu, 11 Dec 2008 15:50:15 -0500 Subject: [region] Get rid of clip->has_region --- src/cairo-clip-private.h | 1 - src/cairo-clip.c | 36 +++++++++++++++--------------------- src/cairo-surface.c | 2 +- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h index 517c28cf..b1a9d1af 100644 --- a/src/cairo-clip-private.h +++ b/src/cairo-clip-private.h @@ -79,7 +79,6 @@ struct _cairo_clip { * A clip region that can be placed in the surface */ cairo_region_t *region; - cairo_bool_t has_region; /* * If the surface supports path clipping, we store the list of * clipping paths that has been set here as a linked list. diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 095af10b..75348810 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -72,34 +72,30 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target) cairo_status_t _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) { - cairo_status_t status; - clip->mode = other->mode; clip->all_clipped = other->all_clipped; - + clip->surface = cairo_surface_reference (other->surface); clip->surface_rect = other->surface_rect; clip->serial = other->serial; - if (other->has_region) { - clip->has_region = TRUE; + if (other->region) { + cairo_status_t status; clip->region = _cairo_region_copy (other->region); - } else { - clip->has_region = FALSE; - - clip->region = _cairo_region_create (); - } - status = _cairo_region_status (clip->region); - if (unlikely (status)) { - cairo_surface_destroy (clip->surface); - _cairo_region_destroy (clip->region); + status = _cairo_region_status (clip->region); + if (unlikely (status)) { + cairo_surface_destroy (clip->surface); + _cairo_region_destroy (clip->region); + clip->region = NULL; + + return status; + } + } else { clip->region = NULL; - - return status; } clip->path = _cairo_clip_path_reference (other->path); @@ -118,10 +114,10 @@ _cairo_clip_reset (cairo_clip_t *clip) clip->serial = 0; - if (clip->has_region) { - _cairo_region_clear (clip->region); + if (clip->region) { + _cairo_region_destroy (clip->region); - clip->has_region = FALSE; + clip->region = NULL; } _cairo_clip_path_destroy (clip->path); @@ -788,8 +784,6 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, clip->region = _cairo_region_copy (other->region); if (unlikely ((status = _cairo_region_status (clip->region)))) goto BAIL; - - clip->has_region = TRUE; } if (other->surface) { diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 22e67f71..635575ac 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2389,7 +2389,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip) clip->path, clip->serial); - if (clip->has_region) + if (clip->region) return _cairo_surface_set_clip_region (surface, clip->region, clip->serial); -- cgit v1.2.3 From c88321d0a2b9d200b2044674d02fa0683feca74c Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Thu, 11 Dec 2008 16:20:23 -0500 Subject: [region] Miscellaneous bug fixes. - Initialize region->status in _cairo_region_create_boxes() - Make _cairo_region_copy() actually return a region. - Fix a bug where a NULL region could be dereferenced Also add an assertion that the result of cairo_region_copy() is never NULL. --- src/cairo-clip.c | 2 ++ src/cairo-image-surface.c | 2 +- src/cairo-region.c | 4 +++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 75348810..380949c2 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -357,6 +357,8 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, status = _cairo_region_intersect (clip->region, region); } else { clip->region = _cairo_region_copy (region); + + assert (clip->region != NULL); if ((status = _cairo_region_status (clip->region))) clip->region = NULL; diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index e9e544dc..746fca11 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -1427,7 +1427,7 @@ _cairo_image_surface_set_clip_region (void *abstract_surface, { cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface; - if (! pixman_image_set_clip_region32 (surface->pixman_image, ®ion->rgn)) + if (! pixman_image_set_clip_region32 (surface->pixman_image, region? ®ion->rgn : NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); surface->has_clip = region != NULL; diff --git a/src/cairo-region.c b/src/cairo-region.c index 804c64d7..8224582d 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -88,6 +88,8 @@ _cairo_region_create_boxes (cairo_box_int_t *boxes, if (!region) return (cairo_region_t *)&_cairo_region_nil; + region->status = CAIRO_STATUS_SUCCESS; + if (count > ARRAY_LENGTH (stack_pboxes)) { pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t)); @@ -144,7 +146,7 @@ _cairo_region_copy (cairo_region_t *original) return (cairo_region_t *)&_cairo_region_nil; } - return CAIRO_STATUS_SUCCESS; + return copy; } int -- cgit v1.2.3 From c29aeee2d3569cd43e88adc05662bb6306987b8b Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Thu, 11 Dec 2008 18:37:40 -0500 Subject: [region] Change sense of _cairo_region_not_empty() to _cairo_region_empty() Having "not" in the name causes double negatives. --- src/cairo-clip.c | 2 +- src/cairo-region-private.h | 2 +- src/cairo-region.c | 6 +++--- src/cairo-surface-fallback.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 380949c2..649fa7aa 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -367,7 +367,7 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, clip->serial = _cairo_surface_allocate_clip_serial (target); _cairo_region_destroy (region); - if (!clip->region || ! _cairo_region_not_empty (clip->region)) + if (!clip->region || _cairo_region_empty (clip->region)) _cairo_clip_set_all_clipped (clip, target); return status; diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index f762fea7..8852af37 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -99,7 +99,7 @@ _cairo_region_union_rect (cairo_region_t *dst, cairo_rectangle_int_t *rect); cairo_private cairo_bool_t -_cairo_region_not_empty (cairo_region_t *region); +_cairo_region_empty (cairo_region_t *region); cairo_private void _cairo_region_translate (cairo_region_t *region, diff --git a/src/cairo-region.c b/src/cairo-region.c index 8224582d..1d5de7ce 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -261,12 +261,12 @@ _cairo_region_union_rect (cairo_region_t *dst, } cairo_bool_t -_cairo_region_not_empty (cairo_region_t *region) +_cairo_region_empty (cairo_region_t *region) { if (region->status) - return FALSE; + return TRUE; - return (cairo_bool_t) pixman_region32_not_empty (®ion->rgn); + return !pixman_region32_not_empty (®ion->rgn); } void diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index da2f9438..d41c645a 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -583,7 +583,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, if (unlikely (status)) goto out; - if (!_cairo_region_not_empty (clear_region)) { + if (_cairo_region_empty (clear_region)) { _cairo_region_destroy (clear_region); clear_region = NULL; } -- cgit v1.2.3 From ebd0e685ae2d76c3af96d748a33a7194c70749f3 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Mon, 16 Feb 2009 05:41:31 -0500 Subject: [region] Consistently use rectangles in the API of regions Usually, rectangles are more useful than boxes, so regions should only expose rectangles in their public API. Specifically, _cairo_region_num_boxes becomes _cairo_region_num_rectangles _cairo_region_get_box becomes _cairo_region_get_rectangle Remove the cairo_box_int_t type --- src/cairo-clip.c | 22 ++++++++------------ src/cairo-directfb-surface.c | 26 +++++++++++------------ src/cairo-paginated-surface.c | 34 +++++++++++++++--------------- src/cairo-region-private.h | 14 ++++++------- src/cairo-region.c | 28 ++++++++++++------------- src/cairo-surface-fallback.c | 2 +- src/cairo-surface.c | 25 ++++++++-------------- src/cairo-traps.c | 31 ++++++++++++++-------------- src/cairo-types-private.h | 6 ------ src/cairo-win32-surface.c | 48 +++++++++++++++++++++---------------------- src/cairo-xcb-surface.c | 24 +++++++++++----------- src/cairo-xlib-surface.c | 29 +++++++++++++------------- 12 files changed, 134 insertions(+), 155 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 649fa7aa..4ca3e9aa 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -859,7 +859,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) { cairo_rectangle_list_t *list; cairo_rectangle_t *rectangles = NULL; - int n_boxes = 0; + int n_rects = 0; if (clip->all_clipped) goto DONE; @@ -872,25 +872,19 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) if (clip->region) { int i; - n_boxes = _cairo_region_num_boxes (clip->region); + n_rects = _cairo_region_num_rectangles (clip->region); - if (n_boxes) { - rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t)); + if (n_rects) { + rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t)); if (unlikely (rectangles == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; } - for (i = 0; i < n_boxes; ++i) { - cairo_box_int_t box; + for (i = 0; i < n_rects; ++i) { cairo_rectangle_int_t clip_rect; - _cairo_region_get_box (clip->region, i, &box); - - clip_rect.x = box.p1.x; - clip_rect.y = box.p1.y; - clip_rect.width = box.p2.x - box.p1.x; - clip_rect.height = box.p2.y - box.p1.y; + _cairo_region_get_rectangle (clip->region, i, &clip_rect); if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) { _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); @@ -902,7 +896,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) } else { cairo_rectangle_int_t extents; - n_boxes = 1; + n_rects = 1; rectangles = malloc(sizeof (cairo_rectangle_t)); if (unlikely (rectangles == NULL)) { @@ -929,7 +923,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) list->status = CAIRO_STATUS_SUCCESS; list->rectangles = rectangles; - list->num_rectangles = n_boxes; + list->num_rectangles = n_rects; return list; } diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c index b902cca1..3873f3e9 100644 --- a/src/cairo-directfb-surface.c +++ b/src/cairo-directfb-surface.c @@ -1299,39 +1299,39 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface, __FUNCTION__, surface, region); if (region) { - int n_boxes; + int n_rects; cairo_status_t status; int i; surface->has_clip = TRUE; - n_boxes = _cairo_region_num_boxes (region); + n_rects = _cairo_region_num_rectangles (region); - if (n_boxes == 0) + if (n_rects == 0) return CAIRO_STATUS_SUCCESS; - if (surface->n_clips != n_boxes) { + if (surface->n_clips != n_rects) { if (surface->clips) free (surface->clips); - surface->clips = _cairo_malloc_ab (n_boxes, sizeof (DFBRegion)); + surface->clips = _cairo_malloc_ab (n_rects, sizeof (DFBRegion)); if (!surface->clips) { surface->n_clips = 0; return _cairo_error (CAIRO_STATUS_NO_MEMORY); } - surface->n_clips = n_boxes; + surface->n_clips = n_rects; } - for (i = 0; i < n_boxes; i++) { - cairo_box_int_t box; + for (i = 0; i < n_rects; i++) { + cairo_rectangle_int_t rect; - _cairo_region_get_box (region, i, &box); + _cairo_region_get_rectangle (region, i, &rect); - surface->clips[i].x1 = box.p1.x; - surface->clips[i].y1 = box.p1.y; - surface->clips[i].x2 = box.p2.x - 1; - surface->clips[i].y2 = box.p2.y - 1; + surface->clips[i].x1 = rect.x; + surface->clips[i].y1 = rect.y; + surface->clips[i].x2 = rect.x + rect.width - 1; + surface->clips[i].y2 = rect.y + rect.height - 1; } } else { surface->has_clip = FALSE; diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index 8c62644a..cc09b59c 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -244,7 +244,7 @@ _cairo_paginated_surface_release_source_image (void *abstract_surface, static cairo_int_status_t _paint_fallback_image (cairo_paginated_surface_t *surface, - cairo_box_int_t *box) + cairo_rectangle_int_t *rect) { double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution; double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution; @@ -254,10 +254,10 @@ _paint_fallback_image (cairo_paginated_surface_t *surface, cairo_surface_t *image; cairo_surface_pattern_t pattern; - x = box->p1.x; - y = box->p1.y; - width = box->p2.x - x; - height = box->p2.y - y; + x = rect->x; + y = rect->y; + width = rect->width; + height = rect->height; image = _cairo_paginated_surface_create_image_surface (surface, ceil (width * x_scale), ceil (height * y_scale)); @@ -365,23 +365,23 @@ _paint_page (cairo_paginated_surface_t *surface) } if (has_page_fallback) { - cairo_box_int_t box; + cairo_rectangle_int_t rect; surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_FALLBACK); - box.p1.x = 0; - box.p1.y = 0; - box.p2.x = surface->width; - box.p2.y = surface->height; - status = _paint_fallback_image (surface, &box); + rect.x = 0; + rect.y = 0; + rect.width = surface->width; + rect.height = surface->height; + status = _paint_fallback_image (surface, &rect); if (unlikely (status)) goto FAIL; } if (has_finegrained_fallback) { cairo_region_t *region; - int num_boxes, i; + int num_rects, i; surface->backend->set_paginated_mode (surface->target, CAIRO_PAGINATED_MODE_FALLBACK); @@ -397,13 +397,13 @@ _paint_page (cairo_paginated_surface_t *surface) region = _cairo_analysis_surface_get_unsupported (analysis); - num_boxes = _cairo_region_num_boxes (region); - for (i = 0; i < num_boxes; i++) { - cairo_box_int_t box; + num_rects = _cairo_region_num_rectangles (region); + for (i = 0; i < num_rects; i++) { + cairo_rectangle_int_t rect; - _cairo_region_get_box (region, i, &box); + _cairo_region_get_rectangle (region, i, &rect); - status = _paint_fallback_image (surface, &box); + status = _paint_fallback_image (surface, &rect); if (unlikely (status)) goto FAIL; diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index 8852af37..5a93ebd2 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -65,8 +65,8 @@ cairo_private void _cairo_region_clear (cairo_region_t *region); cairo_private cairo_region_t * -_cairo_region_create_boxes (cairo_box_int_t *boxes, - int count); +_cairo_region_create_rectangles (cairo_rectangle_int_t *rects, + int count); cairo_private void _cairo_region_destroy (cairo_region_t *region); @@ -75,12 +75,12 @@ cairo_private cairo_region_t * _cairo_region_copy (cairo_region_t *original); cairo_private int -_cairo_region_num_boxes (cairo_region_t *region); +_cairo_region_num_rectangles (cairo_region_t *region); cairo_private void -_cairo_region_get_box (cairo_region_t *region, - int nth_box, - cairo_box_int_t *box); +_cairo_region_get_rectangle (cairo_region_t *region, + int nth_rectangle, + cairo_rectangle_int_t *rectangle); cairo_private void _cairo_region_get_extents (cairo_region_t *region, @@ -107,7 +107,7 @@ _cairo_region_translate (cairo_region_t *region, cairo_private pixman_region_overlap_t _cairo_region_contains_rectangle (cairo_region_t *region, - const cairo_rectangle_int_t *box); + const cairo_rectangle_int_t *rect); CAIRO_END_DECLS diff --git a/src/cairo-region.c b/src/cairo-region.c index 1d5de7ce..5f53bc92 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -75,8 +75,8 @@ _cairo_region_create_rect (cairo_rectangle_int_t *rect) } cairo_region_t * -_cairo_region_create_boxes (cairo_box_int_t *boxes, - int count) +_cairo_region_create_rectangles (cairo_rectangle_int_t *rects, + int count) { pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)]; pixman_box32_t *pboxes = stack_pboxes; @@ -100,10 +100,10 @@ _cairo_region_create_boxes (cairo_box_int_t *boxes, } for (i = 0; i < count; i++) { - pboxes[i].x1 = boxes[i].p1.x; - pboxes[i].y1 = boxes[i].p1.y; - pboxes[i].x2 = boxes[i].p2.x; - pboxes[i].y2 = boxes[i].p2.y; + pboxes[i].x1 = rects[i].x; + pboxes[i].y1 = rects[i].y; + pboxes[i].x2 = rects[i].x + rects[i].width; + pboxes[i].y2 = rects[i].y + rects[i].height; } if (! pixman_region32_init_rects (®ion->rgn, pboxes, count)) { @@ -150,7 +150,7 @@ _cairo_region_copy (cairo_region_t *original) } int -_cairo_region_num_boxes (cairo_region_t *region) +_cairo_region_num_rectangles (cairo_region_t *region) { if (region->status) return 0; @@ -159,9 +159,9 @@ _cairo_region_num_boxes (cairo_region_t *region) } cairo_private void -_cairo_region_get_box (cairo_region_t *region, - int nth_box, - cairo_box_int_t *box) +_cairo_region_get_rectangle (cairo_region_t *region, + int nth_box, + cairo_rectangle_int_t *rect) { pixman_box32_t *pbox; @@ -170,10 +170,10 @@ _cairo_region_get_box (cairo_region_t *region, pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth_box; - box->p1.x = pbox->x1; - box->p1.y = pbox->y1; - box->p2.x = pbox->x2; - box->p2.y = pbox->y2; + rect->x = pbox->x1; + rect->y = pbox->y1; + rect->width = pbox->x2 - pbox->x1; + rect->height = pbox->y2 - pbox->y1; } /** diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index d41c645a..876268f5 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -417,7 +417,7 @@ _composite_trap_region (cairo_clip_t *clip, cairo_status_t status; cairo_solid_pattern_t solid_pattern; cairo_surface_pattern_t mask; - int num_rects = _cairo_region_num_boxes (trap_region); + int num_rects = _cairo_region_num_rectangles (trap_region); unsigned int clip_serial; cairo_surface_t *clip_surface = clip ? clip->surface : NULL; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 635575ac..42fc6da8 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1570,14 +1570,13 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface, * * Return value: %CAIRO_STATUS_SUCCESS or the error that occurred **/ -COMPILE_TIME_ASSERT (sizeof (cairo_box_int_t) <= sizeof (cairo_rectangle_int_t)); cairo_status_t _cairo_surface_fill_region (cairo_surface_t *surface, cairo_operator_t op, const cairo_color_t *color, cairo_region_t *region) { - int num_boxes; + int num_rects; cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; cairo_rectangle_int_t *rects = stack_rects; cairo_status_t status; @@ -1588,12 +1587,12 @@ _cairo_surface_fill_region (cairo_surface_t *surface, assert (! surface->is_snapshot); - num_boxes = _cairo_region_num_boxes (region); - if (num_boxes == 0) + num_rects = _cairo_region_num_rectangles (region); + if (num_rects == 0) return CAIRO_STATUS_SUCCESS; - if (num_boxes > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (num_boxes, + if (num_rects > ARRAY_LENGTH (stack_rects)) { + rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t)); if (rects == NULL) { return _cairo_surface_set_error (surface, @@ -1601,19 +1600,11 @@ _cairo_surface_fill_region (cairo_surface_t *surface, } } - for (i = 0; i < num_boxes; i++) { - cairo_box_int_t box; - - _cairo_region_get_box (region, i, &box); - - rects[i].x = box.p1.x; - rects[i].y = box.p1.y; - rects[i].width = box.p2.x - rects[i].x; - rects[i].height = box.p2.y - rects[i].y; - } + for (i = 0; i < num_rects; i++) + _cairo_region_get_rectangle (region, i, &rects[i]); status = _cairo_surface_fill_rectangles (surface, op, - color, rects, num_boxes); + color, rects, num_rects); if (rects != stack_rects) free (rects); diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 3b6dedf7..96db4ba1 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -610,9 +610,9 @@ cairo_int_status_t _cairo_traps_extract_region (const cairo_traps_t *traps, cairo_region_t **region) { - cairo_box_int_t stack_boxes[CAIRO_STACK_ARRAY_LENGTH (cairo_box_int_t)]; - cairo_box_int_t *boxes = stack_boxes; - int i, box_count; + cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; + cairo_rectangle_int_t *rects = stack_rects; + int i, rect_count; cairo_int_status_t status; if (traps->num_traps == 0) { @@ -632,14 +632,15 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, } } - if (traps->num_traps > ARRAY_LENGTH (stack_boxes)) { - boxes = _cairo_malloc_ab (traps->num_traps, sizeof (cairo_box_int_t)); + if (traps->num_traps > ARRAY_LENGTH (stack_rects)) { + rects = _cairo_malloc_ab (traps->num_traps, + sizeof (cairo_rectangle_int_t)); - if (unlikely (boxes == NULL)) + if (unlikely (rects == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } - box_count = 0; + rect_count = 0; for (i = 0; i < traps->num_traps; i++) { int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x); @@ -653,19 +654,19 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, if (x1 == x2 || y1 == y2) continue; - boxes[box_count].p1.x = x1; - boxes[box_count].p1.y = y1; - boxes[box_count].p2.x = x2; - boxes[box_count].p2.y = y2; + rects[rect_count].x = x1; + rects[rect_count].y = y1; + rects[rect_count].width = x2 - x1; + rects[rect_count].height = y2 - y1; - box_count++; + rect_count++; } - *region = _cairo_region_create_boxes (boxes, box_count); + *region = _cairo_region_create_rectangles (rects, rect_count); status = _cairo_region_status (*region); - if (boxes != stack_boxes) - free (boxes); + if (rects != stack_rects) + free (rects); if (unlikely (status)) { diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index 0a3ec2e4..e8cf4b1f 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -250,12 +250,6 @@ typedef struct _cairo_point_int32 cairo_point_int_t; #error Not sure how to pick a cairo_rectangle_int_t and cairo_point_int_t for your CAIRO_FIXED_BITS! #endif -typedef struct _cairo_box_int { - cairo_point_int_t p1; - cairo_point_int_t p2; -} cairo_box_int_t; - - /* Rectangles that take part in a composite operation. * * This defines four translations that define which pixels of the diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index f0c7aa2c..f182642f 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -1461,36 +1461,36 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, /* Then combine any new region with it */ if (region) { cairo_rectangle_int_t extents; - int num_boxes; + int num_rects; RGNDATA *data; size_t data_size; RECT *rects; int i; HRGN gdi_region; - cairo_box_int_t box0; + cairo_rectangle_int_t rect0; /* Create a GDI region for the cairo region */ _cairo_region_get_extents (region, &extents); - num_boxes = _cairo_region_num_boxes (region); + num_rects = _cairo_region_num_rectangles (region); - if (num_boxes == 1) - _cairo_region_get_box (region, 0, &box0); + if (num_rects == 1) + _cairo_region_get_rectangle (region, 0, &rect0); - if (num_boxes == 1 && - box0.p1.x == 0 && - box0.p1.y == 0 && - box0.p2.x == surface->extents.width && - box0.p2.y == surface->extents.height) + if (num_rects == 1 && + rect0.x == 0 && + rect0.y == 0 && + rect0.width == surface->extents.width && + rect0.width == surface->extents.height) { gdi_region = NULL; SelectClipRgn (surface->dc, NULL); IntersectClipRect (surface->dc, - box0.p1.x, - box0.p1.y, - box0.p2.x, - box0.p2.y); + rect0.x, + rect0.y, + rect0.x + rect0.width, + rect0.y + rect0.height); } else { /* XXX see notes in _cairo_win32_save_initial_clip -- * this code will interact badly with a HDC which had an initial @@ -1499,7 +1499,7 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, * logical units (unlike IntersectClipRect). */ - data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT); + data_size = sizeof (RGNDATAHEADER) + num_rects * sizeof (RECT); data = malloc (data_size); if (!data) return _cairo_error(CAIRO_STATUS_NO_MEMORY); @@ -1507,22 +1507,22 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, data->rdh.dwSize = sizeof (RGNDATAHEADER); data->rdh.iType = RDH_RECTANGLES; - data->rdh.nCount = num_boxes; - data->rdh.nRgnSize = num_boxes * sizeof (RECT); + data->rdh.nCount = num_rects; + data->rdh.nRgnSize = num_rects * sizeof (RECT); data->rdh.rcBound.left = extents.x; data->rdh.rcBound.top = extents.y; data->rdh.rcBound.right = extents.x + extents.width; data->rdh.rcBound.bottom = extents.y + extents.height; - for (i = 0; i < num_boxes; i++) { - cairo_box_int_t box; + for (i = 0; i < num_rects; i++) { + cairo_rectangle_int_t rect; - _cairo_region_get_box (region, i, &box); + _cairo_region_get_rectangle (region, i, &rect); - rects[i].left = box.p1.x; - rects[i].top = box.p1.y; - rects[i].right = box.p2.x; - rects[i].bottom = box.p2.y; + rects[i].left = rect.x; + rects[i].top = rect.y; + rects[i].right = rect.x + rect.width; + rects[i].bottom = rect.y + rect.height; } gdi_region = ExtCreateRegion (NULL, data_size, data); diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index 17a09e3f..ab589e1d 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -1557,32 +1557,32 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface, } else { cairo_status_t status; xcb_rectangle_t *rects = NULL; - int n_boxes, i; + int n_rects, i; - n_boxes = _cairo_region_num_boxes (region); + n_rects = _cairo_region_num_rectangles (region); - if (n_boxes > 0) { - rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t)); + if (n_rects > 0) { + rects = _cairo_malloc_ab (n_rects, sizeof(xcb_rectangle_t)); if (rects == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } else { rects = NULL; } - for (i = 0; i < n_boxes; i++) { - cairo_box_int_t box; + for (i = 0; i < n_rects; i++) { + cairo_rectangle_int_t rect; - _cairo_region_get_box (region, i, &box); + _cairo_region_get_rectangle (region, i, &rect); - rects[i].x = box.p1.x; - rects[i].y = box.p1.y; - rects[i].width = box.p2.x - box.p1.x; - rects[i].height = box.p2.y - box.p1.y; + rects[i].x = rect.x; + rects[i].y = rect.y; + rects[i].width = rect.width; + rects[i].height = rect.height; } surface->have_clip_rects = TRUE; surface->clip_rects = rects; - surface->num_clip_rects = n_boxes; + surface->num_clip_rects = n_rects; if (surface->gc) _cairo_xcb_surface_set_gc_clip_rects (surface); diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index e3a1417a..e411977b 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2269,7 +2269,6 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, return status; } -COMPILE_TIME_ASSERT (sizeof (XRectangle) <= sizeof (cairo_box_int_t)); static cairo_int_status_t _cairo_xlib_surface_set_clip_region (void *abstract_surface, cairo_region_t *region) @@ -2291,7 +2290,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, if (region != NULL) { cairo_status_t status; XRectangle *rects = NULL; - int n_boxes, i; + int n_rects, i; cairo_rectangle_int_t rect; cairo_region_t *bounded; @@ -2310,10 +2309,10 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, return status; } - n_boxes = _cairo_region_num_boxes (bounded); + n_rects = _cairo_region_num_rectangles (bounded); - if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) { - rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle)); + if (n_rects > ARRAY_LENGTH (surface->embedded_clip_rects)) { + rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle)); if (unlikely (rects == NULL)) { _cairo_region_destroy (bounded); return _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -2322,25 +2321,25 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, rects = surface->embedded_clip_rects; } - for (i = 0; i < n_boxes; i++) { - cairo_box_int_t box; + for (i = 0; i < n_rects; i++) { + cairo_rectangle_int_t rect; + + _cairo_region_get_rectangle (bounded, i, &rect); - _cairo_region_get_box (bounded, i, &box); - - rects[i].x = box.p1.x; - rects[i].y = box.p1.y; - rects[i].width = box.p2.x - rects[i].x; - rects[i].height = box.p2.y - rects[i].y; + rects[i].x = rect.x; + rects[i].y = rect.y; + rects[i].width = rect.width; + rects[i].height = rect.height; } _cairo_region_destroy (bounded); surface->have_clip_rects = TRUE; surface->clip_rects = rects; - surface->num_clip_rects = n_boxes; + surface->num_clip_rects = n_rects; /* Discard the trivial clip rectangle that covers the entire surface */ - if (n_boxes == 1 && + if (n_rects == 1 && rects[0].x == 0 && rects[0].y == 0 && rects[0].width == surface->width && -- cgit v1.2.3 From df883aa937d2f3ecf52048b60caff48b1c9edac9 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Tue, 17 Feb 2009 06:06:40 -0500 Subject: [region] Add a cairo_region_overlap_t type --- src/cairo-analysis-surface.c | 4 ++-- src/cairo-region-private.h | 8 +++++++- src/cairo-region.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index 9c97c111..eaa7947e 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -215,7 +215,7 @@ _add_operation (cairo_analysis_surface_t *surface, * region there is no benefit in emitting a native operation as * the fallback image will be painted on top. */ - if (_cairo_region_contains_rectangle (surface->fallback_region, rect) == PIXMAN_REGION_IN) + if (_cairo_region_contains_rectangle (surface->fallback_region, rect) == CAIRO_REGION_OVERLAP_IN) return CAIRO_INT_STATUS_IMAGE_FALLBACK; if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) { @@ -226,7 +226,7 @@ _add_operation (cairo_analysis_surface_t *surface, * natively supported and the backend will blend the * transparency into the white background. */ - if (_cairo_region_contains_rectangle (surface->supported_region, rect) == PIXMAN_REGION_OUT) + if (_cairo_region_contains_rectangle (surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT) backend_status = CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index 5a93ebd2..450b0864 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -52,6 +52,12 @@ struct _cairo_region { pixman_region32_t rgn; }; +typedef enum _cairo_region_overlap { + CAIRO_REGION_OVERLAP_IN, /* completely inside region */ + CAIRO_REGION_OVERLAP_OUT, /* completely outside region */ + CAIRO_REGION_OVERLAP_PART, /* partly inside region */ +} cairo_region_overlap_t; + cairo_private cairo_region_t * _cairo_region_create (void); @@ -105,7 +111,7 @@ cairo_private void _cairo_region_translate (cairo_region_t *region, int x, int y); -cairo_private pixman_region_overlap_t +cairo_private cairo_region_overlap_t _cairo_region_contains_rectangle (cairo_region_t *region, const cairo_rectangle_int_t *rect); diff --git a/src/cairo-region.c b/src/cairo-region.c index 5f53bc92..b951e634 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -279,19 +279,34 @@ _cairo_region_translate (cairo_region_t *region, pixman_region32_translate (®ion->rgn, x, y); } -pixman_region_overlap_t +cairo_region_overlap_t _cairo_region_contains_rectangle (cairo_region_t *region, const cairo_rectangle_int_t *rect) { pixman_box32_t pbox; + pixman_region_overlap_t poverlap; - if (region->status) - return PIXMAN_REGION_OUT; - - pbox.x1 = rect->x; - pbox.y1 = rect->y; - pbox.x2 = rect->x + rect->width; - pbox.y2 = rect->y + rect->height; + if (!region->status) + { + pbox.x1 = rect->x; + pbox.y1 = rect->y; + pbox.x2 = rect->x + rect->width; + pbox.y2 = rect->y + rect->height; + + poverlap = pixman_region32_contains_rectangle (®ion->rgn, &pbox); + + switch (poverlap) + { + case PIXMAN_REGION_OUT: + return CAIRO_REGION_OVERLAP_OUT; + + case PIXMAN_REGION_IN: + return CAIRO_REGION_OVERLAP_IN; + + case PIXMAN_REGION_PART: + return CAIRO_REGION_OVERLAP_PART; + } + } - return pixman_region32_contains_rectangle (®ion->rgn, &pbox); + return CAIRO_REGION_OVERLAP_OUT; } -- cgit v1.2.3 From 15564d1949778124e553d792f85cae2b031aad45 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Tue, 17 Feb 2009 05:58:34 -0500 Subject: [region] Add _cairo_region_union --- src/cairo-region-private.h | 4 ++++ src/cairo-region.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index 450b0864..533b3d69 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -100,6 +100,10 @@ cairo_private cairo_status_t _cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other); +cairo_private cairo_status_t +_cairo_region_union (cairo_region_t *dst, + cairo_region_t *other); + cairo_private cairo_status_t _cairo_region_union_rect (cairo_region_t *dst, cairo_rectangle_int_t *rect); diff --git a/src/cairo-region.c b/src/cairo-region.c index b951e634..e702d2c0 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -246,6 +246,22 @@ _cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) return CAIRO_STATUS_SUCCESS; } +cairo_private cairo_status_t +_cairo_region_union (cairo_region_t *dst, + cairo_region_t *other) +{ + if (dst->status) + return dst->status; + + if (other->status) + return other->status; + + if (!pixman_region32_union (&dst->rgn, &dst->rgn, &other->rgn)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + return CAIRO_STATUS_SUCCESS; +} + cairo_status_t _cairo_region_union_rect (cairo_region_t *dst, cairo_rectangle_int_t *rect) -- cgit v1.2.3 From cfa7a384b730289233bef556fe1919f781eac684 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Tue, 17 Feb 2009 23:40:02 -0500 Subject: [region] Add _cairo_region_contains_point() --- src/cairo-region-private.h | 5 ++++- src/cairo-region.c | 15 +++++++++++++-- src/cairo.h | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index 533b3d69..78ba5fc5 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -113,12 +113,15 @@ _cairo_region_empty (cairo_region_t *region); cairo_private void _cairo_region_translate (cairo_region_t *region, - int x, int y); + int dx, int dy); cairo_private cairo_region_overlap_t _cairo_region_contains_rectangle (cairo_region_t *region, const cairo_rectangle_int_t *rect); +cairo_private cairo_bool_t +_cairo_region_contains_point (cairo_region_t *region, + int x, int y); CAIRO_END_DECLS diff --git a/src/cairo-region.c b/src/cairo-region.c index e702d2c0..04bfbd97 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -287,12 +287,12 @@ _cairo_region_empty (cairo_region_t *region) void _cairo_region_translate (cairo_region_t *region, - int x, int y) + int dx, int dy) { if (region->status) return; - pixman_region32_translate (®ion->rgn, x, y); + pixman_region32_translate (®ion->rgn, dx, dy); } cairo_region_overlap_t @@ -326,3 +326,14 @@ _cairo_region_contains_rectangle (cairo_region_t *region, return CAIRO_REGION_OVERLAP_OUT; } + +cairo_private cairo_bool_t +_cairo_region_contains_point (cairo_region_t *region, + int x, + int y) +{ + if (region->status) + return FALSE; + + return pixman_region32_contains_point (®ion->rgn, x, y, NULL); +} diff --git a/src/cairo.h b/src/cairo.h index 206861da..f359d796 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2353,6 +2353,7 @@ cairo_matrix_transform_point (const cairo_matrix_t *matrix, cairo_public void cairo_debug_reset_static_data (void); + CAIRO_END_DECLS #endif /* CAIRO_H */ -- cgit v1.2.3 From fcdca966941f4f7cc908bd46df1ec9a6b0f757c1 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Tue, 17 Feb 2009 22:52:50 -0500 Subject: [region] Always define cairo_rectangle_int_t with ints Use ints in cairo_rectangle_int_t, no matter the fixed type. --- src/cairo-types-private.h | 38 +++++++++----------------------------- 1 file changed, 9 insertions(+), 29 deletions(-) diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index e8cf4b1f..f0754261 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -218,37 +218,17 @@ typedef struct _cairo_trapezoid { cairo_line_t left, right; } cairo_trapezoid_t; -struct _cairo_rectangle_int16 { - int16_t x, y; - uint16_t width, height; -}; - -struct _cairo_rectangle_int32 { - int32_t x, y; - uint32_t width, height; -}; +typedef struct _cairo_rectangle_int { + int x, y; + unsigned int width, height; +} cairo_rectangle_int_t; -struct _cairo_point_int16 { - int16_t x, y; -}; - -struct _cairo_point_int32 { - int32_t x, y; -}; +typedef struct _cairo_point_int { + int x, y; +} cairo_point_int_t; -#if CAIRO_FIXED_BITS == 32 && CAIRO_FIXED_FRAC_BITS >= 16 -typedef struct _cairo_rectangle_int16 cairo_rectangle_int_t; -typedef struct _cairo_point_int16 cairo_point_int_t; -#define CAIRO_RECT_INT_MIN (INT16_MIN >> (CAIRO_FIXED_FRAC_BITS - 16)) -#define CAIRO_RECT_INT_MAX (INT16_MAX >> (CAIRO_FIXED_FRAC_BITS - 16)) -#elif CAIRO_FIXED_BITS == 32 -typedef struct _cairo_rectangle_int32 cairo_rectangle_int_t; -typedef struct _cairo_point_int32 cairo_point_int_t; -#define CAIRO_RECT_INT_MIN (INT32_MIN >> CAIRO_FIXED_FRAC_BITS) -#define CAIRO_RECT_INT_MAX (INT32_MAX >> CAIRO_FIXED_FRAC_BITS) -#else -#error Not sure how to pick a cairo_rectangle_int_t and cairo_point_int_t for your CAIRO_FIXED_BITS! -#endif +#define CAIRO_RECT_INT_MIN (INT_MIN >> CAIRO_FIXED_FRAC_BITS) +#define CAIRO_RECT_INT_MAX (INT_MAX >> CAIRO_FIXED_FRAC_BITS) /* Rectangles that take part in a composite operation. * -- cgit v1.2.3 From 1cca5a1348d071a3c8e2ba9d3ba0d9670b9564f4 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Tue, 17 Feb 2009 23:52:18 -0500 Subject: [region] Remove underscores from _cairo_region_* --- src/cairo-analysis-surface.c | 18 ++++++------- src/cairo-clip.c | 50 +++++++++++++++++------------------ src/cairo-directfb-surface.c | 4 +-- src/cairo-paginated-surface.c | 4 +-- src/cairo-region-private.h | 36 ++++++++++++------------- src/cairo-region.c | 61 +++++++++++++++++++++---------------------- src/cairo-surface-fallback.c | 20 +++++++------- src/cairo-surface.c | 14 +++++----- src/cairo-traps.c | 10 +++---- src/cairo-win32-surface.c | 8 +++--- src/cairo-xcb-surface.c | 4 +-- src/cairo-xlib-surface.c | 14 +++++----- 12 files changed, 120 insertions(+), 123 deletions(-) diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index eaa7947e..d7d950a7 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -215,7 +215,7 @@ _add_operation (cairo_analysis_surface_t *surface, * region there is no benefit in emitting a native operation as * the fallback image will be painted on top. */ - if (_cairo_region_contains_rectangle (surface->fallback_region, rect) == CAIRO_REGION_OVERLAP_IN) + if (cairo_region_contains_rectangle (surface->fallback_region, rect) == CAIRO_REGION_OVERLAP_IN) return CAIRO_INT_STATUS_IMAGE_FALLBACK; if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) { @@ -226,7 +226,7 @@ _add_operation (cairo_analysis_surface_t *surface, * natively supported and the backend will blend the * transparency into the white background. */ - if (_cairo_region_contains_rectangle (surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT) + if (cairo_region_contains_rectangle (surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT) backend_status = CAIRO_STATUS_SUCCESS; } @@ -235,8 +235,7 @@ _add_operation (cairo_analysis_surface_t *surface, * this region will be emitted as native operations. */ surface->has_supported = TRUE; - status = _cairo_region_union_rect (surface->supported_region, - rect); + status = cairo_region_union_rect (surface->supported_region, rect); return status; } @@ -245,8 +244,7 @@ _add_operation (cairo_analysis_surface_t *surface, * emitted. */ surface->has_unsupported = TRUE; - status = _cairo_region_union_rect (surface->fallback_region, - rect); + status = cairo_region_union_rect (surface->fallback_region, rect); /* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate * unsupported operations to the meta surface as using @@ -265,8 +263,8 @@ _cairo_analysis_surface_finish (void *abstract_surface) { cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - _cairo_region_destroy (surface->supported_region); - _cairo_region_destroy (surface->fallback_region); + cairo_region_destroy (surface->supported_region); + cairo_region_destroy (surface->fallback_region); cairo_surface_destroy (surface->target); @@ -781,8 +779,8 @@ _cairo_analysis_surface_create (cairo_surface_t *target, surface->page_bbox.p2.x = 0; surface->page_bbox.p2.y = 0; - surface->supported_region = _cairo_region_create (); - surface->fallback_region = _cairo_region_create (); + surface->supported_region = cairo_region_create (); + surface->fallback_region = cairo_region_create (); if (width == -1 && height == -1) { surface->current_clip.x = CAIRO_RECT_INT_MIN; diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 4ca3e9aa..58b6335a 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -84,12 +84,12 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) if (other->region) { cairo_status_t status; - clip->region = _cairo_region_copy (other->region); + clip->region = cairo_region_copy (other->region); - status = _cairo_region_status (clip->region); + status = cairo_region_status (clip->region); if (unlikely (status)) { cairo_surface_destroy (clip->surface); - _cairo_region_destroy (clip->region); + cairo_region_destroy (clip->region); clip->region = NULL; return status; @@ -115,7 +115,7 @@ _cairo_clip_reset (cairo_clip_t *clip) clip->serial = 0; if (clip->region) { - _cairo_region_destroy (clip->region); + cairo_region_destroy (clip->region); clip->region = NULL; } @@ -177,7 +177,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, if (clip->region) { cairo_rectangle_int_t extents; - _cairo_region_get_extents (clip->region, &extents); + cairo_region_get_extents (clip->region, &extents); is_empty = _cairo_rectangle_intersect (rectangle, &extents); if (is_empty) return CAIRO_STATUS_SUCCESS; @@ -201,11 +201,11 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, if (clip->all_clipped) { cairo_region_t *clip_rect; - clip_rect = _cairo_region_create_rect (&clip->surface_rect); + clip_rect = cairo_region_create_rect (&clip->surface_rect); - status = _cairo_region_intersect (region, clip_rect); + status = cairo_region_intersect (region, clip_rect); - _cairo_region_destroy (clip_rect); + cairo_region_destroy (clip_rect); return status; } @@ -215,7 +215,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, } if (clip->region) { - status = _cairo_region_intersect (region, clip->region); + status = cairo_region_intersect (region, clip->region); if (unlikely (status)) return status; } @@ -223,11 +223,11 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, if (clip->surface) { cairo_region_t *clip_rect; - clip_rect = _cairo_region_create_rect (&clip->surface_rect); + clip_rect = cairo_region_create_rect (&clip->surface_rect); - status = _cairo_region_intersect (region, clip_rect); + status = cairo_region_intersect (region, clip_rect); - _cairo_region_destroy (clip_rect); + cairo_region_destroy (clip_rect); if (unlikely (status)) return status; @@ -354,20 +354,20 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, return status; if (clip->region) { - status = _cairo_region_intersect (clip->region, region); + status = cairo_region_intersect (clip->region, region); } else { - clip->region = _cairo_region_copy (region); + clip->region = cairo_region_copy (region); assert (clip->region != NULL); - if ((status = _cairo_region_status (clip->region))) + if ((status = cairo_region_status (clip->region))) clip->region = NULL; } clip->serial = _cairo_surface_allocate_clip_serial (target); - _cairo_region_destroy (region); + cairo_region_destroy (region); - if (!clip->region || _cairo_region_empty (clip->region)) + if (!clip->region || cairo_region_empty (clip->region)) _cairo_clip_set_all_clipped (clip, target); return status; @@ -725,9 +725,9 @@ _cairo_clip_translate (cairo_clip_t *clip, return; if (clip->region) { - _cairo_region_translate (clip->region, - _cairo_fixed_integer_part (tx), - _cairo_fixed_integer_part (ty)); + cairo_region_translate (clip->region, + _cairo_fixed_integer_part (tx), + _cairo_fixed_integer_part (ty)); } if (clip->surface) { @@ -783,8 +783,8 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, * whatever the right handling is happen */ } else { if (other->region) { - clip->region = _cairo_region_copy (other->region); - if (unlikely ((status = _cairo_region_status (clip->region)))) + clip->region = cairo_region_copy (other->region); + if (unlikely ((status = cairo_region_status (clip->region)))) goto BAIL; } @@ -818,7 +818,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, BAIL: if (clip->region) - _cairo_region_destroy (clip->region); + cairo_region_destroy (clip->region); if (clip->surface) cairo_surface_destroy (clip->surface); @@ -872,7 +872,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) if (clip->region) { int i; - n_rects = _cairo_region_num_rectangles (clip->region); + n_rects = cairo_region_num_rectangles (clip->region); if (n_rects) { rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t)); @@ -884,7 +884,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) for (i = 0; i < n_rects; ++i) { cairo_rectangle_int_t clip_rect; - _cairo_region_get_rectangle (clip->region, i, &clip_rect); + cairo_region_get_rectangle (clip->region, i, &clip_rect); if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) { _cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE); diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c index 3873f3e9..3eee33cc 100644 --- a/src/cairo-directfb-surface.c +++ b/src/cairo-directfb-surface.c @@ -1305,7 +1305,7 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface, surface->has_clip = TRUE; - n_rects = _cairo_region_num_rectangles (region); + n_rects = cairo_region_num_rectangles (region); if (n_rects == 0) return CAIRO_STATUS_SUCCESS; @@ -1326,7 +1326,7 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface, for (i = 0; i < n_rects; i++) { cairo_rectangle_int_t rect; - _cairo_region_get_rectangle (region, i, &rect); + cairo_region_get_rectangle (region, i, &rect); surface->clips[i].x1 = rect.x; surface->clips[i].y1 = rect.y; diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index cc09b59c..b84fbffe 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -397,11 +397,11 @@ _paint_page (cairo_paginated_surface_t *surface) region = _cairo_analysis_surface_get_unsupported (analysis); - num_rects = _cairo_region_num_rectangles (region); + num_rects = cairo_region_num_rectangles (region); for (i = 0; i < num_rects; i++) { cairo_rectangle_int_t rect; - _cairo_region_get_rectangle (region, i, &rect); + cairo_region_get_rectangle (region, i, &rect); status = _paint_fallback_image (surface, &rect); diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index 78ba5fc5..c9b2ae1c 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -59,68 +59,68 @@ typedef enum _cairo_region_overlap { } cairo_region_overlap_t; cairo_private cairo_region_t * -_cairo_region_create (void); +cairo_region_create (void); cairo_private cairo_region_t * -_cairo_region_create_rect (cairo_rectangle_int_t *rect); +cairo_region_create_rect (cairo_rectangle_int_t *rect); cairo_private cairo_status_t -_cairo_region_status (cairo_region_t *region); +cairo_region_status (cairo_region_t *region); cairo_private void -_cairo_region_clear (cairo_region_t *region); +cairo_region_clear (cairo_region_t *region); cairo_private cairo_region_t * -_cairo_region_create_rectangles (cairo_rectangle_int_t *rects, +cairo_region_create_rectangles (cairo_rectangle_int_t *rects, int count); cairo_private void -_cairo_region_destroy (cairo_region_t *region); +cairo_region_destroy (cairo_region_t *region); cairo_private cairo_region_t * -_cairo_region_copy (cairo_region_t *original); +cairo_region_copy (cairo_region_t *original); cairo_private int -_cairo_region_num_rectangles (cairo_region_t *region); +cairo_region_num_rectangles (cairo_region_t *region); cairo_private void -_cairo_region_get_rectangle (cairo_region_t *region, +cairo_region_get_rectangle (cairo_region_t *region, int nth_rectangle, cairo_rectangle_int_t *rectangle); cairo_private void -_cairo_region_get_extents (cairo_region_t *region, +cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents); cairo_private cairo_status_t -_cairo_region_subtract (cairo_region_t *dst, +cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other); cairo_private cairo_status_t -_cairo_region_intersect (cairo_region_t *dst, +cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other); cairo_private cairo_status_t -_cairo_region_union (cairo_region_t *dst, +cairo_region_union (cairo_region_t *dst, cairo_region_t *other); cairo_private cairo_status_t -_cairo_region_union_rect (cairo_region_t *dst, +cairo_region_union_rect (cairo_region_t *dst, cairo_rectangle_int_t *rect); cairo_private cairo_bool_t -_cairo_region_empty (cairo_region_t *region); +cairo_region_empty (cairo_region_t *region); cairo_private void -_cairo_region_translate (cairo_region_t *region, +cairo_region_translate (cairo_region_t *region, int dx, int dy); cairo_private cairo_region_overlap_t -_cairo_region_contains_rectangle (cairo_region_t *region, +cairo_region_contains_rectangle (cairo_region_t *region, const cairo_rectangle_int_t *rect); cairo_private cairo_bool_t -_cairo_region_contains_point (cairo_region_t *region, +cairo_region_contains_point (cairo_region_t *region, int x, int y); CAIRO_END_DECLS diff --git a/src/cairo-region.c b/src/cairo-region.c index 04bfbd97..59ce0bf8 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -43,7 +43,7 @@ const cairo_region_t _cairo_region_nil = { }; cairo_region_t * -_cairo_region_create (void) +cairo_region_create (void) { cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t)); @@ -58,7 +58,7 @@ _cairo_region_create (void) } cairo_region_t * -_cairo_region_create_rect (cairo_rectangle_int_t *rect) +cairo_region_create_rect (cairo_rectangle_int_t *rect) { cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t)); @@ -75,8 +75,8 @@ _cairo_region_create_rect (cairo_rectangle_int_t *rect) } cairo_region_t * -_cairo_region_create_rectangles (cairo_rectangle_int_t *rects, - int count) +cairo_region_create_rectangles (cairo_rectangle_int_t *rects, + int count) { pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)]; pixman_box32_t *pboxes = stack_pboxes; @@ -119,7 +119,7 @@ _cairo_region_create_rectangles (cairo_rectangle_int_t *rects, } void -_cairo_region_destroy (cairo_region_t *region) +cairo_region_destroy (cairo_region_t *region) { if (region->status) return; @@ -129,19 +129,19 @@ _cairo_region_destroy (cairo_region_t *region) } cairo_region_t * -_cairo_region_copy (cairo_region_t *original) +cairo_region_copy (cairo_region_t *original) { cairo_region_t *copy; if (original->status) return (cairo_region_t *)&_cairo_region_nil; - copy = _cairo_region_create (); + copy = cairo_region_create (); if (!copy) return (cairo_region_t *)&_cairo_region_nil; if (!pixman_region32_copy (©->rgn, &original->rgn)) { - _cairo_region_destroy (copy); + cairo_region_destroy (copy); return (cairo_region_t *)&_cairo_region_nil; } @@ -150,7 +150,7 @@ _cairo_region_copy (cairo_region_t *original) } int -_cairo_region_num_rectangles (cairo_region_t *region) +cairo_region_num_rectangles (cairo_region_t *region) { if (region->status) return 0; @@ -159,9 +159,9 @@ _cairo_region_num_rectangles (cairo_region_t *region) } cairo_private void -_cairo_region_get_rectangle (cairo_region_t *region, - int nth_box, - cairo_rectangle_int_t *rect) +cairo_region_get_rectangle (cairo_region_t *region, + int nth_box, + cairo_rectangle_int_t *rect) { pixman_box32_t *pbox; @@ -177,15 +177,15 @@ _cairo_region_get_rectangle (cairo_region_t *region, } /** - * _cairo_region_get_extents: + * cairo_region_get_extents: * @region: a #cairo_region_t * @rect: rectangle into which to store the extents * * Gets the bounding box of a region as a #cairo_rectangle_int_t **/ void -_cairo_region_get_extents (cairo_region_t *region, - cairo_rectangle_int_t *extents) +cairo_region_get_extents (cairo_region_t *region, + cairo_rectangle_int_t *extents) { pixman_box32_t *pextents; @@ -201,13 +201,13 @@ _cairo_region_get_extents (cairo_region_t *region, } cairo_status_t -_cairo_region_status (cairo_region_t *region) +cairo_region_status (cairo_region_t *region) { return region->status; } void -_cairo_region_clear (cairo_region_t *region) +cairo_region_clear (cairo_region_t *region) { if (region->status) return; @@ -217,7 +217,7 @@ _cairo_region_clear (cairo_region_t *region) } cairo_status_t -_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) +cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) { if (dst->status) return dst->status; @@ -232,7 +232,7 @@ _cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) } cairo_status_t -_cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) +cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) { if (dst->status) return dst->status; @@ -247,8 +247,8 @@ _cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) } cairo_private cairo_status_t -_cairo_region_union (cairo_region_t *dst, - cairo_region_t *other) +cairo_region_union (cairo_region_t *dst, + cairo_region_t *other) { if (dst->status) return dst->status; @@ -263,8 +263,8 @@ _cairo_region_union (cairo_region_t *dst, } cairo_status_t -_cairo_region_union_rect (cairo_region_t *dst, - cairo_rectangle_int_t *rect) +cairo_region_union_rect (cairo_region_t *dst, + cairo_rectangle_int_t *rect) { if (!pixman_region32_union_rect (&dst->rgn, &dst->rgn, rect->x, rect->y, @@ -277,7 +277,7 @@ _cairo_region_union_rect (cairo_region_t *dst, } cairo_bool_t -_cairo_region_empty (cairo_region_t *region) +cairo_region_empty (cairo_region_t *region) { if (region->status) return TRUE; @@ -286,8 +286,8 @@ _cairo_region_empty (cairo_region_t *region) } void -_cairo_region_translate (cairo_region_t *region, - int dx, int dy) +cairo_region_translate (cairo_region_t *region, + int dx, int dy) { if (region->status) return; @@ -296,8 +296,8 @@ _cairo_region_translate (cairo_region_t *region, } cairo_region_overlap_t -_cairo_region_contains_rectangle (cairo_region_t *region, - const cairo_rectangle_int_t *rect) +cairo_region_contains_rectangle (cairo_region_t *region, + const cairo_rectangle_int_t *rect) { pixman_box32_t pbox; pixman_region_overlap_t poverlap; @@ -328,9 +328,8 @@ _cairo_region_contains_rectangle (cairo_region_t *region, } cairo_private cairo_bool_t -_cairo_region_contains_point (cairo_region_t *region, - int x, - int y) +cairo_region_contains_point (cairo_region_t *region, + int x, int y) { if (region->status) return FALSE; diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 876268f5..42d86e73 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -417,7 +417,7 @@ _composite_trap_region (cairo_clip_t *clip, cairo_status_t status; cairo_solid_pattern_t solid_pattern; cairo_surface_pattern_t mask; - int num_rects = _cairo_region_num_rectangles (trap_region); + int num_rects = cairo_region_num_rectangles (trap_region); unsigned int clip_serial; cairo_surface_t *clip_surface = clip ? clip->surface : NULL; @@ -544,7 +544,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, if (unlikely (status)) goto out; - _cairo_region_get_extents (trap_region, &trap_extents); + cairo_region_get_extents (trap_region, &trap_extents); } else { cairo_box_t trap_box; _cairo_traps_extents (traps, &trap_box); @@ -567,9 +567,9 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, * _cairo_surface_fill_rectangles() or to drawing with a * clip region, then we have an additional region to clear. */ - clear_region = _cairo_region_create_rect (&extents); + clear_region = cairo_region_create_rect (&extents); - status = _cairo_region_status (clear_region); + status = cairo_region_status (clear_region); if (unlikely (status)) goto out; @@ -577,14 +577,14 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, if (unlikely (status)) goto out; - _cairo_region_get_extents (clear_region, &extents); + cairo_region_get_extents (clear_region, &extents); - status = _cairo_region_subtract (clear_region, trap_region); + status = cairo_region_subtract (clear_region, trap_region); if (unlikely (status)) goto out; - if (_cairo_region_empty (clear_region)) { - _cairo_region_destroy (clear_region); + if (cairo_region_empty (clear_region)) { + cairo_region_destroy (clear_region); clear_region = NULL; } } else { @@ -659,9 +659,9 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, out: if (trap_region) - _cairo_region_destroy (trap_region); + cairo_region_destroy (trap_region); if (clear_region) - _cairo_region_destroy (clear_region); + cairo_region_destroy (clear_region); return status; } diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 42fc6da8..e0931221 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1587,7 +1587,7 @@ _cairo_surface_fill_region (cairo_surface_t *surface, assert (! surface->is_snapshot); - num_rects = _cairo_region_num_rectangles (region); + num_rects = cairo_region_num_rectangles (region); if (num_rects == 0) return CAIRO_STATUS_SUCCESS; @@ -1601,7 +1601,7 @@ _cairo_surface_fill_region (cairo_surface_t *surface, } for (i = 0; i < num_rects; i++) - _cairo_region_get_rectangle (region, i, &rects[i]); + cairo_region_get_rectangle (region, i, &rects[i]); status = _cairo_surface_fill_rectangles (surface, op, color, rects, num_rects); @@ -2692,7 +2692,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, dst_rectangle.width = width; dst_rectangle.height = height; - clear_region = _cairo_region_create_rect (&dst_rectangle); + clear_region = cairo_region_create_rect (&dst_rectangle); drawn_rectangle = dst_rectangle; @@ -2708,10 +2708,10 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, /* Now compute the area that is in dst_rectangle but not in drawn_rectangle */ - drawn_region = _cairo_region_create_rect (&drawn_rectangle); + drawn_region = cairo_region_create_rect (&drawn_rectangle); has_drawn_region = TRUE; - status = _cairo_region_subtract (clear_region, drawn_region); + status = cairo_region_subtract (clear_region, drawn_region); if (unlikely (status)) goto CLEANUP_REGIONS; @@ -2722,8 +2722,8 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, CLEANUP_REGIONS: if (drawn_region) - _cairo_region_destroy (drawn_region); - _cairo_region_destroy (clear_region); + cairo_region_destroy (drawn_region); + cairo_region_destroy (clear_region); return _cairo_surface_set_error (dst, status); } diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 96db4ba1..73bb124e 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -600,7 +600,7 @@ _cairo_traps_extents (const cairo_traps_t *traps, * Determines if a set of trapezoids are exactly representable as a * cairo region. If so, the passed-in region is initialized to * the area representing the given traps. It should be finalized - * with _cairo_region_fini(). If not, %CAIRO_INT_STATUS_UNSUPPORTED + * with cairo_region_fini(). If not, %CAIRO_INT_STATUS_UNSUPPORTED * is returned. * * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED @@ -616,7 +616,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, cairo_int_status_t status; if (traps->num_traps == 0) { - *region = _cairo_region_create (); + *region = cairo_region_create (); return CAIRO_STATUS_SUCCESS; } @@ -662,15 +662,15 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, rect_count++; } - *region = _cairo_region_create_rectangles (rects, rect_count); - status = _cairo_region_status (*region); + *region = cairo_region_create_rectangles (rects, rect_count); + status = cairo_region_status (*region); if (rects != stack_rects) free (rects); if (unlikely (status)) { - _cairo_region_destroy (*region); + cairo_region_destroy (*region); *region = NULL; } diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index f182642f..649a96b5 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -1471,11 +1471,11 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, /* Create a GDI region for the cairo region */ - _cairo_region_get_extents (region, &extents); - num_rects = _cairo_region_num_rectangles (region); + cairo_region_get_extents (region, &extents); + num_rects = cairo_region_num_rectangles (region); if (num_rects == 1) - _cairo_region_get_rectangle (region, 0, &rect0); + cairo_region_get_rectangle (region, 0, &rect0); if (num_rects == 1 && rect0.x == 0 && @@ -1517,7 +1517,7 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface, for (i = 0; i < num_rects; i++) { cairo_rectangle_int_t rect; - _cairo_region_get_rectangle (region, i, &rect); + cairo_region_get_rectangle (region, i, &rect); rects[i].left = rect.x; rects[i].top = rect.y; diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index ab589e1d..8d0090b0 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -1559,7 +1559,7 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface, xcb_rectangle_t *rects = NULL; int n_rects, i; - n_rects = _cairo_region_num_rectangles (region); + n_rects = cairo_region_num_rectangles (region); if (n_rects > 0) { rects = _cairo_malloc_ab (n_rects, sizeof(xcb_rectangle_t)); @@ -1572,7 +1572,7 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface, for (i = 0; i < n_rects; i++) { cairo_rectangle_int_t rect; - _cairo_region_get_rectangle (region, i, &rect); + cairo_region_get_rectangle (region, i, &rect); rects[i].x = rect.x; rects[i].y = rect.y; diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index e411977b..f547f5fa 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2302,19 +2302,19 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, * is necessary so we don't wrap around when we convert cairo's * 32 bit region into 16 bit rectangles. */ - bounded = _cairo_region_create_rect (&rect); - status = _cairo_region_intersect (bounded, region); + bounded = cairo_region_create_rect (&rect); + status = cairo_region_intersect (bounded, region); if (unlikely (status)) { - _cairo_region_destroy (bounded); + cairo_region_destroy (bounded); return status; } - n_rects = _cairo_region_num_rectangles (bounded); + n_rects = cairo_region_num_rectangles (bounded); if (n_rects > ARRAY_LENGTH (surface->embedded_clip_rects)) { rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle)); if (unlikely (rects == NULL)) { - _cairo_region_destroy (bounded); + cairo_region_destroy (bounded); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } } else { @@ -2324,7 +2324,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, for (i = 0; i < n_rects; i++) { cairo_rectangle_int_t rect; - _cairo_region_get_rectangle (bounded, i, &rect); + cairo_region_get_rectangle (bounded, i, &rect); rects[i].x = rect.x; rects[i].y = rect.y; @@ -2332,7 +2332,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, rects[i].height = rect.height; } - _cairo_region_destroy (bounded); + cairo_region_destroy (bounded); surface->have_clip_rects = TRUE; surface->clip_rects = rects; -- cgit v1.2.3 From e29103c08189cab9de34f577951219a69bd7c8e2 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Wed, 18 Feb 2009 00:11:35 -0500 Subject: [region] Move region function prototypes to cairo.h along with helper types. Move struct _cairo_region to cairoint.h and delete cairo-region-private.h. Delete cairo_private from the function definitions that had it. --- src/Makefile.sources | 1 - src/cairo-analysis-surface.c | 1 - src/cairo-clip-private.h | 1 - src/cairo-region-private.h | 128 ------------------------------------------- src/cairo-region.c | 6 +- src/cairo-types-private.h | 6 -- src/cairo.h | 75 +++++++++++++++++++++++++ src/cairoint.h | 6 +- 8 files changed, 83 insertions(+), 141 deletions(-) delete mode 100644 src/cairo-region-private.h diff --git a/src/Makefile.sources b/src/Makefile.sources index 7305995e..c1df770c 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -78,7 +78,6 @@ cairo_private = \ cairo-path-private.h \ cairo-private.h \ cairo-reference-count-private.h \ - cairo-region-private.h \ cairo-scaled-font-private.h \ cairo-skiplist-private.h \ cairo-spans-private.h \ diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index d7d950a7..feaa9d30 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -38,7 +38,6 @@ #include "cairo-analysis-surface-private.h" #include "cairo-paginated-private.h" -#include "cairo-region-private.h" #include "cairo-meta-surface-private.h" typedef struct { diff --git a/src/cairo-clip-private.h b/src/cairo-clip-private.h index b1a9d1af..4229e4fb 100644 --- a/src/cairo-clip-private.h +++ b/src/cairo-clip-private.h @@ -40,7 +40,6 @@ #include "cairo-compiler-private.h" #include "cairo-path-fixed-private.h" #include "cairo-reference-count-private.h" -#include "cairo-region-private.h" extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil; diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h deleted file mode 100644 index c9b2ae1c..00000000 --- a/src/cairo-region-private.h +++ /dev/null @@ -1,128 +0,0 @@ -/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ -/* Cairo - a vector graphics library with display and print output - * - * Copyright © 2007 Mozilla Corporation - * - * This library is free software; you can redistribute it and/or - * modify it either under the terms of the GNU Lesser General Public - * License version 2.1 as published by the Free Software Foundation - * (the "LGPL") or, at your option, under the terms of the Mozilla - * Public License Version 1.1 (the "MPL"). If you do not alter this - * notice, a recipient may use your version of this file under either - * the MPL or the LGPL. - * - * You should have received a copy of the LGPL along with this library - * in the file COPYING-LGPL-2.1; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * You should have received a copy of the MPL along with this library - * in the file COPYING-MPL-1.1 - * - * The contents of this file are subject to the Mozilla Public License - * Version 1.1 (the "License"); you may not use this file except in - * compliance with the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY - * OF ANY KIND, either express or implied. See the LGPL or the MPL for - * the specific language governing rights and limitations. - * - * The Original Code is the cairo graphics library. - * - * The Initial Developer of the Original Code is Mozilla Corporation - * - * Contributor(s): - * Vladimir Vukicevic - */ - -#ifndef CAIRO_REGION_PRIVATE_H -#define CAIRO_REGION_PRIVATE_H - -#include "cairo-compiler-private.h" -#include "cairo-types-private.h" - -#include - -CAIRO_BEGIN_DECLS - -/* #cairo_region_t is defined in cairoint.h */ - -struct _cairo_region { - cairo_status_t status; - - pixman_region32_t rgn; -}; - -typedef enum _cairo_region_overlap { - CAIRO_REGION_OVERLAP_IN, /* completely inside region */ - CAIRO_REGION_OVERLAP_OUT, /* completely outside region */ - CAIRO_REGION_OVERLAP_PART, /* partly inside region */ -} cairo_region_overlap_t; - -cairo_private cairo_region_t * -cairo_region_create (void); - -cairo_private cairo_region_t * -cairo_region_create_rect (cairo_rectangle_int_t *rect); - -cairo_private cairo_status_t -cairo_region_status (cairo_region_t *region); - -cairo_private void -cairo_region_clear (cairo_region_t *region); - -cairo_private cairo_region_t * -cairo_region_create_rectangles (cairo_rectangle_int_t *rects, - int count); - -cairo_private void -cairo_region_destroy (cairo_region_t *region); - -cairo_private cairo_region_t * -cairo_region_copy (cairo_region_t *original); - -cairo_private int -cairo_region_num_rectangles (cairo_region_t *region); - -cairo_private void -cairo_region_get_rectangle (cairo_region_t *region, - int nth_rectangle, - cairo_rectangle_int_t *rectangle); - -cairo_private void -cairo_region_get_extents (cairo_region_t *region, - cairo_rectangle_int_t *extents); - -cairo_private cairo_status_t -cairo_region_subtract (cairo_region_t *dst, - cairo_region_t *other); - -cairo_private cairo_status_t -cairo_region_intersect (cairo_region_t *dst, - cairo_region_t *other); - -cairo_private cairo_status_t -cairo_region_union (cairo_region_t *dst, - cairo_region_t *other); - -cairo_private cairo_status_t -cairo_region_union_rect (cairo_region_t *dst, - cairo_rectangle_int_t *rect); - -cairo_private cairo_bool_t -cairo_region_empty (cairo_region_t *region); - -cairo_private void -cairo_region_translate (cairo_region_t *region, - int dx, int dy); - -cairo_private cairo_region_overlap_t -cairo_region_contains_rectangle (cairo_region_t *region, - const cairo_rectangle_int_t *rect); - -cairo_private cairo_bool_t -cairo_region_contains_point (cairo_region_t *region, - int x, int y); - -CAIRO_END_DECLS - -#endif /* CAIRO_REGION_PRIVATE_H */ diff --git a/src/cairo-region.c b/src/cairo-region.c index 59ce0bf8..5d01d370 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -158,7 +158,7 @@ cairo_region_num_rectangles (cairo_region_t *region) return pixman_region32_n_rects (®ion->rgn); } -cairo_private void +void cairo_region_get_rectangle (cairo_region_t *region, int nth_box, cairo_rectangle_int_t *rect) @@ -246,7 +246,7 @@ cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) return CAIRO_STATUS_SUCCESS; } -cairo_private cairo_status_t +cairo_status_t cairo_region_union (cairo_region_t *dst, cairo_region_t *other) { @@ -327,7 +327,7 @@ cairo_region_contains_rectangle (cairo_region_t *region, return CAIRO_REGION_OVERLAP_OUT; } -cairo_private cairo_bool_t +cairo_bool_t cairo_region_contains_point (cairo_region_t *region, int x, int y) { diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index f0754261..bb62351d 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -59,7 +59,6 @@ typedef struct _cairo_output_stream cairo_output_stream_t; typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t; typedef struct _cairo_path_fixed cairo_path_fixed_t; typedef struct _cairo_rectangle_int16 cairo_glyph_size_t; -typedef struct _cairo_region cairo_region_t; typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t; typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t; typedef struct _cairo_solid_pattern cairo_solid_pattern_t; @@ -218,11 +217,6 @@ typedef struct _cairo_trapezoid { cairo_line_t left, right; } cairo_trapezoid_t; -typedef struct _cairo_rectangle_int { - int x, y; - unsigned int width, height; -} cairo_rectangle_int_t; - typedef struct _cairo_point_int { int x, y; } cairo_point_int_t; diff --git a/src/cairo.h b/src/cairo.h index f359d796..adf34b97 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2349,6 +2349,81 @@ cairo_public void cairo_matrix_transform_point (const cairo_matrix_t *matrix, double *x, double *y); +/* Region functions */ + +typedef struct _cairo_region cairo_region_t; + +typedef struct _cairo_rectangle_int { + int x, y; + unsigned int width, height; +} cairo_rectangle_int_t; + +typedef enum _cairo_region_overlap { + CAIRO_REGION_OVERLAP_IN, /* completely inside region */ + CAIRO_REGION_OVERLAP_OUT, /* completely outside region */ + CAIRO_REGION_OVERLAP_PART, /* partly inside region */ +} cairo_region_overlap_t; + +cairo_public cairo_region_t * +cairo_region_create (void); + +cairo_public cairo_region_t * +cairo_region_create_rect (cairo_rectangle_int_t *rect); + +cairo_public cairo_region_t * +cairo_region_create_rectangles (cairo_rectangle_int_t *rects, + int count); + +cairo_public cairo_region_t * +cairo_region_copy (cairo_region_t *original); + +cairo_public void +cairo_region_destroy (cairo_region_t *region); + +cairo_public cairo_status_t +cairo_region_status (cairo_region_t *region); + +cairo_public void +cairo_region_get_extents (cairo_region_t *region, + cairo_rectangle_int_t *extents); + +cairo_public int +cairo_region_num_rectangles (cairo_region_t *region); + +cairo_public void +cairo_region_get_rectangle (cairo_region_t *region, + int nth_rectangle, + cairo_rectangle_int_t *rectangle); + +cairo_public cairo_bool_t +cairo_region_empty (cairo_region_t *region); + +cairo_public cairo_region_overlap_t +cairo_region_contains_rectangle (cairo_region_t *region, + const cairo_rectangle_int_t *rect); + +cairo_public cairo_bool_t +cairo_region_contains_point (cairo_region_t *region, int x, int y); + +cairo_public void +cairo_region_clear (cairo_region_t *region); + +cairo_public void +cairo_region_translate (cairo_region_t *region, int dx, int dy); + +cairo_public cairo_status_t +cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other); + +cairo_public cairo_status_t +cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other); + +cairo_public cairo_status_t +cairo_region_union (cairo_region_t *dst, cairo_region_t *other); + +cairo_public cairo_status_t +cairo_region_union_rect (cairo_region_t *dst, cairo_rectangle_int_t *rect); + + /* Functions to be used while debugging (not intended for use in production code) */ cairo_public void cairo_debug_reset_static_data (void); diff --git a/src/cairoint.h b/src/cairoint.h index 30273c22..071ac154 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2528,7 +2528,11 @@ _cairo_pattern_reset_static_data (void); /* cairo-region.c */ -#include "cairo-region-private.h" +struct _cairo_region { + cairo_status_t status; + + pixman_region32_t rgn; +}; /* cairo-unicode.c */ -- cgit v1.2.3 From e6d82afcab01cc91b88185abc8d1bfb9df5c2c19 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Wed, 18 Feb 2009 00:20:46 -0500 Subject: [region] Add slim_hidden_proto for region functions --- src/cairoint.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/cairoint.h b/src/cairoint.h index 071ac154..9d02d350 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2694,6 +2694,24 @@ slim_hidden_proto (cairo_user_font_face_set_unicode_to_glyph_func); slim_hidden_proto (cairo_user_to_device); slim_hidden_proto (cairo_user_to_device_distance); slim_hidden_proto (cairo_version_string); +slim_hidden_proto (cairo_region_create); +slim_hidden_proto (cairo_region_create_rect); +slim_hidden_proto (cairo_region_create_rectangles); +slim_hidden_proto (cairo_region_copy); +slim_hidden_proto (cairo_region_destroy); +slim_hidden_proto (cairo_region_status); +slim_hidden_proto (cairo_region_get_extents); +slim_hidden_proto (cairo_region_num_rectangles); +slim_hidden_proto (cairo_region_get_rectangle); +slim_hidden_proto (cairo_region_empty); +slim_hidden_proto (cairo_region_contains_rectangle); +slim_hidden_proto (cairo_region_contains_point); +slim_hidden_proto (cairo_region_clear); +slim_hidden_proto (cairo_region_translate); +slim_hidden_proto (cairo_region_subtract); +slim_hidden_proto (cairo_region_intersect); +slim_hidden_proto (cairo_region_union); +slim_hidden_proto (cairo_region_union_rect); #if CAIRO_HAS_PNG_FUNCTIONS -- cgit v1.2.3 From bf6d9bc1758ac1971485b6565d29934d6b06bef2 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Wed, 18 Feb 2009 08:01:19 -0500 Subject: [region] Delete cairo_region_create_rectangles() It was only used in _cairo_traps_extract_region() which could be simplified significantly by calling cairo_region_union_rect() repeatedly instead. --- src/cairo-region.c | 44 --------------------------------------- src/cairo-traps.c | 60 +++++++++++++++++++++--------------------------------- src/cairo.h | 4 ---- src/cairoint.h | 1 - 4 files changed, 23 insertions(+), 86 deletions(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index 5d01d370..bc6598ac 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -74,50 +74,6 @@ cairo_region_create_rect (cairo_rectangle_int_t *rect) return region; } -cairo_region_t * -cairo_region_create_rectangles (cairo_rectangle_int_t *rects, - int count) -{ - pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)]; - pixman_box32_t *pboxes = stack_pboxes; - cairo_region_t *region; - int i; - - region = _cairo_malloc (sizeof (cairo_region_t)); - - if (!region) - return (cairo_region_t *)&_cairo_region_nil; - - region->status = CAIRO_STATUS_SUCCESS; - - if (count > ARRAY_LENGTH (stack_pboxes)) { - pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t)); - - if (unlikely (pboxes == NULL)) { - free (region); - return (cairo_region_t *)&_cairo_region_nil; - } - } - - for (i = 0; i < count; i++) { - pboxes[i].x1 = rects[i].x; - pboxes[i].y1 = rects[i].y; - pboxes[i].x2 = rects[i].x + rects[i].width; - pboxes[i].y2 = rects[i].y + rects[i].height; - } - - if (! pixman_region32_init_rects (®ion->rgn, pboxes, count)) { - free (region); - - region = (cairo_region_t *)&_cairo_region_nil; - } - - if (pboxes != stack_pboxes) - free (pboxes); - - return region; -} - void cairo_region_destroy (cairo_region_t *region) { diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 73bb124e..2fc2fac2 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -610,17 +610,12 @@ cairo_int_status_t _cairo_traps_extract_region (const cairo_traps_t *traps, cairo_region_t **region) { - cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; - cairo_rectangle_int_t *rects = stack_rects; - int i, rect_count; - cairo_int_status_t status; - - if (traps->num_traps == 0) { - *region = cairo_region_create (); - return CAIRO_STATUS_SUCCESS; - } + cairo_int_status_t status = CAIRO_STATUS_SUCCESS; + cairo_region_t *r; + int i; - for (i = 0; i < traps->num_traps; i++) { + for (i = 0; i < traps->num_traps; i++) + { if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x || traps->traps[i].right.p1.x != traps->traps[i].right.p2.x || ! _cairo_fixed_is_integer (traps->traps[i].top) || @@ -632,17 +627,12 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, } } - if (traps->num_traps > ARRAY_LENGTH (stack_rects)) { - rects = _cairo_malloc_ab (traps->num_traps, - sizeof (cairo_rectangle_int_t)); - - if (unlikely (rects == NULL)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } - - rect_count = 0; - - for (i = 0; i < traps->num_traps; i++) { + r = cairo_region_create (); + + for (i = 0; i < traps->num_traps; i++) + { + cairo_rectangle_int_t rect; + int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x); int y1 = _cairo_fixed_integer_part (traps->traps[i].top); int x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x); @@ -654,26 +644,22 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, if (x1 == x2 || y1 == y2) continue; - rects[rect_count].x = x1; - rects[rect_count].y = y1; - rects[rect_count].width = x2 - x1; - rects[rect_count].height = y2 - y1; + rect.x = x1; + rect.y = y1; + rect.width = x2 - x1; + rect.height = y2 - y1; - rect_count++; + status = cairo_region_union_rect (r, &rect); + if (unlikely (status)) + { + cairo_region_destroy (r); + r = NULL; + break; + } } - *region = cairo_region_create_rectangles (rects, rect_count); - status = cairo_region_status (*region); + *region = r; - if (rects != stack_rects) - free (rects); - - if (unlikely (status)) - { - cairo_region_destroy (*region); - *region = NULL; - } - return status; } diff --git a/src/cairo.h b/src/cairo.h index adf34b97..16b203dc 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2370,10 +2370,6 @@ cairo_region_create (void); cairo_public cairo_region_t * cairo_region_create_rect (cairo_rectangle_int_t *rect); -cairo_public cairo_region_t * -cairo_region_create_rectangles (cairo_rectangle_int_t *rects, - int count); - cairo_public cairo_region_t * cairo_region_copy (cairo_region_t *original); diff --git a/src/cairoint.h b/src/cairoint.h index 9d02d350..fbf8e350 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2696,7 +2696,6 @@ slim_hidden_proto (cairo_user_to_device_distance); slim_hidden_proto (cairo_version_string); slim_hidden_proto (cairo_region_create); slim_hidden_proto (cairo_region_create_rect); -slim_hidden_proto (cairo_region_create_rectangles); slim_hidden_proto (cairo_region_copy); slim_hidden_proto (cairo_region_destroy); slim_hidden_proto (cairo_region_status); -- cgit v1.2.3 From 4b3245481cfbf96388c140421a071fd1f79ad601 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Sat, 21 Feb 2009 08:13:25 -0500 Subject: [region] Expand rect to rectangle in a couple of names Specifically, cairo_region_union_rect -> cairo_region_union_rectangle cairo_region_create_rect -> cairo_region_create_rectangle Also delete cairo_region_clear() which is not that useful. --- src/cairo-analysis-surface.c | 4 ++-- src/cairo-clip.c | 4 ++-- src/cairo-region.c | 16 +++------------- src/cairo-surface-fallback.c | 2 +- src/cairo-surface.c | 4 ++-- src/cairo-traps.c | 2 +- src/cairo-xlib-surface.c | 2 +- src/cairo.h | 7 ++----- src/cairoint.h | 5 ++--- 9 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index feaa9d30..cd799852 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -234,7 +234,7 @@ _add_operation (cairo_analysis_surface_t *surface, * this region will be emitted as native operations. */ surface->has_supported = TRUE; - status = cairo_region_union_rect (surface->supported_region, rect); + status = cairo_region_union_rectangle (surface->supported_region, rect); return status; } @@ -243,7 +243,7 @@ _add_operation (cairo_analysis_surface_t *surface, * emitted. */ surface->has_unsupported = TRUE; - status = cairo_region_union_rect (surface->fallback_region, rect); + status = cairo_region_union_rectangle (surface->fallback_region, rect); /* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate * unsupported operations to the meta surface as using diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 58b6335a..8ee6a644 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -201,7 +201,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, if (clip->all_clipped) { cairo_region_t *clip_rect; - clip_rect = cairo_region_create_rect (&clip->surface_rect); + clip_rect = cairo_region_create_rectangle (&clip->surface_rect); status = cairo_region_intersect (region, clip_rect); @@ -223,7 +223,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, if (clip->surface) { cairo_region_t *clip_rect; - clip_rect = cairo_region_create_rect (&clip->surface_rect); + clip_rect = cairo_region_create_rectangle (&clip->surface_rect); status = cairo_region_intersect (region, clip_rect); diff --git a/src/cairo-region.c b/src/cairo-region.c index bc6598ac..a2a7a825 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -58,7 +58,7 @@ cairo_region_create (void) } cairo_region_t * -cairo_region_create_rect (cairo_rectangle_int_t *rect) +cairo_region_create_rectangle (cairo_rectangle_int_t *rect) { cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t)); @@ -162,16 +162,6 @@ cairo_region_status (cairo_region_t *region) return region->status; } -void -cairo_region_clear (cairo_region_t *region) -{ - if (region->status) - return; - - pixman_region32_fini (®ion->rgn); - pixman_region32_init (®ion->rgn); -} - cairo_status_t cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) { @@ -219,8 +209,8 @@ cairo_region_union (cairo_region_t *dst, } cairo_status_t -cairo_region_union_rect (cairo_region_t *dst, - cairo_rectangle_int_t *rect) +cairo_region_union_rectangle (cairo_region_t *dst, + cairo_rectangle_int_t *rect) { if (!pixman_region32_union_rect (&dst->rgn, &dst->rgn, rect->x, rect->y, diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 42d86e73..cbe92b23 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -567,7 +567,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, * _cairo_surface_fill_rectangles() or to drawing with a * clip region, then we have an additional region to clear. */ - clear_region = cairo_region_create_rect (&extents); + clear_region = cairo_region_create_rectangle (&extents); status = cairo_region_status (clear_region); if (unlikely (status)) diff --git a/src/cairo-surface.c b/src/cairo-surface.c index e0931221..82cd57ea 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2692,7 +2692,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, dst_rectangle.width = width; dst_rectangle.height = height; - clear_region = cairo_region_create_rect (&dst_rectangle); + clear_region = cairo_region_create_rectangle (&dst_rectangle); drawn_rectangle = dst_rectangle; @@ -2708,7 +2708,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, /* Now compute the area that is in dst_rectangle but not in drawn_rectangle */ - drawn_region = cairo_region_create_rect (&drawn_rectangle); + drawn_region = cairo_region_create_rectangle (&drawn_rectangle); has_drawn_region = TRUE; status = cairo_region_subtract (clear_region, drawn_region); diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 2fc2fac2..d91e0d8f 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -649,7 +649,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, rect.width = x2 - x1; rect.height = y2 - y1; - status = cairo_region_union_rect (r, &rect); + status = cairo_region_union_rectangle (r, &rect); if (unlikely (status)) { cairo_region_destroy (r); diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index f547f5fa..a6820afd 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2302,7 +2302,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, * is necessary so we don't wrap around when we convert cairo's * 32 bit region into 16 bit rectangles. */ - bounded = cairo_region_create_rect (&rect); + bounded = cairo_region_create_rectangle (&rect); status = cairo_region_intersect (bounded, region); if (unlikely (status)) { cairo_region_destroy (bounded); diff --git a/src/cairo.h b/src/cairo.h index 16b203dc..7a5a4d3d 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2368,7 +2368,7 @@ cairo_public cairo_region_t * cairo_region_create (void); cairo_public cairo_region_t * -cairo_region_create_rect (cairo_rectangle_int_t *rect); +cairo_region_create_rectangle (cairo_rectangle_int_t *rect); cairo_public cairo_region_t * cairo_region_copy (cairo_region_t *original); @@ -2401,9 +2401,6 @@ cairo_region_contains_rectangle (cairo_region_t *region, cairo_public cairo_bool_t cairo_region_contains_point (cairo_region_t *region, int x, int y); -cairo_public void -cairo_region_clear (cairo_region_t *region); - cairo_public void cairo_region_translate (cairo_region_t *region, int dx, int dy); @@ -2417,7 +2414,7 @@ cairo_public cairo_status_t cairo_region_union (cairo_region_t *dst, cairo_region_t *other); cairo_public cairo_status_t -cairo_region_union_rect (cairo_region_t *dst, cairo_rectangle_int_t *rect); +cairo_region_union_rectangle (cairo_region_t *dst, cairo_rectangle_int_t *rectangle); /* Functions to be used while debugging (not intended for use in production code) */ diff --git a/src/cairoint.h b/src/cairoint.h index fbf8e350..1f209a76 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2695,7 +2695,7 @@ slim_hidden_proto (cairo_user_to_device); slim_hidden_proto (cairo_user_to_device_distance); slim_hidden_proto (cairo_version_string); slim_hidden_proto (cairo_region_create); -slim_hidden_proto (cairo_region_create_rect); +slim_hidden_proto (cairo_region_create_rectangle); slim_hidden_proto (cairo_region_copy); slim_hidden_proto (cairo_region_destroy); slim_hidden_proto (cairo_region_status); @@ -2705,12 +2705,11 @@ slim_hidden_proto (cairo_region_get_rectangle); slim_hidden_proto (cairo_region_empty); slim_hidden_proto (cairo_region_contains_rectangle); slim_hidden_proto (cairo_region_contains_point); -slim_hidden_proto (cairo_region_clear); slim_hidden_proto (cairo_region_translate); slim_hidden_proto (cairo_region_subtract); slim_hidden_proto (cairo_region_intersect); slim_hidden_proto (cairo_region_union); -slim_hidden_proto (cairo_region_union_rect); +slim_hidden_proto (cairo_region_union_rectangle); #if CAIRO_HAS_PNG_FUNCTIONS -- cgit v1.2.3 From 26999e5aa8b5d353596e31d4b3823cafe007125c Mon Sep 17 00:00:00 2001 From: Søren Sandmann Date: Fri, 27 Mar 2009 08:48:42 -0400 Subject: [region] Add cairo_region_intersect_rectangle() and _subtract_rectangle() Intersecting with and subtracting rectangles is quite common, and we already have cairo_union_rectangle(). --- src/cairo-clip.c | 27 ++++----------------------- src/cairo-region.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- src/cairo-surface.c | 9 +-------- src/cairo.h | 11 ++++++++++- src/cairoint.h | 2 ++ 5 files changed, 61 insertions(+), 33 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 8ee6a644..cc43c037 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -198,17 +198,8 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, if (!clip) return CAIRO_STATUS_SUCCESS; - if (clip->all_clipped) { - cairo_region_t *clip_rect; - - clip_rect = cairo_region_create_rectangle (&clip->surface_rect); - - status = cairo_region_intersect (region, clip_rect); - - cairo_region_destroy (clip_rect); - - return status; - } + if (clip->all_clipped) + return cairo_region_intersect_rectangle (region, &clip->surface_rect); if (clip->path) { /* Intersect clip path into region. */ @@ -220,18 +211,8 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, return status; } - if (clip->surface) { - cairo_region_t *clip_rect; - - clip_rect = cairo_region_create_rectangle (&clip->surface_rect); - - status = cairo_region_intersect (region, clip_rect); - - cairo_region_destroy (clip_rect); - - if (unlikely (status)) - return status; - } + if (clip->surface) + return cairo_region_intersect_rectangle (region, &clip->surface_rect); return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-region.c b/src/cairo-region.c index a2a7a825..55898d9c 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -177,6 +177,28 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) return CAIRO_STATUS_SUCCESS; } +cairo_status_t +cairo_region_subtract_rectangle (cairo_region_t *dst, + cairo_rectangle_int_t *rectangle) +{ + cairo_status_t status = CAIRO_STATUS_SUCCESS; + pixman_region32_t region; + + if (dst->status) + return dst->status; + + pixman_region32_init_rect (®ion, + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); + + if (!pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion)) + status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + + pixman_region32_fini (®ion); + + return status; +} + cairo_status_t cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) { @@ -192,6 +214,27 @@ cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) return CAIRO_STATUS_SUCCESS; } +cairo_status_t +cairo_region_intersect_rectangle (cairo_region_t *dst, + const cairo_rectangle_int_t *rect) +{ + cairo_status_t result = CAIRO_STATUS_SUCCESS; + pixman_region32_t region; + + if (dst->status) + return dst->status; + + pixman_region32_init_rect (®ion, + rect->x, rect->y, rect->width, rect->height); + + if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion)) + result = _cairo_error (CAIRO_STATUS_NO_MEMORY); + + pixman_region32_fini (®ion); + + return result; +} + cairo_status_t cairo_region_union (cairo_region_t *dst, cairo_region_t *other) @@ -210,7 +253,7 @@ cairo_region_union (cairo_region_t *dst, cairo_status_t cairo_region_union_rectangle (cairo_region_t *dst, - cairo_rectangle_int_t *rect) + const cairo_rectangle_int_t *rect) { if (!pixman_region32_union_rect (&dst->rgn, &dst->rgn, rect->x, rect->y, diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 82cd57ea..1c8445f9 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2679,8 +2679,6 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, { cairo_rectangle_int_t dst_rectangle; cairo_rectangle_int_t drawn_rectangle; - cairo_bool_t has_drawn_region = FALSE; - cairo_region_t *drawn_region = NULL; cairo_region_t *clear_region = NULL; cairo_status_t status; @@ -2708,10 +2706,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, /* Now compute the area that is in dst_rectangle but not in drawn_rectangle */ - drawn_region = cairo_region_create_rectangle (&drawn_rectangle); - has_drawn_region = TRUE; - - status = cairo_region_subtract (clear_region, drawn_region); + status = cairo_region_subtract_rectangle (clear_region, &drawn_rectangle); if (unlikely (status)) goto CLEANUP_REGIONS; @@ -2721,8 +2716,6 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, clear_region); CLEANUP_REGIONS: - if (drawn_region) - cairo_region_destroy (drawn_region); cairo_region_destroy (clear_region); return _cairo_surface_set_error (dst, status); diff --git a/src/cairo.h b/src/cairo.h index 7a5a4d3d..269fe4d9 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2407,14 +2407,23 @@ cairo_region_translate (cairo_region_t *region, int dx, int dy); cairo_public cairo_status_t cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other); +cairo_public cairo_status_t +cairo_region_subtract_rectangle (cairo_region_t *dst, + cairo_rectangle_int_t *rectangle); + cairo_public cairo_status_t cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other); +cairo_public cairo_status_t +cairo_region_intersect_rectangle (cairo_region_t *dst, + const cairo_rectangle_int_t *rect); + cairo_public cairo_status_t cairo_region_union (cairo_region_t *dst, cairo_region_t *other); cairo_public cairo_status_t -cairo_region_union_rectangle (cairo_region_t *dst, cairo_rectangle_int_t *rectangle); +cairo_region_union_rectangle (cairo_region_t *dst, + const cairo_rectangle_int_t *rectangle); /* Functions to be used while debugging (not intended for use in production code) */ diff --git a/src/cairoint.h b/src/cairoint.h index 1f209a76..6c5fd5a6 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2707,7 +2707,9 @@ slim_hidden_proto (cairo_region_contains_rectangle); slim_hidden_proto (cairo_region_contains_point); slim_hidden_proto (cairo_region_translate); slim_hidden_proto (cairo_region_subtract); +slim_hidden_proto (cairo_region_subtract_rectangle); slim_hidden_proto (cairo_region_intersect); +slim_hidden_proto (cairo_region_intersect_rectangle); slim_hidden_proto (cairo_region_union); slim_hidden_proto (cairo_region_union_rectangle); -- cgit v1.2.3 From 64e490a464472cfe06d779503601d41972ed4518 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Sat, 28 Mar 2009 01:10:24 -0400 Subject: [region] Use signed ints for width and height in cairo_rectangle_int_t --- src/cairo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo.h b/src/cairo.h index 269fe4d9..c496185d 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2355,7 +2355,7 @@ typedef struct _cairo_region cairo_region_t; typedef struct _cairo_rectangle_int { int x, y; - unsigned int width, height; + int width, height; } cairo_rectangle_int_t; typedef enum _cairo_region_overlap { -- cgit v1.2.3 From 980e9f0dbd4f21c0ccf4cc33b0b0f2f370667290 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Sat, 28 Mar 2009 03:04:28 -0400 Subject: [region] Fix status propagation for regions When an operation fails, store the status code in the destination region rather than leaving it unchanged. --- src/cairo-region.c | 66 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index 55898d9c..aec1bdf1 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -42,6 +42,40 @@ const cairo_region_t _cairo_region_nil = { CAIRO_STATUS_NO_MEMORY, /* status */ }; +/** + * cairo_region_set_error: + * @region: a region + * @status: a status value indicating an error + * + * Atomically sets region->status to @status and calls _cairo_error; + * Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal + * status values. + * + * All assignments of an error status to region->status should happen + * through cairo_region_set_error(). Note that due to the nature of + * the atomic operation, it is not safe to call this function on the + * nil objects. + * + * The purpose of this function is to allow the user to set a + * breakpoint in _cairo_error() to generate a stack trace for when the + * user causes cairo to detect an error. + * + * Return value: the error status. + **/ +static cairo_status_t +cairo_region_set_error (cairo_region_t *region, + cairo_status_t status) +{ + if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED) + return status; + + /* Don't overwrite an existing error. This preserves the first + * error, which is the most significant. */ + _cairo_status_set_error (®ion->status, status); + + return _cairo_error (status); +} + cairo_region_t * cairo_region_create (void) { @@ -172,7 +206,7 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) return other->status; if (!pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -207,9 +241,9 @@ cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) if (other->status) return other->status; - + if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, &other->rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -218,7 +252,7 @@ cairo_status_t cairo_region_intersect_rectangle (cairo_region_t *dst, const cairo_rectangle_int_t *rect) { - cairo_status_t result = CAIRO_STATUS_SUCCESS; + cairo_status_t status = CAIRO_STATUS_SUCCESS; pixman_region32_t region; if (dst->status) @@ -228,11 +262,11 @@ cairo_region_intersect_rectangle (cairo_region_t *dst, rect->x, rect->y, rect->width, rect->height); if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion)) - result = _cairo_error (CAIRO_STATUS_NO_MEMORY); + status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); pixman_region32_fini (®ion); - return result; + return status; } cairo_status_t @@ -246,7 +280,7 @@ cairo_region_union (cairo_region_t *dst, return other->status; if (!pixman_region32_union (&dst->rgn, &dst->rgn, &other->rgn)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -255,14 +289,18 @@ cairo_status_t cairo_region_union_rectangle (cairo_region_t *dst, const cairo_rectangle_int_t *rect) { - if (!pixman_region32_union_rect (&dst->rgn, &dst->rgn, - rect->x, rect->y, - rect->width, rect->height)) - { - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - } + cairo_status_t status = CAIRO_STATUS_SUCCESS; + pixman_region32_t region; - return CAIRO_STATUS_SUCCESS; + pixman_region32_init_rect (®ion, + rect->x, rect->y, rect->width, rect->height); + + if (!pixman_region32_union (&dst->rgn, &dst->rgn, ®ion)) + status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + + pixman_region32_fini (®ion); + + return status; } cairo_bool_t -- cgit v1.2.3 From 62d84847c3b857b8fd5aeea3f4b5c0f2f4c91625 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Sat, 28 Mar 2009 03:58:51 -0400 Subject: [region] Add documentation for all the new region methods. --- src/cairo-region.c | 260 ++++++++++++++++++++++++++++++++++++++++++++++------- src/cairo.h | 6 +- 2 files changed, 232 insertions(+), 34 deletions(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index aec1bdf1..e162321b 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -76,6 +76,19 @@ cairo_region_set_error (cairo_region_t *region, return _cairo_error (status); } +/** + * cairo_region_create: + * + * Allocates a new empty region object. + * + * Return value: A newly allocated #cairo_region_t. Free with + * cairo_region_destroy(). This function always returns a + * valid pointer; if memory cannot be allocated, then a special + * error object is returned where all operations on the object do nothing. + * You can check for this with cairo_region_status(). + * + * Since: 1.10 + **/ cairo_region_t * cairo_region_create (void) { @@ -91,8 +104,22 @@ cairo_region_create (void) return region; } +/** + * cairo_region_create_rectangle: + * @rectangle: a #cairo_rectangle_int_t + * + * Allocates a new region object containing @rectangle. + * + * Return value: A newly allocated #cairo_region_t. Free with + * cairo_region_destroy(). This function always returns a + * valid pointer; if memory cannot be allocated, then a special + * error object is returned where all operations on the object do nothing. + * You can check for this with cairo_region_status(). + * + * Since: 1.10 + **/ cairo_region_t * -cairo_region_create_rectangle (cairo_rectangle_int_t *rect) +cairo_region_create_rectangle (cairo_rectangle_int_t *rectangle) { cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t)); @@ -102,22 +129,26 @@ cairo_region_create_rectangle (cairo_rectangle_int_t *rect) region->status = CAIRO_STATUS_SUCCESS; pixman_region32_init_rect (®ion->rgn, - rect->x, rect->y, - rect->width, rect->height); + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); return region; } -void -cairo_region_destroy (cairo_region_t *region) -{ - if (region->status) - return; - - pixman_region32_fini (®ion->rgn); - free (region); -} - +/** + * cairo_region_copy: + * @original: a #cairo_region_t + * + * Allocates a new region object copying the area from @original. + * + * Return value: A newly allocated #cairo_region_t. Free with + * cairo_region_destroy(). This function always returns a + * valid pointer; if memory cannot be allocated, then a special + * error object is returned where all operations on the object do nothing. + * You can check for this with cairo_region_status(). + * + * Since: 1.10 + **/ cairo_region_t * cairo_region_copy (cairo_region_t *original) { @@ -139,6 +170,36 @@ cairo_region_copy (cairo_region_t *original) return copy; } +/** + * cairo_region_destroy: + * @region: a #cairo_region_t + * + * Destroys a #cairo_region_t object created with + * cairo_region_create(), cairo_region_copy(), or + * or cairo_region_create_rectangle(). + * + * Since: 1.10 + **/ +void +cairo_region_destroy (cairo_region_t *region) +{ + if (region->status) + return; + + pixman_region32_fini (®ion->rgn); + free (region); +} + +/** + * cairo_region_num_rectangles: + * @region: a #cairo_region_t + * + * Returns the number of rectangles contained in @region. + * + * Return value: The number of rectangles contained in @region. + * + * Since: 1.10 + **/ int cairo_region_num_rectangles (cairo_region_t *region) { @@ -148,30 +209,42 @@ cairo_region_num_rectangles (cairo_region_t *region) return pixman_region32_n_rects (®ion->rgn); } +/** + * cairo_region_get_rectangle: + * @region: a #cairo_region_t + * @nth: a number indicating which rectangle should be returned + * @rectangle: return location for a #cairo_rectangle_int_t + * + * Stores the @nth rectangle from the region in @rectangle. + * + * Since: 1.10 + **/ void cairo_region_get_rectangle (cairo_region_t *region, - int nth_box, - cairo_rectangle_int_t *rect) + int nth, + cairo_rectangle_int_t *rectangle) { pixman_box32_t *pbox; if (region->status) return; - pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth_box; + pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth; - rect->x = pbox->x1; - rect->y = pbox->y1; - rect->width = pbox->x2 - pbox->x1; - rect->height = pbox->y2 - pbox->y1; + rectangle->x = pbox->x1; + rectangle->y = pbox->y1; + rectangle->width = pbox->x2 - pbox->x1; + rectangle->height = pbox->y2 - pbox->y1; } /** * cairo_region_get_extents: * @region: a #cairo_region_t - * @rect: rectangle into which to store the extents + * @rectangle: rectangle into which to store the extents * - * Gets the bounding box of a region as a #cairo_rectangle_int_t + * Gets the bounding rectangle of @region as a #cairo_rectangle_int_t + * + * Since: 1.10 **/ void cairo_region_get_extents (cairo_region_t *region, @@ -190,12 +263,34 @@ cairo_region_get_extents (cairo_region_t *region, extents->height = pextents->y2 - pextents->y1; } +/** + * cairo_region_status: + * @region: a #cairo_region_t + * + * Checks whether an error has previous occured for this + * region object. + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ cairo_status_t cairo_region_status (cairo_region_t *region) { return region->status; } +/** + * cairo_region_subtract: + * @dst: a #cairo_region_t + * @other: another #cairo_region_t + * + * Subtracts @other from @dst and places the result in @dst + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ cairo_status_t cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) { @@ -211,6 +306,17 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) return CAIRO_STATUS_SUCCESS; } +/** + * cairo_region_subtract_rectangle: + * @dst: a #cairo_region_t + * @rectangle: a #cairo_rectangle_int_t + * + * Subtracts @rectangle from @dst and places the result in @dst + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ cairo_status_t cairo_region_subtract_rectangle (cairo_region_t *dst, cairo_rectangle_int_t *rectangle) @@ -233,6 +339,17 @@ cairo_region_subtract_rectangle (cairo_region_t *dst, return status; } +/** + * cairo_region_intersect: + * @dst: a #cairo_region_t + * @other: another #cairo_region_t + * + * Computes the intersection of @dst with @other and places the result in @dst + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ cairo_status_t cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) { @@ -248,9 +365,20 @@ cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) return CAIRO_STATUS_SUCCESS; } +/** + * cairo_region_intersect_rectangle: + * @dst: a #cairo_region_t + * @rectangle: a #cairo_rectangle_int_t + * + * Computes the intersection of @dst with @rectangle and places the result in @dst + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ cairo_status_t cairo_region_intersect_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rect) + const cairo_rectangle_int_t *rectangle) { cairo_status_t status = CAIRO_STATUS_SUCCESS; pixman_region32_t region; @@ -259,7 +387,8 @@ cairo_region_intersect_rectangle (cairo_region_t *dst, return dst->status; pixman_region32_init_rect (®ion, - rect->x, rect->y, rect->width, rect->height); + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion)) status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); @@ -269,6 +398,17 @@ cairo_region_intersect_rectangle (cairo_region_t *dst, return status; } +/** + * cairo_region_union: + * @dst: a #cairo_region_t + * @other: another #cairo_region_t + * + * Computes the union of @dst with @other and places the result in @dst + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ cairo_status_t cairo_region_union (cairo_region_t *dst, cairo_region_t *other) @@ -285,15 +425,27 @@ cairo_region_union (cairo_region_t *dst, return CAIRO_STATUS_SUCCESS; } +/** + * cairo_region_union_rectangle: + * @dst: a #cairo_region_t + * @rectangle: a #cairo_rectangle_int_t + * + * Computes the union of @dst with @rectangle and places the result in @dst. + * + * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY + * + * Since: 1.10 + **/ cairo_status_t cairo_region_union_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rect) + const cairo_rectangle_int_t *rectangle) { cairo_status_t status = CAIRO_STATUS_SUCCESS; pixman_region32_t region; pixman_region32_init_rect (®ion, - rect->x, rect->y, rect->width, rect->height); + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); if (!pixman_region32_union (&dst->rgn, &dst->rgn, ®ion)) status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); @@ -303,6 +455,16 @@ cairo_region_union_rectangle (cairo_region_t *dst, return status; } +/** + * cairo_region_empty: + * @region: a #cairo_region_t + * + * Checks whether @region is empty. + * + * Return value: %TRUE if @region is empty, %FALSE if it isn't. + * + * Since: 1.10 + **/ cairo_bool_t cairo_region_empty (cairo_region_t *region) { @@ -312,6 +474,16 @@ cairo_region_empty (cairo_region_t *region) return !pixman_region32_not_empty (®ion->rgn); } +/** + * cairo_region_translate: + * @region: a #cairo_region_t + * @dx: Amount to translate in the x direction + * @dy: Amount to translate in the y direction + * + * Translates @region by (@dx, @dy). + * + * Since: 1.10 + **/ void cairo_region_translate (cairo_region_t *region, int dx, int dy) @@ -322,19 +494,33 @@ cairo_region_translate (cairo_region_t *region, pixman_region32_translate (®ion->rgn, dx, dy); } +/** + * cairo_region_contains_rectangle: + * @region: a #cairo_region_t + * @rectangle: a #cairo_rectangle_int_t + * + * Checks whether @rectangle is inside, outside or partially contained in @region + * + * Return value: + * %CAIRO_REGION_OVERLAP_IN if @rectangle is entirely inside @region, + * %CAIRO_REGION_OVERLAP_OUT if @rectangle is entirely outside @region, or + * %CAIRO_REGION_OVERLAP_PART if @rectangle is partially inside and partially outside @region. + * + * Since: 1.10 + **/ cairo_region_overlap_t cairo_region_contains_rectangle (cairo_region_t *region, - const cairo_rectangle_int_t *rect) + const cairo_rectangle_int_t *rectangle) { pixman_box32_t pbox; pixman_region_overlap_t poverlap; if (!region->status) { - pbox.x1 = rect->x; - pbox.y1 = rect->y; - pbox.x2 = rect->x + rect->width; - pbox.y2 = rect->y + rect->height; + pbox.x1 = rectangle->x; + pbox.y1 = rectangle->y; + pbox.x2 = rectangle->x + rectangle->width; + pbox.y2 = rectangle->y + rectangle->height; poverlap = pixman_region32_contains_rectangle (®ion->rgn, &pbox); @@ -354,6 +540,18 @@ cairo_region_contains_rectangle (cairo_region_t *region, return CAIRO_REGION_OVERLAP_OUT; } +/** + * cairo_region_contains_point: + * @region: a #cairo_region_t + * @x: the x coordinate of a point + * @y: the y coordinate of a point + * + * Checks whether (@x, @y) is contained in @region. + * + * Return value: %TRUE if (@x, @y) is contained in @region, %FALSE if it is not. + * + * Since: 1.10 + **/ cairo_bool_t cairo_region_contains_point (cairo_region_t *region, int x, int y) diff --git a/src/cairo.h b/src/cairo.h index c496185d..025ca6c9 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2368,7 +2368,7 @@ cairo_public cairo_region_t * cairo_region_create (void); cairo_public cairo_region_t * -cairo_region_create_rectangle (cairo_rectangle_int_t *rect); +cairo_region_create_rectangle (cairo_rectangle_int_t *rectangle); cairo_public cairo_region_t * cairo_region_copy (cairo_region_t *original); @@ -2396,7 +2396,7 @@ cairo_region_empty (cairo_region_t *region); cairo_public cairo_region_overlap_t cairo_region_contains_rectangle (cairo_region_t *region, - const cairo_rectangle_int_t *rect); + const cairo_rectangle_int_t *rectangle); cairo_public cairo_bool_t cairo_region_contains_point (cairo_region_t *region, int x, int y); @@ -2416,7 +2416,7 @@ cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other); cairo_public cairo_status_t cairo_region_intersect_rectangle (cairo_region_t *dst, - const cairo_rectangle_int_t *rect); + const cairo_rectangle_int_t *rectangle); cairo_public cairo_status_t cairo_region_union (cairo_region_t *dst, cairo_region_t *other); -- cgit v1.2.3 From f31c6548f818e1d4e257d94d623705284bcc4274 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 28 Mar 2009 19:26:03 +0000 Subject: Silence compiler warnings for CAIRO_STATUS_LAST_STATUS Add ASSERT_NOT_REACHED (or similar) cases to the error handling switches to silence the compiler. --- src/cairo-misc.c | 5 +++-- src/cairo-spans.c | 2 ++ src/cairo-surface.c | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cairo-misc.c b/src/cairo-misc.c index a6d4ffae..aaf849b9 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -123,9 +123,10 @@ cairo_status_to_string (cairo_status_t status) return "invalid value for an input #cairo_font_weight_t"; case CAIRO_STATUS_INVALID_SIZE: return "invalid value for the size of the input (surface, pattern, etc.)"; + default: + case CAIRO_STATUS_LAST_STATUS: + return ""; } - - return ""; } diff --git a/src/cairo-spans.c b/src/cairo-spans.c index b6ac2c56..625f83f1 100644 --- a/src/cairo-spans.c +++ b/src/cairo-spans.c @@ -255,6 +255,7 @@ _cairo_scan_converter_create_in_error (cairo_status_t status) } switch (status) { case CAIRO_STATUS_SUCCESS: + case CAIRO_STATUS_LAST_STATUS: ASSERT_NOT_REACHED; break; case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL; @@ -359,6 +360,7 @@ _cairo_span_renderer_create_in_error (cairo_status_t status) } switch (status) { case CAIRO_STATUS_SUCCESS: + case CAIRO_STATUS_LAST_STATUS: ASSERT_NOT_REACHED; break; case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 1c8445f9..3df8c7ab 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2950,6 +2950,7 @@ _cairo_surface_create_in_error (cairo_status_t status) case CAIRO_STATUS_INVALID_STRIDE: return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride; case CAIRO_STATUS_SUCCESS: + case CAIRO_STATUS_LAST_STATUS: ASSERT_NOT_REACHED; /* fall-through */ case CAIRO_STATUS_INVALID_RESTORE: -- cgit v1.2.3 From ed7188a471f73abcc4ca3e2a92685088134391c7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 10:07:48 +0100 Subject: [region] Add slim_hidden_def. Fixes for check-plt.sh (and a few adjacent whitespace). --- src/cairo-region.c | 244 +++++++++++++++++++++++++++++------------------------ 1 file changed, 133 insertions(+), 111 deletions(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index e162321b..2eab3344 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -38,7 +38,7 @@ #include "cairoint.h" -const cairo_region_t _cairo_region_nil = { +static const cairo_region_t _cairo_region_nil = { CAIRO_STATUS_NO_MEMORY, /* status */ }; @@ -80,22 +80,23 @@ cairo_region_set_error (cairo_region_t *region, * cairo_region_create: * * Allocates a new empty region object. - * + * * Return value: A newly allocated #cairo_region_t. Free with * cairo_region_destroy(). This function always returns a * valid pointer; if memory cannot be allocated, then a special * error object is returned where all operations on the object do nothing. * You can check for this with cairo_region_status(). - * + * * Since: 1.10 **/ cairo_region_t * cairo_region_create (void) { - cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t)); + cairo_region_t *region; - if (!region) - return (cairo_region_t *)&_cairo_region_nil; + region = _cairo_malloc (sizeof (cairo_region_t)); + if (region == NULL) + return (cairo_region_t *) &_cairo_region_nil; region->status = CAIRO_STATUS_SUCCESS; @@ -103,101 +104,105 @@ cairo_region_create (void) return region; } +slim_hidden_def (cairo_region_create); /** * cairo_region_create_rectangle: * @rectangle: a #cairo_rectangle_int_t * * Allocates a new region object containing @rectangle. - * + * * Return value: A newly allocated #cairo_region_t. Free with * cairo_region_destroy(). This function always returns a * valid pointer; if memory cannot be allocated, then a special * error object is returned where all operations on the object do nothing. * You can check for this with cairo_region_status(). - * + * * Since: 1.10 **/ cairo_region_t * cairo_region_create_rectangle (cairo_rectangle_int_t *rectangle) { - cairo_region_t *region = _cairo_malloc (sizeof (cairo_region_t)); + cairo_region_t *region; + + region = _cairo_malloc (sizeof (cairo_region_t)); + if (region == NULL) + return (cairo_region_t *) &_cairo_region_nil; - if (!region) - return (cairo_region_t *)&_cairo_region_nil; - region->status = CAIRO_STATUS_SUCCESS; - + pixman_region32_init_rect (®ion->rgn, rectangle->x, rectangle->y, rectangle->width, rectangle->height); return region; } +slim_hidden_def (cairo_region_create_rectangle); /** * cairo_region_copy: * @original: a #cairo_region_t - * + * * Allocates a new region object copying the area from @original. - * + * * Return value: A newly allocated #cairo_region_t. Free with * cairo_region_destroy(). This function always returns a * valid pointer; if memory cannot be allocated, then a special * error object is returned where all operations on the object do nothing. * You can check for this with cairo_region_status(). - * + * * Since: 1.10 **/ cairo_region_t * cairo_region_copy (cairo_region_t *original) { cairo_region_t *copy; - + if (original->status) - return (cairo_region_t *)&_cairo_region_nil; + return (cairo_region_t *) &_cairo_region_nil; copy = cairo_region_create (); - if (!copy) - return (cairo_region_t *)&_cairo_region_nil; + if (copy->status) + return copy; - if (!pixman_region32_copy (©->rgn, &original->rgn)) { + if (! pixman_region32_copy (©->rgn, &original->rgn)) { cairo_region_destroy (copy); - - return (cairo_region_t *)&_cairo_region_nil; + return (cairo_region_t *) &_cairo_region_nil; } return copy; } +slim_hidden_def (cairo_region_copy); /** * cairo_region_destroy: * @region: a #cairo_region_t - * + * * Destroys a #cairo_region_t object created with * cairo_region_create(), cairo_region_copy(), or * or cairo_region_create_rectangle(). - * + * * Since: 1.10 **/ void cairo_region_destroy (cairo_region_t *region) { - if (region->status) + if (region == (cairo_region_t *) &_cairo_region_nil) return; - + pixman_region32_fini (®ion->rgn); free (region); } +slim_hidden_def (cairo_region_destroy); /** * cairo_region_num_rectangles: * @region: a #cairo_region_t - * + * * Returns the number of rectangles contained in @region. - * + * * Return value: The number of rectangles contained in @region. - * + * * Since: 1.10 **/ int @@ -205,18 +210,19 @@ cairo_region_num_rectangles (cairo_region_t *region) { if (region->status) return 0; - + return pixman_region32_n_rects (®ion->rgn); } +slim_hidden_def (cairo_region_num_rectangles); /** * cairo_region_get_rectangle: * @region: a #cairo_region_t * @nth: a number indicating which rectangle should be returned * @rectangle: return location for a #cairo_rectangle_int_t - * + * * Stores the @nth rectangle from the region in @rectangle. - * + * * Since: 1.10 **/ void @@ -226,9 +232,12 @@ cairo_region_get_rectangle (cairo_region_t *region, { pixman_box32_t *pbox; - if (region->status) + if (region->status) { + rectangle->x = rectangle->y = 0; + rectangle->width = rectangle->height = 0; return; - + } + pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth; rectangle->x = pbox->x1; @@ -236,6 +245,7 @@ cairo_region_get_rectangle (cairo_region_t *region, rectangle->width = pbox->x2 - pbox->x1; rectangle->height = pbox->y2 - pbox->y1; } +slim_hidden_def (cairo_region_get_rectangle); /** * cairo_region_get_extents: @@ -252,8 +262,11 @@ cairo_region_get_extents (cairo_region_t *region, { pixman_box32_t *pextents; - if (region->status || !extents) + if (region->status) { + extents->x = extents->y = 0; + extents->width = extents->height = 0; return; + } pextents = pixman_region32_extents (®ion->rgn); @@ -262,16 +275,17 @@ cairo_region_get_extents (cairo_region_t *region, extents->width = pextents->x2 - pextents->x1; extents->height = pextents->y2 - pextents->y1; } +slim_hidden_def (cairo_region_get_extents); /** * cairo_region_status: * @region: a #cairo_region_t - * + * * Checks whether an error has previous occured for this * region object. - * + * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * + * * Since: 1.10 **/ cairo_status_t @@ -279,16 +293,17 @@ cairo_region_status (cairo_region_t *region) { return region->status; } +slim_hidden_def (cairo_region_status); /** * cairo_region_subtract: - * @dst: a #cairo_region_t + * @dst: a #cairo_region_t * @other: another #cairo_region_t - * + * * Subtracts @other from @dst and places the result in @dst - * + * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * + * * Since: 1.10 **/ cairo_status_t @@ -298,13 +313,14 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) return dst->status; if (other->status) - return other->status; - - if (!pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn)) + return cairo_region_set_error (dst, other->status); + + if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn)) return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } +slim_hidden_def (cairo_region_subtract); /** * cairo_region_subtract_rectangle: @@ -312,9 +328,9 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) * @rectangle: a #cairo_rectangle_int_t * * Subtracts @rectangle from @dst and places the result in @dst - * + * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * + * * Since: 1.10 **/ cairo_status_t @@ -326,28 +342,29 @@ cairo_region_subtract_rectangle (cairo_region_t *dst, if (dst->status) return dst->status; - + pixman_region32_init_rect (®ion, rectangle->x, rectangle->y, rectangle->width, rectangle->height); - if (!pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion)) + if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion)) status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); pixman_region32_fini (®ion); - + return status; } +slim_hidden_def (cairo_region_subtract_rectangle); /** * cairo_region_intersect: * @dst: a #cairo_region_t * @other: another #cairo_region_t - * + * * Computes the intersection of @dst with @other and places the result in @dst - * + * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * + * * Since: 1.10 **/ cairo_status_t @@ -357,23 +374,25 @@ cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) return dst->status; if (other->status) - return other->status; + return cairo_region_set_error (dst, other->status); - if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, &other->rgn)) + if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, &other->rgn)) return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } +slim_hidden_def (cairo_region_intersect); /** * cairo_region_intersect_rectangle: * @dst: a #cairo_region_t * @rectangle: a #cairo_rectangle_int_t - * - * Computes the intersection of @dst with @rectangle and places the result in @dst - * + * + * Computes the intersection of @dst with @rectangle and places the + * result in @dst + * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * + * * Since: 1.10 **/ cairo_status_t @@ -385,28 +404,29 @@ cairo_region_intersect_rectangle (cairo_region_t *dst, if (dst->status) return dst->status; - + pixman_region32_init_rect (®ion, rectangle->x, rectangle->y, rectangle->width, rectangle->height); - if (!pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion)) + if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion)) status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); pixman_region32_fini (®ion); - + return status; } +slim_hidden_def (cairo_region_intersect_rectangle); /** * cairo_region_union: * @dst: a #cairo_region_t * @other: another #cairo_region_t - * + * * Computes the union of @dst with @other and places the result in @dst - * + * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * + * * Since: 1.10 **/ cairo_status_t @@ -417,23 +437,24 @@ cairo_region_union (cairo_region_t *dst, return dst->status; if (other->status) - return other->status; + return cairo_region_set_error (dst, other->status); - if (!pixman_region32_union (&dst->rgn, &dst->rgn, &other->rgn)) + if (! pixman_region32_union (&dst->rgn, &dst->rgn, &other->rgn)) return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } +slim_hidden_def (cairo_region_union); /** * cairo_region_union_rectangle: * @dst: a #cairo_region_t * @rectangle: a #cairo_rectangle_int_t - * + * * Computes the union of @dst with @rectangle and places the result in @dst. - * + * * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY - * + * * Since: 1.10 **/ cairo_status_t @@ -443,26 +464,30 @@ cairo_region_union_rectangle (cairo_region_t *dst, cairo_status_t status = CAIRO_STATUS_SUCCESS; pixman_region32_t region; + if (dst->status) + return dst->status; + pixman_region32_init_rect (®ion, rectangle->x, rectangle->y, rectangle->width, rectangle->height); - - if (!pixman_region32_union (&dst->rgn, &dst->rgn, ®ion)) + + if (! pixman_region32_union (&dst->rgn, &dst->rgn, ®ion)) status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); pixman_region32_fini (®ion); - + return status; } +slim_hidden_def (cairo_region_union_rectangle); /** * cairo_region_empty: * @region: a #cairo_region_t - * + * * Checks whether @region is empty. - * + * * Return value: %TRUE if @region is empty, %FALSE if it isn't. - * + * * Since: 1.10 **/ cairo_bool_t @@ -470,18 +495,19 @@ cairo_region_empty (cairo_region_t *region) { if (region->status) return TRUE; - - return !pixman_region32_not_empty (®ion->rgn); + + return ! pixman_region32_not_empty (®ion->rgn); } +slim_hidden_def (cairo_region_empty); /** * cairo_region_translate: * @region: a #cairo_region_t * @dx: Amount to translate in the x direction * @dy: Amount to translate in the y direction - * + * * Translates @region by (@dx, @dy). - * + * * Since: 1.10 **/ void @@ -490,22 +516,24 @@ cairo_region_translate (cairo_region_t *region, { if (region->status) return; - + pixman_region32_translate (®ion->rgn, dx, dy); } +slim_hidden_def (cairo_region_translate); /** * cairo_region_contains_rectangle: * @region: a #cairo_region_t * @rectangle: a #cairo_rectangle_int_t - * - * Checks whether @rectangle is inside, outside or partially contained in @region - * + * + * Checks whether @rectangle is inside, outside or partially contained + * in @region + * * Return value: * %CAIRO_REGION_OVERLAP_IN if @rectangle is entirely inside @region, * %CAIRO_REGION_OVERLAP_OUT if @rectangle is entirely outside @region, or * %CAIRO_REGION_OVERLAP_PART if @rectangle is partially inside and partially outside @region. - * + * * Since: 1.10 **/ cairo_region_overlap_t @@ -515,41 +543,34 @@ cairo_region_contains_rectangle (cairo_region_t *region, pixman_box32_t pbox; pixman_region_overlap_t poverlap; - if (!region->status) - { - pbox.x1 = rectangle->x; - pbox.y1 = rectangle->y; - pbox.x2 = rectangle->x + rectangle->width; - pbox.y2 = rectangle->y + rectangle->height; - - poverlap = pixman_region32_contains_rectangle (®ion->rgn, &pbox); - - switch (poverlap) - { - case PIXMAN_REGION_OUT: - return CAIRO_REGION_OVERLAP_OUT; - - case PIXMAN_REGION_IN: - return CAIRO_REGION_OVERLAP_IN; - - case PIXMAN_REGION_PART: - return CAIRO_REGION_OVERLAP_PART; - } + if (region->status) + return CAIRO_REGION_OVERLAP_OUT; + + pbox.x1 = rectangle->x; + pbox.y1 = rectangle->y; + pbox.x2 = rectangle->x + rectangle->width; + pbox.y2 = rectangle->y + rectangle->height; + + poverlap = pixman_region32_contains_rectangle (®ion->rgn, &pbox); + switch (poverlap) { + default: + case PIXMAN_REGION_OUT: return CAIRO_REGION_OVERLAP_OUT; + case PIXMAN_REGION_IN: return CAIRO_REGION_OVERLAP_IN; + case PIXMAN_REGION_PART: return CAIRO_REGION_OVERLAP_PART; } - - return CAIRO_REGION_OVERLAP_OUT; } +slim_hidden_def (cairo_region_contains_rectangle); /** * cairo_region_contains_point: * @region: a #cairo_region_t * @x: the x coordinate of a point * @y: the y coordinate of a point - * + * * Checks whether (@x, @y) is contained in @region. - * + * * Return value: %TRUE if (@x, @y) is contained in @region, %FALSE if it is not. - * + * * Since: 1.10 **/ cairo_bool_t @@ -561,3 +582,4 @@ cairo_region_contains_point (cairo_region_t *region, return pixman_region32_contains_point (®ion->rgn, x, y, NULL); } +slim_hidden_def (cairo_region_contains_point); -- cgit v1.2.3 From f027405429d0133b2840c4b82bc553355fa5f3d2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 10:12:41 +0100 Subject: [region] Add leading underscore to private _cairo_region_set_error() Differentiate the private _cairo_region_set_error() function by using a leading underscore. --- src/cairo-region.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index 2eab3344..e61e441d 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -43,7 +43,7 @@ static const cairo_region_t _cairo_region_nil = { }; /** - * cairo_region_set_error: + * _cairo_region_set_error: * @region: a region * @status: a status value indicating an error * @@ -52,7 +52,7 @@ static const cairo_region_t _cairo_region_nil = { * status values. * * All assignments of an error status to region->status should happen - * through cairo_region_set_error(). Note that due to the nature of + * through _cairo_region_set_error(). Note that due to the nature of * the atomic operation, it is not safe to call this function on the * nil objects. * @@ -63,7 +63,7 @@ static const cairo_region_t _cairo_region_nil = { * Return value: the error status. **/ static cairo_status_t -cairo_region_set_error (cairo_region_t *region, +_cairo_region_set_error (cairo_region_t *region, cairo_status_t status) { if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED) @@ -313,10 +313,10 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other) return dst->status; if (other->status) - return cairo_region_set_error (dst, other->status); + return _cairo_region_set_error (dst, other->status); if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn)) - return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -348,7 +348,7 @@ cairo_region_subtract_rectangle (cairo_region_t *dst, rectangle->width, rectangle->height); if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion)) - status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); pixman_region32_fini (®ion); @@ -374,10 +374,10 @@ cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other) return dst->status; if (other->status) - return cairo_region_set_error (dst, other->status); + return _cairo_region_set_error (dst, other->status); if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, &other->rgn)) - return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -410,7 +410,7 @@ cairo_region_intersect_rectangle (cairo_region_t *dst, rectangle->width, rectangle->height); if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion)) - status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); pixman_region32_fini (®ion); @@ -437,10 +437,10 @@ cairo_region_union (cairo_region_t *dst, return dst->status; if (other->status) - return cairo_region_set_error (dst, other->status); + return _cairo_region_set_error (dst, other->status); if (! pixman_region32_union (&dst->rgn, &dst->rgn, &other->rgn)) - return cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -472,7 +472,7 @@ cairo_region_union_rectangle (cairo_region_t *dst, rectangle->width, rectangle->height); if (! pixman_region32_union (&dst->rgn, &dst->rgn, ®ion)) - status = cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); + status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY); pixman_region32_fini (®ion); -- cgit v1.2.3 From de1612bdd767ca37e01938f8e41d9699531a49d9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 10:17:49 +0100 Subject: [region] Use _cairo_status_is_error Replace the open-coded version with the more readable macro. --- src/cairo-region.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index e61e441d..2ec3941c 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -66,7 +66,7 @@ static cairo_status_t _cairo_region_set_error (cairo_region_t *region, cairo_status_t status) { - if (status == CAIRO_STATUS_SUCCESS || status >= CAIRO_INT_STATUS_UNSUPPORTED) + if (! _cairo_status_is_error (status)) return status; /* Don't overwrite an existing error. This preserves the first -- cgit v1.2.3 From e238d10b30e18084bf07eb1643fdf48ef35467ab Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 10:22:18 +0100 Subject: [region] Use const cairo_rectangle_int_t consistently. Add the const declaration to a couple of functions. --- src/cairo-region.c | 4 ++-- src/cairo.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index 2ec3941c..3f2b9789 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -121,7 +121,7 @@ slim_hidden_def (cairo_region_create); * Since: 1.10 **/ cairo_region_t * -cairo_region_create_rectangle (cairo_rectangle_int_t *rectangle) +cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle) { cairo_region_t *region; @@ -335,7 +335,7 @@ slim_hidden_def (cairo_region_subtract); **/ cairo_status_t cairo_region_subtract_rectangle (cairo_region_t *dst, - cairo_rectangle_int_t *rectangle) + const cairo_rectangle_int_t *rectangle) { cairo_status_t status = CAIRO_STATUS_SUCCESS; pixman_region32_t region; diff --git a/src/cairo.h b/src/cairo.h index 025ca6c9..917d3640 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2368,7 +2368,7 @@ cairo_public cairo_region_t * cairo_region_create (void); cairo_public cairo_region_t * -cairo_region_create_rectangle (cairo_rectangle_int_t *rectangle); +cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle); cairo_public cairo_region_t * cairo_region_copy (cairo_region_t *original); @@ -2409,7 +2409,7 @@ cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other); cairo_public cairo_status_t cairo_region_subtract_rectangle (cairo_region_t *dst, - cairo_rectangle_int_t *rectangle); + const cairo_rectangle_int_t *rectangle); cairo_public cairo_status_t cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other); -- cgit v1.2.3 From c35d226f7d3654b312e18068b8ccb47a51002a39 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 10:46:37 +0100 Subject: [traps] Propagate allocation failure. Report failure to allocation region. --- src/cairo-traps.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/cairo-traps.c b/src/cairo-traps.c index d91e0d8f..faf7722f 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -610,12 +610,11 @@ cairo_int_status_t _cairo_traps_extract_region (const cairo_traps_t *traps, cairo_region_t **region) { - cairo_int_status_t status = CAIRO_STATUS_SUCCESS; + cairo_int_status_t status; cairo_region_t *r; int i; - for (i = 0; i < traps->num_traps; i++) - { + for (i = 0; i < traps->num_traps; i++) { if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x || traps->traps[i].right.p1.x != traps->traps[i].right.p2.x || ! _cairo_fixed_is_integer (traps->traps[i].top) || @@ -628,11 +627,12 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, } r = cairo_region_create (); - - for (i = 0; i < traps->num_traps; i++) - { + if (unlikely (r->status)) + return r->status; + + for (i = 0; i < traps->num_traps; i++) { cairo_rectangle_int_t rect; - + int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x); int y1 = _cairo_fixed_integer_part (traps->traps[i].top); int x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x); @@ -650,17 +650,14 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, rect.height = y2 - y1; status = cairo_region_union_rectangle (r, &rect); - if (unlikely (status)) - { + if (unlikely (status)) { cairo_region_destroy (r); - r = NULL; - break; + return status; } } *region = r; - - return status; + return CAIRO_STATUS_SUCCESS; } /* moves trap points such that they become the actual corners of the trapezoid */ -- cgit v1.2.3 From ea6197c2f5f04d5e8e8035a330c5199b37beb702 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 10:54:26 +0100 Subject: [surface] Propagate region allocation failure. Propagate the error status from failing to allocate the region. --- src/cairo-surface.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 3df8c7ab..a4a70846 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2678,12 +2678,11 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, unsigned int height) { cairo_rectangle_int_t dst_rectangle; - cairo_rectangle_int_t drawn_rectangle; - cairo_region_t *clear_region = NULL; + cairo_region_t *clear_region; cairo_status_t status; - /* The area that was drawn is the area in the destination rectangle but not within - * the source or the mask. + /* The area that was drawn is the area in the destination rectangle but + * not within the source or the mask. */ dst_rectangle.x = dst_x; dst_rectangle.y = dst_y; @@ -2691,22 +2690,22 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, dst_rectangle.height = height; clear_region = cairo_region_create_rectangle (&dst_rectangle); - - drawn_rectangle = dst_rectangle; + status = clear_region->status; + if (unlikely (status)) + goto CLEANUP_REGIONS; if (src_rectangle) { - if (! _cairo_rectangle_intersect (&drawn_rectangle, src_rectangle)) + if (! _cairo_rectangle_intersect (&dst_rectangle, src_rectangle)) goto EMPTY; } if (mask_rectangle) { - if (! _cairo_rectangle_intersect (&drawn_rectangle, mask_rectangle)) + if (! _cairo_rectangle_intersect (&dst_rectangle, mask_rectangle)) goto EMPTY; } - /* Now compute the area that is in dst_rectangle but not in drawn_rectangle - */ - status = cairo_region_subtract_rectangle (clear_region, &drawn_rectangle); + /* Now compute the area that is in dst but not drawn */ + status = cairo_region_subtract_rectangle (clear_region, &dst_rectangle); if (unlikely (status)) goto CLEANUP_REGIONS; -- cgit v1.2.3 From aee71e2063b1d6d23cd8dcef7789c9cf106af32a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 13:41:00 +0100 Subject: [test] Memfault checks. Don't assume an error means the test failed, check for injected allocation errors. --- test/create-from-png.c | 164 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 113 insertions(+), 51 deletions(-) diff --git a/test/create-from-png.c b/test/create-from-png.c index d9d2e548..585fac2c 100644 --- a/test/create-from-png.c +++ b/test/create-from-png.c @@ -54,13 +54,19 @@ draw (cairo_t *cr, int width, int height) surface = cairo_image_surface_create_from_png (filename); if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error reading PNG image %s: %s\n", - filename, - cairo_status_to_string (cairo_surface_status (surface))); + cairo_test_status_t result; + + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error reading PNG image %s: %s\n", + filename, + cairo_status_to_string (cairo_surface_status (surface))); + } + free (filename); - return CAIRO_TEST_FAILURE; + return result; } - free (filename); cairo_set_source_surface (cr, surface, 0, 0); cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST); @@ -68,6 +74,7 @@ draw (cairo_t *cr, int width, int height) cairo_surface_destroy (surface); + free (filename); return CAIRO_TEST_SUCCESS; } @@ -81,27 +88,42 @@ preamble (cairo_test_context_t *ctx) surface = cairo_image_surface_create_from_png ("___THIS_FILE_DOES_NOT_EXIST___"); if (cairo_surface_status (surface) != CAIRO_STATUS_FILE_NOT_FOUND) { - cairo_test_log (ctx, "Error: expected \"file not found\", but got: %s\n", - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error: expected \"file not found\", but got: %s\n", + cairo_status_to_string (cairo_surface_status (surface))); + } } cairo_surface_destroy (surface); + if (result != CAIRO_TEST_SUCCESS) + return result; surface = cairo_image_surface_create_from_png_stream (no_memory_error, NULL); if (cairo_surface_status (surface) != CAIRO_STATUS_NO_MEMORY) { - cairo_test_log (ctx, "Error: expected \"out of memory\", but got: %s\n", - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error: expected \"out of memory\", but got: %s\n", + cairo_status_to_string (cairo_surface_status (surface))); + } } cairo_surface_destroy (surface); + if (result != CAIRO_TEST_SUCCESS) + return result; surface = cairo_image_surface_create_from_png_stream (read_error, NULL); if (cairo_surface_status (surface) != CAIRO_STATUS_READ_ERROR) { - cairo_test_log (ctx, "Error: expected \"read error\", but got: %s\n", - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error: expected \"read error\", but got: %s\n", + cairo_status_to_string (cairo_surface_status (surface))); + } } cairo_surface_destroy (surface); + if (result != CAIRO_TEST_SUCCESS) + return result; /* cheekily test error propagation from the user write funcs as well ... */ xasprintf (&filename, "%s/%s", ctx->srcdir, @@ -109,48 +131,63 @@ preamble (cairo_test_context_t *ctx) surface = cairo_image_surface_create_from_png (filename); if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error reading PNG image %s: %s\n", - filename, - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error reading PNG image %s: %s\n", + filename, + cairo_status_to_string (cairo_surface_status (surface))); + } } else { status = cairo_surface_write_to_png_stream (surface, (cairo_write_func_t) no_memory_error, NULL); if (status != CAIRO_STATUS_NO_MEMORY) { - cairo_test_log (ctx, "Error: expected \"out of memory\", but got: %s\n", - cairo_status_to_string (status)); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, status); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error: expected \"out of memory\", but got: %s\n", + cairo_status_to_string (status)); + } } status = cairo_surface_write_to_png_stream (surface, (cairo_write_func_t) read_error, NULL); if (status != CAIRO_STATUS_READ_ERROR) { - cairo_test_log (ctx, "Error: expected \"read error\", but got: %s\n", - cairo_status_to_string (status)); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, status); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error: expected \"read error\", but got: %s\n", + cairo_status_to_string (status)); + } } /* and check that error has not propagated to the surface */ if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error: user write error propagated to surface: %s", - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error: user write error propagated to surface: %s", + cairo_status_to_string (cairo_surface_status (surface))); + } } } cairo_surface_destroy (surface); free (filename); + if (result != CAIRO_TEST_SUCCESS) + return result; /* check that loading alpha/opaque PNGs generate the correct surfaces */ xasprintf (&filename, "%s/%s", ctx->srcdir, "create-from-png.alpha.ref.png"); surface = cairo_image_surface_create_from_png (filename); if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error reading PNG image %s: %s\n", - filename, - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error reading PNG image %s: %s\n", + filename, + cairo_status_to_string (cairo_surface_status (surface))); + } } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) { cairo_test_log (ctx, "Error reading PNG image %s: did not create an ARGB32 image\n", filename); @@ -158,15 +195,20 @@ preamble (cairo_test_context_t *ctx) } free (filename); cairo_surface_destroy (surface); + if (result != CAIRO_TEST_SUCCESS) + return result; xasprintf (&filename, "%s/%s", ctx->srcdir, "create-from-png.ref.png"); surface = cairo_image_surface_create_from_png (filename); if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error reading PNG image %s: %s\n", - filename, - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error reading PNG image %s: %s\n", + filename, + cairo_status_to_string (cairo_surface_status (surface))); + } } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) { cairo_test_log (ctx, "Error reading PNG image %s: did not create an RGB24 image\n", filename); @@ -174,16 +216,21 @@ preamble (cairo_test_context_t *ctx) } free (filename); cairo_surface_destroy (surface); + if (result != CAIRO_TEST_SUCCESS) + return result; /* check paletted PNGs */ xasprintf (&filename, "%s/%s", ctx->srcdir, "create-from-png.indexed-alpha.ref.png"); surface = cairo_image_surface_create_from_png (filename); if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error reading PNG image %s: %s\n", - filename, - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error reading PNG image %s: %s\n", + filename, + cairo_status_to_string (cairo_surface_status (surface))); + } } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) { cairo_test_log (ctx, "Error reading PNG image %s: did not create an ARGB32 image\n", filename); @@ -191,15 +238,20 @@ preamble (cairo_test_context_t *ctx) } free (filename); cairo_surface_destroy (surface); + if (result != CAIRO_TEST_SUCCESS) + return result; xasprintf (&filename, "%s/%s", ctx->srcdir, "create-from-png.indexed.ref.png"); surface = cairo_image_surface_create_from_png (filename); if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error reading PNG image %s: %s\n", - filename, - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error reading PNG image %s: %s\n", + filename, + cairo_status_to_string (cairo_surface_status (surface))); + } } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) { cairo_test_log (ctx, "Error reading PNG image %s: did not create an RGB24 image\n", filename); @@ -207,16 +259,21 @@ preamble (cairo_test_context_t *ctx) } free (filename); cairo_surface_destroy (surface); + if (result != CAIRO_TEST_SUCCESS) + return result; /* check grayscale PNGs */ xasprintf (&filename, "%s/%s", ctx->srcdir, "create-from-png.gray-alpha.ref.png"); surface = cairo_image_surface_create_from_png (filename); if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error reading PNG image %s: %s\n", - filename, - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error reading PNG image %s: %s\n", + filename, + cairo_status_to_string (cairo_surface_status (surface))); + } } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32) { cairo_test_log (ctx, "Error reading PNG image %s: did not create an ARGB32 image\n", filename); @@ -224,15 +281,20 @@ preamble (cairo_test_context_t *ctx) } free (filename); cairo_surface_destroy (surface); + if (result != CAIRO_TEST_SUCCESS) + return result; xasprintf (&filename, "%s/%s", ctx->srcdir, "create-from-png.gray.ref.png"); surface = cairo_image_surface_create_from_png (filename); if (cairo_surface_status (surface)) { - cairo_test_log (ctx, "Error reading PNG image %s: %s\n", - filename, - cairo_status_to_string (cairo_surface_status (surface))); - result = CAIRO_TEST_FAILURE; + result = cairo_test_status_from_status (ctx, + cairo_surface_status (surface)); + if (result == CAIRO_TEST_FAILURE) { + cairo_test_log (ctx, "Error reading PNG image %s: %s\n", + filename, + cairo_status_to_string (cairo_surface_status (surface))); + } } else if (cairo_image_surface_get_format (surface) != CAIRO_FORMAT_RGB24) { cairo_test_log (ctx, "Error reading PNG image %s: did not create an RGB24 image\n", filename); -- cgit v1.2.3 From 77ee65fd03d06064be023f022d565c5038fe26df Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Mon, 30 Mar 2009 14:45:48 -0400 Subject: [win32] Fix horizontal glyph positioning bug The _cairo_win32_scaled_font_backend version of show_glyphs collects glyph runs to hand to ExtTextOutW until the y-offset changes, then flushes the glyphs buffered so far. As each glyph is buffered, it also calculates and buffers the dx value for the preceding glyph. However, when it sees a change in dy and decides to flush, it should *not* append an entry to the dx buffer, as this would be the "dx" of the previous glyph, and instead the new start_x value will be used for the new glyph run that's being collected. This bug means that after any vertically-offset glyph, the remaining glyphs in the run will get incorrect dx values (horizontal escapement). Mozilla bug #475092 --- src/cairo-win32-font.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index e9abfda0..e0ece5b7 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -1180,12 +1180,12 @@ _add_glyph (cairo_glyph_state_t *state, if (status) return status; state->start_x = logical_x; + } else { + dx = logical_x - state->last_x; + status = _cairo_array_append (&state->dx, &dx); + if (status) + return status; } - - dx = logical_x - state->last_x; - status = _cairo_array_append (&state->dx, &dx); - if (status) - return status; } else { state->start_x = logical_x; } -- cgit v1.2.3 From 80d5b53b474c94219c51ae16dcc19098a2d86165 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Tue, 31 Mar 2009 05:47:44 -0400 Subject: [region] Change name of cairo_region_empty() to cairo_region_is_empty() --- src/cairo-clip.c | 2 +- src/cairo-region.c | 6 +++--- src/cairo-surface-fallback.c | 2 +- src/cairo.h | 2 +- src/cairoint.h | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index cc43c037..7066b932 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -348,7 +348,7 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, clip->serial = _cairo_surface_allocate_clip_serial (target); cairo_region_destroy (region); - if (!clip->region || cairo_region_empty (clip->region)) + if (!clip->region || cairo_region_is_empty (clip->region)) _cairo_clip_set_all_clipped (clip, target); return status; diff --git a/src/cairo-region.c b/src/cairo-region.c index 3f2b9789..6bdfd247 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -481,7 +481,7 @@ cairo_region_union_rectangle (cairo_region_t *dst, slim_hidden_def (cairo_region_union_rectangle); /** - * cairo_region_empty: + * cairo_region_is_empty: * @region: a #cairo_region_t * * Checks whether @region is empty. @@ -491,14 +491,14 @@ slim_hidden_def (cairo_region_union_rectangle); * Since: 1.10 **/ cairo_bool_t -cairo_region_empty (cairo_region_t *region) +cairo_region_is_empty (cairo_region_t *region) { if (region->status) return TRUE; return ! pixman_region32_not_empty (®ion->rgn); } -slim_hidden_def (cairo_region_empty); +slim_hidden_def (cairo_region_is_empty); /** * cairo_region_translate: diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index cbe92b23..a78c6ad7 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -583,7 +583,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, if (unlikely (status)) goto out; - if (cairo_region_empty (clear_region)) { + if (cairo_region_is_empty (clear_region)) { cairo_region_destroy (clear_region); clear_region = NULL; } diff --git a/src/cairo.h b/src/cairo.h index 917d3640..a9b4f610 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2392,7 +2392,7 @@ cairo_region_get_rectangle (cairo_region_t *region, cairo_rectangle_int_t *rectangle); cairo_public cairo_bool_t -cairo_region_empty (cairo_region_t *region); +cairo_region_is_empty (cairo_region_t *region); cairo_public cairo_region_overlap_t cairo_region_contains_rectangle (cairo_region_t *region, diff --git a/src/cairoint.h b/src/cairoint.h index 6c5fd5a6..21b28648 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2702,7 +2702,7 @@ slim_hidden_proto (cairo_region_status); slim_hidden_proto (cairo_region_get_extents); slim_hidden_proto (cairo_region_num_rectangles); slim_hidden_proto (cairo_region_get_rectangle); -slim_hidden_proto (cairo_region_empty); +slim_hidden_proto (cairo_region_is_empty); slim_hidden_proto (cairo_region_contains_rectangle); slim_hidden_proto (cairo_region_contains_point); slim_hidden_proto (cairo_region_translate); -- cgit v1.2.3 From b580a4a8d6c056ba8b47be32ea8c5b9a1d90d01e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 16:50:10 +0100 Subject: [test] Improve fault injection coverage In order to exercise the meta-surfaces, we need to inject faults into cairo_surface_finish(). --- boilerplate/cairo-boilerplate.c | 16 +++++++++++++--- test/cairo-test.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c index b6c2c80b..fcc05b87 100644 --- a/boilerplate/cairo-boilerplate.c +++ b/boilerplate/cairo-boilerplate.c @@ -76,6 +76,7 @@ #include #include #include +#include #if HAVE_UNISTD_H && HAVE_FCNTL_H && HAVE_SIGNAL_H && HAVE_SYS_STAT_H && HAVE_SYS_SOCKET_H && HAVE_SYS_UN_H #include @@ -170,6 +171,9 @@ _cairo_boilerplate_get_image_surface (cairo_surface_t *src, cairo_surface_t *surface; cairo_t *cr; + if (cairo_surface_status (src)) + return cairo_surface_reference (src); + #if 0 if (cairo_surface_get_type (src) == CAIRO_SURFACE_TYPE_IMAGE) { int ww = cairo_image_surface_get_width (src); @@ -973,7 +977,7 @@ cairo_boilerplate_image_surface_create_from_ppm_stream (FILE *file) goto FAIL; } if (cairo_surface_status (image)) - goto FAIL; + return image; data = cairo_image_surface_get_data (image); stride = cairo_image_surface_get_stride (image); @@ -1017,8 +1021,14 @@ cairo_boilerplate_convert_to_image (const char *filename, int page) RETRY: file = cairo_boilerplate_open_any2ppm (filename, page, flags); - if (file == NULL) - return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR); + if (file == NULL) { + switch (errno) { + case ENOMEM: + return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); + default: + return cairo_boilerplate_surface_create_in_error (CAIRO_STATUS_READ_ERROR); + } + } image = cairo_boilerplate_image_surface_create_from_ppm_stream (file); ret = pclose (file); diff --git a/test/cairo-test.c b/test/cairo-test.c index 264fed50..568d8f81 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -910,7 +910,42 @@ REPEAT: cairo_status_t diff_status; if (target->finish_surface != NULL) { +#if HAVE_MEMFAULT + /* We need to re-enable faults as most meta-surface processing + * is done during cairo_surface_finish(). + */ + VALGRIND_CLEAR_FAULTS (); + last_fault_count = VALGRIND_COUNT_FAULTS (); + VALGRIND_ENABLE_FAULTS (); +#endif + diff_status = target->finish_surface (surface); + +#if HAVE_MEMFAULT + VALGRIND_DISABLE_FAULTS (); + + if (ctx->malloc_failure && + VALGRIND_COUNT_FAULTS () - last_fault_count > 0 && + diff_status == CAIRO_STATUS_NO_MEMORY) + { + cairo_destroy (cr); + cairo_surface_destroy (surface); + if (target->cleanup) + target->cleanup (closure); + if (ctx->thread == 0) { + cairo_debug_reset_static_data (); +#if HAVE_FCFINI + FcFini (); +#endif + if (VALGRIND_COUNT_LEAKS () > 0) { + VALGRIND_PRINT_FAULTS (); + VALGRIND_PRINT_LEAKS (); + } + } + + goto REPEAT; + } +#endif if (diff_status) { cairo_test_log (ctx, "Error: Failed to finish surface: %s\n", cairo_status_to_string (diff_status)); -- cgit v1.2.3 From edce97a750acf4368bd7249ec6b9a195f8584cdf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 16:50:51 +0100 Subject: [pdf] Remove false assertion. The stream itself may be in an error state, so an error could be raised. --- src/cairo-pdf-surface.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index f562e3fd..2faa9420 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1324,10 +1324,12 @@ _cairo_pdf_surface_finish (void *abstract_surface) "%%%%EOF\n", offset); - status2 = _cairo_pdf_operators_fini (&surface->pdf_operators); /* pdf_operators has already been flushed when the last stream was - * closed so we should never be writing anything here. */ - assert(status2 == CAIRO_STATUS_SUCCESS); + * closed so we should never be writing anything here - however, + * the stream may itself be in an error state. */ + status2 = _cairo_pdf_operators_fini (&surface->pdf_operators); + if (status == CAIRO_STATUS_SUCCESS) + status = status2; /* close any active streams still open due to fatal errors */ status2 = _cairo_pdf_surface_close_stream (surface); -- cgit v1.2.3 From ba1a0fa601a817ff489bc5373af57977e41eb99f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 19:08:41 +0100 Subject: [truetype] Free local names on failure. Ensure that all local allocations are freed on the error path. --- src/cairo-truetype-subset.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c index 31e39710..8d1b5975 100644 --- a/src/cairo-truetype-subset.c +++ b/src/cairo-truetype-subset.c @@ -1329,8 +1329,8 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font, tt_name_record_t *record; unsigned long size; int i, j; - char *ps_name; - char *font_name; + char *ps_name = NULL; + char *font_name = NULL; backend = scaled_font->backend; if (!backend->load_truetype_table) @@ -1360,8 +1360,6 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font, * name. It should be extended to use any suitable font name in * the name table. */ - ps_name = NULL; - font_name = NULL; for (i = 0; i < be16_to_cpu(name->num_records); i++) { record = &(name->records[i]); if ((be16_to_cpu (record->platform) == 1) && @@ -1415,6 +1413,13 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font, fail: free (name); + + if (ps_name != NULL) + free (ps_name); + + if (font_name != NULL) + free (font_name); + *ps_name_out = NULL; *font_name_out = NULL; -- cgit v1.2.3 From 9f63cbb870892253f363ddb7aac908263672c8dc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 30 Mar 2009 19:09:13 +0100 Subject: [pdf] Free compressed stream after error. Ensure that the compressed stream is destroyed after encountering an error. --- src/cairo-pdf-surface.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 2faa9420..94da4ae5 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1015,18 +1015,21 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface, static cairo_status_t _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface) { - cairo_status_t status = CAIRO_STATUS_SUCCESS; + cairo_status_t status; long length; if (! surface->pdf_stream.active) return CAIRO_STATUS_SUCCESS; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (unlikely (status)) - return status; if (surface->pdf_stream.compressed) { - status = _cairo_output_stream_destroy (surface->output); + cairo_status_t status2; + + status2 = _cairo_output_stream_destroy (surface->output); + if (likely (status == CAIRO_STATUS_SUCCESS)) + status = status2; + surface->output = surface->pdf_stream.old_output; _cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output); surface->pdf_stream.old_output = NULL; @@ -1051,7 +1054,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface) surface->pdf_stream.active = FALSE; - if (status == CAIRO_STATUS_SUCCESS) + if (likely (status == CAIRO_STATUS_SUCCESS)) status = _cairo_output_stream_get_status (surface->output); return status; -- cgit v1.2.3 From b0689f56118dd8ccda6f29901d41cf8f80983aa0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 31 Mar 2009 10:27:15 +0100 Subject: Check for errors during get_mime_data() cairo_surface_get_mime_data() may raise an error on the surface, so we need to check lest it goes unnoticed and we generate a corrupt file. --- src/cairo-pdf-surface.c | 2 ++ src/cairo-ps-surface.c | 2 ++ src/cairo-svg-surface.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 94da4ae5..04be7e9a 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1728,6 +1728,8 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface, cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG, &mime_data, &mime_data_length); + if (unlikely (source->status)) + return source->status; if (mime_data == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 346bb88c..dfdc785c 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -2138,6 +2138,8 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface, cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG, &mime_data, &mime_data_length); + if (unlikely (source->status)) + return source->status; if (mime_data == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index db554a10..7a35fab9 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -1025,6 +1025,8 @@ _cairo_surface_base64_encode_png (cairo_surface_t *surface, cairo_surface_get_mime_data (surface, CAIRO_MIME_TYPE_PNG, &mime_data, &mime_data_length); + if (unlikely (surface->status)) + return surface->status; if (mime_data == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; -- cgit v1.2.3 From 043352aa8d1e3aeacf3b877f45e1bc451a676e15 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 31 Mar 2009 10:34:41 +0100 Subject: [pdf] Prevent leak of pad_image on error path. Ensure that the local pad_image is destroyed after an error. --- src/cairo-pdf-surface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 04be7e9a..886dd6b9 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -1797,7 +1797,7 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface, status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra); if (unlikely (status)) - goto BAIL; + return status; pad_image = &image->base; if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD) { @@ -1847,10 +1847,10 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface, *origin_x = x; *origin_y = y; +BAIL: if (pad_image != &image->base) cairo_surface_destroy (pad_image); -BAIL: _cairo_surface_release_source_image (pattern->surface, image, image_extra); return status; -- cgit v1.2.3 From 88956cd42e9cc03cb8b4ec730062993eaaf3938d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 31 Mar 2009 10:35:24 +0100 Subject: [ps] Check for error during stroking. Add a missing error status check that caused errors during stroke to be masked. --- src/cairo-ps-surface.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index dfdc785c..0037905a 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -3317,6 +3317,9 @@ _cairo_ps_surface_stroke (void *abstract_surface, if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; + if (unlikely (status)) + return status; + return _cairo_pdf_operators_stroke (&surface->pdf_operators, path, style, -- cgit v1.2.3 From 8362c6f726979abc43ad9f7303bd45fcb03f83b3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 31 Mar 2009 10:36:08 +0100 Subject: [type1] Fixup error path during write_charstrings() On the common error path we attempted to unlock a mutex that was not always held, so reorder the error paths appropriately. --- src/cairo-type1-fallback.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c index 2b6768dc..1023bbdc 100644 --- a/src/cairo-type1-fallback.c +++ b/src/cairo-type1-fallback.c @@ -449,14 +449,14 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, /* four "random" bytes required by encryption algorithm */ status = _cairo_array_append_multiple (&data, zeros, 4); if (unlikely (status)) - goto fail; + break; status = cairo_type1_font_create_charstring (font, i, font->scaled_font_subset->glyphs[i], CAIRO_CHARSTRING_TYPE1, &data); if (unlikely (status)) - goto fail; + break; charstring_encrypt (&data); length = _cairo_array_num_elements (&data); @@ -474,9 +474,9 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, length); _cairo_output_stream_printf (encrypted_output, " ND\n"); } + _cairo_scaled_font_thaw_cache (font->type1_scaled_font); fail: - _cairo_scaled_font_thaw_cache (font->type1_scaled_font); _cairo_array_fini (&data); return status; } -- cgit v1.2.3 From 180b964aac4e058e6783778d33772f08e13b3669 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 31 Mar 2009 10:37:44 +0100 Subject: [scaled-font-subset] Propagate error from scaled-font to collection. Don't attempt to collect the sub_font if it is in error. --- src/cairo-scaled-font-subsets.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index c802c314..1d16e4ab 100644 --- a/src/cairo-scaled-font-subsets.c +++ b/src/cairo-scaled-font-subsets.c @@ -539,6 +539,10 @@ _cairo_sub_font_collect (void *entry, void *closure) int i; unsigned int j; + if (collection->status) + return; + + collection->status = sub_font->scaled_font->status; if (collection->status) return; -- cgit v1.2.3 From e46c1d7fa34b4ba89fc3e0fe6f3042a6fa8c0398 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 31 Mar 2009 10:39:46 +0100 Subject: [scaled-font-subset] Cleanup after failure to convert to utf16. Avoid leaking the local hashtable and strings after failing to convert the string to utf16. --- src/cairo-scaled-font-subsets.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index 1d16e4ab..44e850e4 100644 --- a/src/cairo-scaled-font-subsets.c +++ b/src/cairo-scaled-font-subsets.c @@ -1025,7 +1025,7 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset if (utf8 && *utf8) { status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len); if (unlikely (status)) - return status; /* FIXME */ + goto CLEANUP_HASH; } if (utf16_len == 1) { -- cgit v1.2.3 From 0f21893b0510a188439c2d8cd448bcfcf17ef8c6 Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Wed, 1 Apr 2009 08:54:30 -0400 Subject: [region] pixman_region32_contains_point() does not allow NULL for box --- src/cairo-region.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index 6bdfd247..15bf2f16 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -577,9 +577,11 @@ cairo_bool_t cairo_region_contains_point (cairo_region_t *region, int x, int y) { + pixman_box32_t box; + if (region->status) return FALSE; - return pixman_region32_contains_point (®ion->rgn, x, y, NULL); + return pixman_region32_contains_point (®ion->rgn, x, y, &box); } slim_hidden_def (cairo_region_contains_point); -- cgit v1.2.3 From 2d6336624c33e9c674c192b68eb501373a96dc87 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Wed, 1 Apr 2009 11:32:58 -0400 Subject: [test-win32] Fix static linking of the test suite. Previously, the test suite needed to be dynamically linked to work. --- boilerplate/Makefile.win32 | 2 +- test/Makefile.win32 | 9 ++++++--- test/pdiff/Makefile.win32 | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/boilerplate/Makefile.win32 b/boilerplate/Makefile.win32 index 84075dab..286ea2b1 100644 --- a/boilerplate/Makefile.win32 +++ b/boilerplate/Makefile.win32 @@ -13,7 +13,7 @@ SOURCES = \ $(enabled_cairo_boilerplate_sources) \ $(NULL) -OBJECTS = $(patsubst %.c, $(CFG)/%.obj, $(SOURCES)) +OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(SOURCES)) all: $(CFG)/boiler.lib diff --git a/test/Makefile.win32 b/test/Makefile.win32 index f4c12916..f6a936ed 100644 --- a/test/Makefile.win32 +++ b/test/Makefile.win32 @@ -19,14 +19,17 @@ cairo-test-constructors.c: $(test_sources) SOURCES = $(cairo_test_suite_sources) $(test_sources) cairo-test-constructors.c -OBJECTS = $(patsubst %.c, $(CFG)/%.obj, $(SOURCES)) +OBJECTS = $(patsubst %.c, $(CFG)/%-static.obj, $(SOURCES)) -cairo-test-suite.exe: $(OBJECTS) - $(CC) $(OPT) $(MS_MDFLAGS) $(OBJECTS) -Fe"$@" -link $(LDFLAGS) /NODEFAULTLIB:library +cairo-test-suite.exe: $(OBJECTS) ./pdiff/pdiff.lib ../boilerplate/$(CFG)/boiler.lib + $(CC) $(OPT) $(MS_MDFLAGS) $(OBJECTS) -Fe"$@" -link $(LDFLAGS) $(CAIRO_LIBS) /NODEFAULTLIB:library ./pdiff/pdiff.lib: (cd pdiff ; $(MAKE) -f Makefile.win32) +../boilerplate/$(CFG)/boiler.lib: + (cd ../boilerplate ; $(MAKE) -f Makefile.win32) + .PHONY: check test html check: cairo-test-suite.exe diff --git a/test/pdiff/Makefile.win32 b/test/pdiff/Makefile.win32 index 5e6680dd..851d3af6 100644 --- a/test/pdiff/Makefile.win32 +++ b/test/pdiff/Makefile.win32 @@ -16,4 +16,4 @@ pdiff.lib: $(OBJECTS) lib -NOLOGO -OUT:$@ $(OBJECTS) %.obj: %.c - @$(CC) $(CFLAGS) -c -Fo"$@" $< + @$(CC) $(CFLAGS) -DCAIRO_WIN32_STATIC_BUILD=1 -c -Fo"$@" $< -- cgit v1.2.3 From ba2ec8e1d9144c4a27917e59cb15039552eb008c Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Wed, 1 Apr 2009 13:29:12 -0400 Subject: Remove trailing comma in cairo_region_overlap_t enum. --- src/cairo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo.h b/src/cairo.h index a9b4f610..1347187f 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -2361,7 +2361,7 @@ typedef struct _cairo_rectangle_int { typedef enum _cairo_region_overlap { CAIRO_REGION_OVERLAP_IN, /* completely inside region */ CAIRO_REGION_OVERLAP_OUT, /* completely outside region */ - CAIRO_REGION_OVERLAP_PART, /* partly inside region */ + CAIRO_REGION_OVERLAP_PART /* partly inside region */ } cairo_region_overlap_t; cairo_public cairo_region_t * -- cgit v1.2.3 From 9b496af5c214283c297a52c90a04743f9da9f6a3 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 5 Apr 2009 00:44:02 +1030 Subject: Fix buffer size check in TrueType subsetting Andrew Cowie reported a problem with the Charis SIL font being embedded as a fallback font. The buffer size check for composite glyphs was incorrect causing the subsetting to fail for some fonts. --- src/cairo-truetype-subset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c index 8d1b5975..323a10c8 100644 --- a/src/cairo-truetype-subset.c +++ b/src/cairo-truetype-subset.c @@ -495,7 +495,7 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font, composite_glyph = &glyph_data->glyph; do { - if ((unsigned char *)(&composite_glyph->args[1]) >= end) + if ((unsigned char *)(&composite_glyph->args[0]) >= end) return CAIRO_INT_STATUS_UNSUPPORTED; flags = be16_to_cpu (composite_glyph->flags); -- cgit v1.2.3 From fe97e815e81f4429889fd52bb525c260f9967356 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 5 Apr 2009 01:04:12 +1030 Subject: Fix TrueType subsetting bug Fix incorrect counting of arguments in composite glyphs --- src/cairo-truetype-subset-private.h | 2 +- src/cairo-truetype-subset.c | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/cairo-truetype-subset-private.h b/src/cairo-truetype-subset-private.h index 397a9f38..978256f6 100644 --- a/src/cairo-truetype-subset-private.h +++ b/src/cairo-truetype-subset-private.h @@ -185,7 +185,7 @@ typedef struct _tt_name { typedef struct _tt_composite_glyph { uint16_t flags; uint16_t index; - uint16_t args[7]; /* 1 to 7 arguments depending on value of flags */ + uint16_t args[6]; /* 1 to 6 arguments depending on value of flags */ } tt_composite_glyph_t; typedef struct _tt_glyph_data { diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c index 323a10c8..59be9055 100644 --- a/src/cairo-truetype-subset.c +++ b/src/cairo-truetype-subset.c @@ -105,8 +105,8 @@ check (tt_maxp_t, 32); check (tt_name_record_t, 12); check (tt_name_t, 18); check (tt_name_t, 18); -check (tt_composite_glyph_t, 18); -check (tt_glyph_data_t, 28); +check (tt_composite_glyph_t, 16); +check (tt_glyph_data_t, 26); #undef check static cairo_status_t @@ -508,13 +508,15 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font, num_args = 1; if (flags & TT_ARG_1_AND_2_ARE_WORDS) num_args += 1; - if (flags & TT_WE_HAVE_A_SCALE) + + if (flags & TT_WE_HAVE_A_SCALE) num_args += 1; else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE) num_args += 2; else if (flags & TT_WE_HAVE_A_TWO_BY_TWO) - num_args += 3; - composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]); + num_args += 4; + + composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]); } while (has_more_components); return CAIRO_STATUS_SUCCESS; -- cgit v1.2.3 From 1798fc6607a89811929d1f21cc71c751438f5699 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 5 Apr 2009 11:17:02 +0930 Subject: Fix the TrueType subsetting fix in 9b496af5c Oops. --- src/cairo-truetype-subset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c index 59be9055..b3de972a 100644 --- a/src/cairo-truetype-subset.c +++ b/src/cairo-truetype-subset.c @@ -495,7 +495,7 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font, composite_glyph = &glyph_data->glyph; do { - if ((unsigned char *)(&composite_glyph->args[0]) >= end) + if ((unsigned char *)(&composite_glyph->args[1]) > end) return CAIRO_INT_STATUS_UNSUPPORTED; flags = be16_to_cpu (composite_glyph->flags); -- cgit v1.2.3 From f8539726368141f8b42c7817cfd59b4abfce33f3 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 7 Apr 2009 14:50:25 -0400 Subject: [win32] Fix building with libpng and zlib Include zlib and libpng dependencies using something like '$(cairo_dir)/../zlib/zdll.lib' instead of just 'zdll.lib'. Also, do similarly for the headers. --- build/Makefile.win32.common | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build/Makefile.win32.common b/build/Makefile.win32.common index 2fa3255c..c1f0cb84 100644 --- a/build/Makefile.win32.common +++ b/build/Makefile.win32.common @@ -27,17 +27,19 @@ PIXMAN_LIBS := $(top_builddir)/../pixman/pixman/$(CFG)/pixman-1.lib CAIRO_LIBS = gdi32.lib msimg32.lib user32.lib ifeq ($(CAIRO_HAS_PNG_FUNCTIONS),1) -CAIRO_LIBS += libpng.lib +LIBPNG_CFLAGS += -I$(top_srcdir)/../libpng/ +CAIRO_LIBS += $(top_builddir)/../libpng/libpng.lib endif ifeq ($(CAIRO_HAS_PS_SURFACE)$(CAIRO_HAS_PDF_SURFACE),00) else -CAIRO_LIBS += zdll.lib +ZLIB_CFLAGS += -I$(top_srcdir)/../zlib/ +CAIRO_LIBS += $(top_builddir)/../zlib/zdll.lib endif DEFAULT_CFLAGS = -nologo $(MS_MDFLAGS) $(OPT) DEFAULT_CFLAGS += -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE DEFAULT_CFLAGS += -I. -I$(top_srcdir) -DEFAULT_CFLAGS += $(PIXMAN_CFLAGS) +DEFAULT_CFLAGS += $(PIXMAN_CFLAGS) $(LIBPNG_CFLAGS) $(ZLIB_CFLAGS) CAIRO_CFLAGS = $(DEFAULT_CFLAGS) $(CFLAGS) -- cgit v1.2.3 From ca501d99bbec432252cbb134d863801d4a792a44 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 1 Apr 2009 11:41:59 +0100 Subject: [test] Disable signal handling under valgrind Capturing and handling the signals prevents valgrind from providing backtraces for fatal signals -- which is often more useful. --- test/cairo-test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cairo-test.c b/test/cairo-test.c index 568d8f81..897332ab 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -1228,7 +1228,7 @@ _cairo_test_context_run_for_target (cairo_test_context_t *ctx, } #if defined(HAVE_SIGNAL_H) && defined(HAVE_SETJMP_H) - if (ctx->thread == 0) { + if (ctx->thread == 0 && ! RUNNING_ON_VALGRIND) { void (* volatile old_segfault_handler)(int); void (* volatile old_sigpipe_handler)(int); void (* volatile old_sigabrt_handler)(int); -- cgit v1.2.3 From f12d52bfcae0792729b33a1fd1b2d23bd3fc7cf3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 4 Apr 2009 19:02:15 +0100 Subject: [test] Use xmalloc() to evade memfault. Do not use the simple malloc() as memfault will inject allocation failures (unlike xmalloc() for which faults are excluded) - as this is unnecessary inside the test harness and thus does not exercise any cairo code paths. --- test/show-glyphs-many.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/show-glyphs-many.c b/test/show-glyphs-many.c index 9657e283..dbfd6a1c 100644 --- a/test/show-glyphs-many.c +++ b/test/show-glyphs-many.c @@ -109,7 +109,7 @@ get_glyph (cairo_t *cr, const char *utf8, cairo_glyph_t *glyph) static cairo_test_status_t draw (cairo_t *cr, int width, int height) { - cairo_glyph_t *glyphs = malloc(NUM_GLYPHS * sizeof(cairo_glyph_t)); + cairo_glyph_t *glyphs = xmalloc (NUM_GLYPHS * sizeof (cairo_glyph_t)); const char *characters[] = { /* try to exercise different widths of index */ "m", /* Latin letter m, index=0x50 */ "μ", /* Greek letter mu, index=0x349 */ -- cgit v1.2.3 From 82cccb26723697492504f395fed33afba28d84ba Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Apr 2009 11:01:39 +0100 Subject: [test] Handle memfaults during surface-finish-twice Check and report memory allocation failures. --- test/surface-finish-twice.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/test/surface-finish-twice.c b/test/surface-finish-twice.c index 5154e99e..f63b5017 100644 --- a/test/surface-finish-twice.c +++ b/test/surface-finish-twice.c @@ -45,21 +45,26 @@ static cairo_test_status_t draw (cairo_t *cr, int width, int height) { + const cairo_test_context_t *ctx = cairo_test_get_context (cr); cairo_surface_t *surface; + cairo_status_t status; surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 1, 1); cairo_surface_finish (surface); - if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) - return CAIRO_TEST_FAILURE; + status = cairo_surface_status (surface); + if (status != CAIRO_STATUS_SUCCESS) + return cairo_test_status_from_status (ctx, status); cairo_surface_finish (surface); - if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) - return CAIRO_TEST_FAILURE; + status = cairo_surface_status (surface); + if (status != CAIRO_STATUS_SUCCESS) + return cairo_test_status_from_status (ctx, status); cairo_surface_finish (surface); - if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) - return CAIRO_TEST_FAILURE; + status = cairo_surface_status (surface); + if (status != CAIRO_STATUS_SUCCESS) + return cairo_test_status_from_status (ctx, status); cairo_surface_destroy (surface); -- cgit v1.2.3 From 75b06b8bdb5efaf030e063c1f66583d8fde347dc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 1 Apr 2009 11:43:16 +0100 Subject: [pattern] Do not modify outparam on error path. The pdf backend was crashing as a failed pattern copy stored an invalid pointer with the resource group. --- src/cairo-pattern.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index bd7e07af..0ecfbe39 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -250,9 +250,10 @@ _cairo_pattern_fini (cairo_pattern_t *pattern) } cairo_status_t -_cairo_pattern_create_copy (cairo_pattern_t **pattern, +_cairo_pattern_create_copy (cairo_pattern_t **pattern_out, const cairo_pattern_t *other) { + cairo_pattern_t *pattern; cairo_status_t status; if (other->status) @@ -260,29 +261,29 @@ _cairo_pattern_create_copy (cairo_pattern_t **pattern, switch (other->type) { case CAIRO_PATTERN_TYPE_SOLID: - *pattern = malloc (sizeof (cairo_solid_pattern_t)); + pattern = malloc (sizeof (cairo_solid_pattern_t)); break; case CAIRO_PATTERN_TYPE_SURFACE: - *pattern = malloc (sizeof (cairo_surface_pattern_t)); + pattern = malloc (sizeof (cairo_surface_pattern_t)); break; case CAIRO_PATTERN_TYPE_LINEAR: - *pattern = malloc (sizeof (cairo_linear_pattern_t)); + pattern = malloc (sizeof (cairo_linear_pattern_t)); break; case CAIRO_PATTERN_TYPE_RADIAL: - *pattern = malloc (sizeof (cairo_radial_pattern_t)); + pattern = malloc (sizeof (cairo_radial_pattern_t)); break; } - if (unlikely (*pattern == NULL)) + if (unlikely (pattern == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - status = _cairo_pattern_init_copy (*pattern, other); + status = _cairo_pattern_init_copy (pattern, other); if (unlikely (status)) { - free (*pattern); + free (pattern); return status; } - CAIRO_REFERENCE_COUNT_INIT (&(*pattern)->ref_count, 1); - + CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 1); + *pattern_out = pattern; return CAIRO_STATUS_SUCCESS; } -- cgit v1.2.3 From ad83765a1441cb369c3e7f3de77c243297406c7a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 3 Apr 2009 09:23:58 +0100 Subject: [xlib] Allocate bounded region on stack. Eliminate the extremely short-lived and oft unnecessary heap allocation of the region by first checking to see whether the clip exceeds the surface bounds and only then intersect the clip with a local stack-allocated region. --- src/cairo-region.c | 23 +++++++++++++++++++ src/cairo-xlib-surface.c | 58 +++++++++++++++++++++++++++++++----------------- src/cairoint.h | 10 +++++++++ 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/cairo-region.c b/src/cairo-region.c index 15bf2f16..5d1f2c5f 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -76,6 +76,29 @@ _cairo_region_set_error (cairo_region_t *region, return _cairo_error (status); } +void +_cairo_region_init (cairo_region_t *region) +{ + region->status = CAIRO_STATUS_SUCCESS; + pixman_region32_init (®ion->rgn); +} + +void +_cairo_region_init_rectangle (cairo_region_t *region, + const cairo_rectangle_int_t *rectangle) +{ + region->status = CAIRO_STATUS_SUCCESS; + pixman_region32_init_rect (®ion->rgn, + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); +} + +void +_cairo_region_fini (cairo_region_t *region) +{ + pixman_region32_fini (®ion->rgn); +} + /** * cairo_region_create: * diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index a6820afd..d1e7391c 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -2269,6 +2269,32 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, return status; } +static cairo_region_t * +_surface_maybe_clip_region (cairo_xlib_surface_t *surface, + cairo_region_t *clip, + cairo_region_t *bounded) +{ + cairo_rectangle_int_t rect; + + cairo_region_get_extents (clip, &rect); + if (rect.x >= 0 && + rect.y >= 0 && + rect.x + rect.width <= surface->width && + rect.y + rect.height <= surface->height) + { + return clip; + } + + rect.x = rect.y = 0; + rect.width = surface->width; + rect.height = surface->height; + _cairo_region_init_rectangle (bounded, &rect); + + bounded->status = cairo_region_intersect (bounded, clip); + + return bounded; +} + static cairo_int_status_t _cairo_xlib_surface_set_clip_region (void *abstract_surface, cairo_region_t *region) @@ -2288,33 +2314,24 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, surface->num_clip_rects = 0; if (region != NULL) { - cairo_status_t status; XRectangle *rects = NULL; int n_rects, i; - cairo_rectangle_int_t rect; - cairo_region_t *bounded; - - rect.x = rect.y = 0; - rect.width = surface->width; - rect.height = surface->height; + cairo_region_t bounded; /* Intersect the region with the bounds of the surface. This * is necessary so we don't wrap around when we convert cairo's * 32 bit region into 16 bit rectangles. */ - bounded = cairo_region_create_rectangle (&rect); - status = cairo_region_intersect (bounded, region); - if (unlikely (status)) { - cairo_region_destroy (bounded); - return status; - } - - n_rects = cairo_region_num_rectangles (bounded); + region = _surface_maybe_clip_region (surface, region, &bounded); + if (unlikely (region->status)) + return region->status; + n_rects = cairo_region_num_rectangles (region); if (n_rects > ARRAY_LENGTH (surface->embedded_clip_rects)) { rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle)); if (unlikely (rects == NULL)) { - cairo_region_destroy (bounded); + if (unlikely (region == &bounded)) + _cairo_region_fini (&bounded); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } } else { @@ -2323,16 +2340,17 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, for (i = 0; i < n_rects; i++) { cairo_rectangle_int_t rect; - - cairo_region_get_rectangle (bounded, i, &rect); + + cairo_region_get_rectangle (region, i, &rect); rects[i].x = rect.x; rects[i].y = rect.y; rects[i].width = rect.width; rects[i].height = rect.height; } - - cairo_region_destroy (bounded); + + if (unlikely (region == &bounded)) + _cairo_region_fini (&bounded); surface->have_clip_rects = TRUE; surface->clip_rects = rects; diff --git a/src/cairoint.h b/src/cairoint.h index 21b28648..29e7ccf9 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2534,6 +2534,16 @@ struct _cairo_region { pixman_region32_t rgn; }; +cairo_private void +_cairo_region_init (cairo_region_t *region); + +cairo_private void +_cairo_region_init_rectangle (cairo_region_t *region, + const cairo_rectangle_int_t *rectangle); + +cairo_private void +_cairo_region_fini (cairo_region_t *region); + /* cairo-unicode.c */ cairo_private int -- cgit v1.2.3 From 1496c5cf51a2304dfd4e9d359a0645ff44fadd3e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 10 Apr 2009 14:50:26 +0100 Subject: [analysis] Use _cairo_region_init() Avoid secondary allocations of the thin region wrappers during surface creation by embedding them into the parent structure. This has the satisfactory side-effect of not requiring status checks which current code lacks. --- src/cairo-analysis-surface.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index cd799852..c767d07c 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -51,8 +51,8 @@ typedef struct { cairo_bool_t has_supported; cairo_bool_t has_unsupported; - cairo_region_t *supported_region; - cairo_region_t *fallback_region; + cairo_region_t supported_region; + cairo_region_t fallback_region; cairo_rectangle_int_t current_clip; cairo_box_t page_bbox; @@ -214,7 +214,7 @@ _add_operation (cairo_analysis_surface_t *surface, * region there is no benefit in emitting a native operation as * the fallback image will be painted on top. */ - if (cairo_region_contains_rectangle (surface->fallback_region, rect) == CAIRO_REGION_OVERLAP_IN) + if (cairo_region_contains_rectangle (&surface->fallback_region, rect) == CAIRO_REGION_OVERLAP_IN) return CAIRO_INT_STATUS_IMAGE_FALLBACK; if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) { @@ -225,7 +225,7 @@ _add_operation (cairo_analysis_surface_t *surface, * natively supported and the backend will blend the * transparency into the white background. */ - if (cairo_region_contains_rectangle (surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT) + if (cairo_region_contains_rectangle (&surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT) backend_status = CAIRO_STATUS_SUCCESS; } @@ -234,7 +234,7 @@ _add_operation (cairo_analysis_surface_t *surface, * this region will be emitted as native operations. */ surface->has_supported = TRUE; - status = cairo_region_union_rectangle (surface->supported_region, rect); + status = cairo_region_union_rectangle (&surface->supported_region, rect); return status; } @@ -243,7 +243,7 @@ _add_operation (cairo_analysis_surface_t *surface, * emitted. */ surface->has_unsupported = TRUE; - status = cairo_region_union_rectangle (surface->fallback_region, rect); + status = cairo_region_union_rectangle (&surface->fallback_region, rect); /* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate * unsupported operations to the meta surface as using @@ -262,8 +262,8 @@ _cairo_analysis_surface_finish (void *abstract_surface) { cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - cairo_region_destroy (surface->supported_region); - cairo_region_destroy (surface->fallback_region); + _cairo_region_fini (&surface->supported_region); + _cairo_region_fini (&surface->fallback_region); cairo_surface_destroy (surface->target); @@ -773,14 +773,14 @@ _cairo_analysis_surface_create (cairo_surface_t *target, surface->has_supported = FALSE; surface->has_unsupported = FALSE; + _cairo_region_init (&surface->supported_region); + _cairo_region_init (&surface->fallback_region); + surface->page_bbox.p1.x = 0; surface->page_bbox.p1.y = 0; surface->page_bbox.p2.x = 0; surface->page_bbox.p2.y = 0; - surface->supported_region = cairo_region_create (); - surface->fallback_region = cairo_region_create (); - if (width == -1 && height == -1) { surface->current_clip.x = CAIRO_RECT_INT_MIN; surface->current_clip.y = CAIRO_RECT_INT_MIN; @@ -826,7 +826,7 @@ _cairo_analysis_surface_get_supported (cairo_surface_t *abstract_surface) { cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - return surface->supported_region; + return &surface->supported_region; } cairo_region_t * @@ -834,7 +834,7 @@ _cairo_analysis_surface_get_unsupported (cairo_surface_t *abstract_surface) { cairo_analysis_surface_t *surface = (cairo_analysis_surface_t *) abstract_surface; - return surface->fallback_region; + return &surface->fallback_region; } cairo_bool_t -- cgit v1.2.3 From 0f0e2d738437176e72317b37ef66fbc56c60ba93 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 10 Apr 2009 14:52:48 +0100 Subject: [pdf] Propagate failure from type3 glyph surface creation. Add an early check that we successfully created the glyph surface. --- src/cairo-pdf-surface.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 886dd6b9..b1458d8e 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -3934,6 +3934,11 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su null_stream, _cairo_pdf_emit_imagemask, surface->font_subsets); + if (unlikely (type3_surface->status)) { + status2 = _cairo_output_stream_destroy (null_stream); + return type3_surface->status; + } + _cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface, _cairo_pdf_surface_add_font, surface); @@ -3990,6 +3995,12 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, NULL, _cairo_pdf_emit_imagemask, surface->font_subsets); + if (unlikely (type3_surface->status)) { + free (glyphs); + free (widths); + return type3_surface->status; + } + _cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface, _cairo_pdf_surface_add_font, surface); -- cgit v1.2.3 From 21d1138da9bcf9c006e0cf3f3d1d50e1c7cec1de Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 10 Apr 2009 14:53:55 +0100 Subject: [scaled-font-subsets] Check for malloc failure. Check that the utf8 string is successfully allocated before writing to it, otherwise propagate the error status back to the callers. --- src/cairo-scaled-font-subsets.c | 63 +++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index 44e850e4..02b32aa7 100644 --- a/src/cairo-scaled-font-subsets.c +++ b/src/cairo-scaled-font-subsets.c @@ -372,13 +372,16 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph, return CAIRO_STATUS_SUCCESS; } -static cairo_bool_t +static cairo_status_t _cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph, const char *utf8, - int utf8_len) + int utf8_len, + cairo_bool_t *is_mapped) { + *is_mapped = FALSE; + if (utf8_len < 0) - return FALSE; + return CAIRO_STATUS_SUCCESS; if (utf8 != NULL && utf8_len != 0 && utf8[utf8_len - 1] == '\0') utf8_len--; @@ -389,28 +392,25 @@ _cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph, memcmp (utf8, sub_font_glyph->utf8, utf8_len) == 0) { /* Requested utf8 mapping matches the existing mapping */ - return TRUE; - } - else - { - /* Requested utf8 mapping does not match the existing mapping */ - return FALSE; + *is_mapped = TRUE; } } else { /* No existing mapping. Use the requested mapping */ sub_font_glyph->utf8 = malloc (utf8_len + 1); + if (unlikely (sub_font_glyph->utf8 == NULL)) + return CAIRO_STATUS_NO_MEMORY; + memcpy (sub_font_glyph->utf8, utf8, utf8_len); sub_font_glyph->utf8[utf8_len] = 0; sub_font_glyph->utf8_len = utf8_len; - return TRUE; + *is_mapped = TRUE; } } - /* No mapping was requested. */ - return FALSE; + return CAIRO_STATUS_SUCCESS; } -static cairo_bool_t +static cairo_int_status_t _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font, unsigned long scaled_font_glyph_index, const char *utf8, @@ -418,6 +418,7 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font, cairo_scaled_font_subsets_glyph_t *subset_glyph) { cairo_sub_font_glyph_t key, *sub_font_glyph; + cairo_int_status_t status; _cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index); sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs, @@ -430,13 +431,15 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font, subset_glyph->is_composite = sub_font->is_composite; subset_glyph->x_advance = sub_font_glyph->x_advance; subset_glyph->y_advance = sub_font_glyph->y_advance; - subset_glyph->utf8_is_mapped = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, utf8, utf8_len); + status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, + utf8, utf8_len, + &subset_glyph->utf8_is_mapped); subset_glyph->unicode = sub_font_glyph->unicode; - return TRUE; + return status; } - return FALSE; + return CAIRO_INT_STATUS_UNSUPPORTED; } static cairo_status_t @@ -524,10 +527,12 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, subset_glyph->is_composite = sub_font->is_composite; subset_glyph->x_advance = sub_font_glyph->x_advance; subset_glyph->y_advance = sub_font_glyph->y_advance; - subset_glyph->utf8_is_mapped = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, utf8, utf8_len); + status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, + utf8, utf8_len, + &subset_glyph->utf8_is_mapped); subset_glyph->unicode = sub_font_glyph->unicode; - return CAIRO_STATUS_SUCCESS; + return status; } static void @@ -686,11 +691,12 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, sub_font = _cairo_hash_table_lookup (subsets->unscaled_sub_fonts, &key.base); if (sub_font != NULL) { - if (_cairo_sub_font_lookup_glyph (sub_font, - scaled_font_glyph_index, - utf8, utf8_len, - subset_glyph)) - return CAIRO_STATUS_SUCCESS; + status = _cairo_sub_font_lookup_glyph (sub_font, + scaled_font_glyph_index, + utf8, utf8_len, + subset_glyph); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; } } @@ -700,11 +706,12 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, sub_font = _cairo_hash_table_lookup (subsets->scaled_sub_fonts, &key.base); if (sub_font != NULL) { - if (_cairo_sub_font_lookup_glyph (sub_font, - scaled_font_glyph_index, - utf8, utf8_len, - subset_glyph)) - return CAIRO_STATUS_SUCCESS; + status = _cairo_sub_font_lookup_glyph (sub_font, + scaled_font_glyph_index, + utf8, utf8_len, + subset_glyph); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; } /* Glyph not found. Determine whether the glyph is outline or -- cgit v1.2.3 From a6ffb69a54f15659dac7c6b2e1c98bd7893ccdf1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 3 Apr 2009 17:28:05 +0100 Subject: [type3] Check error status before emit_image(). Be careful not to pass an error object down to emit_image() hook, propagate the error instead. This relieves the burden of the error check from the callee -- which was causing an assertion failure in the ps backend. --- src/cairo-type3-glyph-surface.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c index 3ff5003b..c52915f7 100644 --- a/src/cairo-type3-glyph-surface.c +++ b/src/cairo-type3-glyph-surface.c @@ -88,6 +88,12 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface, { cairo_status_t status; + /* The only image type supported by Type 3 fonts are 1-bit masks */ + image = _cairo_image_surface_coerce (image, CAIRO_FORMAT_A1); + status = image->base.status; + if (unlikely (status)) + return status; + _cairo_output_stream_printf (surface->stream, "q %f %f %f %f %f %f cm\n", image_matrix->xx, @@ -97,8 +103,6 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface, image_matrix->x0, image_matrix->y0); - /* The only image type supported by Type 3 fonts are 1-bit masks */ - image = _cairo_image_surface_coerce (image, CAIRO_FORMAT_A1); status = surface->emit_image (image, surface->stream); cairo_surface_destroy (&image->base); -- cgit v1.2.3 From d46bd67c8b3f63d6286845e814f8f1e040f89737 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 10 Apr 2009 14:55:24 +0100 Subject: [type3] Add status checks. Propagate error from the stream when creating the surface and add status guards before writing to the potential nil object. --- src/cairo-type3-glyph-surface.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c index c52915f7..2ffc0187 100644 --- a/src/cairo-type3-glyph-surface.c +++ b/src/cairo-type3-glyph-surface.c @@ -46,14 +46,17 @@ static const cairo_surface_backend_t cairo_type3_glyph_surface_backend; cairo_surface_t * -_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, - cairo_output_stream_t *stream, +_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, + cairo_output_stream_t *stream, cairo_type3_glyph_surface_emit_image_t emit_image, - cairo_scaled_font_subsets_t *font_subsets) + cairo_scaled_font_subsets_t *font_subsets) { cairo_type3_glyph_surface_t *surface; cairo_matrix_t invert_y_axis; + if (unlikely (stream != NULL && stream->status)) + return _cairo_surface_create_in_error (stream->status); + surface = malloc (sizeof (cairo_type3_glyph_surface_t)); if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); @@ -379,6 +382,9 @@ _cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract { cairo_type3_glyph_surface_t *surface = abstract_surface; + if (unlikely (surface->base.status)) + return; + _cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators, use_font_subset, closure); @@ -393,7 +399,13 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface, cairo_status_t status, status2; cairo_output_stream_t *null_stream; + if (unlikely (surface->base.status)) + return surface->base.status; + null_stream = _cairo_null_stream_create (); + if (unlikely (null_stream->status)) + return null_stream->status; + _cairo_type3_glyph_surface_set_stream (surface, null_stream); _cairo_scaled_font_freeze_cache (surface->scaled_font); @@ -446,6 +458,9 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface, double x_advance, y_advance; cairo_matrix_t font_matrix_inverse; + if (unlikely (surface->base.status)) + return surface->base.status; + _cairo_type3_glyph_surface_set_stream (surface, stream); _cairo_scaled_font_freeze_cache (surface->scaled_font); @@ -496,6 +511,10 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface, cairo_output_stream_t *mem_stream; mem_stream = _cairo_memory_stream_create (); + status = mem_stream->status; + if (unlikely (status)) + goto FAIL; + _cairo_type3_glyph_surface_set_stream (surface, mem_stream); _cairo_output_stream_printf (surface->stream, "q\n"); @@ -520,6 +539,7 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface, if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK) status = _cairo_type3_glyph_surface_emit_fallback_image (surface, glyph_index); + FAIL: _cairo_scaled_font_thaw_cache (surface->scaled_font); return status; -- cgit v1.2.3 From 5a76c233bffda65140c6ada9b5f2ed7d3bcc999e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Apr 2009 11:02:40 +0100 Subject: [type3] Propagate error from font creation. Perform an error check after creating a scaled-font to prevent operations on a nil-object. --- src/cairo-type3-glyph-surface.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c index 2ffc0187..104da53d 100644 --- a/src/cairo-type3-glyph-surface.c +++ b/src/cairo-type3-glyph-surface.c @@ -285,6 +285,8 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface, &scaled_font->font_matrix, &new_ctm, &scaled_font->options); + if (unlikely (font->status)) + return font->status; status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators, NULL, 0, -- cgit v1.2.3 From 8bf109bd2a9c9bf755671185733def898a4f96f2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Apr 2009 17:17:06 +0100 Subject: [pattern] Silence compiler with impossible case. Assert that the pattern is one of the four known types, and return an error so that the compiler knows that the local variable can not be used uninitialised. --- src/cairo-pattern.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 0ecfbe39..81fd5670 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -272,6 +272,9 @@ _cairo_pattern_create_copy (cairo_pattern_t **pattern_out, case CAIRO_PATTERN_TYPE_RADIAL: pattern = malloc (sizeof (cairo_radial_pattern_t)); break; + default: + ASSERT_NOT_REACHED; + return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH); } if (unlikely (pattern == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); -- cgit v1.2.3 From 50302f156dfba4dcb3639843d7eda819f2c6797c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Apr 2009 12:59:36 +0100 Subject: [ft] Check (correctly!) for pattern duplication failure. Check the return from FcPatternDuplicate() for allocation failure (and not the original pattern)! --- src/cairo-ft-font.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 3cfe344a..6e9d5f9b 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -2352,7 +2352,7 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern, font_face->next = NULL; font_face->pattern = FcPatternDuplicate (pattern); - if (unlikely (pattern == NULL)) { + if (unlikely (font_face->pattern == NULL)) { free (font_face); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } -- cgit v1.2.3 From d46c56f18c8a93d3d50be9333292c7c9b0ac0a78 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Apr 2009 13:00:59 +0100 Subject: [ft] Check for pattern duplication failure. Check the return of FcPatternDuplicate() for failure, and propagate the error. --- src/cairo-ft-font.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 6e9d5f9b..f5b33305 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -2558,6 +2558,8 @@ _cairo_ft_resolve_pattern (FcPattern *pattern, return status; pattern = FcPatternDuplicate (pattern); + if (pattern == NULL) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); if (! FcPatternAddDouble (pattern, FC_PIXEL_SIZE, sf.y_scale)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); -- cgit v1.2.3 From be27e844c83c0f5cf25dee1c62768dbf70897a06 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Apr 2009 17:13:52 +0100 Subject: [ft] Propagate status from font creation Return the true error status whel _cairo_ft_unscaled_font_create_internal(). This ensures that the original error is not masked and we are able to report the error during fontconfig pattern resolution. --- src/cairo-ft-font.c | 90 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 39 deletions(-) diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index f5b33305..e701c213 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -414,11 +414,12 @@ _cairo_ft_unscaled_font_keys_equal (const void *key_a, /* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from * pattern. Returns a new reference to the unscaled font. */ -static cairo_ft_unscaled_font_t * +static cairo_status_t _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face, char *filename, int id, - FT_Face font_face) + FT_Face font_face, + cairo_ft_unscaled_font_t **out) { cairo_ft_unscaled_font_t key, *unscaled; cairo_ft_unscaled_font_map_t *font_map; @@ -426,7 +427,7 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face, font_map = _cairo_ft_unscaled_font_map_lock (); if (unlikely (font_map == NULL)) - goto UNWIND; + return _cairo_error (CAIRO_STATUS_NO_MEMORY); _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face); @@ -435,14 +436,13 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face, &key.base.hash_entry); if (unscaled != NULL) { _cairo_unscaled_font_reference (&unscaled->base); - _cairo_ft_unscaled_font_map_unlock (); - return unscaled; + goto DONE; } /* Otherwise create it and insert into hash table. */ unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); if (unlikely (unscaled == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto UNWIND_FONT_MAP_LOCK; } @@ -456,9 +456,10 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face, if (unlikely (status)) goto UNWIND_UNSCALED_FONT_INIT; +DONE: _cairo_ft_unscaled_font_map_unlock (); - - return unscaled; + *out = unscaled; + return CAIRO_STATUS_SUCCESS; UNWIND_UNSCALED_FONT_INIT: _cairo_ft_unscaled_font_fini (unscaled); @@ -466,39 +467,52 @@ UNWIND_UNSCALED_MALLOC: free (unscaled); UNWIND_FONT_MAP_LOCK: _cairo_ft_unscaled_font_map_unlock (); -UNWIND: - return NULL; + return status; } #if CAIRO_HAS_FC_FONT -static cairo_ft_unscaled_font_t * -_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern) +static cairo_status_t +_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern, + cairo_ft_unscaled_font_t **out) { FT_Face font_face = NULL; char *filename = NULL; int id = 0; + FcResult ret; - if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face) == FcResultMatch) - goto DONE; - - if (FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &filename) == FcResultMatch) { - /* If FC_INDEX is not set, we just use 0 */ - FcPatternGetInteger (pattern, FC_INDEX, 0, &id); + ret = FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face); + switch ((int) ret) { + case FcResultMatch: goto DONE; + case FcResultOutOfMemory: + break; + default: + if (FcPatternGetString (pattern, FC_FILE, 0, + (FcChar8 **) &filename) == FcResultMatch) + { + /* If FC_INDEX is not set, we just use 0 */ + if (FcPatternGetInteger (pattern, + FC_INDEX, 0, &id) != FcResultOutOfMemory) + goto DONE; + } + break; } - return NULL; + return _cairo_error (CAIRO_STATUS_NO_MEMORY); DONE: - return _cairo_ft_unscaled_font_create_internal (font_face != NULL, filename, id, font_face); + return _cairo_ft_unscaled_font_create_internal (font_face != NULL, + filename, id, font_face, + out); } #endif -static cairo_ft_unscaled_font_t * -_cairo_ft_unscaled_font_create_from_face (FT_Face face) +static cairo_status_t +_cairo_ft_unscaled_font_create_from_face (FT_Face face, + cairo_ft_unscaled_font_t **out) { - return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face); + return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face, out); } static void @@ -2311,7 +2325,6 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face, *scaled_font = _cairo_scaled_font_create_in_error (status); return CAIRO_STATUS_SUCCESS; } - } else #endif { @@ -2319,11 +2332,11 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face, ft_options = font_face->ft_options; } - return _cairo_ft_scaled_font_create (unscaled, - &font_face->base, - font_matrix, ctm, - options, ft_options, - scaled_font); + return _cairo_ft_scaled_font_create (unscaled, + &font_face->base, + font_matrix, ctm, + options, ft_options, + scaled_font); } const cairo_font_face_backend_t _cairo_ft_font_face_backend = { @@ -2583,11 +2596,9 @@ _cairo_ft_resolve_pattern (FcPattern *pattern, goto FREE_PATTERN; } - *unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved); - if (!*unscaled) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + status = _cairo_ft_unscaled_font_create_for_pattern (resolved, unscaled); + if (unlikely (status)) goto FREE_RESOLVED; - } _get_pattern_ft_options (resolved, ft_options); @@ -2643,10 +2654,12 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern) cairo_ft_unscaled_font_t *unscaled; cairo_font_face_t *font_face; cairo_ft_options_t ft_options; + cairo_status_t status; - unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern); + status = _cairo_ft_unscaled_font_create_for_pattern (pattern, &unscaled); + if (unlikely (status)) + return (cairo_font_face_t *) &_cairo_font_face_nil; if (unlikely (unscaled == NULL)) { - cairo_status_t status; /* Store the pattern. We will resolve it and create unscaled * font when creating scaled fonts */ status = _cairo_ft_font_face_create_for_pattern (pattern, @@ -2718,12 +2731,11 @@ cairo_ft_font_face_create_for_ft_face (FT_Face face, cairo_ft_unscaled_font_t *unscaled; cairo_font_face_t *font_face; cairo_ft_options_t ft_options; + cairo_status_t status; - unscaled = _cairo_ft_unscaled_font_create_from_face (face); - if (unlikely (unscaled == NULL)) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); + status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled); + if (unlikely (status)) return (cairo_font_face_t *)&_cairo_font_face_nil; - } ft_options.load_flags = load_flags; ft_options.extra_flags = 0; -- cgit v1.2.3 From 817589e1967ebdd5e5bda1781eb76010fd8c37dc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Apr 2009 13:01:52 +0100 Subject: [test] Call FcInit() manually. Pre-initialise fontconfig whilst memfault is disabled to avoid a lot of expensive, redundant testing of FcInit() throughout the test suite. --- test/cairo-test.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/cairo-test.c b/test/cairo-test.c index 897332ab..96ab2dcd 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -743,6 +743,12 @@ REPEAT: VALGRIND_RESET_LEAKS (); ctx->last_fault_count = 0; last_fault_count = VALGRIND_COUNT_FAULTS (); + + /* Pre-initialise fontconfig so that the configuration is loaded without + * malloc failures (our primary goal is to test cairo fault tolerance). + */ + FcInit (); + VALGRIND_ENABLE_FAULTS (); #endif have_output = FALSE; -- cgit v1.2.3 From 1ae2ddc1dd4c90d50b8c57c4de677f8ab96b1fa2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 16 Apr 2009 17:19:12 +0100 Subject: [memfault] Manually inject faults when using stack allocations Ensure that no assumptions are made that a small allocation will succeed by manually injecting faults when we may be simply allocating from an embedded memory pool. The main advantage in manual fault injection is improved code coverage - from within the test suite most allocations are handled by the embedded memory pools. --- src/cairo-array.c | 3 +++ src/cairo-bentley-ottmann.c | 3 +++ src/cairo-gstate.c | 3 +++ src/cairo-hull.c | 3 +++ src/cairo-image-surface.c | 6 ++++++ src/cairo-malloc-private.h | 7 +++++++ src/cairo-misc.c | 3 +++ src/cairo-path-stroke.c | 2 ++ src/cairo-pattern.c | 9 +++++++++ src/cairo-pen.c | 9 +++++++++ src/cairo-polygon.c | 5 +++++ src/cairo-scaled-font.c | 3 +++ src/cairo-stroke-style.c | 3 +++ src/cairo-traps.c | 5 +++++ 14 files changed, 64 insertions(+) diff --git a/src/cairo-array.c b/src/cairo-array.c index 318fd07e..77e575ff 100644 --- a/src/cairo-array.c +++ b/src/cairo-array.c @@ -125,6 +125,9 @@ _cairo_array_grow_by (cairo_array_t *array, unsigned int additional) if (required_size > INT_MAX || required_size < array->num_elements) return _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (required_size <= old_size) return CAIRO_STATUS_SUCCESS; diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c index 81eed1d6..1d59d703 100644 --- a/src/cairo-bentley-ottmann.c +++ b/src/cairo-bentley-ottmann.c @@ -1660,6 +1660,9 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps, if (0 == polygon->num_edges) return CAIRO_STATUS_SUCCESS; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + has_limits = _cairo_traps_get_limit (traps, &limit); edges = stack_edges; diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 9ee31b07..c7c4cf55 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -222,6 +222,9 @@ _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist) cairo_gstate_t *top; cairo_status_t status; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + top = *freelist; if (top == NULL) { top = malloc (sizeof (cairo_gstate_t)); diff --git a/src/cairo-hull.c b/src/cairo-hull.c index a699a524..1fa919bf 100644 --- a/src/cairo-hull.c +++ b/src/cairo-hull.c @@ -198,6 +198,9 @@ _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices) cairo_hull_t *hull; int num_hull = *num_vertices; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (num_hull > ARRAY_LENGTH (hull_stack)) { hull = _cairo_malloc_ab (num_hull, sizeof (cairo_hull_t)); if (unlikely (hull == NULL)) diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 746fca11..b601ac40 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -1044,6 +1044,9 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface, cairo_int_status_t status = CAIRO_STATUS_SUCCESS; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + pixman_color.red = color->red_short; pixman_color.green = color->green_short; pixman_color.blue = color->blue_short; @@ -1112,6 +1115,9 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, if (height == 0 || width == 0) return CAIRO_STATUS_SUCCESS; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + /* Convert traps to pixman traps */ if (num_traps > ARRAY_LENGTH (stack_traps)) { pixman_traps = _cairo_malloc_ab (num_traps, sizeof (pixman_trapezoid_t)); diff --git a/src/cairo-malloc-private.h b/src/cairo-malloc-private.h index f8094f91..e36f93b8 100644 --- a/src/cairo-malloc-private.h +++ b/src/cairo-malloc-private.h @@ -39,6 +39,13 @@ #include "cairo-wideint-private.h" +#if HAVE_MEMFAULT +#include +#define CAIRO_INJECT_FAULT() VALGRIND_INJECT_FAULT() +#else +#define CAIRO_INJECT_FAULT() 0 +#endif + /** * _cairo_malloc: * @size: size in bytes diff --git a/src/cairo-misc.c b/src/cairo-misc.c index aaf849b9..d4b10e1c 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -704,6 +704,9 @@ _cairo_intern_string (const char **str_inout, int len) cairo_intern_string_t tmpl, *istring; cairo_status_t status = CAIRO_STATUS_SUCCESS; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (len < 0) len = strlen (str); tmpl.hash_entry.hash = _intern_string_hash (str, len); diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index d6e5790c..37ac79c7 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -1278,6 +1278,8 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker, cairo_bool_t is_horizontal, cairo_bool_t has_join) { + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); if (stroker->num_segments == stroker->segments_size) { int new_size = stroker->segments_size * 2; diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 81fd5670..0fb36bfa 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -119,6 +119,9 @@ static cairo_status_t _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, const cairo_gradient_pattern_t *other) { + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (other->base.type == CAIRO_PATTERN_TYPE_LINEAR) { cairo_linear_pattern_t *dst = (cairo_linear_pattern_t *) pattern; @@ -841,6 +844,9 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern) return CAIRO_STATUS_SUCCESS; } + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + assert (pattern->n_stops <= pattern->stops_size); if (pattern->stops == pattern->stops_embedded) { @@ -1257,6 +1263,9 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat int clone_offset_x, clone_offset_y; cairo_matrix_t matrix = pattern->base.matrix; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) { pixman_stops = _cairo_malloc_ab (pattern->n_stops, sizeof(pixman_gradient_stop_t)); diff --git a/src/cairo-pen.c b/src/cairo-pen.c index 9d5e8959..eb66b1a0 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -55,6 +55,9 @@ _cairo_pen_init (cairo_pen_t *pen, int i; int reflect; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + pen->radius = radius; pen->tolerance = tolerance; @@ -109,6 +112,9 @@ _cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other) { *pen = *other; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + pen->vertices = pen->vertices_embedded; if (pen->num_vertices) { if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) { @@ -132,6 +138,9 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) int num_vertices; int i; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + num_vertices = pen->num_vertices + num_points; if (num_vertices > ARRAY_LENGTH (pen->vertices_embedded) || pen->vertices != pen->vertices_embedded) diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c index 0b0fa991..d74d098d 100644 --- a/src/cairo-polygon.c +++ b/src/cairo-polygon.c @@ -64,6 +64,11 @@ _cairo_polygon_grow (cairo_polygon_t *polygon) int old_size = polygon->edges_size; int new_size = 4 * old_size; + if (CAIRO_INJECT_FAULT ()) { + polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + return FALSE; + } + if (polygon->edges == polygon->edges_embedded) { new_edges = _cairo_malloc_ab (new_size, sizeof (cairo_edge_t)); if (new_edges != NULL) diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 249ab6c2..b8d9602d 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -2558,6 +2558,9 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, if (unlikely (scaled_font->status)) return scaled_font->status; + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + /* * Check cache for glyph */ diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c index d808ad8b..462b868a 100644 --- a/src/cairo-stroke-style.c +++ b/src/cairo-stroke-style.c @@ -52,6 +52,9 @@ cairo_status_t _cairo_stroke_style_init_copy (cairo_stroke_style_t *style, cairo_stroke_style_t *other) { + if (CAIRO_INJECT_FAULT ()) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + style->line_width = other->line_width; style->line_cap = other->line_cap; style->line_join = other->line_join; diff --git a/src/cairo-traps.c b/src/cairo-traps.c index faf7722f..fed3f101 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -131,6 +131,11 @@ _cairo_traps_grow (cairo_traps_t *traps) cairo_trapezoid_t *new_traps; int new_size = 2 * MAX (traps->traps_size, 16); + if (CAIRO_INJECT_FAULT ()) { + traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + return FALSE; + } + if (traps->traps == traps->traps_embedded) { new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t)); if (new_traps != NULL) -- cgit v1.2.3 From 526fcdb7e6cc8b522508762b1a68a5585fddf823 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 20 Apr 2009 10:56:06 +0100 Subject: [build] Enable shave support shave transforms the messy output of autotools into a pretty (quiet!) Kbuild-like one. Lets see how controversial a simple change can be... --- build/.gitignore | 2 ++ build/aclocal.dolt.m4 | 1 + build/aclocal.shave.m4 | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ build/shave-libtool.in | 69 +++++++++++++++++++++++++++++++++++++++++++ build/shave.in | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 4 +++ 6 files changed, 232 insertions(+) create mode 100644 build/aclocal.shave.m4 create mode 100644 build/shave-libtool.in create mode 100644 build/shave.in diff --git a/build/.gitignore b/build/.gitignore index 53f31d77..ce1256a5 100644 --- a/build/.gitignore +++ b/build/.gitignore @@ -10,3 +10,5 @@ mkinstalldirs #Makefile.win32.features-h libtool.m4 lt*.m4 +shave +shave-libtool diff --git a/build/aclocal.dolt.m4 b/build/aclocal.dolt.m4 index 8f94582f..ece5eea9 100644 --- a/build/aclocal.dolt.m4 +++ b/build/aclocal.dolt.m4 @@ -155,6 +155,7 @@ modeok=false tagok=false for arg in "$[]@"; do case "$arg" in + --silent) ;; --mode=compile) modeok=true ;; --tag=CC|--tag=CXX) tagok=true ;; *) args@<:@${#args[@]}@:>@="$arg" ;; diff --git a/build/aclocal.shave.m4 b/build/aclocal.shave.m4 new file mode 100644 index 00000000..0a3509e5 --- /dev/null +++ b/build/aclocal.shave.m4 @@ -0,0 +1,77 @@ +dnl Make automake/libtool output more friendly to humans +dnl Damien Lespiau +dnl +dnl SHAVE_INIT([shavedir],[default_mode]) +dnl +dnl shavedir: the directory where the shave scripts are, it defaults to +dnl $(top_builddir) +dnl default_mode: (enable|disable) default shave mode. This parameter +dnl controls shave's behaviour when no option has been +dnl given to configure. It defaults to disable. +dnl +dnl * SHAVE_INIT should be called late in your configure.(ac|in) file (just +dnl before AC_CONFIG_FILE/AC_OUTPUT is perfect. This macro rewrites CC and +dnl LIBTOOL, you don't want the configure tests to have these variables +dnl re-defined. +dnl * This macro requires GNU make's -s option. + +AC_DEFUN([_SHAVE_ARG_ENABLE], +[ + AC_ARG_ENABLE([shave], + AS_HELP_STRING( + [--enable-shave], + [use shave to make the build pretty [[default=$1]]]),, + [enable_shave=$1] + ) +]) + +AC_DEFUN([SHAVE_INIT], +[ + dnl you can tweak the default value of enable_shave + m4_if([$2], [enable], [_SHAVE_ARG_ENABLE(yes)], [_SHAVE_ARG_ENABLE(no)]) + + if test x"$enable_shave" = xyes; then + dnl where can we find the shave scripts? + m4_if([$1],, + [shavedir="$ac_pwd"], + [shavedir="$ac_pwd/$1"]) + AC_SUBST(shavedir) + + dnl make is now quiet + AC_SUBST([MAKEFLAGS], [-s]) + AC_SUBST([AM_MAKEFLAGS], ['`test -z $V && echo -s`']) + + dnl we need sed + AC_CHECK_PROG(SED,sed,sed,false) + + dnl substitute libtool + SHAVE_SAVED_LIBTOOL=$LIBTOOL + LIBTOOL="${SHELL} ${shavedir}/shave-libtool '${SHAVE_SAVED_LIBTOOL}'" + AC_SUBST(LIBTOOL) + + dnl substitute cc/cxx + SHAVE_SAVED_CC=$CC + SHAVE_SAVED_CXX=$CXX + SHAVE_SAVED_FC=$FC + SHAVE_SAVED_F77=$F77 + SHAVE_SAVED_OBJC=$OBJC + CC="${SHELL} ${shavedir}/shave cc ${SHAVE_SAVED_CC}" + CXX="${SHELL} ${shavedir}/shave cxx ${SHAVE_SAVED_CXX}" + FC="${SHELL} ${shavedir}/shave fc ${SHAVE_SAVED_FC}" + F77="${SHELL} ${shavedir}/shave f77 ${SHAVE_SAVED_F77}" + OBJC="${SHELL} ${shavedir}/shave objc ${SHAVE_SAVED_OBJC}" + AC_SUBST(CC) + AC_SUBST(CXX) + AC_SUBST(FC) + AC_SUBST(F77) + AC_SUBST(OBJC) + + V=@ + else + V=1 + fi + Q='$(V:1=)' + AC_SUBST(V) + AC_SUBST(Q) +]) + diff --git a/build/shave-libtool.in b/build/shave-libtool.in new file mode 100644 index 00000000..1f3a720c --- /dev/null +++ b/build/shave-libtool.in @@ -0,0 +1,69 @@ +#!/bin/sh + +# we need sed +SED=@SED@ +if test -z "$SED" ; then +SED=sed +fi + +lt_unmangle () +{ + last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'` +} + +# the real libtool to use +LIBTOOL="$1" +shift + +# if 1, don't print anything, the underlaying wrapper will do it +pass_though=0 + +# scan the arguments, keep the right ones for libtool, and discover the mode +preserved_args= +while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --mode=*) + mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'` + preserved_args="$preserved_args $opt" + ;; + -o) + lt_output="$1" + preserved_args="$preserved_args $opt" + ;; + *) + preserved_args="$preserved_args $opt" + ;; + esac +done + +case "$mode" in +compile) + # shave will be called and print the actual CC/CXX/LINK line + preserved_args="$preserved_args --shave-mode=$mode" + pass_though=1 + ;; +link) + preserved_args="$preserved_args --shave-mode=$mode" + Q=" LINK " + ;; +*) + # let's u + # echo "*** libtool: Unimplemented mode: $mode, fill a bug report" + ;; +esac + +lt_unmangle "$lt_output" +output=$last_result + +if test -z $V; then + if test $pass_though -eq 0; then + echo "$Q$output" + fi + $LIBTOOL --silent $preserved_args +else + echo $LIBTOOL $preserved_args + $LIBTOOL $preserved_args +fi diff --git a/build/shave.in b/build/shave.in new file mode 100644 index 00000000..5c16f27a --- /dev/null +++ b/build/shave.in @@ -0,0 +1,79 @@ +#!/bin/sh + +# we need sed +SED=@SED@ +if test -z "$SED" ; then +SED=sed +fi + +lt_unmangle () +{ + last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'` +} + +# the tool to wrap (cc, cxx, ar, ranlib, ..) +tool="$1" +shift + +# the reel tool (to call) +REEL_TOOL="$1" +shift + +pass_through=0 +preserved_args= +while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --shave-mode=*) + mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'` + ;; + -o) + lt_output="$1" + preserved_args="$preserved_args $opt" + ;; + *) + preserved_args="$preserved_args $opt" + ;; + esac +done + +# mode=link is handled in the libtool wrapper +case "$mode,$tool" in +link,*) + pass_through=1 + ;; +*,cxx) + Q=" CXX " + ;; +*,cc) + Q=" CC " + ;; +*,fc) + Q=" FC " + ;; +*,f77) + Q=" F77 " + ;; +*,objc) + Q=" OBJC " + ;; +*,*) + # should not happen + Q=" CC " + ;; +esac + +lt_unmangle "$lt_output" +output=$last_result + +if test -z $V; then + if test $pass_through -eq 0; then + echo "$Q$output" + fi + $REEL_TOOL $preserved_args +else + echo $REEL_TOOL $preserved_args + $REEL_TOOL $preserved_args +fi diff --git a/configure.ac b/configure.ac index d0b69269..8afadcc8 100644 --- a/configure.ac +++ b/configure.ac @@ -539,7 +539,11 @@ dnl =========================================================================== # We use GTK+ for some utility/debugging tools PKG_CHECK_MODULES(gtk, "gtk+-2.0",, AC_MSG_RESULT(no)) +SHAVE_INIT([build], [enable]) # dnl Make the output pretty + AC_CONFIG_FILES([ +build/shave +build/shave-libtool Makefile boilerplate/Makefile src/Makefile -- cgit v1.2.3 From 6675cf558719f81afe2a4331bc6adb3cda637a26 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 1 May 2009 09:31:53 +0100 Subject: [build] Add lcov-1.7 to known list --- build/configure.ac.analysis | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/configure.ac.analysis b/build/configure.ac.analysis index 49928a56..f425a9af 100644 --- a/build/configure.ac.analysis +++ b/build/configure.ac.analysis @@ -25,7 +25,7 @@ if test "x$use_gcov" = "xyes"; then AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) fi - ltp_version_list="1.6 1.5 1.4" + ltp_version_list="1.7 1.6 1.5 1.4" AC_CHECK_PROG(LTP, lcov, lcov) AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml) -- cgit v1.2.3 From 4be6de9fc6192d59c8d61e8edafed941e868a756 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Apr 2009 10:03:20 +0100 Subject: [image] Return FORMAT_INVALID for an error surface. The default error value should be CAIRO_FORMAT_INVALID [-1] not 0 (which corresponds to CAIRO_FORMAT_ARGB32). --- src/cairo-image-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index b601ac40..baead108 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -569,7 +569,7 @@ cairo_image_surface_get_format (cairo_surface_t *surface) if (! _cairo_surface_is_image (surface)) { _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - return 0; + return CAIRO_FORMAT_INVALID; } return image_surface->format; -- cgit v1.2.3 From aac132a76a2af3719088678295169f1962a555e6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Apr 2009 10:14:36 +0100 Subject: [image] Make _cairo_image_analayze_transparency() more format agnostic Use the content in preference to the format to determine CAIRO_IMAGE_IS_OPAQUE/CAIRO_IMAGE_HAS_ALPHA. --- src/cairo-image-surface.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index baead108..3225a722 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -1576,15 +1576,13 @@ _cairo_image_analyze_transparency (cairo_image_surface_t *image) if (image->transparency != CAIRO_IMAGE_UNKNOWN) return image->transparency; - if (image->format == CAIRO_FORMAT_RGB24) { - image->transparency = CAIRO_IMAGE_IS_OPAQUE; - return CAIRO_IMAGE_IS_OPAQUE; - } + if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0) + return image->transparency = CAIRO_IMAGE_IS_OPAQUE; + if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) + return image->transparency = CAIRO_IMAGE_HAS_ALPHA; - if (image->format != CAIRO_FORMAT_ARGB32) { - image->transparency = CAIRO_IMAGE_HAS_ALPHA; - return CAIRO_IMAGE_HAS_ALPHA; - } + if (image->format != CAIRO_FORMAT_ARGB32) + return image->transparency = CAIRO_IMAGE_HAS_ALPHA; image->transparency = CAIRO_IMAGE_IS_OPAQUE; for (y = 0; y < image->height; y++) { @@ -1593,8 +1591,7 @@ _cairo_image_analyze_transparency (cairo_image_surface_t *image) for (x = 0; x < image->width; x++, pixel++) { int a = (*pixel & 0xff000000) >> 24; if (a > 0 && a < 255) { - image->transparency = CAIRO_IMAGE_HAS_ALPHA; - return CAIRO_IMAGE_HAS_ALPHA; + return image->transparency = CAIRO_IMAGE_HAS_ALPHA; } else if (a == 0) { image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; } -- cgit v1.2.3 From 1d609d672273da494fd596606b59ab1c0010ae6d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 May 2009 17:11:55 +0100 Subject: [image] Treat A1 image surfaces as BILEVEL_ALPHA Categorise the transparency of FORMAT_A1 image surfaces as BILEVEL_ALPHA. --- src/cairo-image-surface.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 3225a722..a027f728 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -1578,8 +1578,13 @@ _cairo_image_analyze_transparency (cairo_image_surface_t *image) if ((image->base.content & CAIRO_CONTENT_ALPHA) == 0) return image->transparency = CAIRO_IMAGE_IS_OPAQUE; - if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) - return image->transparency = CAIRO_IMAGE_HAS_ALPHA; + + if ((image->base.content & CAIRO_CONTENT_COLOR) == 0) { + if (image->format == CAIRO_FORMAT_A1) + return image->transparency = CAIRO_IMAGE_HAS_BILEVEL_ALPHA; + else + return image->transparency = CAIRO_IMAGE_HAS_ALPHA; + } if (image->format != CAIRO_FORMAT_ARGB32) return image->transparency = CAIRO_IMAGE_HAS_ALPHA; -- cgit v1.2.3 From c488b336449a1a7ca4d3f90785afeec9e21784c3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 May 2009 13:59:07 +0100 Subject: [test] Create a new fallback surface to exercise 16-bit paths. Add a variation of test-fallback-surface that forces the use of a 16-bit pixman format code instead of the standard 32-bit types. This creates an image surface akin to the fallbacks used with low bit-depth xservers. --- .../cairo-boilerplate-test-surfaces-private.h | 11 + boilerplate/cairo-boilerplate-test-surfaces.c | 16 ++ boilerplate/cairo-boilerplate.c | 18 ++ src/Makefile.sources | 2 + src/test-fallback16-surface.c | 234 +++++++++++++++++++++ src/test-fallback16-surface.h | 52 +++++ test/Makefile.am | 4 + test/Makefile.sources | 3 + test/test-fallback16-surface-source.c | 43 ++++ test/test-fallback16-surface-source.ref.png | Bin 0 -> 268 bytes 10 files changed, 383 insertions(+) create mode 100644 src/test-fallback16-surface.c create mode 100644 src/test-fallback16-surface.h create mode 100644 test/test-fallback16-surface-source.c create mode 100644 test/test-fallback16-surface-source.ref.png diff --git a/boilerplate/cairo-boilerplate-test-surfaces-private.h b/boilerplate/cairo-boilerplate-test-surfaces-private.h index 481b531e..24a1ae81 100644 --- a/boilerplate/cairo-boilerplate-test-surfaces-private.h +++ b/boilerplate/cairo-boilerplate-test-surfaces-private.h @@ -38,6 +38,17 @@ _cairo_boilerplate_test_fallback_create_surface (const char *name, int id, void **closure); +cairo_surface_t * +_cairo_boilerplate_test_fallback16_create_surface (const char *name, + cairo_content_t content, + int width, + int height, + int max_width, + int max_height, + cairo_boilerplate_mode_t mode, + int id, + void **closure); + cairo_surface_t * _cairo_boilerplate_test_meta_create_surface (const char *name, diff --git a/boilerplate/cairo-boilerplate-test-surfaces.c b/boilerplate/cairo-boilerplate-test-surfaces.c index f6fd63af..644b2787 100644 --- a/boilerplate/cairo-boilerplate-test-surfaces.c +++ b/boilerplate/cairo-boilerplate-test-surfaces.c @@ -28,6 +28,7 @@ #include "cairo-boilerplate-test-surfaces-private.h" #include +#include #include #include @@ -48,6 +49,21 @@ _cairo_boilerplate_test_fallback_create_surface (const char *name, return _cairo_test_fallback_surface_create (content, width, height); } +cairo_surface_t * +_cairo_boilerplate_test_fallback16_create_surface (const char *name, + cairo_content_t content, + int width, + int height, + int max_width, + int max_height, + cairo_boilerplate_mode_t mode, + int id, + void **closure) +{ + *closure = NULL; + return _cairo_test_fallback16_surface_create (content, width, height); +} + cairo_surface_t * _cairo_boilerplate_test_meta_create_surface (const char *name, cairo_content_t content, diff --git a/boilerplate/cairo-boilerplate.c b/boilerplate/cairo-boilerplate.c index fcc05b87..da2a6181 100644 --- a/boilerplate/cairo-boilerplate.c +++ b/boilerplate/cairo-boilerplate.c @@ -310,6 +310,24 @@ static cairo_boilerplate_target_t targets[] = _cairo_boilerplate_get_image_surface, cairo_surface_write_to_png }, + { + "test-fallback16", "image", NULL, + CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, + CAIRO_CONTENT_COLOR_ALPHA, 0, + _cairo_boilerplate_test_fallback16_create_surface, NULL, + NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png + }, + { + "test-fallback16", "image", NULL, + CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, + CAIRO_CONTENT_COLOR, 0, + _cairo_boilerplate_test_fallback16_create_surface, NULL, + NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png + }, { "test-meta", "image", NULL, CAIRO_INTERNAL_SURFACE_TYPE_TEST_META, diff --git a/src/Makefile.sources b/src/Makefile.sources index c1df770c..534feec9 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -190,11 +190,13 @@ cairo_ft_sources = cairo-ft-font.c # These are private, even though they look like public headers cairo_test_surfaces_private = \ test-fallback-surface.h \ + test-fallback16-surface.h \ test-meta-surface.h \ test-paginated-surface.h \ $(NULL) cairo_test_surfaces_sources = \ test-fallback-surface.c \ + test-fallback16-surface.c \ test-meta-surface.c \ test-paginated-surface.c \ $(NULL) diff --git a/src/test-fallback16-surface.c b/src/test-fallback16-surface.c new file mode 100644 index 00000000..7974c1f9 --- /dev/null +++ b/src/test-fallback16-surface.c @@ -0,0 +1,234 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc + * Copyright © 2009 Chris Wilson + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Carl Worth + * Chris Wilson + */ + +/* This isn't a "real" surface, but just something to be used by the + * test suite to force use of a non-standard pixman image fallback - as + * may be exposed by xlib fallbacks with weird xservers, for example. + */ + +#include "cairoint.h" + +#include "test-fallback16-surface.h" + +typedef struct _test_fallback16_surface { + cairo_surface_t base; + + /* This is a cairo_image_surface to hold the actual contents. */ + cairo_surface_t *backing; +} test_fallback16_surface_t; + +static const cairo_surface_backend_t test_fallback16_surface_backend; + +slim_hidden_proto (_cairo_test_fallback16_surface_create); + +cairo_surface_t * +_cairo_test_fallback16_surface_create (cairo_content_t content, + int width, + int height) +{ + test_fallback16_surface_t *surface; + cairo_surface_t *backing; + pixman_format_code_t format; + + format = content & CAIRO_CONTENT_ALPHA ? PIXMAN_a1r5g5b5: PIXMAN_r5g6b5; + + backing = _cairo_image_surface_create_with_pixman_format (NULL, format, + width, height, + -1); + if (cairo_surface_status (backing)) + return backing; + + surface = malloc (sizeof (test_fallback16_surface_t)); + if (unlikely (surface == NULL)) { + cairo_surface_destroy (backing); + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); + } + + _cairo_surface_init (&surface->base, + &test_fallback16_surface_backend, + content); + + surface->backing = backing; + + return &surface->base; +} +slim_hidden_def (_cairo_test_fallback16_surface_create); + +static cairo_surface_t * +_test_fallback16_surface_create_similar (void *abstract_surface, + cairo_content_t content, + int width, + int height) +{ + assert (CAIRO_CONTENT_VALID (content)); + + return _cairo_test_fallback16_surface_create (content, width, height); +} + +static cairo_status_t +_test_fallback16_surface_finish (void *abstract_surface) +{ + test_fallback16_surface_t *surface = abstract_surface; + + cairo_surface_destroy (surface->backing); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_test_fallback16_surface_acquire_source_image (void *abstract_surface, + cairo_image_surface_t **image_out, + void **image_extra) +{ + test_fallback16_surface_t *surface = abstract_surface; + + return _cairo_surface_acquire_source_image (surface->backing, + image_out, image_extra); +} + +static void +_test_fallback16_surface_release_source_image (void *abstract_surface, + cairo_image_surface_t *image, + void *image_extra) +{ + test_fallback16_surface_t *surface = abstract_surface; + + _cairo_surface_release_source_image (surface->backing, + image, image_extra); +} + +static cairo_status_t +_test_fallback16_surface_acquire_dest_image (void *abstract_surface, + cairo_rectangle_int_t *interest_rect, + cairo_image_surface_t **image_out, + cairo_rectangle_int_t *image_rect_out, + void **image_extra) +{ + test_fallback16_surface_t *surface = abstract_surface; + + return _cairo_surface_acquire_dest_image (surface->backing, + interest_rect, + image_out, + image_rect_out, + image_extra); +} + +static void +_test_fallback16_surface_release_dest_image (void *abstract_surface, + cairo_rectangle_int_t *interest_rect, + cairo_image_surface_t *image, + cairo_rectangle_int_t *image_rect, + void *image_extra) +{ + test_fallback16_surface_t *surface = abstract_surface; + + _cairo_surface_release_dest_image (surface->backing, + interest_rect, + image, + image_rect, + image_extra); +} + +static cairo_status_t +_test_fallback16_surface_clone_similar (void *abstract_surface, + cairo_surface_t *src, + int src_x, + int src_y, + int width, + int height, + int *clone_offset_x, + int *clone_offset_y, + cairo_surface_t **clone_out) +{ + test_fallback16_surface_t *surface = abstract_surface; + + if (src->backend == surface->base.backend) { + *clone_offset_x = 0; + *clone_offset_y = 0; + *clone_out = cairo_surface_reference (src); + + return CAIRO_STATUS_SUCCESS; + } else { + return _cairo_surface_clone_similar (surface->backing, src, + src_x, src_y, + width, height, + clone_offset_x, clone_offset_y, + clone_out); + } +} + +static cairo_int_status_t +_test_fallback16_surface_get_extents (void *abstract_surface, + cairo_rectangle_int_t *rectangle) +{ + test_fallback16_surface_t *surface = abstract_surface; + + return _cairo_surface_get_extents (surface->backing, rectangle); +} + +static const cairo_surface_backend_t test_fallback16_surface_backend = { + CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK, + _test_fallback16_surface_create_similar, + _test_fallback16_surface_finish, + _test_fallback16_surface_acquire_source_image, + _test_fallback16_surface_release_source_image, + _test_fallback16_surface_acquire_dest_image, + _test_fallback16_surface_release_dest_image, + _test_fallback16_surface_clone_similar, + NULL, /* composite */ + NULL, /* fill_rectangles */ + NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ + NULL, /* copy_page */ + NULL, /* show_page */ + NULL, /* set_clip_region */ + NULL, /* intersect_clip_path */ + _test_fallback16_surface_get_extents, + NULL, /* old_show_glyphs */ + NULL, /* get_font_options */ + NULL, /* flush */ + NULL, /* mark_dirty_rectangle */ + NULL, /* scaled_font_fini */ + NULL, /* scaled_glyph_fini */ + NULL, /* paint */ + NULL, /* mask */ + NULL, /* stroke */ + NULL, /* fill */ + NULL, /* show_glyphs */ + NULL /* snapshot */ +}; diff --git a/src/test-fallback16-surface.h b/src/test-fallback16-surface.h new file mode 100644 index 00000000..2c5b2ca7 --- /dev/null +++ b/src/test-fallback16-surface.h @@ -0,0 +1,52 @@ +/* cairo - a vector graphics library with display and print output + * + * Copyright © 2005 Red Hat, Inc + * Copyright © 2009 Chris Wilson + * + * This library is free software; you can redistribute it and/or + * modify it either under the terms of the GNU Lesser General Public + * License version 2.1 as published by the Free Software Foundation + * (the "LGPL") or, at your option, under the terms of the Mozilla + * Public License Version 1.1 (the "MPL"). If you do not alter this + * notice, a recipient may use your version of this file under either + * the MPL or the LGPL. + * + * You should have received a copy of the LGPL along with this library + * in the file COPYING-LGPL-2.1; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the MPL along with this library + * in the file COPYING-MPL-1.1 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY + * OF ANY KIND, either express or implied. See the LGPL or the MPL for + * the specific language governing rights and limitations. + * + * The Original Code is the cairo graphics library. + * + * The Initial Developer of the Original Code is Red Hat, Inc. + * + * Contributor(s): + * Carl Worth + * Chris Wilson + */ + +#ifndef TEST_FALLBACK16_SURFACE_H +#define TEST_FALLBACK16_SURFACE_H + +#include "cairo.h" + +CAIRO_BEGIN_DECLS + +cairo_surface_t * +_cairo_test_fallback16_surface_create (cairo_content_t content, + int width, + int height); + +CAIRO_END_DECLS + +#endif /* TEST_FALLBACK16_SURFACE_H */ diff --git a/test/Makefile.am b/test/Makefile.am index 2a1d93bc..efac53f7 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -37,6 +37,10 @@ if CAIRO_HAS_SVG_SURFACE test_sources += $(svg_surface_test_sources) endif +if CAIRO_HAS_TEST_SURFACES +test_sources += $(test_fallback16_surface_test_sources) +endif + if CAIRO_HAS_XLIB_SURFACE test_sources += $(xlib_surface_test_sources) endif diff --git a/test/Makefile.sources b/test/Makefile.sources index f8c19fd3..eeb9294e 100644 --- a/test/Makefile.sources +++ b/test/Makefile.sources @@ -229,6 +229,9 @@ svg_surface_test_sources = \ svg-clip.c \ svg-surface-source.c +test_fallback16_surface_test_sources = \ + test-fallback16-surface-source.c + xlib_surface_test_sources = \ xlib-expose-event.c \ xlib-surface.c \ diff --git a/test/test-fallback16-surface-source.c b/test/test-fallback16-surface-source.c new file mode 100644 index 00000000..7e9f920f --- /dev/null +++ b/test/test-fallback16-surface-source.c @@ -0,0 +1,43 @@ +/* + * Copyright © 2009 Chris Wilson + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of + * Chris Wilson not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. Chris Wilson makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Chris Wilson + */ + +#include "cairo-test.h" +#include + +#include "surface-source.c" + +static cairo_surface_t * +create_source_surface (int size) +{ + return _cairo_test_fallback16_surface_create (CAIRO_CONTENT_COLOR_ALPHA, + size, size); +} + +CAIRO_TEST (test_fallback16_surface_source, + "Test using a 16-bit image (e.g. a low bit-depth XServer) surface as the source", + "source", /* keywords */ + NULL, /* requirements */ + SIZE, SIZE, + preamble, draw) diff --git a/test/test-fallback16-surface-source.ref.png b/test/test-fallback16-surface-source.ref.png new file mode 100644 index 00000000..3fa8bbe5 Binary files /dev/null and b/test/test-fallback16-surface-source.ref.png differ -- cgit v1.2.3 From 31f5a2e94d669b9d2785de944d4aee584fd1d76e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 May 2009 15:52:55 +0100 Subject: [png] Coerce FORMAT_INVALID to a known image format It is possible for cairo_surface_write_to_png() to acquire a non-standard image surface when, for example, we try to dump a low bit-depth XServer. Handle this scenario by coercing the unknown image format to a standard type via pixman. --- src/cairo-png.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/cairo-png.c b/src/cairo-png.c index 0e8f63d8..c6643286 100644 --- a/src/cairo-png.c +++ b/src/cairo-png.c @@ -143,6 +143,7 @@ write_png (cairo_surface_t *surface, int i; cairo_status_t status; cairo_image_surface_t *image; + cairo_image_surface_t * volatile clone; void *image_extra; png_struct *png; png_info *info; @@ -166,40 +167,52 @@ write_png (cairo_surface_t *surface, goto BAIL1; } - rows = _cairo_malloc_ab (image->height, sizeof (png_byte*)); + /* Handle the various fallback formats (e.g. low bit-depth XServers) + * by coercing them to a simpler format using pixman. + */ + if (image->format == CAIRO_FORMAT_INVALID) { + clone = _cairo_image_surface_coerce (image, + _cairo_format_from_content (image->base.content)); + status = clone->base.status; + if (unlikely (status)) + goto BAIL1; + } else + clone = image; + + rows = _cairo_malloc_ab (clone->height, sizeof (png_byte*)); if (unlikely (rows == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL1; + goto BAIL2; } - for (i = 0; i < image->height; i++) - rows[i] = (png_byte *) image->data + i * image->stride; + for (i = 0; i < clone->height; i++) + rows[i] = (png_byte *) clone->data + i * clone->stride; png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status, png_simple_error_callback, png_simple_warning_callback); if (unlikely (png == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL2; + goto BAIL3; } info = png_create_info_struct (png); if (unlikely (info == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto BAIL3; + goto BAIL4; } #ifdef PNG_SETJMP_SUPPORTED if (setjmp (png_jmpbuf (png))) - goto BAIL3; + goto BAIL4; #endif png_set_write_fn (png, closure, write_func, png_simple_output_flush_fn); - switch (image->format) { + switch (clone->format) { case CAIRO_FORMAT_ARGB32: depth = 8; - if (_cairo_image_analyze_transparency (image) == CAIRO_IMAGE_IS_OPAQUE) + if (_cairo_image_analyze_transparency (clone) == CAIRO_IMAGE_IS_OPAQUE) png_color_type = PNG_COLOR_TYPE_RGB; else png_color_type = PNG_COLOR_TYPE_RGB_ALPHA; @@ -221,12 +234,12 @@ write_png (cairo_surface_t *surface, break; default: status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT); - goto BAIL3; + goto BAIL4; } png_set_IHDR (png, info, - image->width, - image->height, depth, + clone->width, + clone->height, depth, png_color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, @@ -259,10 +272,13 @@ write_png (cairo_surface_t *surface, png_write_image (png, rows); png_write_end (png, info); -BAIL3: +BAIL4: png_destroy_write_struct (&png, &info); -BAIL2: +BAIL3: free (rows); +BAIL2: + if (clone != image) + cairo_surface_destroy (&clone->base); BAIL1: _cairo_surface_release_source_image (surface, image, image_extra); -- cgit v1.2.3 From 60e38d0530443aa9c78e74e47ba5574887ae220c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 May 2009 17:05:39 +0100 Subject: [surface] Convert FORMAT_INVALID during snapshots Currently the surface snapshotting attempts to clone the source using a new surface of identical format. This will raise an error if the source is an unusual xserver, for example one operating at 16bpp. The solution to this is to create the surface using the content type rather than the format (as elsewhere within the code base). However, we also wish to preserve FORMAT_A1 (which is lost if we only choose the format based on _cairo_format_from_content) as the various backends may be able to trivially special case such bitmaps. --- src/cairo-surface-fallback.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index a78c6ad7..90191023 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -1115,6 +1115,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) { cairo_surface_t *snapshot; cairo_status_t status; + cairo_format_t format; cairo_surface_pattern_t pattern; cairo_image_surface_t *image; void *image_extra; @@ -1124,7 +1125,14 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) if (unlikely (status)) return _cairo_surface_create_in_error (status); - snapshot = cairo_image_surface_create (image->format, + format = image->format; + if (format == CAIRO_FORMAT_INVALID) { + /* Non-standard images formats can be generated when retrieving + * images from unusual xservers, for example. + */ + format = _cairo_format_from_content (image->base.content); + } + snapshot = cairo_image_surface_create (format, image->width, image->height); if (cairo_surface_status (snapshot)) { -- cgit v1.2.3 From 30735f790aa3cef822f132932f43a4738cd8cd95 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 5 May 2009 18:37:25 +0100 Subject: [xlib] Use a similar content surface for cloning images Simply request a surface with a similar content to the source image when uploading pixel data. Failing to do so prevents using a 16-bit (or otherwise non-standard pixman image format) window as a source - in fact it will trigger an infinite recursion. --- src/cairo-xlib-surface.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index d1e7391c..b56b340f 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -950,7 +950,8 @@ _draw_image_surface (cairo_xlib_surface_t *surface, ximage.blue_mask = surface->b_mask; ximage.xoffset = 0; - if (image_masks.red_mask == surface->r_mask && + if (image_masks.alpha_mask == surface->a_mask && + image_masks.red_mask == surface->r_mask && image_masks.green_mask == surface->g_mask && image_masks.blue_mask == surface->b_mask) { @@ -1016,8 +1017,8 @@ _draw_image_surface (cairo_xlib_surface_t *surface, goto BAIL; } - rowstride = cairo_image_surface_get_stride (&image->base) >> 2; - row = (uint32_t *) cairo_image_surface_get_data (&image->base); + rowstride = image->stride >> 2; + row = (uint32_t *) image->data; x0 = dst_x + surface->base.device_transform.x0; y0 = dst_y + surface->base.device_transform.y0; for (y = 0, y_off = y0 % ARRAY_LENGTH (dither_pattern); @@ -1194,16 +1195,17 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, } } else if (_cairo_surface_is_image (src)) { cairo_image_surface_t *image_src = (cairo_image_surface_t *)src; - - if (! CAIRO_FORMAT_VALID (image_src->format)) - return CAIRO_INT_STATUS_UNSUPPORTED; + cairo_format_t format; if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) return _cairo_error (CAIRO_STATUS_INVALID_SIZE); + format = image_src->format; + if (format == CAIRO_FORMAT_INVALID) + format = _cairo_format_from_content (image_src->base.content); clone = (cairo_xlib_surface_t *) _cairo_xlib_surface_create_similar_with_format (surface, - image_src->format, + format, width, height); if (clone == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; -- cgit v1.2.3 From f9573d03dde2c38674d36b783044715ab5104b0a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 17 Mar 2009 19:48:12 -0400 Subject: Err, make gtk-doc happy again --- doc/public/tmpl/cairo-status.sgml | 2 +- src/cairo.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/public/tmpl/cairo-status.sgml b/doc/public/tmpl/cairo-status.sgml index b74856f7..e8ad9699 100644 --- a/doc/public/tmpl/cairo-status.sgml +++ b/doc/public/tmpl/cairo-status.sgml @@ -71,7 +71,7 @@ code is required before or after each individual cairo function call. @CAIRO_STATUS_INVALID_SLANT: @CAIRO_STATUS_INVALID_WEIGHT: @CAIRO_STATUS_INVALID_SIZE: -@_CAIRO_STATUS_LAST_STATUS: +@CAIRO_STATUS_LAST_STATUS: diff --git a/src/cairo.h b/src/cairo.h index 1347187f..58f1cd0e 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -208,7 +208,6 @@ typedef struct _cairo_user_data_key { /** * cairo_status_t: * @CAIRO_STATUS_SUCCESS: no error has occurred - * * @CAIRO_STATUS_NO_MEMORY: out of memory * @CAIRO_STATUS_INVALID_RESTORE: cairo_restore() called without matching cairo_save() * @CAIRO_STATUS_INVALID_POP_GROUP: no saved group to pop @@ -241,7 +240,6 @@ typedef struct _cairo_user_data_key { * @CAIRO_STATUS_INVALID_SLANT: invalid value for an input #cairo_font_slant_t (Since 1.8) * @CAIRO_STATUS_INVALID_WEIGHT: invalid value for an input #cairo_font_weight_t (Since 1.8) * @CAIRO_STATUS_INVALID_SIZE: invalid value (typically too big) for a size (Since 1.10) - * * @CAIRO_STATUS_LAST_STATUS: this is a special value indicating the number of * status values defined in this enumeration. When using this value, note * that the version of cairo at run-time may have additional status values -- cgit v1.2.3 From 428fb58a4c96391f96f48026be49a4533cd12834 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 28 Apr 2009 15:03:53 -0400 Subject: [user-font] Add CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED This is useful for language bindings to signal that a method is not implemented. --- src/cairo-misc.c | 2 ++ src/cairo-surface.c | 1 + src/cairo-user-font.c | 14 +++++++++++--- src/cairo.h | 23 ++++++++++++++--------- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/cairo-misc.c b/src/cairo-misc.c index d4b10e1c..20f0ef1b 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -123,6 +123,8 @@ cairo_status_to_string (cairo_status_t status) return "invalid value for an input #cairo_font_weight_t"; case CAIRO_STATUS_INVALID_SIZE: return "invalid value for the size of the input (surface, pattern, etc.)"; + case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: + return "user-font method not implemented"; default: case CAIRO_STATUS_LAST_STATUS: return ""; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index a4a70846..42b101ac 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2975,6 +2975,7 @@ _cairo_surface_create_in_error (cairo_status_t status) case CAIRO_STATUS_INVALID_SLANT: case CAIRO_STATUS_INVALID_WEIGHT: case CAIRO_STATUS_INVALID_SIZE: + case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: default: _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_surface_t *) &_cairo_surface_nil; diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c index fe475ab4..6b4f0d43 100644 --- a/src/cairo-user-font.c +++ b/src/cairo-user-font.c @@ -118,7 +118,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font, _cairo_scaled_glyph_index(scaled_glyph), cr, &extents); else - status = CAIRO_STATUS_USER_FONT_ERROR; + status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED; if (status == CAIRO_STATUS_SUCCESS) status = cairo_status (cr); @@ -260,12 +260,16 @@ _cairo_user_ucs4_to_index (void *abstract_font, status = face->scaled_font_methods.unicode_to_glyph (&scaled_font->base, ucs4, &glyph); + if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED) + goto not_implemented; + if (status != CAIRO_STATUS_SUCCESS) { status = _cairo_scaled_font_set_error (&scaled_font->base, status); glyph = 0; } } else { +not_implemented: glyph = ucs4; } @@ -300,10 +304,11 @@ _cairo_user_text_to_glyphs (void *abstract_font, glyphs, num_glyphs, clusters, num_clusters, cluster_flags); - if (status != CAIRO_STATUS_SUCCESS) + if (status != CAIRO_STATUS_SUCCESS && + status != CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED) return status; - if (*num_glyphs < 0) { + if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED || *num_glyphs < 0) { if (orig_glyphs != *glyphs) { cairo_glyph_free (*glyphs); *glyphs = orig_glyphs; @@ -434,6 +439,9 @@ _cairo_user_font_face_scaled_font_create (void *abstract_ cr, &font_extents); + if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED) + status = CAIRO_STATUS_SUCCESS; + if (status == CAIRO_STATUS_SUCCESS) status = cairo_status (cr); diff --git a/src/cairo.h b/src/cairo.h index 58f1cd0e..a92c26c4 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -240,6 +240,7 @@ typedef struct _cairo_user_data_key { * @CAIRO_STATUS_INVALID_SLANT: invalid value for an input #cairo_font_slant_t (Since 1.8) * @CAIRO_STATUS_INVALID_WEIGHT: invalid value for an input #cairo_font_weight_t (Since 1.8) * @CAIRO_STATUS_INVALID_SIZE: invalid value (typically too big) for a size (Since 1.10) + * @CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: user-font method not implemented (Since 1.10) * @CAIRO_STATUS_LAST_STATUS: this is a special value indicating the number of * status values defined in this enumeration. When using this value, note * that the version of cairo at run-time may have additional status values @@ -288,6 +289,7 @@ typedef enum _cairo_status { CAIRO_STATUS_INVALID_SLANT, CAIRO_STATUS_INVALID_WEIGHT, CAIRO_STATUS_INVALID_SIZE, + CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, CAIRO_STATUS_LAST_STATUS } cairo_status_t; @@ -1453,8 +1455,7 @@ cairo_user_font_face_create (void); * point and trying to use it for text operations in the callback will result * in deadlock. * - * Returns: %CAIRO_STATUS_SUCCESS upon success, or - * %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. + * Returns: %CAIRO_STATUS_SUCCESS upon success, or an error status on error. * * Since: 1.8 **/ @@ -1555,7 +1556,8 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal * will free the allocated cluster array using cairo_text_cluster_free(). * * The callback is optional. If @num_glyphs is negative upon - * the callback returning, the unicode_to_glyph callback + * the callback returning or if the return value + * isCAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, the unicode_to_glyph callback * is tried. See #cairo_user_scaled_font_unicode_to_glyph_func_t. * * Note: While cairo does not impose any limitation on glyph indices, @@ -1566,8 +1568,9 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal * are advised to use glyph 0 for such purposes and do not use that * glyph value for other purposes. * - * Returns: %CAIRO_STATUS_SUCCESS upon success, or - * %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. + * Returns: %CAIRO_STATUS_SUCCESS upon success, + * CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED if fallback options should be tried, + * or %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. * * Since: 1.8 **/ @@ -1600,8 +1603,9 @@ typedef cairo_status_t (*cairo_user_scaled_font_text_to_glyphs_func_t) (cairo_sc * complex scripts can be implemented using this callback. * * The callback is optional, and only used if text_to_glyphs callback is not - * set or fails to return glyphs. If this callback is not set, an identity - * mapping from Unicode code-points to glyph indices is assumed. + * set or fails to return glyphs. If this callback is not set or if it returns + * CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, an identity mapping from Unicode + * code-points to glyph indices is assumed. * * Note: While cairo does not impose any limitation on glyph indices, * some applications may assume that a glyph index fits in a 16-bit @@ -1611,8 +1615,9 @@ typedef cairo_status_t (*cairo_user_scaled_font_text_to_glyphs_func_t) (cairo_sc * are advised to use glyph 0 for such purposes and do not use that * glyph value for other purposes. * - * Returns: %CAIRO_STATUS_SUCCESS upon success, or - * %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. + * Returns: %CAIRO_STATUS_SUCCESS upon success, + * CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED if fallback options should be tried, + * or %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. * * Since: 1.8 **/ -- cgit v1.2.3 From fd72c56af833a738ddc8f188cabe03d9f8b45475 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 11:27:43 +0100 Subject: [build] Report status of gtk-doc in summary --- build/configure.ac.features | 1 + 1 file changed, 1 insertion(+) diff --git a/build/configure.ac.features b/build/configure.ac.features index 2d5fb8a5..8ccee7bb 100644 --- a/build/configure.ac.features +++ b/build/configure.ac.features @@ -387,6 +387,7 @@ AC_DEFUN([CAIRO_REPORT], echo " PNG functions: $use_png" echo "" echo "And the following internal features:" + echo " gtk-doc: $enable_gtk_doc" echo " gcov support: $use_gcov" echo " test surfaces: $use_test_surfaces" echo " ps testing: $test_ps" -- cgit v1.2.3 From 84fad4b11bc26cfd0847660e3309eb902d783713 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 11:31:22 +0100 Subject: [build] Fix gtk-doc interoperation with shave Add --tag=CC to the libtool invocations. --- build/Makefile.am.gtk-doc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/Makefile.am.gtk-doc b/build/Makefile.am.gtk-doc index cb815991..50cd6279 100644 --- a/build/Makefile.am.gtk-doc +++ b/build/Makefile.am.gtk-doc @@ -10,8 +10,8 @@ #################################### if GTK_DOC_USE_LIBTOOL -GTKDOC_CC = $(LIBTOOL) --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -GTKDOC_LD = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) +GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) else GTKDOC_CC = $(CC) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) GTKDOC_LD = $(CC) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -- cgit v1.2.3 From 849bdee199b5ebba467603a69d30bb519c10bc75 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 11:36:38 +0100 Subject: [check] Quieten output during checking headers-standalone Remove the duplication of the compile line and enable shave to replace it entirely with a "CHECK $header". This should make errors more obvious. --- build/shave.in | 3 +++ src/Makefile.am.analysis | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/build/shave.in b/build/shave.in index 5c16f27a..cedccd47 100644 --- a/build/shave.in +++ b/build/shave.in @@ -69,6 +69,9 @@ lt_unmangle "$lt_output" output=$last_result if test -z $V; then + if test $output = "/dev/null"; then + pass_through=1 + fi if test $pass_through -eq 0; then echo "$Q$output" fi diff --git a/src/Makefile.am.analysis b/src/Makefile.am.analysis index 4d527bf1..ea9caec4 100644 --- a/src/Makefile.am.analysis +++ b/src/Makefile.am.analysis @@ -23,7 +23,7 @@ uno: headers-standalone: $(enabled_cairo_headers) $(enabled_cairo_private) @echo Checking that enabled public/private headers can be compiled standalone @status=true; for f in $(enabled_cairo_headers) $(enabled_cairo_private); do \ - echo $(COMPILE) -o /dev/null $(srcdir)/$$f; \ + echo " CHECK $$f"; \ $(COMPILE) -o /dev/null $(srcdir)/$$f || status=false; \ done; $$status @touch $@ -- cgit v1.2.3 From 695f648607dd5a78cf29dcc33ed19aa223d0416a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 11:16:10 +0100 Subject: [cairo] Fix errors reported by check-doc Identity a few new instances of CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED in comments with %. --- src/cairo.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cairo.h b/src/cairo.h index a92c26c4..b9c47db9 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -1557,7 +1557,7 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal * * The callback is optional. If @num_glyphs is negative upon * the callback returning or if the return value - * isCAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, the unicode_to_glyph callback + * is %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, the unicode_to_glyph callback * is tried. See #cairo_user_scaled_font_unicode_to_glyph_func_t. * * Note: While cairo does not impose any limitation on glyph indices, @@ -1569,7 +1569,7 @@ typedef cairo_status_t (*cairo_user_scaled_font_render_glyph_func_t) (cairo_scal * glyph value for other purposes. * * Returns: %CAIRO_STATUS_SUCCESS upon success, - * CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED if fallback options should be tried, + * %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED if fallback options should be tried, * or %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. * * Since: 1.8 @@ -1604,7 +1604,7 @@ typedef cairo_status_t (*cairo_user_scaled_font_text_to_glyphs_func_t) (cairo_sc * * The callback is optional, and only used if text_to_glyphs callback is not * set or fails to return glyphs. If this callback is not set or if it returns - * CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, an identity mapping from Unicode + * %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, an identity mapping from Unicode * code-points to glyph indices is assumed. * * Note: While cairo does not impose any limitation on glyph indices, @@ -1616,7 +1616,7 @@ typedef cairo_status_t (*cairo_user_scaled_font_text_to_glyphs_func_t) (cairo_sc * glyph value for other purposes. * * Returns: %CAIRO_STATUS_SUCCESS upon success, - * CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED if fallback options should be tried, + * %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED if fallback options should be tried, * or %CAIRO_STATUS_USER_FONT_ERROR or any other error status on error. * * Since: 1.8 -- cgit v1.2.3 From d86ad461cf7a9d857bd07a6b775c84acbf35647b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 14:16:05 +0100 Subject: [cairo] Convert C99 comments to /* ... */ First victim of -pedantic... --- src/cairoint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairoint.h b/src/cairoint.h index 29e7ccf9..b06126db 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -85,7 +85,7 @@ CAIRO_BEGIN_DECLS -#if _WIN32 && !_WIN32_WCE // we don't have to worry about permissions on WinCE +#if _WIN32 && !_WIN32_WCE /* Permissions on WinCE? No worries! */ cairo_private FILE * _cairo_win32_tmpfile (void); #define tmpfile() _cairo_win32_tmpfile() -- cgit v1.2.3 From 5f4f2ab01ab3fa6b07ac7521dfeaf90a787a5dee Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 14:34:47 +0100 Subject: [cairo] Remove stray semi-colon Pedantic finds another victim. --- src/cairoint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairoint.h b/src/cairoint.h index b06126db..0aa9ebf1 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -151,7 +151,7 @@ do { \ assert (NOT_REACHED); \ } while (0) #define COMPILE_TIME_ASSERT1(condition, line) \ - typedef int compile_time_assertion_at_line_##line##_failed [(condition)?1:-1]; + typedef int compile_time_assertion_at_line_##line##_failed [(condition)?1:-1] #define COMPILE_TIME_ASSERT0(condition, line) COMPILE_TIME_ASSERT1(condition, line) #define COMPILE_TIME_ASSERT(condition) COMPILE_TIME_ASSERT0(condition, __LINE__) -- cgit v1.2.3 From e5752865ab0ebefec313ab9a6f90451ef2d7af95 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 14:58:45 +0100 Subject: [cairo] Protect typeof against -ansi s/typeof/__typeof__/ to allow the [gcc-specific] macro to continue to work despite -ansi. --- src/cairoint.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairoint.h b/src/cairoint.h index 0aa9ebf1..29b8ea68 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -127,7 +127,7 @@ _cairo_win32_tmpfile (void); #ifdef __GNUC__ #define cairo_container_of(ptr, type, member) ({ \ - const typeof(((type *) 0)->member) *mptr__ = (ptr); \ + const __typeof__ (((type *) 0)->member) *mptr__ = (ptr); \ (type *) ((char *) mptr__ - offsetof (type, member)); \ }) #else -- cgit v1.2.3 From 3d3d10a31e04498ef91a288d89b3dec291bfc323 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 14:10:47 +0100 Subject: [skiplist] Missing include for ffs() --- src/cairo-skiplist.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c index 5c2c477e..776e7e78 100644 --- a/src/cairo-skiplist.c +++ b/src/cairo-skiplist.c @@ -25,6 +25,8 @@ #include "cairo-skiplist-private.h" +#include /* ffs() */ + #define ELT_DATA(elt) (void *) ((char*) (elt) - list->data_size) #define NEXT_TO_ELT(next) (skip_elt_t *) ((char *) (next) - offsetof (skip_elt_t, next)) -- cgit v1.2.3 From 0c00556990a842e0ee0056134c6e196c2fb372b7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 14:11:12 +0100 Subject: [script] Missing include for INT32_MAX Avoid depending upon stdint.h, or rather cut'n'pasting Cairo's portable defines, by using INT_MAX and limits.h instead. --- util/cairo-script/cairo-script-file.c | 3 ++- util/cairo-script/cairo-script-objects.c | 3 ++- util/cairo-script/cairo-script-operators.c | 13 +++++++------ util/cairo-script/cairo-script-scanner.c | 5 +++-- util/cairo-script/cairo-script-stack.c | 7 ++++--- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/util/cairo-script/cairo-script-file.c b/util/cairo-script/cairo-script-file.c index fcdccf14..9a3ff70a 100644 --- a/util/cairo-script/cairo-script-file.c +++ b/util/cairo-script/cairo-script-file.c @@ -35,6 +35,7 @@ #include "cairo-script-private.h" #include +#include /* INT_MAX */ #include #define CHUNK_SIZE 32768 @@ -996,7 +997,7 @@ _csi_file_as_string (csi_t *ctx, char *newbytes; int newlen; - if (_csi_unlikely (allocated > INT32_MAX / 2)) + if (_csi_unlikely (allocated > INT_MAX / 2)) return _csi_error (CAIRO_STATUS_NO_MEMORY); newlen = allocated * 2; diff --git a/util/cairo-script/cairo-script-objects.c b/util/cairo-script/cairo-script-objects.c index 552241f3..2e81df4d 100644 --- a/util/cairo-script/cairo-script-objects.c +++ b/util/cairo-script/cairo-script-objects.c @@ -34,6 +34,7 @@ #include "cairo-script-private.h" +#include /* INT_MAX */ #include csi_status_t @@ -523,7 +524,7 @@ csi_string_new (csi_t *ctx, if (len < 0) len = strlen (str); - if (_csi_unlikely (len >= INT32_MAX)) + if (_csi_unlikely (len >= INT_MAX)) return _csi_error (CSI_STATUS_NO_MEMORY); if (ctx->free_string == NULL || ctx->free_string->len <= len) { diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c index d2bdb4c8..a39fbef2 100644 --- a/util/cairo-script/cairo-script-operators.c +++ b/util/cairo-script/cairo-script-operators.c @@ -39,6 +39,7 @@ #include /* snprintf */ #include #include +#include /* INT_MAX */ #include typedef struct _csi_proxy { @@ -2136,7 +2137,7 @@ _glyph_path (csi_t *ctx) } if (nglyphs > ARRAY_LENGTH (stack_glyphs)) { - if (_csi_unlikely ((unsigned) nglyphs >= INT32_MAX / sizeof (cairo_glyph_t))) + if (_csi_unlikely ((unsigned) nglyphs >= INT_MAX / sizeof (cairo_glyph_t))) return _csi_error (CSI_STATUS_NO_MEMORY); glyphs = _csi_alloc (ctx, sizeof (cairo_glyph_t) * nglyphs); if (_csi_unlikely (glyphs == NULL)) @@ -3898,7 +3899,7 @@ _set_dash (csi_t *ctx) if (_csi_likely (array->stack.len < ARRAY_LENGTH (stack_dashes))) { dashes = stack_dashes; } else { - if (_csi_unlikely ((unsigned) array->stack.len >= INT32_MAX / sizeof (double))) + if (_csi_unlikely ((unsigned) array->stack.len >= INT_MAX / sizeof (double))) return _csi_error (CSI_STATUS_NO_MEMORY); dashes = _csi_alloc (ctx, sizeof (double) * array->stack.len); if (_csi_unlikely (dashes == NULL)) @@ -4734,7 +4735,7 @@ _show_glyphs (csi_t *ctx) } if (nglyphs > ARRAY_LENGTH (stack_glyphs)) { - if (_csi_unlikely ((unsigned) nglyphs >= INT32_MAX / sizeof (cairo_glyph_t))) + if (_csi_unlikely ((unsigned) nglyphs >= INT_MAX / sizeof (cairo_glyph_t))) return _csi_error (CSI_STATUS_NO_MEMORY); glyphs = _csi_alloc (ctx, sizeof (cairo_glyph_t) * nglyphs); if (_csi_unlikely (glyphs == NULL)) @@ -4880,7 +4881,7 @@ _show_text_glyphs (csi_t *ctx) array = obj->datum.array; nclusters = array->stack.len / 2; if (nclusters > ARRAY_LENGTH (stack_clusters)) { - if (_csi_unlikely ((unsigned) nclusters >= INT32_MAX / sizeof (cairo_text_cluster_t))) + if (_csi_unlikely ((unsigned) nclusters >= INT_MAX / sizeof (cairo_text_cluster_t))) return _csi_error (CSI_STATUS_NO_MEMORY); clusters = _csi_alloc (ctx, sizeof (cairo_text_cluster_t) * nclusters); if (_csi_unlikely (clusters == NULL)) @@ -4898,7 +4899,7 @@ _show_text_glyphs (csi_t *ctx) string = obj->datum.string; nclusters = string->len / 2; if (nclusters > ARRAY_LENGTH (stack_clusters)) { - if (_csi_unlikely ((unsigned) nclusters >= INT32_MAX / sizeof (cairo_text_cluster_t))) + if (_csi_unlikely ((unsigned) nclusters >= INT_MAX / sizeof (cairo_text_cluster_t))) return _csi_error (CSI_STATUS_NO_MEMORY); clusters = _csi_alloc (ctx, sizeof (cairo_text_cluster_t) * nclusters); if (_csi_unlikely (clusters == NULL)) @@ -4943,7 +4944,7 @@ _show_text_glyphs (csi_t *ctx) return CSI_STATUS_SUCCESS; if (nglyphs > ARRAY_LENGTH (stack_glyphs)) { - if (_csi_unlikely ((unsigned) nglyphs >= INT32_MAX / sizeof (cairo_glyph_t))) + if (_csi_unlikely ((unsigned) nglyphs >= INT_MAX / sizeof (cairo_glyph_t))) return _csi_error (CSI_STATUS_NO_MEMORY); glyphs = _csi_alloc (ctx, sizeof (cairo_glyph_t) * nglyphs); if (_csi_unlikely (glyphs == NULL)) { diff --git a/util/cairo-script/cairo-script-scanner.c b/util/cairo-script/cairo-script-scanner.c index c08e447d..22d1721e 100644 --- a/util/cairo-script/cairo-script-scanner.c +++ b/util/cairo-script/cairo-script-scanner.c @@ -34,9 +34,10 @@ #include "cairo-script-private.h" +#include /* INT_MAX */ +#include /* pow */ #include /* EOF */ #include /* memset */ -#include /* pow */ /* * whitespace: @@ -88,7 +89,7 @@ _csi_buffer_grow (csi_t *ctx, csi_buffer_t *buffer) if (_csi_unlikely (buffer->status)) return buffer->status; - if (_csi_unlikely (buffer->size > INT32_MAX / 2)) + if (_csi_unlikely (buffer->size > INT_MAX / 2)) return buffer->status = _csi_error (CSI_STATUS_NO_MEMORY); offset = buffer->ptr - buffer->base; diff --git a/util/cairo-script/cairo-script-stack.c b/util/cairo-script/cairo-script-stack.c index d6c123b4..59d2c6a0 100644 --- a/util/cairo-script/cairo-script-stack.c +++ b/util/cairo-script/cairo-script-stack.c @@ -34,6 +34,7 @@ #include "cairo-script-private.h" +#include /* INT_MAX */ #include csi_status_t @@ -43,7 +44,7 @@ _csi_stack_init (csi_t *ctx, csi_stack_t *stack, csi_integer_t size) stack->len = 0; stack->size = size; - /* assert ((unsigned) size < INT32_MAX / sizeof (csi_object_t)); */ + /* assert ((unsigned) size < INT_MAX / sizeof (csi_object_t)); */ stack->objects = _csi_alloc (ctx, size * sizeof (csi_object_t)); if (_csi_unlikely (stack->objects == NULL)) status = _csi_error (CSI_STATUS_NO_MEMORY); @@ -90,7 +91,7 @@ _csi_stack_roll (csi_t *ctx, /* fall back to a copy */ if (n > ARRAY_LENGTH (stack_copy)) { - if (_csi_unlikely ((unsigned) n > INT32_MAX / sizeof (csi_object_t))) + if (_csi_unlikely ((unsigned) n > INT_MAX / sizeof (csi_object_t))) return _csi_error (CSI_STATUS_NO_MEMORY); copy = _csi_alloc (ctx, n * sizeof (csi_object_t)); if (copy == NULL) @@ -124,7 +125,7 @@ _csi_stack_grow (csi_t *ctx, csi_stack_t *stack, csi_integer_t cnt) if (_csi_likely (cnt <= stack->size)) return CSI_STATUS_SUCCESS; - if (_csi_unlikely ((unsigned) cnt >= INT32_MAX / sizeof (csi_object_t))) + if (_csi_unlikely ((unsigned) cnt >= INT_MAX / sizeof (csi_object_t))) return _csi_error (CSI_STATUS_NO_MEMORY); newsize = stack->size; -- cgit v1.2.3 From e38f85c5de51016b8858e755e2752816c9995ab2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 14:42:15 +0100 Subject: [script] Pedantic violations Fixup a few trivial errors with -pedantic. --- util/cairo-script/cairo-script-operators.c | 2 +- util/cairo-script/cairo-script-private.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c index a39fbef2..0ed3dd3f 100644 --- a/util/cairo-script/cairo-script-operators.c +++ b/util/cairo-script/cairo-script-operators.c @@ -5416,7 +5416,7 @@ _debug_print (csi_t *ctx) fprintf (stderr, "name: %s\n", (char *) obj->datum.name); break; case CSI_OBJECT_TYPE_OPERATOR: - fprintf (stderr, "operator: %p\n", obj->datum.op); + fprintf (stderr, "operator: %p\n", obj->datum.ptr); break; case CSI_OBJECT_TYPE_REAL: fprintf (stderr, "real: %g\n", obj->datum.real); diff --git a/util/cairo-script/cairo-script-private.h b/util/cairo-script/cairo-script-private.h index f74cb49f..d2ebc0c8 100644 --- a/util/cairo-script/cairo-script-private.h +++ b/util/cairo-script/cairo-script-private.h @@ -247,7 +247,7 @@ typedef enum { CSI_OBJECT_TYPE_FONT, CSI_OBJECT_TYPE_PATTERN, CSI_OBJECT_TYPE_SCALED_FONT, - CSI_OBJECT_TYPE_SURFACE, + CSI_OBJECT_TYPE_SURFACE } csi_object_type_t; #define CSI_OBJECT_IS_ATOM(OBJ) (((OBJ)->type & CSI_OBJECT_TYPE_MASK) < 0x08) @@ -256,7 +256,7 @@ typedef enum { enum { /* attributes */ CSI_OBJECT_ATTR_EXECUTABLE = 1 << 6, - CSI_OBJECT_ATTR_WRITABLE = 1 << 7, + CSI_OBJECT_ATTR_WRITABLE = 1 << 7 }; #define CSI_OBJECT_ATTR_MASK (CSI_OBJECT_ATTR_EXECUTABLE | \ CSI_OBJECT_ATTR_WRITABLE) @@ -400,7 +400,7 @@ struct _csi_file { STDIO, BYTES, PROCEDURE, - FILTER, + FILTER } type; void *src; void *data; @@ -429,7 +429,7 @@ struct _csi_scanner { COMMENT, STRING, HEX, - BASE85, + BASE85 } state; csi_buffer_t buffer; -- cgit v1.2.3 From d8fb6a03d3034cf776687bcc1f0625a8a9f2ae07 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 14:57:13 +0100 Subject: [path] Define _BSD_SOURCE to enable hypot() hypot() is only declared for BSD/SVID/XOPEN/C99 sources. Choose BSD as we've used that elsewhere. --- src/cairo-path-stroke.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 37ac79c7..79bf09b0 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -35,6 +35,7 @@ * Carl D. Worth */ +#define _BSD_SOURCE /* for hypot() */ #include "cairoint.h" #include "cairo-path-fixed-private.h" -- cgit v1.2.3 From 088d2a6cc70b01f55d178d235542247180b3e5ee Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 7 May 2009 11:35:17 +0100 Subject: [doc] Update identifiers --- doc/public/tmpl/cairo-status.sgml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/public/tmpl/cairo-status.sgml b/doc/public/tmpl/cairo-status.sgml index e8ad9699..aed8aa64 100644 --- a/doc/public/tmpl/cairo-status.sgml +++ b/doc/public/tmpl/cairo-status.sgml @@ -71,7 +71,8 @@ code is required before or after each individual cairo function call. @CAIRO_STATUS_INVALID_SLANT: @CAIRO_STATUS_INVALID_WEIGHT: @CAIRO_STATUS_INVALID_SIZE: -@CAIRO_STATUS_LAST_STATUS: +@CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: +@CAIRO_STATUS_LAST_STATUS: -- cgit v1.2.3 From a352fd46020e18f9d9f839f0c3f3a63c1d8c0ae1 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Fri, 15 May 2009 15:34:05 -0400 Subject: Only include for ffs() when we HAVE_FFS This fixes breakage caused by 3d3d10a31e04498ef91a288d89b3dec291bfc323 --- src/cairo-skiplist.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c index 776e7e78..18d69ca6 100644 --- a/src/cairo-skiplist.c +++ b/src/cairo-skiplist.c @@ -25,7 +25,9 @@ #include "cairo-skiplist-private.h" +#if HAVE_FFS #include /* ffs() */ +#endif #define ELT_DATA(elt) (void *) ((char*) (elt) - list->data_size) #define NEXT_TO_ELT(next) (skip_elt_t *) ((char *) (next) - offsetof (skip_elt_t, next)) -- cgit v1.2.3 From d6f6ec9082c86b9fd9e2389b9627f08a91c2cdd3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 May 2009 16:43:43 +0100 Subject: [ft] Restore the ability to lazily resolve patterns. I broke the ability for the ft font backend to resolve patterns whilst fixing the font creation to propagate the error status from fontconfig (be27e8). By adjusting the sequence of error checks we do not confuse the absence of a match with a fatal error and thereby restoring the lazy pattern resolution whilst ensuring error propagation. --- src/cairo-ft-font.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index e701c213..1e2a18ee 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -482,24 +482,26 @@ _cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern, FcResult ret; ret = FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face); - switch ((int) ret) { - case FcResultMatch: + if (ret == FcResultMatch) + goto DONE; + if (ret == FcResultOutOfMemory) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + ret = FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &filename); + if (ret == FcResultOutOfMemory) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + if (ret == FcResultMatch) { + /* If FC_INDEX is not set, we just use 0 */ + ret = FcPatternGetInteger (pattern, FC_INDEX, 0, &id); + if (ret == FcResultOutOfMemory) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto DONE; - case FcResultOutOfMemory: - break; - default: - if (FcPatternGetString (pattern, FC_FILE, 0, - (FcChar8 **) &filename) == FcResultMatch) - { - /* If FC_INDEX is not set, we just use 0 */ - if (FcPatternGetInteger (pattern, - FC_INDEX, 0, &id) != FcResultOutOfMemory) - goto DONE; - } - break; } - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + /* The pattern contains neither a face nor a filename, resolve it later. */ + *out = NULL; + return CAIRO_STATUS_SUCCESS; DONE: return _cairo_ft_unscaled_font_create_internal (font_face != NULL, -- cgit v1.2.3 From 0238fe2cafea2e1ed19bb222117bd73ee6898d4d Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Thu, 14 May 2009 11:46:29 +0100 Subject: [ft] Resolve mutual referencing problems with zombie faces Bug 21706 -- zombie ft_font_face / ft_unscaled_font mutual referencing problems [http://bugs.freedesktop.org/show_bug.cgi?id=21706] There can be more than one zombie font_face belonging to an unscaled_font, but only the first is destroyed. This leaks the client's FT_Face (and associated font data) as release of the FT_Face depends on release of the font_face. (The reason why Firefox ends up with two different font_faces for one unscaled_font is that load_flags for faces with artificial oblique have FT_LOAD_NO_BITMAP set. https://bugzilla.mozilla.org/show_bug.cgi?id=486974) Also it's possible for _cairo_ft_font_face_create to pull out a zombie font_face from the unscaled_font, which would crash _cairo_ft_font_face_scaled_font_create, as that expects non-null font_face->unscaled (if !font-face->pattern). --- AUTHORS | 2 +- src/cairo-ft-font.c | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/AUTHORS b/AUTHORS index 289fecba..8c061743 100644 --- a/AUTHORS +++ b/AUTHORS @@ -86,7 +86,7 @@ Travis Spencer XCB backend fix Bill Spitzak Build fix to find Xrender.h without xrender.pc Zhe Su Add support for fontconfig's embeddedbitmap option Owen Taylor Font rewrite, documentation, win32 backend -Karl Tomlinson +Karl Tomlinson Optimisation and obscure bug fixes (mozilla) Alp Toker Fix several code/comment typos Malcolm Tredinnick Documentation fixes David Turner Optimize gradient calculations diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 1e2a18ee..f9ff0b10 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -543,8 +543,10 @@ _cairo_ft_unscaled_font_destroy (void *abstract_font) /* See comments in _ft_font_face_destroy about the "zombie" state * for a _ft_font_face. */ - if (unscaled->faces && !unscaled->faces->unscaled) + if (unscaled->faces && unscaled->faces->unscaled == NULL) { + assert (unscaled->faces->next == NULL); cairo_font_face_destroy (&unscaled->faces->base); + } } else { _font_map_release_face_lock_held (font_map, unscaled); } @@ -2233,9 +2235,10 @@ _cairo_ft_font_face_destroy (void *abstract_face) if (font_face == NULL) return; - /* When destroying the face created by cairo_ft_font_face_create_for_ft_face, + /* When destroying a face created by cairo_ft_font_face_create_for_ft_face, * we have a special "zombie" state for the face when the unscaled font - * is still alive but there are no public references to the font face. + * is still alive but there are no other references to a font face with + * the same FT_Face. * * We go from: * @@ -2249,6 +2252,8 @@ _cairo_ft_font_face_destroy (void *abstract_face) if (font_face->unscaled && font_face->unscaled->from_face && + font_face->next == NULL && + font_face->unscaled->faces == font_face && CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->unscaled->base.ref_count) > 1) { cairo_font_face_reference (&font_face->base); @@ -2394,12 +2399,21 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, font_face->ft_options.extra_flags == ft_options->extra_flags && cairo_font_options_equal (&font_face->ft_options.base, &ft_options->base)) { - if (font_face->base.status == CAIRO_STATUS_SUCCESS) - return cairo_font_face_reference (&font_face->base); + if (font_face->base.status) { + /* The font_face has been left in an error state, abandon it. */ + *prev_font_face = font_face->next; + break; + } - /* The font_face has been left in an error state, abandon it. */ - *prev_font_face = font_face->next; - break; + if (font_face->unscaled == NULL) { + /* Resurrect this "zombie" font_face (from + * _cairo_ft_font_face_destroy), switching its unscaled_font + * from owner to ownee. */ + font_face->unscaled = unscaled; + _cairo_unscaled_font_reference (&unscaled->base); + return &font_face->base; + } else + return cairo_font_face_reference (&font_face->base); } } @@ -2415,6 +2429,14 @@ _cairo_ft_font_face_create (cairo_ft_unscaled_font_t *unscaled, font_face->ft_options = *ft_options; + if (unscaled->faces && unscaled->faces->unscaled == NULL) { + /* This "zombie" font_face (from _cairo_ft_font_face_destroy) + * is no longer needed. */ + assert (unscaled->from_face && unscaled->faces->next == NULL); + cairo_font_face_destroy (&unscaled->faces->base); + unscaled->faces = NULL; + } + font_face->next = unscaled->faces; unscaled->faces = font_face; -- cgit v1.2.3 From c25992479aca481d326f72665ebdcf0904273eac Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 May 2009 10:10:14 +0100 Subject: [xlib] Use minimal depth for similar clones. Damian Frank noted [http://lists.cairographics.org/archives/cairo/2009-May/017095.html] a performance problem with an older XServer with an unaccelerated composite - similar problems will be seen with non-XRender servers which will trigger extraneous fallbacks. The problem he found was that painting an ARGB32 image onto an RGB24 destination window (using SOURCE) was going via the RENDER protocol and not core. He was able to demonstrate that this could be worked around by declaring the pixel data as an RGB24 image. The issue is that the image is uploaded into a temporary pixmap of matching depth (i.e. 32 bit for ARGB32 and 24 bit for RGB23 data), however the core protocol can only blit between Drawables of matching depth - so without the work-around the Drawables are mismatched and we either need to use RENDER or fallback. This patch adds a content mask to _cairo_surface_clone_similar() to provide the extra bit of information to the backends for when it is possible for them to drop channels from the clone. This is used by the xlib backend to only create a 24 bit source when blitting to a Window. --- src/cairo-clip.c | 1 + src/cairo-directfb-surface.c | 2 ++ src/cairo-glitz-surface.c | 3 +++ src/cairo-image-surface.c | 4 ++++ src/cairo-pattern.c | 18 +++++++++++++--- src/cairo-quartz-surface.c | 1 + src/cairo-surface-fallback-private.h | 1 + src/cairo-surface-fallback.c | 3 ++- src/cairo-surface.c | 7 +++++- src/cairo-win32-surface.c | 3 ++- src/cairo-xcb-surface.c | 5 +++++ src/cairo-xlib-surface.c | 42 +++++++++++++++++++++++++++--------- src/cairoint.h | 4 ++++ src/test-fallback-surface.c | 1 + src/test-fallback16-surface.c | 2 ++ test/surface-source.c | 1 + 16 files changed, 82 insertions(+), 16 deletions(-) diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 7066b932..bb04a9e2 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -772,6 +772,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, if (other->surface) { int dx, dy; status = _cairo_surface_clone_similar (target, other->surface, + CAIRO_CONTENT_ALPHA, 0, 0, other->surface_rect.width, diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c index 3eee33cc..df9c0e98 100644 --- a/src/cairo-directfb-surface.c +++ b/src/cairo-directfb-surface.c @@ -617,6 +617,7 @@ _cairo_directfb_surface_release_dest_image (void *abstract_surf static cairo_status_t _cairo_directfb_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -763,6 +764,7 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst, } status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, *src_x, *src_y, width, height, (cairo_surface_t **) &src, &src_attr); diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 284198b2..9ee8a88b 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -352,6 +352,7 @@ _cairo_glitz_surface_release_dest_image (void *abstract_surfa static cairo_status_t _cairo_glitz_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -716,6 +717,7 @@ _cairo_glitz_pattern_acquire_surface (const cairo_pattern_t *pattern, cairo_int_status_t status; status = _cairo_pattern_acquire_surface (pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, x, y, width, height, (cairo_surface_t **) &src, &attr->base); @@ -2133,6 +2135,7 @@ _cairo_glitz_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font, status = _cairo_glitz_surface_clone_similar (abstract_surface, image, + CAIRO_CONTENT_COLOR_ALPHA, 0, 0, glyph_width, diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index a027f728..cf233934 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -784,6 +784,7 @@ _cairo_image_surface_release_dest_image (void *abstract_surfa static cairo_status_t _cairo_image_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -962,6 +963,7 @@ _cairo_image_surface_composite (cairo_operator_t op, status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, src_x, src_y, mask_x, mask_y, width, height, @@ -1164,6 +1166,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, } status = _cairo_pattern_acquire_surface (pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, src_x, src_y, width, height, (cairo_surface_t **) &src, &attributes); @@ -1398,6 +1401,7 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op, status = _cairo_pattern_acquire_surface ( renderer->pattern, &renderer->dst->base, + CAIRO_CONTENT_COLOR_ALPHA, rects->src.x, rects->src.y, width, height, (cairo_surface_t **) &renderer->src, diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 0fb36bfa..67447a5e 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -1256,6 +1256,7 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat pixman_transform_t pixman_transform; cairo_status_t status; cairo_bool_t repeat = FALSE; + cairo_bool_t opaque = TRUE; pixman_gradient_stop_t pixman_stops_static[2]; pixman_gradient_stop_t *pixman_stops = pixman_stops_static; @@ -1279,6 +1280,8 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat pixman_stops[i].color.green = pattern->stops[i].color.green_short; pixman_stops[i].color.blue = pattern->stops[i].color.blue_short; pixman_stops[i].color.alpha = pattern->stops[i].color.alpha_short; + if (! CAIRO_ALPHA_SHORT_IS_OPAQUE (pixman_stops[i].color.alpha)) + opaque = FALSE; } if (pattern->base.type == CAIRO_PATTERN_TYPE_LINEAR) @@ -1450,6 +1453,9 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat pixman_image_unref (pixman_image); status = _cairo_surface_clone_similar (dst, &image->base, + opaque ? + CAIRO_CONTENT_COLOR : + CAIRO_CONTENT_COLOR_ALPHA, 0, 0, width, height, &clone_offset_x, &clone_offset_y, @@ -1781,6 +1787,7 @@ _pixman_nearest_sample (double d) static cairo_int_status_t _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pattern, cairo_surface_t *dst, + cairo_content_t content, int x, int y, unsigned int width, @@ -1855,7 +1862,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat if (unlikely (status)) goto BAIL; - status = _cairo_surface_clone_similar (dst, surface, + status = _cairo_surface_clone_similar (dst, surface, content, extents.x, extents.y, extents.width, extents.height, &extents.x, &extents.y, &src); @@ -1978,7 +1985,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat /* XXX can we use is_empty? */ - status = _cairo_surface_clone_similar (dst, surface, + status = _cairo_surface_clone_similar (dst, surface, content, extents.x, extents.y, extents.width, extents.height, &x, &y, out); @@ -2052,6 +2059,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat cairo_int_status_t _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern, cairo_surface_t *dst, + cairo_content_t content, int x, int y, unsigned int width, @@ -2144,6 +2152,7 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern, cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) pattern; status = _cairo_pattern_acquire_surface_for_surface (src, dst, + content, x, y, width, height, surface_out, attributes); @@ -2176,6 +2185,7 @@ cairo_int_status_t _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, const cairo_pattern_t *mask, cairo_surface_t *dst, + cairo_content_t src_content, int src_x, int src_y, int mask_x, @@ -2212,13 +2222,14 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, _cairo_color_multiply_alpha (&combined, mask_solid->color.alpha); _cairo_pattern_init_solid (&src_tmp.solid, &combined, - src_solid->content | mask_solid->content); + (src_solid->content | mask_solid->content) & src_content); src = &src_tmp.base; mask = NULL; } status = _cairo_pattern_acquire_surface (src, dst, + src_content, src_x, src_y, width, height, src_out, src_attributes); @@ -2231,6 +2242,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, } status = _cairo_pattern_acquire_surface (mask, dst, + CAIRO_CONTENT_ALPHA, mask_x, mask_y, width, height, mask_out, mask_attributes); diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index c827f97a..982ede42 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -1598,6 +1598,7 @@ _cairo_quartz_surface_create_similar (void *abstract_surface, static cairo_status_t _cairo_quartz_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, diff --git a/src/cairo-surface-fallback-private.h b/src/cairo-surface-fallback-private.h index 61e5b903..cd181780 100644 --- a/src/cairo-surface-fallback-private.h +++ b/src/cairo-surface-fallback-private.h @@ -121,6 +121,7 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, cairo_private cairo_status_t _cairo_surface_fallback_clone_similar (cairo_surface_t *surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 90191023..469e9b3e 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -1336,6 +1336,7 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, cairo_status_t _cairo_surface_fallback_clone_similar (cairo_surface_t *surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -1349,7 +1350,7 @@ _cairo_surface_fallback_clone_similar (cairo_surface_t *surface, cairo_status_t status; new_surface = _cairo_surface_create_similar_scratch (surface, - src->content, + src->content & content, width, height); if (new_surface->status) return new_surface->status; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 42b101ac..26a7a13f 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1268,6 +1268,7 @@ _cairo_surface_release_dest_image (cairo_surface_t *surface, * _cairo_surface_clone_similar: * @surface: a #cairo_surface_t * @src: the source image + * @content: target content mask * @src_x: extent for the rectangle in src we actually care about * @src_y: extent for the rectangle in src we actually care about * @width: extent for the rectangle in src we actually care about @@ -1287,6 +1288,7 @@ _cairo_surface_release_dest_image (cairo_surface_t *surface, cairo_status_t _cairo_surface_clone_similar (cairo_surface_t *surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -1307,6 +1309,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, if (surface->backend->clone_similar) { status = surface->backend->clone_similar (surface, src, + content, src_x, src_y, width, height, clone_offset_x, @@ -1319,7 +1322,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, cairo_surface_t *similar; similar = cairo_surface_create_similar (surface, - src->content, + src->content & content, width, height); status = similar->status; if (unlikely (status)) @@ -1344,6 +1347,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, if (status == CAIRO_STATUS_SUCCESS) { status = surface->backend->clone_similar (surface, &image->base, + content, src_x, src_y, width, height, clone_offset_x, @@ -1359,6 +1363,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, if (status == CAIRO_INT_STATUS_UNSUPPORTED) status = _cairo_surface_fallback_clone_similar (surface, src, + content, src_x, src_y, width, height, clone_offset_x, diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index 649a96b5..389515be 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -431,6 +431,7 @@ _cairo_win32_surface_create_similar (void *abstract_src, cairo_status_t _cairo_win32_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -444,7 +445,7 @@ _cairo_win32_surface_clone_similar (void *abstract_surface, cairo_status_t status; cairo_surface_pattern_t pattern; - src_content = cairo_surface_get_content(src); + src_content = src->content & content; new_surface = _cairo_win32_surface_create_similar_internal (abstract_surface, src_content, diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index 8d0090b0..c21e6000 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -671,6 +671,7 @@ _cairo_xcb_surface_same_screen (cairo_xcb_surface_t *dst, static cairo_status_t _cairo_xcb_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -1119,6 +1120,7 @@ _cairo_xcb_surface_composite (cairo_operator_t op, status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, src_x, src_y, mask_x, mask_y, width, height, @@ -1407,6 +1409,7 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op, return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_pattern_acquire_surface (pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, src_x, src_y, width, height, (cairo_surface_t **) &src, &attributes); @@ -2499,6 +2502,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) { status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, 0, 0, 1, 1, (cairo_surface_t **) &src, &attributes); @@ -2513,6 +2517,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst, goto BAIL; status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, glyph_extents.x, glyph_extents.y, glyph_extents.width, glyph_extents.height, (cairo_surface_t **) &src, diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index b56b340f..bbbdc4bd 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -950,10 +950,10 @@ _draw_image_surface (cairo_xlib_surface_t *surface, ximage.blue_mask = surface->b_mask; ximage.xoffset = 0; - if (image_masks.alpha_mask == surface->a_mask && - image_masks.red_mask == surface->r_mask && - image_masks.green_mask == surface->g_mask && - image_masks.blue_mask == surface->b_mask) + if ((image_masks.alpha_mask == surface->a_mask || surface->a_mask == 0) && + (image_masks.red_mask == surface->r_mask || surface->r_mask == 0) && + (image_masks.green_mask == surface->g_mask || surface->g_mask == 0) && + (image_masks.blue_mask == surface->b_mask || surface->b_mask == 0)) { int ret; @@ -1169,6 +1169,7 @@ _cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst, static cairo_status_t _cairo_xlib_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -1201,8 +1202,11 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, return _cairo_error (CAIRO_STATUS_INVALID_SIZE); format = image_src->format; - if (format == CAIRO_FORMAT_INVALID) - format = _cairo_format_from_content (image_src->base.content); + if (format == CAIRO_FORMAT_INVALID || + (_cairo_content_from_format (format) & ~content)) + { + format = _cairo_format_from_content (image_src->base.content & content); + } clone = (cairo_xlib_surface_t *) _cairo_xlib_surface_create_similar_with_format (surface, format, @@ -1508,14 +1512,15 @@ _surface_has_alpha (cairo_xlib_surface_t *surface) */ static cairo_bool_t _operator_needs_alpha_composite (cairo_operator_t op, - cairo_bool_t surface_has_alpha) + cairo_bool_t destination_has_alpha, + cairo_bool_t source_has_alpha) { if (op == CAIRO_OPERATOR_SOURCE || - (!surface_has_alpha && + (! source_has_alpha && (op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ATOP || op == CAIRO_OPERATOR_IN))) - return FALSE; + return destination_has_alpha; return TRUE; } @@ -1624,7 +1629,9 @@ _recategorize_composite_operation (cairo_xlib_surface_t *dst, return DO_UNSUPPORTED; needs_alpha_composite = - _operator_needs_alpha_composite (op, _surface_has_alpha (src)); + _operator_needs_alpha_composite (op, + _surface_has_alpha (dst), + _surface_has_alpha (src)); if (! have_mask && is_integer_translation && @@ -1721,6 +1728,8 @@ _cairo_xlib_surface_composite (cairo_operator_t op, composite_operation_t operation; int itx, ity; cairo_bool_t is_integer_translation; + cairo_bool_t needs_alpha_composite; + cairo_content_t src_content; _cairo_xlib_display_notify (dst->display); @@ -1729,8 +1738,17 @@ _cairo_xlib_surface_composite (cairo_operator_t op, if (operation == DO_UNSUPPORTED) return CAIRO_INT_STATUS_UNSUPPORTED; + needs_alpha_composite = + _operator_needs_alpha_composite (op, + _surface_has_alpha (dst), + ! _cairo_pattern_is_opaque (src_pattern)); + src_content = CAIRO_CONTENT_COLOR_ALPHA; + if (! needs_alpha_composite) + src_content &= ~CAIRO_CONTENT_ALPHA; + status = _cairo_pattern_acquire_surfaces (src_pattern, mask_pattern, &dst->base, + src_content, src_x, src_y, mask_x, mask_y, width, height, @@ -1892,6 +1910,7 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface, return status; status = _cairo_pattern_acquire_surface (&solid.base, &surface->base, + CAIRO_CONTENT_COLOR_ALPHA, 0, 0, ARRAY_LENGTH (dither_pattern[0]), ARRAY_LENGTH (dither_pattern), @@ -2142,6 +2161,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_pattern_acquire_surface (pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, src_x, src_y, width, height, (cairo_surface_t **) &src, &attributes); @@ -4071,6 +4091,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) { status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, 0, 0, 1, 1, (cairo_surface_t **) &src, &attributes); @@ -4087,6 +4108,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, goto BAIL0; status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, + CAIRO_CONTENT_COLOR_ALPHA, glyph_extents.x, glyph_extents.y, glyph_extents.width, glyph_extents.height, (cairo_surface_t **) &src, diff --git a/src/cairoint.h b/src/cairoint.h index 29b8ea68..fc51d60a 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -591,6 +591,7 @@ struct _cairo_surface_backend { cairo_warn cairo_status_t (*clone_similar) (void *surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -1963,6 +1964,7 @@ _cairo_surface_release_dest_image (cairo_surface_t *surface, cairo_private cairo_status_t _cairo_surface_clone_similar (cairo_surface_t *surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -2482,6 +2484,7 @@ _cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern); cairo_private cairo_int_status_t _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern, cairo_surface_t *dst, + cairo_content_t content, int x, int y, unsigned int width, @@ -2498,6 +2501,7 @@ cairo_private cairo_int_status_t _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, const cairo_pattern_t *mask, cairo_surface_t *dst, + cairo_content_t src_content, int src_x, int src_y, int mask_x, diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c index 8acd91ee..2a7f1489 100644 --- a/src/test-fallback-surface.c +++ b/src/test-fallback-surface.c @@ -172,6 +172,7 @@ _test_fallback_surface_release_dest_image (void *abstract_surface, static cairo_status_t _test_fallback_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, diff --git a/src/test-fallback16-surface.c b/src/test-fallback16-surface.c index 7974c1f9..07c06105 100644 --- a/src/test-fallback16-surface.c +++ b/src/test-fallback16-surface.c @@ -166,6 +166,7 @@ _test_fallback16_surface_release_dest_image (void *abstract_surface, static cairo_status_t _test_fallback16_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, @@ -184,6 +185,7 @@ _test_fallback16_surface_clone_similar (void *abstract_surface, return CAIRO_STATUS_SUCCESS; } else { return _cairo_surface_clone_similar (surface->backing, src, + content, src_x, src_y, width, height, clone_offset_x, clone_offset_y, diff --git a/test/surface-source.c b/test/surface-source.c index 09069246..5d978f23 100644 --- a/test/surface-source.c +++ b/test/surface-source.c @@ -102,6 +102,7 @@ draw (cairo_t *cr, int width, int height) (height - INTER_SIZE)/2); cairo_destroy (cr2); cairo_rectangle (cr, 15, 15, 60, 60); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_fill (cr); /* destroy the surface last, as this triggers XCloseDisplay */ -- cgit v1.2.3 From 2f962799a77faef0e6ad62c79bd7eebc9b8c5a4b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 15 May 2009 18:49:03 +0100 Subject: [test] Fix typos that excluded backend test sources --- test/Makefile.am | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Makefile.am b/test/Makefile.am index efac53f7..ef2d875b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -13,16 +13,16 @@ test_sources += $(pthread_test_sources) endif if CAIRO_HAS_FT_FONT -test_sources += $(ft_font_sources) +test_sources += $(ft_font_test_sources) endif # Need to add quartz-surface-source if CAIRO_HAS_QUARTZ_SURFACE -test_sources += $(quartz_surface_sources) +test_sources += $(quartz_surface_test_sources) endif if CAIRO_HAS_GLITZ_SURFACE -test_sources += $(glitz_surface_sources) +test_sources += $(glitz_surface_test_sources) endif if CAIRO_HAS_PDF_SURFACE -- cgit v1.2.3 From fe7410c6cdc19bb366bf1e93481bf8287a14d52e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 May 2009 19:01:06 +0100 Subject: [test] Add a note to "Getting the elusive zero failures" The test suite depends upon many external factors and in order to achieve a pass, your system must match that upon which the reference images were generated. Add a note to read test/README in case of failures so that the casual user is not unduly alarmed by cairo reportedly failing. --- test/cairo-test-runner.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/cairo-test-runner.c b/test/cairo-test-runner.c index 0f437c4c..3652a9b5 100644 --- a/test/cairo-test-runner.c +++ b/test/cairo-test-runner.c @@ -64,6 +64,7 @@ typedef struct _cairo_test_runner { unsigned int num_device_offsets; + cairo_bool_t passed; int num_passed; int num_xpassed; int num_skipped; @@ -339,6 +340,8 @@ _runner_init (cairo_test_runner_t *runner) { cairo_test_init (&runner->base, "cairo-test-suite"); + runner->passed = TRUE; + runner->xpasses_per_target = xcalloc (sizeof (cairo_test_list_t *), runner->base.num_targets); runner->fails_per_target = xcalloc (sizeof (cairo_test_list_t *), @@ -449,6 +452,13 @@ _runner_print_results (cairo_test_runner_t *runner) { _runner_print_summary (runner); _runner_print_details (runner); + + if (! runner->passed) { + _log (&runner->base, +"\n" +"Note: These failures may be due to external factors.\n" +"Please read test/README -- \"Getting the elusive zero failures\".\n"); + } } static cairo_test_status_t @@ -856,6 +866,7 @@ main (int argc, char **argv) targets[len-2] = '\0'; _log (&runner.base, "\n%s: CRASH! (%s)\n", name, targets); runner.num_crashed++; + runner.passed = FALSE; } else if (failed) { if (expectation == CAIRO_TEST_SUCCESS) { len = 0; @@ -878,6 +889,7 @@ main (int argc, char **argv) targets[len-2] = '\0'; _log (&runner.base, "%s: FAIL (%s)\n", name, targets); runner.num_failed++; + runner.passed = FALSE; } } else { _log (&runner.base, "%s: XFAIL\n", name); -- cgit v1.2.3 From 669e7ae5c98812360bf20b798c20024ae2e9810b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 8 May 2009 17:36:01 +0100 Subject: [test] Relax APPROX_EQUALS condition The bounding box of the text is rounded to the nearest pixel boundaries, so therefore the test must accept a similar level of imprecision. --- test/get-path-extents.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/get-path-extents.c b/test/get-path-extents.c index 96fdfccd..337dad2d 100644 --- a/test/get-path-extents.c +++ b/test/get-path-extents.c @@ -74,10 +74,10 @@ check_extents (const cairo_test_context_t *ctx, break; case APPROX_EQUALS: relation_string = "approx. equal"; - if (floor (ext_x1 + 0.5) == floor (x + 0.5) && - floor (ext_y1 + 0.5) == floor (y + 0.5) && - floor (ext_x2 + 0.5) == floor (x + width + 0.5) && - floor (ext_y2 + 0.5) == floor (y + height + 0.5)) + if (fabs (ext_x1 - x) < 1. && + fabs (ext_y1 - y) < 1. && + fabs (ext_x2 - (x + width)) < 1. && + fabs (ext_y2 - (y + height)) < 1.) { return 1; } -- cgit v1.2.3 From f47a93ef30249b531e588335045d052c3dcc71bd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 May 2009 09:55:49 +0100 Subject: [test] Check text->path with user-fonts (twin) Check behaviour of user-fonts, twin in particular, when using the text as a path. --- test/twin.c | 11 ++++++++++- test/twin.ps.ref.png | Bin 1114 -> 2197 bytes test/twin.ref.png | Bin 1492 -> 4038 bytes test/twin.svg.ref.png | Bin 1487 -> 3027 bytes 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/test/twin.c b/test/twin.c index b71d97eb..08865f07 100644 --- a/test/twin.c +++ b/test/twin.c @@ -41,6 +41,15 @@ draw (cairo_t *cr, int width, int height) cairo_move_to (cr, 4, 14); cairo_show_text (cr, "Is cairo's twin giza?"); + cairo_move_to (cr, 4, 34); + cairo_text_path (cr, "Is cairo's twin giza?"); + cairo_fill (cr); + + cairo_move_to (cr, 4, 54); + cairo_text_path (cr, "Is cairo's twin giza?"); + cairo_set_line_width (cr, 2/16.); + cairo_stroke (cr); + return CAIRO_TEST_SUCCESS; } @@ -48,5 +57,5 @@ CAIRO_TEST (twin, "Tests the internal font", "twin, font", /* keywords */ NULL, /* requirements */ - 140, 20, + 140, 60, NULL, draw) diff --git a/test/twin.ps.ref.png b/test/twin.ps.ref.png index f9374e33..e75062ca 100644 Binary files a/test/twin.ps.ref.png and b/test/twin.ps.ref.png differ diff --git a/test/twin.ref.png b/test/twin.ref.png index 8bf098c1..3c46b02a 100644 Binary files a/test/twin.ref.png and b/test/twin.ref.png differ diff --git a/test/twin.svg.ref.png b/test/twin.svg.ref.png index 8b4617f0..b5d4a314 100644 Binary files a/test/twin.svg.ref.png and b/test/twin.svg.ref.png differ -- cgit v1.2.3 From 477df1f5504a507d0c5960aa7e21375284a6f99c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 15 May 2009 10:48:56 +0100 Subject: [test] Clear expected floating point exceptions test/invalid-matrix deliberately feeds garbage into the API to test our error detection. This causes FPE to be raised during the course of the test - so they are deliberately disable for the duration. However, the exceptions were not being cleared and so the FPE could be triggered on the next floating point operation. This was being masked during make check, by the fact that each test is run in its own forked process and was only observed when multiple tests were run in foreground mode. --- build/configure.ac.system | 2 +- test/invalid-matrix.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build/configure.ac.system b/build/configure.ac.system index d71d2d0c..2ee0cc42 100644 --- a/build/configure.ac.system +++ b/build/configure.ac.system @@ -65,7 +65,7 @@ AC_CHECK_HEADERS([sched.h], dnl check for GNU-extensions to fenv AC_CHECK_HEADER(fenv.h, - [AC_CHECK_FUNCS(feenableexcept fedisableexcept)]) + [AC_CHECK_FUNCS(feenableexcept fedisableexcept feclearexcept)]) dnl check for misc headers and functions AC_CHECK_HEADERS([libgen.h byteswap.h signal.h setjmp.h]) diff --git a/test/invalid-matrix.c b/test/invalid-matrix.c index 933e81c9..4fbda614 100644 --- a/test/invalid-matrix.c +++ b/test/invalid-matrix.c @@ -363,6 +363,10 @@ if ((status) == CAIRO_STATUS_SUCCESS) { \ CHECK_STATUS (status, "cairo_rotate(∞)"); cairo_destroy (cr2); +#if HAVE_FECLEAREXCEPT + feclearexcept (FE_INVALID); +#endif + return CAIRO_TEST_SUCCESS; } -- cgit v1.2.3 From c897f36a6b09f3591d858142e3236f256f0bd6a2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 15 May 2009 20:37:52 +0100 Subject: [test] Stress the ft from-face cache Create a set of font faces using the same FT_Face to stress test the handling of from-face fonts within the backend cache. --- test/ft-font-create-for-ft-face.c | 109 +++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 7 deletions(-) diff --git a/test/ft-font-create-for-ft-face.c b/test/ft-font-create-for-ft-face.c index 702b846a..52c838dd 100644 --- a/test/ft-font-create-for-ft-face.c +++ b/test/ft-font-create-for-ft-face.c @@ -26,6 +26,84 @@ #include "cairo-test.h" #include +static void +_stress_font_cache (FT_Face ft_face, cairo_t *cr, int lvl); + +static cairo_font_face_t * +_load_font (FT_Face ft_face, int flags, cairo_t *cr, int lvl) +{ + cairo_font_face_t *font_face; + cairo_font_extents_t font_extents; + + _stress_font_cache (ft_face, cr, lvl+1); + + font_face = cairo_ft_font_face_create_for_ft_face (ft_face, flags); + + cairo_set_font_face (cr, font_face); + cairo_font_extents (cr, &font_extents); + + _stress_font_cache (ft_face, cr, lvl+1); + + return font_face; +} + +static void +_stress_font_cache (FT_Face ft_face, cairo_t *cr, int lvl) +{ +#define A _load_font (ft_face, 0, cr, lvl) +#define B _load_font (ft_face, FT_LOAD_NO_BITMAP, cr, lvl) +#define C _load_font (ft_face, FT_LOAD_NO_RECURSE, cr, lvl) +#define D _load_font (ft_face, FT_LOAD_FORCE_AUTOHINT, cr, lvl) + + cairo_font_face_t *font_face[4]; + + while (lvl++ < 5) { + font_face[0] = A; font_face[1] = A; + font_face[2] = A; font_face[3] = A; + cairo_font_face_destroy (font_face[0]); + cairo_font_face_destroy (font_face[1]); + cairo_font_face_destroy (font_face[2]); + cairo_font_face_destroy (font_face[3]); + + font_face[0] = A; font_face[1] = B; + font_face[2] = C; font_face[3] = D; + cairo_font_face_destroy (font_face[0]); + cairo_font_face_destroy (font_face[1]); + cairo_font_face_destroy (font_face[2]); + cairo_font_face_destroy (font_face[3]); + + font_face[0] = A; font_face[1] = B; + font_face[2] = C; font_face[3] = D; + cairo_font_face_destroy (font_face[3]); + cairo_font_face_destroy (font_face[2]); + cairo_font_face_destroy (font_face[1]); + cairo_font_face_destroy (font_face[0]); + + font_face[0] = A; + font_face[1] = A; + cairo_font_face_destroy (font_face[0]); + font_face[2] = A; + cairo_font_face_destroy (font_face[1]); + font_face[3] = A; + cairo_font_face_destroy (font_face[2]); + cairo_font_face_destroy (font_face[3]); + + font_face[0] = A; + font_face[1] = B; + cairo_font_face_destroy (font_face[0]); + font_face[2] = C; + cairo_font_face_destroy (font_face[1]); + font_face[3] = D; + cairo_font_face_destroy (font_face[2]); + cairo_font_face_destroy (font_face[3]); + } + +#undef A +#undef B +#undef C +#undef D +} + static cairo_test_status_t draw (cairo_t *cr, int width, int height) { @@ -48,23 +126,31 @@ draw (cairo_t *cr, int width, int height) pattern = FcPatternCreate (); if (! pattern) { cairo_test_log (ctx, "FcPatternCreate failed.\n"); - return CAIRO_TEST_FAILURE; + return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY); } FcConfigSubstitute (NULL, pattern, FcMatchPattern); FcDefaultSubstitute (pattern); resolved = FcFontMatch (NULL, pattern, &result); if (! resolved) { + FcPatternDestroy (pattern); cairo_test_log (ctx, "FcFontMatch failed.\n"); - return CAIRO_TEST_FAILURE; + return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY); } font_face = cairo_ft_font_face_create_for_pattern (resolved); + if (cairo_font_face_status (font_face)) { + FcPatternDestroy (resolved); + FcPatternDestroy (pattern); + return cairo_test_status_from_status (ctx, cairo_font_face_status (font_face)); + } if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) { cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n", cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT); cairo_font_face_destroy (font_face); + FcPatternDestroy (resolved); + FcPatternDestroy (pattern); return CAIRO_TEST_FAILURE; } @@ -81,13 +167,16 @@ draw (cairo_t *cr, int width, int height) &ctm, font_options); - ft_face = cairo_ft_scaled_font_lock_face (scaled_font); - cairo_font_options_destroy (font_options); cairo_font_face_destroy (font_face); FcPatternDestroy (pattern); FcPatternDestroy (resolved); + if (cairo_scaled_font_status (scaled_font)) { + return cairo_test_status_from_status (ctx, + cairo_scaled_font_status (scaled_font)); + } + if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_FT) { cairo_test_log (ctx, "Unexpected value from cairo_scaled_font_get_type: %d (expected %d)\n", cairo_scaled_font_get_type (scaled_font), CAIRO_FONT_TYPE_FT); @@ -95,7 +184,8 @@ draw (cairo_t *cr, int width, int height) return CAIRO_TEST_FAILURE; } - if (!ft_face) { + ft_face = cairo_ft_scaled_font_lock_face (scaled_font); + if (ft_face == NULL) { cairo_test_log (ctx, "Failed to get an ft_face with cairo_ft_scaled_font_lock_face\n"); cairo_scaled_font_destroy (scaled_font); return CAIRO_TEST_FAILURE; @@ -107,13 +197,18 @@ draw (cairo_t *cr, int width, int height) * * Now, on to the simple thing we actually want to test. */ - font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0); + + cairo_save (cr); + + /* First we want to test caching behaviour */ + _stress_font_cache (ft_face, cr, 0); /* Set the font_face and force cairo to actually use it for * something. */ - cairo_save (cr); + font_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0); cairo_set_font_face (cr, font_face); cairo_font_extents (cr, &font_extents); + cairo_restore (cr); /* Finally, even more cleanup */ -- cgit v1.2.3 From 791a6fa399894e735d522781b15b7f18c3ecd4d1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 15 May 2009 16:57:49 +0100 Subject: [memfault] Update macros to avoid namescape collision with memcheck Basing the macro names of the memfault skin lead to a namespace collision with memcheck. After updating the headers, update cairo's usage to match. --- src/cairo-malloc-private.h | 2 +- test/cairo-test.c | 62 +++++++++++++++++++++++----------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/cairo-malloc-private.h b/src/cairo-malloc-private.h index e36f93b8..d812058f 100644 --- a/src/cairo-malloc-private.h +++ b/src/cairo-malloc-private.h @@ -41,7 +41,7 @@ #if HAVE_MEMFAULT #include -#define CAIRO_INJECT_FAULT() VALGRIND_INJECT_FAULT() +#define CAIRO_INJECT_FAULT() MEMFAULT_INJECT_FAULT() #else #define CAIRO_INJECT_FAULT() 0 #endif diff --git a/test/cairo-test.c b/test/cairo-test.c index 96ab2dcd..4e3d2fb3 100644 --- a/test/cairo-test.c +++ b/test/cairo-test.c @@ -131,7 +131,7 @@ _cairo_test_init (cairo_test_context_t *ctx, { char *log_name; - MF (VALGRIND_DISABLE_FAULTS ()); + MF (MEMFAULT_DISABLE_FAULTS ()); #if HAVE_FEENABLEEXCEPT feenableexcept (FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); @@ -222,7 +222,7 @@ cairo_test_init_thread (cairo_test_context_t *ctx, cairo_test_context_t *master, int thread) { - MF (VALGRIND_DISABLE_FAULTS ()); + MF (MEMFAULT_DISABLE_FAULTS ()); *ctx = *master; ctx->thread = thread; @@ -739,17 +739,17 @@ cairo_test_for_target (cairo_test_context_t *ctx, #if HAVE_MEMFAULT REPEAT: - VALGRIND_CLEAR_FAULTS (); - VALGRIND_RESET_LEAKS (); + MEMFAULT_CLEAR_FAULTS (); + MEMFAULT_RESET_LEAKS (); ctx->last_fault_count = 0; - last_fault_count = VALGRIND_COUNT_FAULTS (); + last_fault_count = MEMFAULT_COUNT_FAULTS (); /* Pre-initialise fontconfig so that the configuration is loaded without * malloc failures (our primary goal is to test cairo fault tolerance). */ FcInit (); - VALGRIND_ENABLE_FAULTS (); + MEMFAULT_ENABLE_FAULTS (); #endif have_output = FALSE; have_result = FALSE; @@ -772,7 +772,7 @@ REPEAT: #if HAVE_MEMFAULT if (ctx->malloc_failure && - VALGRIND_COUNT_FAULTS () - last_fault_count > 0 && + MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY) { goto REPEAT; @@ -780,7 +780,7 @@ REPEAT: #endif if (cairo_surface_status (surface)) { - MF (VALGRIND_PRINT_FAULTS ()); + MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created an error surface\n"); ret = CAIRO_TEST_FAILURE; goto UNWIND_STRINGS; @@ -788,7 +788,7 @@ REPEAT: /* Check that we created a surface of the expected type. */ if (cairo_surface_get_type (surface) != target->expected_type) { - MF (VALGRIND_PRINT_FAULTS ()); + MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created surface is of type %d (expected %d)\n", cairo_surface_get_type (surface), target->expected_type); ret = CAIRO_TEST_FAILURE; @@ -801,7 +801,7 @@ REPEAT: expected_content = cairo_boilerplate_content (target->content); if (cairo_surface_get_content (surface) != expected_content) { - MF (VALGRIND_PRINT_FAULTS ()); + MF (MEMFAULT_PRINT_FAULTS ()); cairo_test_log (ctx, "Error: Created surface has content %d (expected %d)\n", cairo_surface_get_content (surface), expected_content); ret = CAIRO_TEST_FAILURE; @@ -856,11 +856,11 @@ REPEAT: } #if HAVE_MEMFAULT - VALGRIND_DISABLE_FAULTS (); + MEMFAULT_DISABLE_FAULTS (); /* repeat test after malloc failure injection */ if (ctx->malloc_failure && - VALGRIND_COUNT_FAULTS () - last_fault_count > 0 && + MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && (status == CAIRO_TEST_NO_MEMORY || cairo_status (cr) == CAIRO_STATUS_NO_MEMORY || cairo_surface_status (surface) == CAIRO_STATUS_NO_MEMORY)) @@ -874,9 +874,9 @@ REPEAT: #if HAVE_FCFINI FcFini (); #endif - if (VALGRIND_COUNT_LEAKS () > 0) { - VALGRIND_PRINT_FAULTS (); - VALGRIND_PRINT_LEAKS (); + if (MEMFAULT_COUNT_LEAKS () > 0) { + MEMFAULT_PRINT_FAULTS (); + MEMFAULT_PRINT_LEAKS (); } } @@ -899,11 +899,11 @@ REPEAT: } #if HAVE_MEMFAULT - if (VALGRIND_COUNT_FAULTS () - last_fault_count > 0 && - VALGRIND_HAS_FAULTS ()) + if (MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && + MEMFAULT_HAS_FAULTS ()) { VALGRIND_PRINTF ("Unreported memfaults..."); - VALGRIND_PRINT_FAULTS (); + MEMFAULT_PRINT_FAULTS (); } #endif @@ -920,18 +920,18 @@ REPEAT: /* We need to re-enable faults as most meta-surface processing * is done during cairo_surface_finish(). */ - VALGRIND_CLEAR_FAULTS (); - last_fault_count = VALGRIND_COUNT_FAULTS (); - VALGRIND_ENABLE_FAULTS (); + MEMFAULT_CLEAR_FAULTS (); + last_fault_count = MEMFAULT_COUNT_FAULTS (); + MEMFAULT_ENABLE_FAULTS (); #endif diff_status = target->finish_surface (surface); #if HAVE_MEMFAULT - VALGRIND_DISABLE_FAULTS (); + MEMFAULT_DISABLE_FAULTS (); if (ctx->malloc_failure && - VALGRIND_COUNT_FAULTS () - last_fault_count > 0 && + MEMFAULT_COUNT_FAULTS () - last_fault_count > 0 && diff_status == CAIRO_STATUS_NO_MEMORY) { cairo_destroy (cr); @@ -943,9 +943,9 @@ REPEAT: #if HAVE_FCFINI FcFini (); #endif - if (VALGRIND_COUNT_LEAKS () > 0) { - VALGRIND_PRINT_FAULTS (); - VALGRIND_PRINT_LEAKS (); + if (MEMFAULT_COUNT_LEAKS () > 0) { + MEMFAULT_PRINT_FAULTS (); + MEMFAULT_PRINT_LEAKS (); } } @@ -1135,7 +1135,7 @@ UNWIND_CAIRO: #if HAVE_MEMFAULT if (ret == CAIRO_TEST_FAILURE && ctx->expectation != CAIRO_TEST_FAILURE) - VALGRIND_PRINT_FAULTS (); + MEMFAULT_PRINT_FAULTS (); #endif cairo_destroy (cr); UNWIND_SURFACE: @@ -1152,13 +1152,13 @@ UNWIND_SURFACE: FcFini (); #endif - if (VALGRIND_COUNT_LEAKS () > 0) { + if (MEMFAULT_COUNT_LEAKS () > 0) { if (ret != CAIRO_TEST_FAILURE || ctx->expectation == CAIRO_TEST_FAILURE) { - VALGRIND_PRINT_FAULTS (); + MEMFAULT_PRINT_FAULTS (); } - VALGRIND_PRINT_LEAKS (); + MEMFAULT_PRINT_LEAKS (); } } @@ -1648,7 +1648,7 @@ cairo_test_malloc_failure (const cairo_test_context_t *ctx, int n_faults; /* prevent infinite loops... */ - n_faults = VALGRIND_COUNT_FAULTS (); + n_faults = MEMFAULT_COUNT_FAULTS (); if (n_faults == ctx->last_fault_count) return FALSE; -- cgit v1.2.3 From 31596cf2b298054bbd3e340ae77a3388eadc0d8b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 15 May 2009 17:40:26 +0100 Subject: [debug] Check image contents using memcheck. As an aide to tracking down the source of uninitialised reads, run VALGRIND_CHECK_MEM_IS_DEFINED() over the contents of image surfaces at the boundary between backends, e.g. upon setting a glyph image or acquiring a source image. --- src/cairo-debug.c | 42 ++++++++++++++++++++++++++++++++++++++++++ src/cairo-ft-font.c | 2 ++ src/cairo-pattern.c | 2 ++ src/cairo-png.c | 2 ++ src/cairo-scaled-font.c | 3 +++ src/cairo-surface.c | 32 +++++++++++++++++++++++--------- src/cairoint.h | 11 +++++++++++ 7 files changed, 85 insertions(+), 9 deletions(-) diff --git a/src/cairo-debug.c b/src/cairo-debug.c index 5100a855..d463be29 100644 --- a/src/cairo-debug.c +++ b/src/cairo-debug.c @@ -77,3 +77,45 @@ cairo_debug_reset_static_data (void) CAIRO_MUTEX_FINALIZE (); } + +#if HAVE_VALGRIND +#include + +void +_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface) +{ + const cairo_image_surface_t *image = (cairo_image_surface_t *) surface; + const uint8_t *bits; + int row, width; + + if (surface == NULL) + return; + + if (! RUNNING_ON_VALGRIND) + return; + + bits = image->data; + switch (image->format) { + case CAIRO_FORMAT_A1: + width = (image->width + 7)/8; + break; + case CAIRO_FORMAT_A8: + width = image->width; + break; + case CAIRO_FORMAT_RGB24: + case CAIRO_FORMAT_ARGB32: + width = image->width*4; + break; + default: + ASSERT_NOT_REACHED; + return; + } + + for (row = 0; row < image->height; row++) { + VALGRIND_CHECK_MEM_IS_DEFINED (bits, width); + /* and then silence any future valgrind warnings */ + VALGRIND_MAKE_MEM_DEFINED (bits, width); + bits += image->stride; + } +} +#endif diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index f9ff0b10..8a6b4a20 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -996,6 +996,8 @@ _get_bitmap_surface (FT_Bitmap *bitmap, _cairo_image_surface_assume_ownership_of_data ((*surface)); + _cairo_debug_check_image_surface_is_defined (&(*surface)->base); + return CAIRO_STATUS_SUCCESS; } diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 67447a5e..49187c42 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -1452,6 +1452,8 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat pixman_image_unref (pixman_image); + _cairo_debug_check_image_surface_is_defined (&image->base); + status = _cairo_surface_clone_similar (dst, &image->base, opaque ? CAIRO_CONTENT_COLOR : diff --git a/src/cairo-png.c b/src/cairo-png.c index c6643286..d4f04760 100644 --- a/src/cairo-png.c +++ b/src/cairo-png.c @@ -654,6 +654,8 @@ read_png (struct png_read_closure_t *png_closure) _cairo_image_surface_assume_ownership_of_data ((cairo_image_surface_t*)surface); data = NULL; + _cairo_debug_check_image_surface_is_defined (surface); + status = _cairo_memory_stream_destroy (png_closure->png_data, &mime_data, &mime_data_length); diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index b8d9602d..dbe2de8d 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -2409,6 +2409,9 @@ _cairo_scaled_glyph_set_surface (cairo_scaled_glyph_t *scaled_glyph, { if (scaled_glyph->surface != NULL) cairo_surface_destroy (&scaled_glyph->surface->base); + + /* sanity check the backend glyph contents */ + _cairo_debug_check_image_surface_is_defined (&surface->base); scaled_glyph->surface = surface; } diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 26a7a13f..dbc14900 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1153,6 +1153,8 @@ _cairo_surface_acquire_source_image (cairo_surface_t *surface, cairo_image_surface_t **image_out, void **image_extra) { + cairo_status_t status; + if (surface->status) return surface->status; @@ -1161,9 +1163,14 @@ _cairo_surface_acquire_source_image (cairo_surface_t *surface, if (surface->backend->acquire_source_image == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; - return _cairo_surface_set_error (surface, - surface->backend->acquire_source_image (surface, - image_out, image_extra)); + status = surface->backend->acquire_source_image (surface, + image_out, image_extra); + if (unlikely (status)) + return _cairo_surface_set_error (surface, status); + + _cairo_debug_check_image_surface_is_defined (&(*image_out)->base); + + return CAIRO_STATUS_SUCCESS; } /** @@ -1222,6 +1229,8 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface, cairo_rectangle_int_t *image_rect, void **image_extra) { + cairo_status_t status; + if (surface->status) return surface->status; @@ -1230,12 +1239,17 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface, if (surface->backend->acquire_dest_image == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; - return _cairo_surface_set_error (surface, - surface->backend->acquire_dest_image (surface, - interest_rect, - image_out, - image_rect, - image_extra)); + status = surface->backend->acquire_dest_image (surface, + interest_rect, + image_out, + image_rect, + image_extra); + if (unlikely (status)) + return _cairo_surface_set_error (surface, status); + + _cairo_debug_check_image_surface_is_defined (&(*image_out)->base); + + return CAIRO_STATUS_SUCCESS; } /** diff --git a/src/cairoint.h b/src/cairoint.h index fc51d60a..f1ba063a 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -2741,4 +2741,15 @@ CAIRO_END_DECLS #include "cairo-malloc-private.h" #include "cairo-hash-private.h" +#if HAVE_VALGRIND + +cairo_private void +_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface); + +#else + +#define _cairo_debug_check_image_surface_is_defined(X) + +#endif + #endif -- cgit v1.2.3 From 4c8e5485a10478c19e8a6cb48595473f5bb8ee8a Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 17 May 2009 18:05:42 +0930 Subject: Fix win32 build breakage that was caused by c25992479aca481d326f72665ebdcf0904273eac --- src/cairo-win32-private.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cairo-win32-private.h b/src/cairo-win32-private.h index 51564d04..40ed20ef 100644 --- a/src/cairo-win32-private.h +++ b/src/cairo-win32-private.h @@ -163,6 +163,7 @@ _cairo_win32_surface_create_similar (void *abstract_src, cairo_status_t _cairo_win32_surface_clone_similar (void *abstract_surface, cairo_surface_t *src, + cairo_content_t content, int src_x, int src_y, int width, -- cgit v1.2.3 From 2a34992cccfd77c2acf30fe851311f16137ba32f Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 17 May 2009 18:12:39 +0930 Subject: Ensure win32 font index_to_ucs4() sets ucs4 to -1 if lookup fails --- src/cairo-win32-font.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c index e0ece5b7..d99c2613 100644 --- a/src/cairo-win32-font.c +++ b/src/cairo-win32-font.c @@ -1543,6 +1543,7 @@ _cairo_win32_scaled_font_index_to_ucs4 (void *abstract_font, goto exit1; } + *ucs4 = (uint32_t) -1; for (i = 0; i < glyph_set->cRanges; i++) { num_glyphs = glyph_set->ranges[i].cGlyphs; -- cgit v1.2.3 From 6e87e354e42d1a758a252533407e6e1829638544 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sun, 17 May 2009 18:14:28 +0930 Subject: Correct the comment for the index_to_ucs4 font backend function --- src/cairoint.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cairoint.h b/src/cairoint.h index f1ba063a..d694ae41 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -490,7 +490,8 @@ struct _cairo_scaled_font_backend { unsigned char *buffer, unsigned long *length); - /* returns -1 if the unicode character could not be found for the glyph */ + /* ucs4 is set to -1 if the unicode character could not be found + * for the glyph */ cairo_warn cairo_int_status_t (*index_to_ucs4)(void *scaled_font, unsigned long index, -- cgit v1.2.3 From c7d2b0de830f4c653fbb5016c4efdc5f0e5af0eb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 20 May 2009 17:34:56 +0100 Subject: [win32] Typo Correct function name in error string. --- src/cairo-win32-printing-surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c index 989f0186..0dc889ba 100644 --- a/src/cairo-win32-printing-surface.c +++ b/src/cairo-win32-printing-surface.c @@ -722,7 +722,7 @@ _cairo_win32_printing_surface_paint_image_pattern (cairo_win32_surface_t *surf _cairo_matrix_to_win32_xform (&m, &xform); if (! SetWorldTransform (surface->dc, &xform)) { - status = _cairo_win32_print_gdi_error ("_win32_scaled_font_set_world_transform"); + status = _cairo_win32_print_gdi_error ("_cairo_win32_printing_surface_paint_image_pattern"); goto CLEANUP_OPAQUE_IMAGE; } -- cgit v1.2.3 From 6717f0d748000416172057d0aab2471377456e27 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 20 May 2009 17:35:19 +0100 Subject: [win32] Wrap win32-font usage with CAIRO_HAS_WIN32_FONT Bug 19251: --enable-win32=yes and --enable-win32-font=no causes compilation failure [https://bugs.freedesktop.org/show_bug.cgi?id=19251] Wrap use of the win32 font backend within win32-printing-surface within CAIRO_HAS_WIN32_FONT ifdefs to prevent compilation failure if the user explicitly disables the win32 font backend. --- src/cairo-win32-printing-surface.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c index 0dc889ba..e7ff3bb6 100644 --- a/src/cairo-win32-printing-surface.c +++ b/src/cairo-win32-printing-surface.c @@ -1451,6 +1451,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac * If we are printing a bitmap font, use fallback images to * ensure the font is not substituted. */ +#if CAIRO_HAS_WIN32_FONT if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32) { if (_cairo_win32_scaled_font_is_bitmap (scaled_font)) return CAIRO_INT_STATUS_UNSUPPORTED; @@ -1472,6 +1473,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac if (status) return status; } +#endif return _cairo_win32_printing_surface_analyze_operation (surface, op, source); } @@ -1490,6 +1492,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac source = opaque; } +#if CAIRO_HAS_WIN32_FONT if (cairo_scaled_font_get_type (scaled_font) == CAIRO_FONT_TYPE_WIN32 && source->type == CAIRO_PATTERN_TYPE_SOLID) { @@ -1554,6 +1557,7 @@ _cairo_win32_printing_surface_show_glyphs (void *abstract_surfac return status; } +#endif SaveDC (surface->dc); old_ctm = surface->ctm; -- cgit v1.2.3 From bf2c7356d4c955fb770863874a0ea111e9ba02a4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 22 May 2009 12:52:43 +0100 Subject: [surface] Provide nil-surface for INVALID_SIZE So that we can faithfully report back failure if the user tries to create a surface larger than the backend can support. --- src/cairo-surface.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cairo-surface.c b/src/cairo-surface.c index dbc14900..a5a9b720 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -79,6 +79,7 @@ static DEFINE_NIL_SURFACE(CAIRO_STATUS_TEMP_FILE_ERROR, _cairo_surface_nil_temp_ static DEFINE_NIL_SURFACE(CAIRO_STATUS_READ_ERROR, _cairo_surface_nil_read_error); static DEFINE_NIL_SURFACE(CAIRO_STATUS_WRITE_ERROR, _cairo_surface_nil_write_error); static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_STRIDE, _cairo_surface_nil_invalid_stride); +static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_SIZE, _cairo_surface_nil_invalid_size); static cairo_status_t _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t **pattern, @@ -2967,6 +2968,8 @@ _cairo_surface_create_in_error (cairo_status_t status) return (cairo_surface_t *) &_cairo_surface_nil_temp_file_error; case CAIRO_STATUS_INVALID_STRIDE: return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride; + case CAIRO_STATUS_INVALID_SIZE: + return (cairo_surface_t *) &_cairo_surface_nil_invalid_size; case CAIRO_STATUS_SUCCESS: case CAIRO_STATUS_LAST_STATUS: ASSERT_NOT_REACHED; @@ -2993,7 +2996,6 @@ _cairo_surface_create_in_error (cairo_status_t status) case CAIRO_STATUS_INVALID_CLUSTERS: case CAIRO_STATUS_INVALID_SLANT: case CAIRO_STATUS_INVALID_WEIGHT: - case CAIRO_STATUS_INVALID_SIZE: case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: default: _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); -- cgit v1.2.3 From 3c6838532a62c294e7f18b13b0b7f8da9a1a1e1e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 20 May 2009 18:46:35 +0100 Subject: [surface] Early return if the backend cannot clone an image If the backend cannot create a similar surface to hold the image, then report back the failure before embarking upon an infinite recursion. The UNSUPPORTED return should percolate up through the call stack and trigger a fallback. --- src/cairo-surface.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cairo-surface.c b/src/cairo-surface.c index a5a9b720..fc994b0c 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -1332,6 +1332,9 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, clone_out); if (status == CAIRO_INT_STATUS_UNSUPPORTED) { + if (_cairo_surface_is_image (src)) + return CAIRO_INT_STATUS_UNSUPPORTED; + /* First check to see if we can replay to a similar surface */ if (_cairo_surface_is_meta (src)) { cairo_surface_t *similar; @@ -1375,7 +1378,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, } /* If we're still unsupported, hit our fallback path to get a clone */ - if (status == CAIRO_INT_STATUS_UNSUPPORTED) + if (status == CAIRO_INT_STATUS_UNSUPPORTED) { status = _cairo_surface_fallback_clone_similar (surface, src, content, @@ -1384,6 +1387,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, clone_offset_x, clone_offset_y, clone_out); + } /* We should never get UNSUPPORTED here, so if we have an error, bail. */ if (unlikely (status)) -- cgit v1.2.3 From efd0f0b2922d0801e4e0e8e75ddf9b9892a2f2e6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 20 May 2009 18:49:28 +0100 Subject: [xlib] Handle too-large images gracefully. Trigger a fallback to an image surface for massive patterns. --- src/cairo-xlib-surface.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index bbbdc4bd..e4566914 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -208,7 +208,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src, Pixmap pix; if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) - return _cairo_surface_create_in_error (_cairo_error(CAIRO_STATUS_INVALID_SIZE)); + return NULL; _cairo_xlib_display_notify (src->display); @@ -1199,7 +1199,7 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, cairo_format_t format; if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) - return _cairo_error (CAIRO_STATUS_INVALID_SIZE); + return CAIRO_INT_STATUS_UNSUPPORTED; format = image_src->format; if (format == CAIRO_FORMAT_INVALID || -- cgit v1.2.3 From b71b019fe50a9188ddbecd1945606da8ba3bad53 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 27 Feb 2009 16:32:21 +0000 Subject: [in-fill] Treat on-edge queries as inside. Jeff Muizelaar noted that the treatment of edges differed with firefox's canvas definition, which considers a point on any edge as inside. The current implementation has a similar definition to that of flash, for which the top and right edges are outside. Arguably, firefox has the more intuitive definition here... --- src/cairo-path-in-fill.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/cairo-path-in-fill.c b/src/cairo-path-in-fill.c index d43b1caa..d7b499ca 100644 --- a/src/cairo-path-in-fill.c +++ b/src/cairo-path-in-fill.c @@ -41,6 +41,7 @@ typedef struct cairo_in_fill { int winding; cairo_fixed_t x, y; + cairo_bool_t on_edge; cairo_bool_t has_current_point; cairo_point_t current_point; @@ -58,6 +59,7 @@ _cairo_in_fill_init (cairo_in_fill_t *in_fill, in_fill->x = _cairo_fixed_from_double (x); in_fill->y = _cairo_fixed_from_double (y); + in_fill->on_edge = FALSE; in_fill->has_current_point = FALSE; in_fill->current_point.x = 0; @@ -103,6 +105,9 @@ _cairo_in_fill_add_edge (cairo_in_fill_t *in_fill, { int dir; + if (in_fill->on_edge) + return; + /* count the number of edge crossing to -∞ */ dir = 1; @@ -116,6 +121,18 @@ _cairo_in_fill_add_edge (cairo_in_fill_t *in_fill, dir = -1; } + /* First check whether the query is on an edge */ + if ((p1->x == in_fill->x && p1->x == in_fill->y) || + (p2->x == in_fill->x && p2->x == in_fill->y) || + (! (p2->y < in_fill->y || p1->y > in_fill->y) && + ! (p1->x > in_fill->x && p2->x > in_fill->x) && + ! (p1->x < in_fill->x && p2->x < in_fill->x) && + edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) == 0)) + { + in_fill->on_edge = TRUE; + return; + } + /* edge is entirely above or below, note the shortening rule */ if (p2->y <= in_fill->y || p1->y > in_fill->y) return; @@ -250,7 +267,9 @@ _cairo_path_fixed_in_fill (cairo_path_fixed_t *path, _cairo_in_fill_close_path (&in_fill); - switch (fill_rule) { + if (in_fill.on_edge) { + *is_inside = TRUE; + } else switch (fill_rule) { case CAIRO_FILL_RULE_EVEN_ODD: *is_inside = in_fill.winding & 1; break; -- cgit v1.2.3 From cfd484cd01a77b1f91e27daccfc5f240cf7c692d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 May 2009 22:10:20 +0100 Subject: [test] Change test semantics to match new in-fill definition The in-fill definition has changed to include queries on the edges and vertices, so update the test case to match. --- test/in-fill-trapezoid.c | 77 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/test/in-fill-trapezoid.c b/test/in-fill-trapezoid.c index 57429687..b05f0002 100644 --- a/test/in-fill-trapezoid.c +++ b/test/in-fill-trapezoid.c @@ -43,24 +43,24 @@ draw (cairo_t *cr, int width, int height) } /* rectangular boundary tests */ - if (cairo_in_fill (cr, -10, -10)) { - cairo_test_log (ctx, "Error: Found top-left vertex inside rectangle\n"); + if (! cairo_in_fill (cr, -10, -10)) { + cairo_test_log (ctx, "Error: Failed to find top-left vertex inside rectangle\n"); ret = CAIRO_TEST_FAILURE; } - if (cairo_in_fill (cr, -10, 10)) { - cairo_test_log (ctx, "Error: Found bottom-left vertex inside rectangle\n"); + if (! cairo_in_fill (cr, -10, 10)) { + cairo_test_log (ctx, "Error: Failed to find bottom-left vertex inside rectangle\n"); ret = CAIRO_TEST_FAILURE; } if (! cairo_in_fill (cr, 10, -10)) { cairo_test_log (ctx, "Error: Failed to find top-right vertex inside rectangle\n"); ret = CAIRO_TEST_FAILURE; } - if (cairo_in_fill (cr, 10, 10)) { - cairo_test_log (ctx, "Error: Found bottom-right vertex inside rectangle\n"); + if (! cairo_in_fill (cr, 10, 10)) { + cairo_test_log (ctx, "Error: Failed to find bottom-right vertex inside rectangle\n"); ret = CAIRO_TEST_FAILURE; } - if (cairo_in_fill (cr, -10, 0)) { - cairo_test_log (ctx, "Error: Found left edge inside rectangle\n"); + if (! cairo_in_fill (cr, -10, 0)) { + cairo_test_log (ctx, "Error: Failed to find left edge inside rectangle\n"); ret = CAIRO_TEST_FAILURE; } if (! cairo_in_fill (cr, 0, -10)) { @@ -71,8 +71,8 @@ draw (cairo_t *cr, int width, int height) cairo_test_log (ctx, "Error: Failed to find right edge inside rectangle\n"); ret = CAIRO_TEST_FAILURE; } - if (cairo_in_fill (cr, 0, 10)) { - cairo_test_log (ctx, "Error: Found bottom edge inside rectangle\n"); + if (! cairo_in_fill (cr, 0, 10)) { + cairo_test_log (ctx, "Error: Failed to find bottom edge inside rectangle\n"); ret = CAIRO_TEST_FAILURE; } @@ -89,7 +89,7 @@ draw (cairo_t *cr, int width, int height) cairo_rectangle (cr, -10, -10, 20, 20); cairo_rectangle (cr, -5, -5, 10, 10); if (cairo_in_fill (cr, 0, 0)) { - cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular hole\n"); + cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular eo-hole\n"); ret = CAIRO_TEST_FAILURE; } @@ -98,7 +98,7 @@ draw (cairo_t *cr, int width, int height) cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI); cairo_arc (cr, 0, 0, 5, 0, 2 * M_PI); if (cairo_in_fill (cr, 0, 0)) { - cairo_test_log (ctx, "Error: Found an unexpected point inside circular hole\n"); + cairo_test_log (ctx, "Error: Found an unexpected point inside circular eo-hole\n"); ret = CAIRO_TEST_FAILURE; } @@ -136,7 +136,7 @@ draw (cairo_t *cr, int width, int height) cairo_rectangle (cr, -10, -10, 20, 20); cairo_rectangle (cr, 5, -5, -10, 10); if (cairo_in_fill (cr, 0, 0)) { - cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular hole\n"); + cairo_test_log (ctx, "Error: Found an unexpected point inside rectangular non-zero-hole\n"); ret = CAIRO_TEST_FAILURE; } @@ -145,7 +145,7 @@ draw (cairo_t *cr, int width, int height) cairo_arc (cr, 0, 0, 10, 0, 2 * M_PI); cairo_arc_negative (cr, 0, 0, 5, 0, -2 * M_PI); if (cairo_in_fill (cr, 0, 0)) { - cairo_test_log (ctx, "Error: Found an unexpected point inside circular hole\n"); + cairo_test_log (ctx, "Error: Found an unexpected point inside circular non-zero-hole\n"); ret = CAIRO_TEST_FAILURE; } @@ -163,26 +163,26 @@ draw (cairo_t *cr, int width, int height) cairo_arc (cr, 7.5, 0, 10, 0, 2 * M_PI); cairo_arc_negative (cr, 7.5, 0, 5, 0, -2 * M_PI); if (cairo_in_fill (cr, 7.5, 0)) { - cairo_test_log (ctx, "Error: Found an unexpected point inside circular hole\n"); + cairo_test_log (ctx, "Error: Found an unexpected point inside off-centre-x circular non-zero-hole\n"); ret = CAIRO_TEST_FAILURE; } cairo_new_path (cr); cairo_arc (cr, 0, 7.5, 10, 0, 2 * M_PI); cairo_arc_negative (cr, 0, 7.5, 5, 0, -2 * M_PI); if (cairo_in_fill (cr, 0, 7.5)) { - cairo_test_log (ctx, "Error: Found an unexpected point inside circular hole\n"); + cairo_test_log (ctx, "Error: Found an unexpected point inside off-centre-y circular non-zero-hole\n"); ret = CAIRO_TEST_FAILURE; } cairo_new_path (cr); cairo_arc (cr, 15, 0, 10, 0, 2 * M_PI); if (! cairo_in_fill (cr, 15, 0)) { - cairo_test_log (ctx, "Error: Failed to find point inside circle\n"); + cairo_test_log (ctx, "Error: Failed to find point inside off-centre-x circle\n"); ret = CAIRO_TEST_FAILURE; } cairo_new_path (cr); cairo_arc (cr, 0, 15, 10, 0, 2 * M_PI); if (! cairo_in_fill (cr, 0, 15)) { - cairo_test_log (ctx, "Error: Failed to find point inside circle\n"); + cairo_test_log (ctx, "Error: Failed to find point inside off-centre-y circle\n"); ret = CAIRO_TEST_FAILURE; } @@ -209,12 +209,49 @@ draw (cairo_t *cr, int width, int height) cairo_line_to (cr, 5, 5); cairo_close_path (cr); if (cairo_in_fill (cr, 0, 0) || - cairo_in_fill (cr, 10, 10) || + cairo_in_fill (cr, 5, 0) || + cairo_in_fill (cr, 15, 0) || cairo_in_fill (cr, 20, 0) || + cairo_in_fill (cr, 0, 10) || + cairo_in_fill (cr, 10, 10) || + cairo_in_fill (cr, 20, 10) || cairo_in_fill (cr, 7, 2.5) || cairo_in_fill (cr, 13, 2.5)) { - cairo_test_log (ctx, "Error: Found an unexpected point outside triangle\n"); + cairo_test_log (ctx, + "Error: Found an unexpected point outside triangle\n" + "\t(0, 0) -> %s\n" + "\t(5, 0) -> %s\n" + "\t(15, 0) -> %s\n" + "\t(20, 0) -> %s\n" + "\t(0, 10) -> %s\n" + "\t(10, 10) -> %s\n" + "\t(20, 10) -> %s\n" + "\t(7, 2.5) -> %s\n" + "\t(13, 2.5) -> %s\n", + cairo_in_fill (cr, 0, 0) ? "inside" : "outside", + cairo_in_fill (cr, 5, 0) ? "inside" : "outside", + cairo_in_fill (cr, 15, 0) ? "inside" : "outside", + cairo_in_fill (cr, 20, 0) ? "inside" : "outside", + cairo_in_fill (cr, 0, 10) ? "inside" : "outside", + cairo_in_fill (cr, 10, 10) ? "inside" : "outside", + cairo_in_fill (cr, 20, 10) ? "inside" : "outside", + cairo_in_fill (cr, 7, 2.5) ? "inside" : "outside", + cairo_in_fill (cr, 13, 2.5) ? "inside" : "outside"); + ret = CAIRO_TEST_FAILURE; + } + if (! cairo_in_fill (cr, 7.5, 2.5) || + ! cairo_in_fill (cr, 12.5, 2.5) || + ! cairo_in_fill (cr, 10, 5)) + { + cairo_test_log (ctx, + "Error: Failed to find point on triangle edge\n" + "\t(7.5, 2.5) -> %s\n" + "\t(12.5, 2.5) -> %s\n" + "\t(10, 5) -> %s\n", + cairo_in_fill (cr, 7.5, 2.5) ? "inside" : "outside", + cairo_in_fill (cr, 12.5, 2.5) ? "inside" : "outside", + cairo_in_fill (cr, 10, 5) ? "inside" : "outside"); ret = CAIRO_TEST_FAILURE; } if (! cairo_in_fill (cr, 8, 2.5) || -- cgit v1.2.3 From d840deb57b51236820dc8c320ecd7540973de873 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 May 2009 22:11:22 +0100 Subject: [in-fill] Fix typo in on-vertex test. Eeek! Comparing point->y against in_fill->x is a bad idea. --- src/cairo-path-in-fill.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cairo-path-in-fill.c b/src/cairo-path-in-fill.c index d7b499ca..24f43ca5 100644 --- a/src/cairo-path-in-fill.c +++ b/src/cairo-path-in-fill.c @@ -122,11 +122,11 @@ _cairo_in_fill_add_edge (cairo_in_fill_t *in_fill, } /* First check whether the query is on an edge */ - if ((p1->x == in_fill->x && p1->x == in_fill->y) || - (p2->x == in_fill->x && p2->x == in_fill->y) || - (! (p2->y < in_fill->y || p1->y > in_fill->y) && - ! (p1->x > in_fill->x && p2->x > in_fill->x) && - ! (p1->x < in_fill->x && p2->x < in_fill->x) && + if ((p1->x == in_fill->x && p1->y == in_fill->y) || + (p2->x == in_fill->x && p2->y == in_fill->y) || + (! (p2->y < in_fill->y || p1->y > in_fill->y || + (p1->x > in_fill->x && p2->x > in_fill->x) || + (p1->x < in_fill->x && p2->x < in_fill->x)) && edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) == 0)) { in_fill->on_edge = TRUE; -- cgit v1.2.3 From e4efc80b8e89b05afc22d74f984f4ec9012bc39b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 May 2009 21:15:22 +0100 Subject: [build] Make valgrind support user-configurable As the number of places where we add valgrind client requests grows, it becomes imperative that we should be able to disable them with a simple configure time option. --- build/configure.ac.analysis | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/build/configure.ac.analysis b/build/configure.ac.analysis index f425a9af..4e8a02da 100644 --- a/build/configure.ac.analysis +++ b/build/configure.ac.analysis @@ -82,18 +82,25 @@ AM_CONDITIONAL(CAIRO_HAS_LCOV, test "x$cairo_has_lcov" = "xyes") dnl =========================================================================== dnl Check for some custom valgrind modules -PKG_CHECK_MODULES(VALGRIND, valgrind, [ - _save_CFLAGS="$CFLAGS" - _save_CPPFLAGS="$CPPFLAGS" - CFLAGS="$CFLAGS $VALGRIND_CFLAGS" - CPPFLAGS="$CPPFLAGS $VALGRIND_CFLAGS" - AC_CHECK_HEADER([valgrind.h], [AC_DEFINE([HAVE_VALGRIND], [1], - [Define to 1 if you have Valgrind])]) - AC_CHECK_HEADER([lockdep.h], [AC_DEFINE([HAVE_LOCKDEP], [1], - [Define to 1 if you have the Valgrind lockdep tool])]) - AC_CHECK_HEADER([memfault.h], [AC_DEFINE([HAVE_MEMFAULT], [1], - [Define to 1 if you have the Valgrind memfault tool])]) - CAIRO_CFLAGS="$VALGRIND_CFLAGS $CAIRO_CFLAGS" - CFLAGS="$_save_CFLAGS" - CPPFLAGS="$_save_CPPFLAGS" - ], AC_MSG_RESULT(no)) +AC_ARG_ENABLE(valgrind, + AS_HELP_STRING([--disable-valgrind], + [Disable valgrind support]), + [use_valgrind=$enableval], [use_valgrind=yes]) + +if test "x$use_valgrind" = "xyes"; then + PKG_CHECK_MODULES(VALGRIND, valgrind, [ + _save_CFLAGS="$CFLAGS" + _save_CPPFLAGS="$CPPFLAGS" + CFLAGS="$CFLAGS $VALGRIND_CFLAGS" + CPPFLAGS="$CPPFLAGS $VALGRIND_CFLAGS" + AC_CHECK_HEADER([valgrind.h], [AC_DEFINE([HAVE_VALGRIND], [1], + [Define to 1 if you have Valgrind])]) + AC_CHECK_HEADER([lockdep.h], [AC_DEFINE([HAVE_LOCKDEP], [1], + [Define to 1 if you have the Valgrind lockdep tool])]) + AC_CHECK_HEADER([memfault.h], [AC_DEFINE([HAVE_MEMFAULT], [1], + [Define to 1 if you have the Valgrind memfault tool])]) + CAIRO_CFLAGS="$VALGRIND_CFLAGS $CAIRO_CFLAGS" + CFLAGS="$_save_CFLAGS" + CPPFLAGS="$_save_CPPFLAGS" + ], AC_MSG_RESULT(no)) +fi -- cgit v1.2.3 From b7f199fde25c960bf87302d5e868a7c2dffa4f5d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 May 2009 12:40:35 +0100 Subject: [pattern] Trim REPEAT source size when applicable. Some backends are quite constrained with surface sizes and so trigger fallbacks when asked to clone large images. To avoid this we attempt to trim ROIs (as these are often limited to the destination image, and so can be accommodated by the hardware). This patch allows trimming REPEAT sources both horizontally and vertically independently. --- src/cairo-pattern.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index 49187c42..654989f8 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -1972,13 +1972,28 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat /* Never acquire a larger area than the source itself */ is_empty = _cairo_rectangle_intersect (&extents, &sampled_area); } else { + int trim = 0; + if (sampled_area.x >= extents.x && - sampled_area.y >= extents.y && - sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width && + sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width) + { + /* source is horizontally contained within extents, trim */ + extents.x = sampled_area.x; + extents.width = sampled_area.width; + trim |= 0x1; + } + + if (sampled_area.y >= extents.y && sampled_area.y + (int) sampled_area.height <= extents.y + (int) extents.height) { + /* source is vertically contained within extents, trim */ + extents.y = sampled_area.y; + extents.height = sampled_area.height; + trim |= 0x2; + } + + if (trim == 0x3) { /* source is wholly contained within extents, drop the REPEAT */ - extents = sampled_area; attr->extend = CAIRO_EXTEND_NONE; } -- cgit v1.2.3 From a76e09ea656faa63fbfa159e8f52c9c9ec7d35c6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 May 2009 21:22:43 +0100 Subject: [trace] Missing newlines in error messages. --- util/cairo-trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util/cairo-trace/trace.c b/util/cairo-trace/trace.c index 4a7096db..4826e990 100644 --- a/util/cairo-trace/trace.c +++ b/util/cairo-trace/trace.c @@ -703,7 +703,7 @@ _init_logfile (void) int fd = atoi (filename); logfile = fdopen (fd, "w"); if (logfile == NULL) { - fprintf (stderr, "Failed to open trace file descriptor '%s': %s", + fprintf (stderr, "Failed to open trace file descriptor '%s': %s\n", filename, strerror (errno)); return false; } @@ -730,7 +730,7 @@ _init_logfile (void) logfile = fopen (filename, "wb"); if (logfile == NULL) { - fprintf (stderr, "Failed to open trace file '%s': %s", + fprintf (stderr, "Failed to open trace file '%s': %s\n", filename, strerror (errno)); return false; } -- cgit v1.2.3 From a364f71194aa2ea92071662f156c9b2a4d9211b4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 May 2009 21:25:27 +0100 Subject: [trace] Set output location using pwd Record the current working directory and pass that along to cairo-trace so that the trace output is local to the user and not the application. This is vital if the application is called via a script that changes directory. --- util/cairo-trace/cairo-trace.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/cairo-trace/cairo-trace.in b/util/cairo-trace/cairo-trace.in index 6660ff80..bf17217d 100644 --- a/util/cairo-trace/cairo-trace.in +++ b/util/cairo-trace/cairo-trace.in @@ -86,7 +86,7 @@ if test -n "$flush"; then fi if test -z "$nofile"; then - CAIRO_TRACE_OUTDIR=. "$@" + CAIRO_TRACE_OUTDIR=`pwd` "$@" else CAIRO_TRACE_FD=3 "$@" 3>&1 >/dev/null fi -- cgit v1.2.3 From 0b5e92e66be94ce7cc9c31e911f23c4cb7ec77af Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 May 2009 19:56:57 +0100 Subject: [script] Check hash value between comparing keys --- util/cairo-script/cairo-script-hash.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/util/cairo-script/cairo-script-hash.c b/util/cairo-script/cairo-script-hash.c index 4fa9e492..67451117 100644 --- a/util/cairo-script/cairo-script-hash.c +++ b/util/cairo-script/cairo-script-hash.c @@ -279,7 +279,7 @@ _csi_hash_table_lookup (csi_hash_table_t *hash_table, entry = &hash_table->entries[idx]; if (ENTRY_IS_LIVE (*entry)) { - if (hash_table->keys_equal (key, *entry)) + if ((*entry)->hash == key->hash && hash_table->keys_equal (key, *entry)) return *entry; } else if (ENTRY_IS_FREE (*entry)) return NULL; @@ -295,8 +295,11 @@ _csi_hash_table_lookup (csi_hash_table_t *hash_table, entry = &hash_table->entries[idx]; if (ENTRY_IS_LIVE (*entry)) { - if (hash_table->keys_equal (key, *entry)) + if ((*entry)->hash == key->hash && + hash_table->keys_equal (key, *entry)) + { return *entry; + } } else if (ENTRY_IS_FREE (*entry)) return NULL; } while (++i < table_size); -- cgit v1.2.3 From 7dbc2fe80a4fe0dcee4a293e47ab6edcefc24e18 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 25 May 2009 20:36:34 +0100 Subject: [script] Simplify _dictionary_name_equal Just a simple return TRUE since all necessary checking is performed by _csi_hash_table_lookup(). --- util/cairo-script/cairo-script-objects.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/util/cairo-script/cairo-script-objects.c b/util/cairo-script/cairo-script-objects.c index 2e81df4d..84398f18 100644 --- a/util/cairo-script/cairo-script-objects.c +++ b/util/cairo-script/cairo-script-objects.c @@ -194,9 +194,7 @@ csi_boolean_new (csi_t *ctx, static cairo_bool_t _dictionary_name_equal (const void *_a, const void *_b) { - const csi_dictionary_entry_t *a = _a; - const csi_dictionary_entry_t *b = _b; - return a->hash_entry.hash == b->hash_entry.hash; + return TRUE; } csi_status_t -- cgit v1.2.3 From 4314cae874dec2747df6be88859d7b6174eece31 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Wed, 27 May 2009 17:56:05 +0930 Subject: Fix typo in comment --- src/cairo-truetype-subset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c index b3de972a..92c05477 100644 --- a/src/cairo-truetype-subset.c +++ b/src/cairo-truetype-subset.c @@ -647,7 +647,7 @@ cairo_truetype_font_write_head_table (cairo_truetype_font_t *font, if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); - /* set checkSumAdjustment to 0 for table checksum calcualtion */ + /* set checkSumAdjustment to 0 for table checksum calculation */ *(uint32_t *)(buffer + 8) = 0; return CAIRO_STATUS_SUCCESS; -- cgit v1.2.3 From 4232719af968ed05636fe34f2ffe2520dc02d737 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 30 May 2009 23:03:55 -0400 Subject: [ft] Fix vertical advance metrics of bitmap fonts (#21985) --- src/cairo-ft-font.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 8a6b4a20..6c642846 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -1924,7 +1924,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, FT_Pos x1, x2; FT_Pos y1, y2; FT_Pos advance; - + if (!vertical_layout) { x1 = (metrics->horiBearingX) & -64; x2 = (metrics->horiBearingX + metrics->width + 63) & -64; @@ -1979,7 +1979,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE) fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor; else - fs_metrics.y_advance = DOUBLE_FROM_26_6 (glyph->linearVertAdvance) * y_factor; + fs_metrics.y_advance = DOUBLE_FROM_16_16 (glyph->linearVertAdvance) * y_factor; } } -- cgit v1.2.3