diff options
author | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-02-17 06:30:49 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@redhat.com> | 2009-02-17 06:30:49 -0500 |
commit | f37ebaa8f3089c4fa5f08bf16f8b52064006c64d (patch) | |
tree | 0774a1f052abfe6cad85f2328c1446a2f576a4fd | |
parent | f8ce71d1f519bfad103f019312d536a9a605372b (diff) | |
parent | 2760d558e65696657882f2219218aa71032ac5bc (diff) |
Merge branch 'damage' of git+ssh://sandmann@freedesktop.org/home/sandmann/cairo-damage into damagedamage
Conflicts:
src/cairo.c
388 files changed, 5720 insertions, 1792 deletions
diff --git a/build/Makefile.am.changelog b/build/Makefile.am.changelog index b9fbdcf3..888f4e79 100644 --- a/build/Makefile.am.changelog +++ b/build/Makefile.am.changelog @@ -71,7 +71,7 @@ $(srcdir)/ChangeLog.cache-% $(srcdir)/ChangeLog.pre-%: test "x$$from" = xinitial || from=$$from.0; \ spec=$$from..$$to; \ fi; \ - $(srcdir)/build/missing --run git-log --stat "$$spec") > $@.tmp \ + $(top_srcdir)/build/missing --run git-log --stat "$$spec") > $@.tmp \ && mv -f $@.tmp $@ \ || ($(RM) $@.tmp; \ echo Failed to generate $@, your $@ may be outdated >&2); \ diff --git a/build/configure.ac.system b/build/configure.ac.system index d06b7989..4544a54f 100644 --- a/build/configure.ac.system +++ b/build/configure.ac.system @@ -69,7 +69,7 @@ AC_CHECK_HEADER(fenv.h, dnl check for misc headers and functions AC_CHECK_HEADERS([libgen.h byteswap.h signal.h setjmp.h]) -AC_CHECK_FUNCS([vasnprintf link ctime_r drand48 flockfile]) +AC_CHECK_FUNCS([vasnprintf link ctime_r drand48 flockfile ffs]) dnl check for win32 headers (this detects mingw as well) AC_CHECK_HEADERS([windows.h], have_windows=yes, have_windows=no) diff --git a/configure.ac b/configure.ac index 7384ccc4..47a3ac60 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,10 @@ AC_CACHE_SAVE dnl =========================================================================== AC_CHECK_LIB(z, compress, - [AC_CHECK_HEADER(zlib.h, [have_libz=yes], + [AC_CHECK_HEADER(zlib.h, [ + have_libz=yes + AC_DEFINE(HAVE_ZLIB, 1, [Define to 1 if you have zlib available]) + ], [have_libz="no (requires zlib http://www.gzip.org/zlib/)"])], [have_libz="no (requires zlib http://www.gzip.org/zlib/)"]) diff --git a/perf/Makefile.am b/perf/Makefile.am index 737e96a4..5dcc0ab3 100644 --- a/perf/Makefile.am +++ b/perf/Makefile.am @@ -43,7 +43,9 @@ cairo_perf_SOURCES = \ zrusin-another.h \ long-dashed-lines.c \ dragon.c \ - pythagoras-tree.c + pythagoras-tree.c \ + intersections.c \ + spiral.c if CAIRO_HAS_WIN32_SURFACE cairo_perf_SOURCES += cairo-perf-win32.c @@ -54,6 +56,11 @@ else cairo_perf_SOURCES += cairo-perf-posix.c endif endif +cairo_perf_LDADD = $(LDADD) + +if CAIRO_HAS_SDL_SURFACE +cairo_perf_LDADD += $(sdl_LIBS) +endif libcairoperf_la_SOURCES = \ cairo-perf-report.c \ diff --git a/perf/cairo-perf-diff b/perf/cairo-perf-diff index 50cd1f2c..718cdc57 100755 --- a/perf/cairo-perf-diff +++ b/perf/cairo-perf-diff @@ -89,7 +89,7 @@ fi git_setup() { SUBDIRECTORY_OK='Yes' - . git-sh-setup + . "$(git --exec-path)/git-sh-setup" CAIRO_DIR=`dirname $GIT_DIR` if [ "$CAIRO_DIR" = "." ]; then CAIRO_DIR=`pwd` diff --git a/perf/cairo-perf.c b/perf/cairo-perf.c index d5f69201..6bb48f13 100644 --- a/perf/cairo-perf.c +++ b/perf/cairo-perf.c @@ -33,6 +33,10 @@ #include "cairo-boilerplate-getopt.h" +#if CAIRO_HAS_SDL_SURFACE +#include <SDL_main.h> +#endif + /* For basename */ #ifdef HAVE_LIBGEN_H #include <libgen.h> @@ -461,5 +465,7 @@ const cairo_perf_case_t perf_cases[] = { { twin, 800, 800}, { dragon, 1024, 1024 }, { pythagoras_tree, 768, 768 }, + { intersections, 512, 512 }, + { spiral, 512, 512 }, { NULL } }; diff --git a/perf/cairo-perf.h b/perf/cairo-perf.h index d18be033..3affcb82 100644 --- a/perf/cairo-perf.h +++ b/perf/cairo-perf.h @@ -175,5 +175,7 @@ CAIRO_PERF_DECL (composite_checker); CAIRO_PERF_DECL (twin); CAIRO_PERF_DECL (dragon); CAIRO_PERF_DECL (pythagoras_tree); +CAIRO_PERF_DECL (intersections); +CAIRO_PERF_DECL (spiral); #endif diff --git a/perf/intersections.c b/perf/intersections.c new file mode 100644 index 00000000..5e410366 --- /dev/null +++ b/perf/intersections.c @@ -0,0 +1,97 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ +/* cairo - a vector graphics library with display and print output + * + * Copyright (c) 2008 M Joonas Pihlaja + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "cairo-perf.h" + +#define NUM_SEGMENTS 256 + +static unsigned state; +static double +uniform_random (double minval, double maxval) +{ + static unsigned const poly = 0x9a795537U; + unsigned n = 32; + while (n-->0) + state = 2*state < state ? (2*state ^ poly) : 2*state; + return minval + state * (maxval - minval) / 4294967296.0; +} + +static cairo_perf_ticks_t +draw_random (cairo_t *cr, cairo_fill_rule_t fill_rule, int width, int height) +{ + int i; + double x[NUM_SEGMENTS]; + double y[NUM_SEGMENTS]; + + cairo_save (cr); + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_paint (cr); + + for (i = 0; i < NUM_SEGMENTS; i++) { + x[i] = uniform_random (0, width); + y[i] = uniform_random (0, height); + } + + state = 0x12345678; + cairo_translate (cr, 1, 1); + cairo_set_fill_rule (cr, fill_rule); + cairo_set_source_rgb (cr, 1, 0, 0); + + cairo_perf_timer_start (); { + + cairo_move_to (cr, 0, 0); + for (i = 0; i < NUM_SEGMENTS; i++) { + cairo_line_to (cr, x[i], y[i]); + } + cairo_close_path (cr); + + cairo_fill (cr); + } + cairo_perf_timer_stop (); + + cairo_restore (cr); + + return cairo_perf_timer_elapsed (); +} + +static cairo_perf_ticks_t +random_eo (cairo_t *cr, int width, int height) +{ + return draw_random (cr, CAIRO_FILL_RULE_EVEN_ODD, width, height); +} + +static cairo_perf_ticks_t +random_nz (cairo_t *cr, int width, int height) +{ + return draw_random (cr, CAIRO_FILL_RULE_WINDING, width, height); +} + +void +intersections (cairo_perf_t *perf, cairo_t *cr, int width, int height) +{ + cairo_perf_run (perf, "intersections-nz-fill", random_nz); + cairo_perf_run (perf, "intersections-eo-fill", random_eo); +} diff --git a/perf/spiral.c b/perf/spiral.c new file mode 100644 index 00000000..f26d0a2b --- /dev/null +++ b/perf/spiral.c @@ -0,0 +1,200 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ +/* cairo - a vector graphics library with display and print output + * + * Copyright (c) 2008 M Joonas Pihlaja + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include <assert.h> +#include "cairo-perf.h" + +#define MAX_SEGMENTS 2560 + +typedef enum { + PIXALIGN, /* pixel aligned path */ + NONALIGN /* unaligned path. */ +} align_t; + +typedef enum { + RECTCLOSE, /* keeps the path rectilinear */ + DIAGCLOSE /* forces a diagonal */ +} close_t; + +static cairo_perf_ticks_t +draw_spiral (cairo_t *cr, + cairo_fill_rule_t fill_rule, + align_t align, + close_t close, + int width, int height) +{ + int i; + int n=0; + double x[MAX_SEGMENTS]; + double y[MAX_SEGMENTS]; + int step = 3; + int side = width < height ? width : height; + + assert(5*(side/step/2+1)+2 < MAX_SEGMENTS); + +#define L(x_,y_) (x[n] = (x_), y[n] = (y_), n++) +#define M(x_,y_) L(x_,y_) +#define v(t) L(x[n-1], y[n-1] + (t)) +#define h(t) L(x[n-1] + (t), y[n-1]) + + switch (align) { + case PIXALIGN: M(0,0); break; + case NONALIGN: M(0.1415926, 0.7182818); break; + } + + while (side >= step && side >= 0) { + v(side); + h(side); + v(-side); + h(-side+step); + v(step); + side -= 2*step; + } + + switch (close) { + case RECTCLOSE: L(x[n-1],y[0]); break; + case DIAGCLOSE: L(x[0],y[0]); break; + } + + assert(n < MAX_SEGMENTS); + + cairo_save (cr); + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_paint (cr); + + cairo_translate (cr, 1, 1); + cairo_set_fill_rule (cr, fill_rule); + cairo_set_source_rgb (cr, 1, 0, 0); + + cairo_perf_timer_start (); { + + cairo_move_to (cr, x[0], y[0]); + for (i = 1; i < n; i++) { + cairo_line_to (cr, x[i], y[i]); + } + cairo_close_path (cr); + + cairo_fill (cr); + } + cairo_perf_timer_stop (); + + cairo_restore (cr); + + return cairo_perf_timer_elapsed (); +} + +static cairo_perf_ticks_t +draw_spiral_eo_pa_re (cairo_t *cr, int width, int height) +{ + return draw_spiral (cr, + CAIRO_FILL_RULE_EVEN_ODD, + PIXALIGN, + RECTCLOSE, + width, height); +} + +static cairo_perf_ticks_t +draw_spiral_nz_pa_re (cairo_t *cr, int width, int height) +{ + return draw_spiral (cr, + CAIRO_FILL_RULE_WINDING, + PIXALIGN, + RECTCLOSE, + width, height); +} + +static cairo_perf_ticks_t +draw_spiral_eo_na_re (cairo_t *cr, int width, int height) +{ + return draw_spiral (cr, + CAIRO_FILL_RULE_EVEN_ODD, + NONALIGN, + RECTCLOSE, + width, height); +} + +static cairo_perf_ticks_t +draw_spiral_nz_na_re (cairo_t *cr, int width, int height) +{ + return draw_spiral (cr, + CAIRO_FILL_RULE_WINDING, + NONALIGN, + RECTCLOSE, + width, height); +} + +static cairo_perf_ticks_t +draw_spiral_eo_pa_di (cairo_t *cr, int width, int height) +{ + return draw_spiral (cr, + CAIRO_FILL_RULE_EVEN_ODD, + PIXALIGN, + DIAGCLOSE, + width, height); +} + +static cairo_perf_ticks_t +draw_spiral_nz_pa_di (cairo_t *cr, int width, int height) +{ + return draw_spiral (cr, + CAIRO_FILL_RULE_WINDING, + PIXALIGN, + DIAGCLOSE, + width, height); +} + +static cairo_perf_ticks_t +draw_spiral_eo_na_di (cairo_t *cr, int width, int height) +{ + return draw_spiral (cr, + CAIRO_FILL_RULE_EVEN_ODD, + NONALIGN, + DIAGCLOSE, + width, height); +} + +static cairo_perf_ticks_t +draw_spiral_nz_na_di (cairo_t *cr, int width, int height) +{ + return draw_spiral (cr, + CAIRO_FILL_RULE_WINDING, + NONALIGN, + DIAGCLOSE, + width, height); +} + +void +spiral (cairo_perf_t *perf, cairo_t *cr, int width, int height) +{ + 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); + cairo_perf_run (perf, "spiral-diag-pixalign-nonzero-fill", draw_spiral_nz_pa_di); + cairo_perf_run (perf, "spiral-rect-nonalign-evenodd-fill", draw_spiral_eo_na_re); + cairo_perf_run (perf, "spiral-rect-nonalign-nonzero-fill", draw_spiral_nz_na_re); + cairo_perf_run (perf, "spiral-rect-pixalign-evenodd-fill", draw_spiral_eo_pa_re); + cairo_perf_run (perf, "spiral-rect-pixalign-nonzero-fill", draw_spiral_nz_pa_re); +} diff --git a/src/Makefile.sources b/src/Makefile.sources index 5d643dcb..5f387f43 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -81,6 +81,7 @@ cairo_private = \ cairo-region-private.h \ cairo-scaled-font-private.h \ cairo-skiplist-private.h \ + cairo-spans-private.h \ cairo-surface-fallback-private.h \ cairo-surface-private.h \ cairo-types-private.h \ @@ -132,10 +133,12 @@ cairo_sources = \ cairo-scaled-font.c \ cairo-skiplist.c \ cairo-slope.c \ + cairo-spans.c \ cairo-spline.c \ cairo-stroke-style.c \ cairo-surface.c \ cairo-surface-fallback.c \ + cairo-tor-scan-converter.c \ cairo-system.c \ cairo-traps.c \ cairo-unicode.c \ diff --git a/src/cairo-analysis-surface.c b/src/cairo-analysis-surface.c index 3109deed..50005c21 100644 --- a/src/cairo-analysis-surface.c +++ b/src/cairo-analysis-surface.c @@ -337,7 +337,7 @@ _cairo_analysis_surface_paint (void *abstract_surface, cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &source_extents); @@ -407,7 +407,7 @@ _cairo_analysis_surface_mask (void *abstract_surface, cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &source_extents); @@ -417,7 +417,7 @@ _cairo_analysis_surface_mask (void *abstract_surface, cairo_rectangle_int_t mask_extents; status = _cairo_pattern_get_extents (mask, &mask_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &mask_extents); @@ -469,7 +469,7 @@ _cairo_analysis_surface_stroke (void *abstract_surface, cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &source_extents); @@ -489,7 +489,7 @@ _cairo_analysis_surface_stroke (void *abstract_surface, ctm, ctm_inverse, tolerance, &traps); - if (status) { + if (unlikely (status)) { _cairo_traps_fini (&traps); return status; } @@ -541,7 +541,7 @@ _cairo_analysis_surface_fill (void *abstract_surface, cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &source_extents); @@ -560,7 +560,7 @@ _cairo_analysis_surface_fill (void *abstract_surface, fill_rule, tolerance, &traps); - if (status) { + if (unlikely (status)) { _cairo_traps_fini (&traps); return status; } @@ -622,7 +622,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface, cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &source_extents); @@ -635,7 +635,7 @@ _cairo_analysis_surface_show_glyphs (void *abstract_surface, glyphs, num_glyphs, &glyph_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents); @@ -708,7 +708,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &source_extents); @@ -721,7 +721,7 @@ _cairo_analysis_surface_show_text_glyphs (void *abstract_surface, glyphs, num_glyphs, &glyph_extents); - if (status) + if (unlikely (status)) return status; is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents); @@ -746,6 +746,8 @@ static const cairo_surface_backend_t cairo_analysis_surface_backend = { 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 */ @@ -780,11 +782,11 @@ _cairo_analysis_surface_create (cairo_surface_t *target, cairo_status_t status; status = target->status; - if (status) + if (unlikely (status)) return _cairo_surface_create_in_error (status); surface = malloc (sizeof (cairo_analysis_surface_t)); - if (surface == NULL) + if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); /* I believe the content type here is truly arbitrary. I'm quite @@ -961,6 +963,8 @@ static const cairo_surface_backend_t cairo_null_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ (_set_clip_region_func) _return_success, /* set_clip_region */ @@ -992,7 +996,7 @@ _cairo_null_surface_create (cairo_content_t content) cairo_surface_t *surface; surface = malloc (sizeof (cairo_surface_t)); - if (surface == NULL) { + if (unlikely (surface == NULL)) { return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); } diff --git a/src/cairo-array.c b/src/cairo-array.c index f38cfe3e..9c084b9e 100644 --- a/src/cairo-array.c +++ b/src/cairo-array.c @@ -138,7 +138,7 @@ _cairo_array_grow_by (cairo_array_t *array, unsigned int additional) if (array->elements == NULL) { array->elements = malloc (sizeof (char *)); - if (array->elements == NULL) + if (unlikely (array->elements == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); *array->elements = NULL; @@ -148,7 +148,7 @@ _cairo_array_grow_by (cairo_array_t *array, unsigned int additional) new_elements = _cairo_realloc_ab (*array->elements, array->size, array->element_size); - if (new_elements == NULL) { + if (unlikely (new_elements == NULL)) { array->size = old_size; return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -279,7 +279,7 @@ _cairo_array_append_multiple (cairo_array_t *array, assert (! array->is_snapshot); status = _cairo_array_allocate (array, num_elements, &dest); - if (status) + if (unlikely (status)) return status; memcpy (dest, elements, num_elements * array->element_size); @@ -310,7 +310,7 @@ _cairo_array_allocate (cairo_array_t *array, assert (! array->is_snapshot); status = _cairo_array_grow_by (array, num_elements); - if (status) + if (unlikely (status)) return status; assert (array->num_elements + num_elements <= array->size); @@ -489,7 +489,7 @@ _cairo_user_data_array_set_data (cairo_user_data_array_t *array, } status = _cairo_array_append (array, &new_slot); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; diff --git a/src/cairo-base85-stream.c b/src/cairo-base85-stream.c index 4d5a4652..9d42ef48 100644 --- a/src/cairo-base85-stream.c +++ b/src/cairo-base85-stream.c @@ -117,7 +117,7 @@ _cairo_base85_stream_create (cairo_output_stream_t *output) return _cairo_output_stream_create_in_error (output->status); stream = malloc (sizeof (cairo_base85_stream_t)); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c index eca28d5b..cd150218 100644 --- a/src/cairo-bentley-ottmann.c +++ b/src/cairo-bentley-ottmann.c @@ -979,7 +979,7 @@ _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue, sizeof (cairo_bo_event_t) + sizeof (cairo_bo_event_t *), sizeof (cairo_bo_event_t *)); - if (events == NULL) + if (unlikely (events == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events); @@ -1079,8 +1079,8 @@ _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line, cairo_bo_edge_t **prev_of_next, **next_of_prev; sweep_line_elt = _cairo_skip_list_insert (&sweep_line->active_edges, &edge, - 1 /* unique inserts*/); - if (sweep_line_elt == NULL) + 1 /* unique inserts*/); + if (unlikely (sweep_line_elt == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); next_elt = sweep_line_elt->elt.next[0]; @@ -1659,11 +1659,10 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps, has_limits = _cairo_traps_get_limit (traps, &limit); - if (polygon->num_edges < ARRAY_LENGTH (stack_edges)) { - edges = stack_edges; - } else { + edges = stack_edges; + if (polygon->num_edges > ARRAY_LENGTH (stack_edges)) { edges = _cairo_malloc_ab (polygon->num_edges, sizeof (cairo_bo_edge_t)); - if (edges == NULL) + if (unlikely (edges == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } diff --git a/src/cairo-beos-surface.cpp b/src/cairo-beos-surface.cpp index ec4aff03..e527272e 100644 --- a/src/cairo-beos-surface.cpp +++ b/src/cairo-beos-surface.cpp @@ -895,6 +895,8 @@ static const struct _cairo_surface_backend cairo_beos_surface_backend = { _cairo_beos_surface_composite, /* composite */ _cairo_beos_surface_fill_rectangles, NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ _cairo_beos_surface_set_clip_region, diff --git a/src/cairo-cache.c b/src/cairo-cache.c index f5caba4b..07c8b71f 100644 --- a/src/cairo-cache.c +++ b/src/cairo-cache.c @@ -53,7 +53,7 @@ _cairo_cache_init (cairo_cache_t *cache, unsigned long max_size) { cache->hash_table = _cairo_hash_table_create (keys_equal); - if (cache->hash_table == NULL) + if (unlikely (cache->hash_table == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); cache->entry_destroy = entry_destroy; @@ -125,13 +125,13 @@ _cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal, cairo_cache_t *cache; cache = malloc (sizeof (cairo_cache_t)); - if (cache == NULL) { + if (unlikely (cache == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); return NULL; } status = _cairo_cache_init (cache, keys_equal, entry_destroy, max_size); - if (status) { + if (unlikely (status)) { free (cache); return NULL; } @@ -240,7 +240,7 @@ _cairo_cache_remove_random (cairo_cache_t *cache) cairo_cache_entry_t *entry; entry = _cairo_hash_table_random_entry (cache->hash_table, NULL); - if (entry == NULL) + if (unlikely (entry == NULL)) return FALSE; _cairo_cache_remove (cache, entry); @@ -293,7 +293,7 @@ _cairo_cache_insert (cairo_cache_t *cache, status = _cairo_hash_table_insert (cache->hash_table, (cairo_hash_entry_t *) entry); - if (status) + if (unlikely (status)) return status; cache->size += entry->size; diff --git a/src/cairo-cff-subset.c b/src/cairo-cff-subset.c index 45be5d1c..75e1ab51 100644 --- a/src/cairo-cff-subset.c +++ b/src/cairo-cff-subset.c @@ -298,7 +298,7 @@ cff_index_read (cairo_array_t *index, unsigned char **ptr, unsigned char *end_pt element.is_copy = FALSE; element.data = data + start; status = _cairo_array_append (index, &element); - if (status) + if (unlikely (status)) return status; start = end; } @@ -324,7 +324,7 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output) num_elem = _cairo_array_num_elements (index); count = cpu_to_be16 ((uint16_t) num_elem); status = _cairo_array_append_multiple (output, &count, 2); - if (status) + if (unlikely (status)) return status; if (num_elem == 0) @@ -347,13 +347,13 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output) buf[0] = (unsigned char) offset_size; status = _cairo_array_append (output, buf); - if (status) + if (unlikely (status)) return status; offset = 1; encode_index_offset (buf, offset_size, offset); status = _cairo_array_append_multiple (output, buf, offset_size); - if (status) + if (unlikely (status)) return status; for (i = 0; i < num_elem; i++) { @@ -361,7 +361,7 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output) offset += element->length; encode_index_offset (buf, offset_size, offset); status = _cairo_array_append_multiple (output, buf, offset_size); - if (status) + if (unlikely (status)) return status; } @@ -370,7 +370,7 @@ cff_index_write (cairo_array_t *index, cairo_array_t *output) status = _cairo_array_append_multiple (output, element->data, element->length); - if (status) + if (unlikely (status)) return status; } return CAIRO_STATUS_SUCCESS; @@ -399,13 +399,13 @@ cff_index_append_copy (cairo_array_t *index, element.length = length; element.is_copy = TRUE; element.data = malloc (element.length); - if (element.data == NULL) + if (unlikely (element.data == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memcpy (element.data, object, element.length); status = _cairo_array_append (index, &element); - if (status) { + if (unlikely (status)) { free (element.data); return status; } @@ -440,8 +440,8 @@ static cairo_status_t cff_dict_init (cairo_hash_table_t **dict) { *dict = _cairo_hash_table_create (_cairo_cff_dict_equal); - if (*dict == NULL) - return CAIRO_STATUS_NO_MEMORY; + if (unlikely (*dict == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; } @@ -462,12 +462,12 @@ cff_dict_create_operator (int operator, cff_dict_operator_t *op; op = malloc (sizeof (cff_dict_operator_t)); - if (op == NULL) + if (unlikely (op == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); _cairo_dict_init_key (op, operator); op->operand = malloc (size); - if (op->operand == NULL) { + if (unlikely (op->operand == NULL)) { free (op); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -496,7 +496,7 @@ cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size) size = operand_length (p); if (size != 0) { status = _cairo_array_append_multiple (&operands, p, size); - if (status) + if (unlikely (status)) goto fail; p += size; @@ -506,11 +506,11 @@ cff_dict_read (cairo_hash_table_t *dict, unsigned char *p, int dict_size) _cairo_array_index (&operands, 0), _cairo_array_num_elements (&operands), &op); - if (status) + if (unlikely (status)) goto fail; status = _cairo_hash_table_insert (dict, &op->base); - if (status) + if (unlikely (status)) goto fail; _cairo_array_truncate (&operands, 0); @@ -568,7 +568,7 @@ cff_dict_set_operands (cairo_hash_table_t *dict, if (op != NULL) { free (op->operand); op->operand = malloc (size); - if (op->operand == NULL) + if (unlikely (op->operand == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memcpy (op->operand, operand, size); @@ -577,11 +577,11 @@ cff_dict_set_operands (cairo_hash_table_t *dict, else { status = cff_dict_create_operator (operator, operand, size, &op); - if (status) + if (unlikely (status)) return status; status = _cairo_hash_table_insert (dict, &op->base); - if (status) + if (unlikely (status)) return status; } @@ -724,7 +724,7 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t *font, unsigned char *p; status = cff_dict_read (private_dict, ptr, size); - if (status) + if (unlikely (status)) return status; operand = cff_dict_get_operands (private_dict, LOCAL_SUB_OP, &i); @@ -732,13 +732,13 @@ cairo_cff_font_read_private_dict (cairo_cff_font_t *font, decode_integer (operand, &offset); p = ptr + offset; status = cff_index_read (local_sub_index, &p, font->data_end); - if (status) + if (unlikely (status)) return status; /* Use maximum sized encoding to reserve space for later modification. */ end_buf = encode_integer_max (buf, 0); status = cff_dict_set_operands (private_dict, LOCAL_SUB_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) return status; } @@ -751,7 +751,7 @@ cairo_cff_font_read_fdselect (cairo_cff_font_t *font, unsigned char *p) int type, num_ranges, first, last, fd, i, j; font->fdselect = calloc (font->num_glyphs, sizeof (int)); - if (font->fdselect == NULL) + if (unlikely (font->fdselect == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); type = *p++; @@ -793,37 +793,37 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr) cff_index_init (&index); status = cff_index_read (&index, &ptr, font->data_end); - if (status) + if (unlikely (status)) goto fail; font->num_fontdicts = _cairo_array_num_elements (&index); font->fd_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts); - if (font->fd_dict == NULL) { + if (unlikely (font->fd_dict == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail; } font->fd_private_dict = calloc (sizeof (cairo_hash_table_t *), font->num_fontdicts); - if (font->fd_private_dict == NULL) { + if (unlikely (font->fd_private_dict == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail; } font->fd_local_sub_index = calloc (sizeof (cairo_array_t), font->num_fontdicts); - if (font->fd_local_sub_index == NULL) { + if (unlikely (font->fd_local_sub_index == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail; } for (i = 0; i < font->num_fontdicts; i++) { status = cff_dict_init (&font->fd_dict[i]); - if (status) + if (unlikely (status)) goto fail; element = _cairo_array_index (&index, i); status = cff_dict_read (font->fd_dict[i], element->data, element->length); - if (status) + if (unlikely (status)) goto fail; operand = cff_dict_get_operands (font->fd_dict[i], PRIVATE_OP, &size); @@ -834,7 +834,7 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr) operand = decode_integer (operand, &size); decode_integer (operand, &offset); status = cff_dict_init (&font->fd_private_dict[i]); - if (status) + if (unlikely (status)) goto fail; cff_index_init (&font->fd_local_sub_index[i]); @@ -843,7 +843,7 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr) &font->fd_local_sub_index[i], font->data + offset, size); - if (status) + if (unlikely (status)) goto fail; /* Set integer operand to max value to use max size encoding to reserve @@ -851,7 +851,7 @@ cairo_cff_font_read_cid_fontdict (cairo_cff_font_t *font, unsigned char *ptr) end_buf = encode_integer_max (buf, 0); end_buf = encode_integer_max (end_buf, 0); status = cff_dict_set_operands (font->fd_dict[i], PRIVATE_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) goto fail; } @@ -878,12 +878,12 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font) cff_index_init (&index); status = cff_index_read (&index, &font->current_ptr, font->data_end); - if (status) + if (unlikely (status)) goto fail; element = _cairo_array_index (&index, 0); status = cff_dict_read (font->top_dict, element->data, element->length); - if (status) + if (unlikely (status)) goto fail; if (cff_dict_get_operands (font->top_dict, ROS_OP, &size) != NULL) @@ -895,7 +895,7 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font) decode_integer (operand, &offset); p = font->data + offset; status = cff_index_read (&font->charstrings_index, &p, font->data_end); - if (status) + if (unlikely (status)) goto fail; font->num_glyphs = _cairo_array_num_elements (&font->charstrings_index); @@ -903,13 +903,13 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font) operand = cff_dict_get_operands (font->top_dict, FDSELECT_OP, &size); decode_integer (operand, &offset); status = cairo_cff_font_read_fdselect (font, font->data + offset); - if (status) + if (unlikely (status)) goto fail; operand = cff_dict_get_operands (font->top_dict, FDARRAY_OP, &size); decode_integer (operand, &offset); status = cairo_cff_font_read_cid_fontdict (font, font->data + offset); - if (status) + if (unlikely (status)) goto fail; } else { operand = cff_dict_get_operands (font->top_dict, PRIVATE_OP, &size); @@ -920,7 +920,7 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font) &font->local_sub_index, font->data + offset, size); - if (status) + if (unlikely (status)) goto fail; } @@ -928,22 +928,22 @@ cairo_cff_font_read_top_dict (cairo_cff_font_t *font) end_buf = encode_integer_max (buf, 0); status = cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) goto fail; status = cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) goto fail; status = cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) goto fail; status = cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) goto fail; cff_dict_remove (font->top_dict, ENCODING_OP); @@ -991,7 +991,7 @@ cairo_cff_font_read_font (cairo_cff_font_t *font) for (i = 0; i < ARRAY_LENGTH (font_read_funcs); i++) { status = font_read_funcs[i] (font); - if (status) + if (unlikely (status)) return status; } @@ -1012,26 +1012,26 @@ cairo_cff_font_set_ros_strings (cairo_cff_font_t *font) status = cff_index_append_copy (&font->strings_subset_index, (unsigned char *)registry, strlen(registry)); - if (status) + if (unlikely (status)) return status; sid2 = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index); status = cff_index_append_copy (&font->strings_subset_index, (unsigned char *)ordering, strlen(ordering)); - if (status) + if (unlikely (status)) return status; p = encode_integer (buf, sid1); p = encode_integer (p, sid2); p = encode_integer (p, 0); status = cff_dict_set_operands (font->top_dict, ROS_OP, buf, p - buf); - if (status) + if (unlikely (status)) return status; p = encode_integer (buf, font->scaled_font_subset->num_glyphs); status = cff_dict_set_operands (font->top_dict, CIDCOUNT_OP, buf, p - buf); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -1060,12 +1060,12 @@ cairo_cff_font_subset_dict_string(cairo_cff_font_t *font, element = _cairo_array_index (&font->strings_index, sid - NUM_STD_STRINGS); sid = NUM_STD_STRINGS + _cairo_array_num_elements (&font->strings_subset_index); status = cff_index_append (&font->strings_subset_index, element->data, element->length); - if (status) + if (unlikely (status)) return status; p = encode_integer (buf, sid); status = cff_dict_set_operands (dict, operator, buf, p - buf); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -1092,7 +1092,7 @@ cairo_cff_font_subset_dict_strings (cairo_cff_font_t *font, for (i = 0; i < ARRAY_LENGTH (dict_strings); i++) { status = cairo_cff_font_subset_dict_string (font, dict, dict_strings[i]); - if (status) + if (unlikely (status)) return status; } @@ -1112,7 +1112,7 @@ cairo_cff_font_subset_charstrings (cairo_cff_font_t *font) status = cff_index_append (&font->charstrings_subset_index, element->data, element->length); - if (status) + if (unlikely (status)) return status; } @@ -1128,19 +1128,19 @@ cairo_cff_font_subset_fontdict (cairo_cff_font_t *font) font->fdselect_subset = calloc (font->scaled_font_subset->num_glyphs, sizeof (int)); - if (font->fdselect_subset == NULL) + if (unlikely (font->fdselect_subset == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font->fd_subset_map = calloc (font->num_fontdicts, sizeof (int)); - if (font->fd_subset_map == NULL) + if (unlikely (font->fd_subset_map == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font->private_dict_offset = calloc (font->num_fontdicts, sizeof (int)); - if (font->private_dict_offset == NULL) + if (unlikely (font->private_dict_offset == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); reverse_map = calloc (font->num_fontdicts, sizeof (int)); - if (reverse_map == NULL) + if (unlikely (reverse_map == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); for (i = 0; i < font->num_fontdicts; i++) @@ -1170,7 +1170,7 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font) font->num_fontdicts = 1; font->fd_dict = malloc (sizeof (cairo_hash_table_t *)); - if (font->fd_dict == NULL) + if (unlikely (font->fd_dict == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); if (cff_dict_init (&font->fd_dict[0])) { @@ -1181,11 +1181,11 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font) } font->fd_subset_map = malloc (sizeof (int)); - if (font->fd_subset_map == NULL) + if (unlikely (font->fd_subset_map == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font->private_dict_offset = malloc (sizeof (int)); - if (font->private_dict_offset == NULL) + if (unlikely (font->private_dict_offset == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font->fd_subset_map[0] = 0; @@ -1196,7 +1196,7 @@ cairo_cff_font_create_cid_fontdict (cairo_cff_font_t *font) end_buf = encode_integer_max (buf, 0); end_buf = encode_integer_max (end_buf, 0); status = cff_dict_set_operands (font->fd_dict[0], PRIVATE_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -1209,17 +1209,17 @@ cairo_cff_font_subset_strings (cairo_cff_font_t *font) unsigned int i; status = cairo_cff_font_subset_dict_strings (font, font->top_dict); - if (status) + if (unlikely (status)) return status; if (font->is_cid) { for (i = 0; i < font->num_subset_fontdicts; i++) { status = cairo_cff_font_subset_dict_strings (font, font->fd_dict[font->fd_subset_map[i]]); - if (status) + if (unlikely (status)) return status; status = cairo_cff_font_subset_dict_strings (font, font->fd_private_dict[font->fd_subset_map[i]]); - if (status) + if (unlikely (status)) return status; } } else { @@ -1235,22 +1235,22 @@ cairo_cff_font_subset_font (cairo_cff_font_t *font) cairo_status_t status; status = cairo_cff_font_set_ros_strings (font); - if (status) + if (unlikely (status)) return status; status = cairo_cff_font_subset_charstrings (font); - if (status) + if (unlikely (status)) return status; if (font->is_cid) status = cairo_cff_font_subset_fontdict (font); else status = cairo_cff_font_create_cid_fontdict (font); - if (status) + if (unlikely (status)) return status; status = cairo_cff_font_subset_strings (font); - if (status) + if (unlikely (status)) return status; return status; @@ -1298,11 +1298,11 @@ cairo_cff_font_write_name (cairo_cff_font_t *font) status = cff_index_append_copy (&index, (unsigned char *) font->subset_font_name, strlen(font->subset_font_name)); - if (status) + if (unlikely (status)) goto FAIL; status = cff_index_write (&index, &font->output); - if (status) + if (unlikely (status)) goto FAIL; FAIL: @@ -1326,27 +1326,27 @@ cairo_cff_font_write_top_dict (cairo_cff_font_t *font) count = cpu_to_be16 (1); status = _cairo_array_append_multiple (&font->output, &count, 2); - if (status) + if (unlikely (status)) return status; buf[0] = offset_size; status = _cairo_array_append (&font->output, buf); - if (status) + if (unlikely (status)) return status; encode_index_offset (buf, offset_size, 1); status = _cairo_array_append_multiple (&font->output, buf, offset_size); - if (status) + if (unlikely (status)) return status; /* Reserve space for last element of offset array and update after * dict is written */ offset_index = _cairo_array_num_elements (&font->output); status = _cairo_array_append_multiple (&font->output, buf, offset_size); - if (status) + if (unlikely (status)) return status; dict_start = _cairo_array_num_elements (&font->output); status = cff_dict_write (font->top_dict, &font->output); - if (status) + if (unlikely (status)) return status; dict_size = _cairo_array_num_elements (&font->output) - dict_start; @@ -1381,13 +1381,13 @@ cairo_cff_font_write_fdselect (cairo_cff_font_t *font) if (font->is_cid) { data = 0; status = _cairo_array_append (&font->output, &data); - if (status) + if (unlikely (status)) return status; for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { data = font->fdselect_subset[i]; status = _cairo_array_append (&font->output, &data); - if (status) + if (unlikely (status)) return status; } } else { @@ -1395,7 +1395,7 @@ cairo_cff_font_write_fdselect (cairo_cff_font_t *font) uint16_t word; status = _cairo_array_grow_by (&font->output, 9); - if (status) + if (unlikely (status)) return status; byte = 3; @@ -1431,7 +1431,7 @@ cairo_cff_font_write_charset (cairo_cff_font_t *font) cairo_cff_font_set_topdict_operator_to_cur_pos (font, CHARSET_OP); status = _cairo_array_grow_by (&font->output, 5); - if (status) + if (unlikely (status)) return status; byte = 2; @@ -1470,22 +1470,22 @@ cairo_cff_font_write_cid_fontdict (cairo_cff_font_t *font) cairo_cff_font_set_topdict_operator_to_cur_pos (font, FDARRAY_OP); count = cpu_to_be16 (font->num_subset_fontdicts); status = _cairo_array_append_multiple (&font->output, &count, sizeof (uint16_t)); - if (status) + if (unlikely (status)) return status; status = _cairo_array_append (&font->output, &offset_size); - if (status) + if (unlikely (status)) return status; status = _cairo_array_allocate (&font->output, (font->num_subset_fontdicts + 1)*offset_size, (void **) &offset_array); - if (status) + if (unlikely (status)) return status; offset_base = _cairo_array_num_elements (&font->output) - 1; *offset_array++ = cpu_to_be32(1); for (i = 0; i < font->num_subset_fontdicts; i++) { status = cff_dict_write (font->fd_dict[font->fd_subset_map[i]], &font->output); - if (status) + if (unlikely (status)) return status; *offset_array++ = cpu_to_be32(_cairo_array_num_elements (&font->output) - offset_base); } @@ -1509,7 +1509,7 @@ cairo_cff_font_write_private_dict (cairo_cff_font_t *font, /* Write private dict and update offset and size in top dict */ font->private_dict_offset[dict_num] = _cairo_array_num_elements (&font->output); status = cff_dict_write (private_dict, &font->output); - if (status) + if (unlikely (status)) return status; size = _cairo_array_num_elements (&font->output) - font->private_dict_offset[dict_num]; @@ -1548,7 +1548,7 @@ cairo_cff_font_write_local_sub (cairo_cff_font_t *font, p = _cairo_array_index (&font->output, offset); memcpy (p, buf, buf_end - buf); status = cff_index_write (local_sub_index, &font->output); - if (status) + if (unlikely (status)) return status; } @@ -1569,7 +1569,7 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font) i, font->fd_dict[font->fd_subset_map[i]], font->fd_private_dict[font->fd_subset_map[i]]); - if (status) + if (unlikely (status)) return status; } @@ -1579,7 +1579,7 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font) i, font->fd_private_dict[font->fd_subset_map[i]], &font->fd_local_sub_index[font->fd_subset_map[i]]); - if (status) + if (unlikely (status)) return status; } } else { @@ -1587,14 +1587,14 @@ cairo_cff_font_write_cid_private_dict_and_local_sub (cairo_cff_font_t *font) 0, font->fd_dict[0], font->private_dict); - if (status) + if (unlikely (status)) return status; status = cairo_cff_font_write_local_sub (font, 0, font->private_dict, &font->local_sub_index); - if (status) + if (unlikely (status)) return status; } @@ -1625,7 +1625,7 @@ cairo_cff_font_write_subset (cairo_cff_font_t *font) for (i = 0; i < ARRAY_LENGTH (font_write_funcs); i++) { status = font_write_funcs[i] (font); - if (status) + if (unlikely (status)) return status; } @@ -1640,15 +1640,15 @@ cairo_cff_font_generate (cairo_cff_font_t *font, cairo_int_status_t status; status = cairo_cff_font_read_font (font); - if (status) + if (unlikely (status)) return status; status = cairo_cff_font_subset_font (font); - if (status) + if (unlikely (status)) return status; status = cairo_cff_font_write_subset (font); - if (status) + if (unlikely (status)) return status; *data = _cairo_array_index (&font->output, 0); @@ -1674,7 +1674,7 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font) status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_hhea, 0, (unsigned char*) &hhea, &size); - if (status) + if (unlikely (status)) return status; num_hmetrics = be16_to_cpu (hhea.num_hmetrics); @@ -1687,7 +1687,7 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font) TT_TAG_hmtx, glyph_index * long_entry_size, buf, &short_entry_size); - if (status) + if (unlikely (status)) return status; } else @@ -1696,7 +1696,7 @@ cairo_cff_font_create_set_widths (cairo_cff_font_t *font) TT_TAG_hmtx, (num_hmetrics - 1) * long_entry_size, buf, &short_entry_size); - if (status) + if (unlikely (status)) return status; } font->widths[i] = be16_to_cpu (*((int16_t*)buf)); @@ -1727,47 +1727,47 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset, data_length = 0; status = backend->load_truetype_table( scaled_font_subset->scaled_font, TT_TAG_CFF, 0, NULL, &data_length); - if (status) + if (unlikely (status)) return status; size = sizeof (tt_head_t); status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_head, 0, (unsigned char *) &head, &size); - if (status) + if (unlikely (status)) return status; size = sizeof (tt_hhea_t); status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_hhea, 0, (unsigned char *) &hhea, &size); - if (status) + if (unlikely (status)) return status; size = 0; status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_hmtx, 0, NULL, &size); - if (status) + if (unlikely (status)) return status; size = 0; status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_name, 0, NULL, &size); - if (status) + if (unlikely (status)) return status; name = malloc (size); - if (name == NULL) + if (unlikely (name == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_name, 0, (unsigned char *) name, &size); - if (status) + if (unlikely (status)) goto fail1; font = malloc (sizeof (cairo_cff_font_t)); - if (font == NULL) { + if (unlikely (font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail1; } @@ -1777,11 +1777,11 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset, _cairo_array_init (&font->output, sizeof (char)); status = _cairo_array_grow_by (&font->output, 4096); - if (status) + if (unlikely (status)) goto fail2; font->subset_font_name = strdup (subset_name); - if (font->subset_font_name == NULL) { + if (unlikely (font->subset_font_name == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } @@ -1817,7 +1817,7 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset, if (font->font_name == NULL) { font->font_name = malloc (30); - if (font->font_name == NULL) { + if (unlikely (font->font_name == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } @@ -1834,35 +1834,35 @@ _cairo_cff_font_create (cairo_scaled_font_subset_t *scaled_font_subset, font->font_name[i] = '\0'; font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int)); - if (font->widths == NULL) { + if (unlikely (font->widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail4; } status = cairo_cff_font_create_set_widths (font); - if (status) + if (unlikely (status)) goto fail5; font->data_length = data_length; font->data = malloc (data_length); - if (font->data == NULL) { + if (unlikely (font->data == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail5; } status = font->backend->load_truetype_table ( font->scaled_font_subset->scaled_font, TT_TAG_CFF, 0, font->data, &font->data_length); - if (status) + if (unlikely (status)) goto fail6; font->data_end = font->data + font->data_length; status = cff_dict_init (&font->top_dict); - if (status) + if (unlikely (status)) goto fail6; status = cff_dict_init (&font->private_dict); - if (status) + if (unlikely (status)) goto fail7; cff_index_init (&font->strings_index); @@ -1971,21 +1971,21 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset, unsigned int i; status = _cairo_cff_font_create (font_subset, &font, subset_name); - if (status) + if (unlikely (status)) return status; status = cairo_cff_font_generate (font, &data, &length); - if (status) + if (unlikely (status)) goto fail1; cff_subset->base_font = strdup (font->font_name); - if (cff_subset->base_font == NULL) { + if (unlikely (cff_subset->base_font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail1; } cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs); - if (cff_subset->widths == NULL) { + if (unlikely (cff_subset->widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } @@ -2000,7 +2000,7 @@ _cairo_cff_subset_init (cairo_cff_subset_t *cff_subset, cff_subset->descent = font->descent; cff_subset->data = malloc (length); - if (cff_subset->data == NULL) { + if (unlikely (cff_subset->data == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } @@ -2039,7 +2039,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset cairo_cff_font_t *font; font = malloc (sizeof (cairo_cff_font_t)); - if (font == NULL) + if (unlikely (font == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font->backend = NULL; @@ -2047,17 +2047,17 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset _cairo_array_init (&font->output, sizeof (char)); status = _cairo_array_grow_by (&font->output, 4096); - if (status) + if (unlikely (status)) goto fail1; font->subset_font_name = strdup (subset_name); - if (font->subset_font_name == NULL) { + if (unlikely (font->subset_font_name == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail1; } font->font_name = strdup (subset_name); - if (font->subset_font_name == NULL) { + if (unlikely (font->subset_font_name == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } @@ -2070,7 +2070,7 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset font->descent = 0; font->widths = calloc (font->scaled_font_subset->num_glyphs, sizeof (int)); - if (font->widths == NULL) { + if (unlikely (font->widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } @@ -2080,11 +2080,11 @@ _cairo_cff_font_fallback_create (cairo_scaled_font_subset_t *scaled_font_subset font->data_end = NULL; status = cff_dict_init (&font->top_dict); - if (status) + if (unlikely (status)) goto fail4; status = cff_dict_init (&font->private_dict); - if (status) + if (unlikely (status)) goto fail5; cff_index_init (&font->strings_index); @@ -2147,37 +2147,37 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font, end_buf = encode_integer (end_buf, type2_subset->y_max); status = cff_dict_set_operands (font->top_dict, FONTBBOX_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) return status; end_buf = encode_integer_max (buf, 0); status = cff_dict_set_operands (font->top_dict, CHARSTRINGS_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) return status; status = cff_dict_set_operands (font->top_dict, FDSELECT_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) return status; status = cff_dict_set_operands (font->top_dict, FDARRAY_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) return status; status = cff_dict_set_operands (font->top_dict, CHARSET_OP, buf, end_buf - buf); - if (status) + if (unlikely (status)) return status; status = cairo_cff_font_set_ros_strings (font); - if (status) + if (unlikely (status)) return status; /* Create CID FD dictionary */ status = cairo_cff_font_create_cid_fontdict (font); - if (status) + if (unlikely (status)) return status; /* Create charstrings */ @@ -2188,12 +2188,12 @@ cairo_cff_font_fallback_generate (cairo_cff_font_t *font, _cairo_array_index (charstring, 0), _cairo_array_num_elements (charstring)); - if (status) + if (unlikely (status)) return status; } status = cairo_cff_font_write_subset (font); - if (status) + if (unlikely (status)) return status; *data = _cairo_array_index (&font->output, 0); @@ -2215,25 +2215,25 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset, cairo_type2_charstrings_t type2_subset; status = _cairo_cff_font_fallback_create (font_subset, &font, subset_name); - if (status) + if (unlikely (status)) return status; status = _cairo_type2_charstrings_init (&type2_subset, font_subset); - if (status) + if (unlikely (status)) goto fail1; status = cairo_cff_font_fallback_generate (font, &type2_subset, &data, &length); - if (status) + if (unlikely (status)) goto fail2; cff_subset->base_font = strdup (font->font_name); - if (cff_subset->base_font == NULL) { + if (unlikely (cff_subset->base_font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } cff_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs); - if (cff_subset->widths == NULL) { + if (unlikely (cff_subset->widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } @@ -2248,7 +2248,7 @@ _cairo_cff_fallback_init (cairo_cff_subset_t *cff_subset, cff_subset->descent = type2_subset.y_min; cff_subset->data = malloc (length); - if (cff_subset->data == NULL) { + if (unlikely (cff_subset->data == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail4; } diff --git a/src/cairo-clip.c b/src/cairo-clip.c index ce2a2409..cd423a44 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -88,7 +88,7 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other) cairo_status_t status; status = _cairo_region_copy (&clip->region, &other->region); - if (status) { + if (unlikely (status)) { _cairo_region_fini (&clip->region); cairo_surface_destroy (clip->surface); return status; @@ -174,7 +174,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, if (clip->path) { status = _cairo_clip_path_intersect_to_rectangle (clip->path, rectangle); - if (status) + if (unlikely (status)) return status; } @@ -191,7 +191,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip, _cairo_region_fini (&intersection); - if (status) + if (unlikely (status)) return status; } @@ -228,7 +228,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, if (clip->has_region) { status = _cairo_region_intersect (region, &clip->region, region); - if (status) + if (unlikely (status)) return status; } @@ -241,7 +241,7 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip, _cairo_region_fini (&clip_rect); - if (status) + if (unlikely (status)) return status; } @@ -298,11 +298,11 @@ _cairo_clip_intersect_path (cairo_clip_t *clip, return CAIRO_INT_STATUS_UNSUPPORTED; clip_path = malloc (sizeof (cairo_clip_path_t)); - if (clip_path == NULL) + if (unlikely (clip_path == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _cairo_path_fixed_init_copy (&clip_path->path, path); - if (status) { + if (unlikely (status)) { free (clip_path); return status; } @@ -362,7 +362,6 @@ _cairo_clip_intersect_region (cairo_clip_t *clip, return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_traps_extract_region (traps, ®ion); - if (status) return status; @@ -492,7 +491,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip, _cairo_pattern_fini (&pattern.base); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (surface); return status; } @@ -517,7 +516,7 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip, _cairo_pattern_fini (&pattern.base); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (surface); return status; } @@ -535,6 +534,133 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip, return status; } +static cairo_status_t +_cairo_clip_intersect_mask_using_spans (cairo_clip_t *clip, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + cairo_surface_t *target) +{ + cairo_span_renderer_t *renderer = NULL; + cairo_pattern_union_t pattern; + cairo_rectangle_int_t surface_rect; + cairo_surface_t *surface = NULL; + cairo_status_t status; + cairo_operator_t op; + cairo_composite_rectangles_t rects; + + if (clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE, + CAIRO_CONTENT_COLOR); + + /* If we have a clip surface we're going to use IN to combine our + * new clip with the old clip. The ADD is done to a transparent + * surface, as that's a fast way of doing it currently. We should + * really be using SOURCE instead, but _cairo_surface_composite() + * checks that it's not called with SOURCE or DEST. */ + op = clip->surface ? CAIRO_OPERATOR_IN : CAIRO_OPERATOR_ADD; + + /* Test if the target can composite spans. We're going to assume + * this is a good indicator of whether a similar surface is going + * to be able to composite spans too. */ + if ( !_cairo_surface_check_span_renderer (op, + &pattern.base, + target, + antialias, + NULL)) + { + status = CAIRO_INT_STATUS_UNSUPPORTED; + goto BAIL; + } + + /* We'll create a new surface the size of the intersection of the + * old mask surface and the extents of the new clip path. */ + { + cairo_rectangle_int_t target_rect; + + _cairo_path_fixed_approximate_extents (path, &surface_rect); + + if (clip->surface != NULL && + !_cairo_rectangle_intersect (&surface_rect, &clip->surface_rect)) + goto SUCCESS; + + status = _cairo_surface_get_extents (target, &target_rect); + if (status != CAIRO_STATUS_SUCCESS && + !_cairo_rectangle_intersect (&surface_rect, &target_rect)) + goto SUCCESS; + } + + /* Make the new mask surface and optionally initialise it from the + * previous clip if we have one. */ + surface = _cairo_surface_create_similar_solid (target, + CAIRO_CONTENT_ALPHA, + surface_rect.width, + surface_rect.height, + CAIRO_COLOR_TRANSPARENT); + if (surface->status) { + _cairo_pattern_fini (&pattern.base); + return surface->status; + } + + if (clip->surface) { + cairo_surface_pattern_t old_clip; + _cairo_pattern_init_for_surface (&old_clip, clip->surface); + status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, + &old_clip.base, + NULL, + surface, + surface_rect.x - clip->surface_rect.x, + surface_rect.y - clip->surface_rect.y, + 0, 0, + 0, 0, + surface_rect.width, + surface_rect.height); + _cairo_pattern_fini (&old_clip.base); + if (status) + goto BAIL; + } + + _cairo_composite_rectangles_init (&rects, + surface_rect.x, + surface_rect.y, + surface_rect.width, + surface_rect.height); + rects.dst.x = 0; + rects.dst.y = 0; + + /* Render the new clipping path into the new mask surface. We've + * chosen op to either combine the new clip path with the existing + * clip mask (if there is one) or just render it. */ + status =_cairo_path_fixed_fill_using_spans (op, &pattern.base, + path, surface, + fill_rule, tolerance, + antialias, &rects); + if (status) + goto BAIL; + + SUCCESS: + if (clip->surface != NULL) + cairo_surface_destroy (clip->surface); + clip->surface = surface; + clip->surface_rect = surface_rect; + clip->serial = _cairo_surface_allocate_clip_serial (target); + surface = NULL; + + if (surface_rect.width == 0 || surface_rect.height == 0) + _cairo_clip_set_all_clipped (clip, target); + + BAIL: + if (renderer) + renderer->destroy(renderer); + if (surface) + cairo_surface_destroy (surface); + _cairo_pattern_fini (&pattern.base); + return status; +} + cairo_status_t _cairo_clip_clip (cairo_clip_t *clip, cairo_path_fixed_t *path, @@ -546,6 +672,7 @@ _cairo_clip_clip (cairo_clip_t *clip, cairo_status_t status; cairo_rectangle_int_t rectangle; cairo_traps_t traps; + cairo_box_t ignored_box; if (clip->all_clipped) return CAIRO_STATUS_SUCCESS; @@ -565,6 +692,18 @@ _cairo_clip_clip (cairo_clip_t *clip, if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; + /* TODO: allow ANTIALIAS_NONE when we have a mono scan converter + * again. */ + if (antialias != CAIRO_ANTIALIAS_NONE && + !_cairo_path_fixed_is_box (path, &ignored_box) && + !_cairo_path_fixed_is_region (path)) + { + status = _cairo_clip_intersect_mask_using_spans ( + clip, path, fill_rule, tolerance, antialias, target); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; + } + _cairo_traps_init (&traps); /* Limit the traps to the target surface @@ -581,7 +720,7 @@ _cairo_clip_clip (cairo_clip_t *clip, fill_rule, tolerance, &traps); - if (status) + if (unlikely (status)) goto bail; status = _cairo_clip_intersect_region (clip, &traps, target); @@ -664,7 +803,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, } else { if (other->has_region) { status = _cairo_region_copy (&clip->region, &other->region); - if (status) + if (unlikely (status)) goto BAIL; clip->has_region = TRUE; @@ -679,7 +818,7 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip, other->surface_rect.height, &dx, &dy, &clip->surface); - if (status) + if (unlikely (status)) goto BAIL; clip->surface_rect = other->surface_rect; @@ -760,7 +899,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) if (n_boxes) { rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t)); - if (rectangles == NULL) { + 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; @@ -790,7 +929,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) n_boxes = 1; rectangles = malloc(sizeof (cairo_rectangle_t)); - if (rectangles == NULL) { + if (unlikely (rectangles == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; } @@ -806,7 +945,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate) DONE: list = malloc (sizeof (cairo_rectangle_list_t)); - if (list == NULL) { + if (unlikely (list == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); free (rectangles); return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; diff --git a/src/cairo-deflate-stream.c b/src/cairo-deflate-stream.c index 3bb884ca..863189f4 100644 --- a/src/cairo-deflate-stream.c +++ b/src/cairo-deflate-stream.c @@ -121,7 +121,7 @@ _cairo_deflate_stream_create (cairo_output_stream_t *output) return _cairo_output_stream_create_in_error (output->status); stream = malloc (sizeof (cairo_deflate_stream_t)); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } diff --git a/src/cairo-directfb-surface.c b/src/cairo-directfb-surface.c index 8cbd3bcd..c31cf62c 100644 --- a/src/cairo-directfb-surface.c +++ b/src/cairo-directfb-surface.c @@ -455,7 +455,7 @@ _cairo_directfb_surface_create_similar (void *abstract_src, format = _cairo_format_from_content (content); surface = calloc (1, sizeof (cairo_directfb_surface_t)); - if (surface == NULL) + if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); surface->dfb = source->dfb; @@ -549,6 +549,7 @@ _cairo_directfb_surface_release_source_image (void *abstract_su cairo_image_surface_t *image, void *image_extra) { + cairo_directfb_surface_t *surface = abstract_surface; IDirectFBSurface *buffer = image_extra; D_DEBUG_AT (CairoDFB_Acquire, @@ -1815,6 +1816,8 @@ _cairo_directfb_surface_backend = { #else NULL,/*composite_trapezoids*/ #endif + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ _cairo_directfb_surface_set_clip_region,/* set_clip_region */ diff --git a/src/cairo-font-face.c b/src/cairo-font-face.c index eb4921e3..a78c2aab 100644 --- a/src/cairo-font-face.c +++ b/src/cairo-font-face.c @@ -398,7 +398,7 @@ _cairo_toy_font_face_init (cairo_toy_font_face_t *font_face, char *family_copy; family_copy = strdup (family); - if (family_copy == NULL) + if (unlikely (family_copy == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); _cairo_toy_font_face_init_key (font_face, family_copy, @@ -467,10 +467,12 @@ cairo_toy_font_face_create (const char *family, /* Make sure we've got valid UTF-8 for the family */ status = _cairo_utf8_to_ucs4 (family, -1, NULL, NULL); - if (status == CAIRO_STATUS_INVALID_STRING) - return (cairo_font_face_t*) &_cairo_font_face_invalid_string; - else if (status) + if (unlikely (status)) { + if (status == CAIRO_STATUS_INVALID_STRING) + return (cairo_font_face_t*) &_cairo_font_face_invalid_string; + return (cairo_font_face_t*) &_cairo_font_face_nil; + } switch (slant) { case CAIRO_FONT_SLANT_NORMAL: @@ -493,7 +495,7 @@ cairo_toy_font_face_create (const char *family, family = CAIRO_FONT_FAMILY_DEFAULT; hash_table = _cairo_toy_font_face_hash_table_lock (); - if (hash_table == NULL) + if (unlikely (hash_table == NULL)) goto UNWIND; _cairo_toy_font_face_init_key (&key, family, slant, weight); @@ -517,17 +519,17 @@ cairo_toy_font_face_create (const char *family, /* Otherwise create it and insert into hash table. */ font_face = malloc (sizeof (cairo_toy_font_face_t)); - if (font_face == NULL) { + if (unlikely (font_face == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto UNWIND_HASH_TABLE_LOCK; } status = _cairo_toy_font_face_init (font_face, family, slant, weight); - if (status) + if (unlikely (status)) goto UNWIND_FONT_FACE_MALLOC; status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry); - if (status) + if (unlikely (status)) goto UNWIND_FONT_FACE_INIT; _cairo_toy_font_face_hash_table_unlock (); @@ -614,7 +616,7 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face return font_face->base.status; status = cairo_font_options_status ((cairo_font_options_t *) options); - if (status) + if (unlikely (status)) return status; if (CAIRO_SCALED_FONT_BACKEND_DEFAULT != &_cairo_user_scaled_font_backend && diff --git a/src/cairo-ft-font.c b/src/cairo-ft-font.c index 4245448e..773f6ea0 100644 --- a/src/cairo-ft-font.c +++ b/src/cairo-ft-font.c @@ -182,7 +182,7 @@ _cairo_ft_unscaled_font_map_create (void) assert (cairo_ft_unscaled_font_map == NULL); font_map = malloc (sizeof (cairo_ft_unscaled_font_map_t)); - if (font_map == NULL) { + if (unlikely (font_map == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); goto FAIL; } @@ -190,7 +190,7 @@ _cairo_ft_unscaled_font_map_create (void) font_map->hash_table = _cairo_hash_table_create (_cairo_ft_unscaled_font_keys_equal); - if (font_map->hash_table == NULL) + if (unlikely (font_map->hash_table == NULL)) goto FAIL; if (FT_Init_FreeType (&font_map->ft_library)) @@ -261,7 +261,7 @@ _cairo_ft_unscaled_font_map_lock (void) { _cairo_ft_unscaled_font_map_create (); - if (cairo_ft_unscaled_font_map == NULL) { + if (unlikely (cairo_ft_unscaled_font_map == NULL)) { CAIRO_MUTEX_UNLOCK (_cairo_ft_unscaled_font_map_mutex); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return NULL; @@ -340,8 +340,9 @@ _cairo_ft_unscaled_font_init (cairo_ft_unscaled_font_t *unscaled, unscaled->face = NULL; filename_copy = strdup (filename); - if (filename_copy == NULL) + if (unlikely (filename_copy == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); + _cairo_ft_unscaled_font_init_key (unscaled, FALSE, filename_copy, id, NULL); } @@ -416,7 +417,7 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face, cairo_status_t status; font_map = _cairo_ft_unscaled_font_map_lock (); - if (font_map == NULL) + if (unlikely (font_map == NULL)) goto UNWIND; _cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face); @@ -432,18 +433,18 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face, /* Otherwise create it and insert into hash table. */ unscaled = malloc (sizeof (cairo_ft_unscaled_font_t)); - if (unscaled == NULL) { + if (unlikely (unscaled == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); goto UNWIND_FONT_MAP_LOCK; } status = _cairo_ft_unscaled_font_init (unscaled, from_face, filename, id, font_face); - if (status) + if (unlikely (status)) goto UNWIND_UNSCALED_MALLOC; status = _cairo_hash_table_insert (font_map->hash_table, &unscaled->base.hash_entry); - if (status) + if (unlikely (status)) goto UNWIND_UNSCALED_FONT_INIT; _cairo_ft_unscaled_font_map_unlock (); @@ -621,7 +622,7 @@ _compute_transform (cairo_ft_font_transform_t *sf, status = _cairo_matrix_compute_basis_scale_factors (scale, &x_scale, &y_scale, 1); - if (status) + if (unlikely (status)) return status; /* FreeType docs say this about x_scale and y_scale: @@ -671,7 +672,7 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled, unscaled->current_scale = *scale; status = _compute_transform (&sf, scale); - if (status) + if (unlikely (status)) return status; unscaled->x_scale = sf.x_scale; @@ -874,7 +875,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap, stride = bitmap->pitch; stride_rgba = (width_rgba * 4 + 3) & ~3; data_rgba = calloc (stride_rgba, height); - if (data_rgba == NULL) { + if (unlikely (data_rgba == NULL)) { if (own_buffer) free (bitmap->buffer); return _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -1073,7 +1074,7 @@ _render_glyph_outline (FT_Face face, bitmap.width = width * hmul; bitmap.rows = height * vmul; bitmap.buffer = calloc (stride, bitmap.rows); - if (bitmap.buffer == NULL) + if (unlikely (bitmap.buffer == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); FT_Outline_Translate (outline, -cbox.xMin*hmul, -cbox.yMin*vmul); @@ -1084,7 +1085,7 @@ _render_glyph_outline (FT_Face face, } status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface); - if (status) + if (unlikely (status)) return status; } @@ -1125,7 +1126,7 @@ _render_glyph_bitmap (FT_Face face, return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _get_bitmap_surface (&glyphslot->bitmap, FALSE, font_options, surface); - if (status) + if (unlikely (status)) return status; /* @@ -1212,13 +1213,13 @@ _transform_glyph_bitmap (cairo_matrix_t * shape, transformed_to_original = original_to_transformed; status = cairo_matrix_invert (&transformed_to_original); - if (status) + if (unlikely (status)) return status; /* We need to pad out the width to 32-bit intervals for cairo-xlib-surface.c */ width = (width + 3) & ~3; image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height); - if (image->status) + if (unlikely (image->status)) return image->status; /* Initialize it to empty @@ -1227,7 +1228,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape, CAIRO_COLOR_TRANSPARENT, 0, 0, width, height); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (image); return status; } @@ -1245,7 +1246,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape, _cairo_pattern_fini (&pattern.base); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (image); return status; } @@ -1512,7 +1513,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled, return _cairo_error (CAIRO_STATUS_NO_MEMORY); scaled_font = malloc (sizeof(cairo_ft_scaled_font_t)); - if (scaled_font == NULL) { + if (unlikely (scaled_font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto FAIL; } @@ -1527,7 +1528,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled, font_face, font_matrix, ctm, options, &_cairo_ft_scaled_font_backend); - if (status) { + if (unlikely (status)) { _cairo_unscaled_font_destroy (&unscaled->base); free (scaled_font); goto FAIL; @@ -1535,7 +1536,7 @@ _cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled, status = _cairo_ft_unscaled_font_set_scale (unscaled, &scaled_font->base.scale); - if (status) { + if (unlikely (status)) { _cairo_unscaled_font_destroy (&unscaled->base); free (scaled_font); goto FAIL; @@ -1626,7 +1627,7 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face, cairo_matrix_multiply (&scale, font_matrix, ctm); status = _compute_transform (&sf, &scale); - if (status) + if (unlikely (status)) return status; pattern = FcPatternCreate (); @@ -1686,7 +1687,7 @@ _cairo_ft_scaled_font_create_toy (cairo_toy_font_face_t *toy_face, } status = _cairo_ft_font_options_substitute (font_options, pattern); - if (status) + if (unlikely (status)) goto FREE_PATTERN; FcDefaultSubstitute (pattern); @@ -1863,7 +1864,7 @@ _decompose_glyph_outline (FT_Face face, } status = _cairo_path_fixed_close_path (path); - if (status) { + if (unlikely (status)) { _cairo_path_fixed_destroy (path); return status; } @@ -1918,7 +1919,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale); - if (status) + if (unlikely (status)) goto FAIL; /* Ignore global advance unconditionally */ @@ -2066,14 +2067,16 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, } else { status = _render_glyph_bitmap (face, &scaled_font->ft_options.base, &surface); - if (status == CAIRO_STATUS_SUCCESS && unscaled->have_shape) { + if (likely (status == CAIRO_STATUS_SUCCESS) && + unscaled->have_shape) + { status = _transform_glyph_bitmap (&unscaled->current_shape, &surface); - if (status) + if (unlikely (status)) cairo_surface_destroy (&surface->base); } } - if (status) + if (unlikely (status)) goto FAIL; _cairo_scaled_glyph_set_surface (scaled_glyph, @@ -2115,7 +2118,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font, else status = CAIRO_INT_STATUS_UNSUPPORTED; - if (status) + if (unlikely (status)) goto FAIL; _cairo_scaled_glyph_set_path (scaled_glyph, @@ -2530,7 +2533,7 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern) cairo_ft_options_t ft_options; unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern); - if (unscaled == NULL) { + if (unlikely (unscaled == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_font_face_t *)&_cairo_font_face_nil; } @@ -2597,7 +2600,7 @@ cairo_ft_font_face_create_for_ft_face (FT_Face face, cairo_ft_options_t ft_options; unscaled = _cairo_ft_unscaled_font_create_from_face (face); - if (unscaled == NULL) { + if (unlikely (unscaled == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_font_face_t *)&_cairo_font_face_nil; } @@ -2658,14 +2661,14 @@ cairo_ft_scaled_font_lock_face (cairo_scaled_font_t *abstract_font) return NULL; face = _cairo_ft_unscaled_font_lock_face (scaled_font->unscaled); - if (face == NULL) { + if (unlikely (face == NULL)) { status = _cairo_scaled_font_set_error (&scaled_font->base, CAIRO_STATUS_NO_MEMORY); return NULL; } status = _cairo_ft_unscaled_font_set_scale (scaled_font->unscaled, &scaled_font->base.scale); - if (status) { + if (unlikely (status)) { _cairo_ft_unscaled_font_unlock_face (scaled_font->unscaled); status = _cairo_scaled_font_set_error (&scaled_font->base, status); return NULL; diff --git a/src/cairo-glitz-surface.c b/src/cairo-glitz-surface.c index 3916f8f1..f049f401 100644 --- a/src/cairo-glitz-surface.c +++ b/src/cairo-glitz-surface.c @@ -33,7 +33,8 @@ typedef struct _cairo_glitz_surface { glitz_surface_t *surface; glitz_format_t *format; - cairo_bool_t has_clip; + + cairo_bool_t has_clip; glitz_box_t *clip_boxes; int num_clip_boxes; } cairo_glitz_surface_t; @@ -46,10 +47,8 @@ _cairo_glitz_surface_finish (void *abstract_surface) { cairo_glitz_surface_t *surface = abstract_surface; - if (surface->has_clip) { - glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0); + if (surface->clip_boxes) free (surface->clip_boxes); - } glitz_surface_destroy (surface->surface); @@ -108,7 +107,9 @@ _cairo_glitz_surface_create_similar (void *abstract_src, } static cairo_status_t -_cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes, int *nboxes) +_cairo_glitz_get_boxes_from_region (cairo_region_t *region, + glitz_box_t **boxes, + int *nboxes) { pixman_box32_t *pboxes; cairo_status_t status = CAIRO_STATUS_SUCCESS; @@ -118,15 +119,16 @@ _cairo_glitz_get_boxes_from_region (cairo_region_t *region, glitz_box_t **boxes, n = 0; pboxes = pixman_region32_rectangles (®ion->rgn, &n); if (n == 0) { - *nboxes = 0; - *boxes = NULL; - goto done; + *nboxes = 0; + return CAIRO_STATUS_SUCCESS; } - *boxes = _cairo_malloc_ab (n, sizeof(glitz_box_t)); - if (*boxes == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto done; + if (n > *nboxes) { + *boxes = _cairo_malloc_ab (n, sizeof (glitz_box_t)); + if (*boxes == NULL) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto done; + } } for (i = 0; i < n; i++) { @@ -141,8 +143,6 @@ done: return status; } -#define STRIDE_ALIGNMENT (sizeof (uint32_t)) - static cairo_status_t _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface, cairo_rectangle_int_t *interest, @@ -150,95 +150,62 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface, cairo_rectangle_int_t *rect_out) { cairo_image_surface_t *image; - int x1, y1, x2, y2; - int width, height; - unsigned char *pixels; + cairo_rectangle_int_t extents; + cairo_format_t format; cairo_format_masks_t masks; glitz_buffer_t *buffer; glitz_pixel_format_t pf; - cairo_status_t status; - pixman_format_code_t pixman_format; - x1 = 0; - y1 = 0; - x2 = glitz_surface_get_width (surface->surface); - y2 = glitz_surface_get_height (surface->surface); + extents.x = 0; + extents.y = 0; + extents.width = glitz_surface_get_width (surface->surface); + extents.height = glitz_surface_get_height (surface->surface); - if (interest) - { - if (interest->x > x1) - x1 = interest->x; - if (interest->y > y1) - y1 = interest->y; - if (interest->x + interest->width < (unsigned int)x2) - x2 = interest->x + interest->width; - if (interest->y + interest->height < (unsigned int)y2) - y2 = interest->y + interest->height; - - if (x1 >= x2 || y1 >= y2) - { + if (interest != NULL) { + if (! _cairo_rectangle_intersect (&extents, interest)) { *image_out = NULL; return CAIRO_STATUS_SUCCESS; } } - width = x2 - x1; - height = y2 - y1; - - if (rect_out) - { - rect_out->x = x1; - rect_out->y = y1; - rect_out->width = width; - rect_out->height = height; - } + if (rect_out != NULL) + *rect_out = extents; if (surface->format->color.fourcc == GLITZ_FOURCC_RGB) { if (surface->format->color.red_size > 0) { - masks.bpp = 32; - if (surface->format->color.alpha_size > 0) - masks.alpha_mask = 0xff000000; + format = CAIRO_FORMAT_ARGB32; else - masks.alpha_mask = 0x0; - - masks.red_mask = 0xff0000; - masks.green_mask = 0xff00; - masks.blue_mask = 0xff; + format = CAIRO_FORMAT_RGB24; } else { - masks.bpp = 8; - masks.blue_mask = masks.green_mask = masks.red_mask = 0x0; - masks.alpha_mask = 0xff; + format = CAIRO_FORMAT_A8; } - } else { - masks.bpp = 32; - masks.alpha_mask = 0xff000000; - masks.red_mask = 0xff0000; - masks.green_mask = 0xff00; - masks.blue_mask = 0xff; - } + } else + format = CAIRO_FORMAT_ARGB32; + image = (cairo_image_surface_t*) + cairo_image_surface_create (format, extents.width, extents.height); + if (image->base.status) + return image->base.status; + + _pixman_format_to_masks (image->pixman_format, &masks); pf.fourcc = GLITZ_FOURCC_RGB; pf.masks.bpp = masks.bpp; pf.masks.alpha_mask = masks.alpha_mask; - pf.masks.red_mask = masks.red_mask; + pf.masks.red_mask = masks.red_mask; pf.masks.green_mask = masks.green_mask; - pf.masks.blue_mask = masks.blue_mask; + pf.masks.blue_mask = masks.blue_mask; pf.xoffset = 0; pf.skip_lines = 0; /* XXX: we should eventually return images with negative stride, need to verify that libpixman have no problem with this first. */ - pf.bytes_per_line = ((masks.bpp * width + 7) / 8 + STRIDE_ALIGNMENT - 1) & ~(STRIDE_ALIGNMENT - 1); + pf.bytes_per_line = image->stride; pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; - pixels = _cairo_malloc_ab (height, pf.bytes_per_line); - if (!pixels) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - buffer = glitz_buffer_create_for_data (pixels); - if (!buffer) { - free (pixels); + buffer = glitz_buffer_create_for_data (image->data); + if (buffer == NULL) { + cairo_surface_destroy (&image->base); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -248,83 +215,24 @@ _cairo_glitz_surface_get_image (cairo_glitz_surface_t *surface, 0, 0, NULL, 0); glitz_get_pixels (surface->surface, - x1, y1, - width, height, + extents.x, extents.y, + extents.width, extents.height, &pf, buffer); glitz_buffer_destroy (buffer); /* restore the clip, if any */ - if (surface->has_clip) - glitz_surface_set_clip_region (surface->surface, 0, 0, + if (surface->has_clip) { + glitz_surface_set_clip_region (surface->surface, + 0, 0, surface->clip_boxes, surface->num_clip_boxes); - - if (! _pixman_format_from_masks (&masks, &pixman_format)) - { - status = _cairo_error (CAIRO_STATUS_INVALID_FORMAT); - goto FAIL; - } - - image = (cairo_image_surface_t*) - _cairo_image_surface_create_with_pixman_format ((unsigned char *) pixels, - pixman_format, - width, - height, - pf.bytes_per_line); - if (image->base.status) - { - status = image->base.status; - goto FAIL; } - _cairo_image_surface_assume_ownership_of_data (image); - *image_out = image; return CAIRO_STATUS_SUCCESS; - - FAIL: - free (pixels); - return status; -} - -static void -cairo_format_get_masks (cairo_format_t format, - uint32_t *bpp, - uint32_t *alpha, - uint32_t *red, - uint32_t *green, - uint32_t *blue) -{ - *red = 0x0; - *green = 0x0; - *blue = 0x0; - *alpha = 0x0; - - switch (format) - { - case CAIRO_FORMAT_ARGB32: - *alpha = 0xff000000; - case CAIRO_FORMAT_RGB24: - default: - *bpp = 32; - *red = 0x00ff0000; - *green = 0x0000ff00; - *blue = 0x000000ff; - break; - - case CAIRO_FORMAT_A8: - *bpp = 8; - *alpha = 0xff; - break; - - case CAIRO_FORMAT_A1: - *bpp = 1; - *alpha = 0x1; - break; - } } static cairo_status_t @@ -340,36 +248,33 @@ _cairo_glitz_surface_set_image (void *abstract_surface, cairo_glitz_surface_t *surface = abstract_surface; glitz_buffer_t *buffer; glitz_pixel_format_t pf; - uint32_t bpp, am, rm, gm, bm; + cairo_format_masks_t masks; char *data; - cairo_format_get_masks (image->format, &bpp, &am, &rm, &gm, &bm); + _pixman_format_to_masks (image->pixman_format, &masks); pf.fourcc = GLITZ_FOURCC_RGB; - pf.masks.bpp = bpp; - pf.masks.alpha_mask = am; - pf.masks.red_mask = rm; - pf.masks.green_mask = gm; - pf.masks.blue_mask = bm; + pf.masks.bpp = masks.bpp; + pf.masks.alpha_mask = masks.alpha_mask; + pf.masks.red_mask = masks.red_mask; + pf.masks.green_mask = masks.green_mask; + pf.masks.blue_mask = masks.blue_mask; pf.xoffset = src_x; pf.skip_lines = src_y; /* check for negative stride */ - if (image->stride < 0) - { + if (image->stride < 0) { pf.bytes_per_line = -image->stride; pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; data = (char *) image->data + image->stride * (image->height - 1); - } - else - { + } else { pf.bytes_per_line = image->stride; pf.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; data = (char *) image->data; } buffer = glitz_buffer_create_for_data (data); - if (!buffer) + if (buffer == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); glitz_set_pixels (surface->surface, @@ -473,46 +378,27 @@ _cairo_glitz_surface_clone_similar (void *abstract_surface, else if (_cairo_surface_is_image (src)) { cairo_image_surface_t *image_src = (cairo_image_surface_t *) src; - cairo_content_t content; - cairo_rectangle_int_t image_extent; - cairo_rectangle_int_t extent; - - content = _cairo_content_from_format (image_src->format); clone = (cairo_glitz_surface_t *) - _cairo_glitz_surface_create_similar (surface, content, - image_src->width, - image_src->height); + _cairo_glitz_surface_create_similar (surface, src->content, + width, height); if (clone == NULL) return CAIRO_INT_STATUS_UNSUPPORTED; if (clone->base.status) return clone->base.status; - image_extent.x = 0; - image_extent.y = 0; - image_extent.width = image_src->width; - image_extent.height = image_src->height; - extent.x = src_x; - extent.y = src_y; - extent.width = width; - extent.height = height; - - if (_cairo_rectangle_intersect (&extent, &image_extent)) - { - status = _cairo_glitz_surface_set_image (clone, image_src, - extent.x, extent.y, - extent.width, extent.height, - extent.x, extent.y); - if (status) { - cairo_surface_destroy (&clone->base); - return status; - } + status = _cairo_glitz_surface_set_image (clone, image_src, + src_x, src_y, + width, height, + 0, 0); + if (status) { + cairo_surface_destroy (&clone->base); + return status; } *clone_out = &clone->base; - *clone_offset_x = 0; - *clone_offset_y = 0; - + *clone_offset_x = src_x; + *clone_offset_y = src_y; return CAIRO_STATUS_SUCCESS; } @@ -1113,23 +999,29 @@ _cairo_glitz_surface_fill_rectangles (void *abstract_dst, } switch (op) { + case CAIRO_OPERATOR_CLEAR: case CAIRO_OPERATOR_SOURCE: { glitz_color_t glitz_color; + glitz_format_t *format; glitz_color.red = color->red_short; glitz_color.green = color->green_short; glitz_color.blue = color->blue_short; glitz_color.alpha = color->alpha_short; + /* + * XXX even if the dst surface don't have an alpha channel, the + * above alpha still effect the dst surface because the + * underlying glitz drawable may have an alpha channel. So + * replacing the color with an opaque one is needed. + */ + format = glitz_surface_get_format (dst->surface); + if (format->color.alpha_size == 0) + glitz_color.alpha = 0xffff; + glitz_set_rectangles (dst->surface, &glitz_color, glitz_rects, n_rects); } break; - case CAIRO_OPERATOR_CLEAR: { - static const glitz_color_t glitz_color = { 0, 0, 0, 0 }; - - glitz_set_rectangles (dst->surface, &glitz_color, - glitz_rects, n_rects); - } break; case CAIRO_OPERATOR_SATURATE: return CAIRO_INT_STATUS_UNSUPPORTED; case CAIRO_OPERATOR_OVER: @@ -1206,8 +1098,6 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, cairo_trapezoid_t *traps, int n_traps) { - cairo_pattern_union_t tmp_src_pattern; - const cairo_pattern_t *src_pattern; cairo_glitz_surface_attributes_t attributes; cairo_glitz_surface_t *dst = abstract_dst; cairo_glitz_surface_t *src; @@ -1216,10 +1106,22 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, void *data = NULL; cairo_int_status_t status; unsigned short alpha; - pixman_trapezoid_t stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)]; - pixman_trapezoid_t *pixman_traps = stack_traps; + pixman_trapezoid_t stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)]; + pixman_trapezoid_t *pixman_traps = stack_traps; int i; + if (antialias != CAIRO_ANTIALIAS_DEFAULT && + antialias != CAIRO_ANTIALIAS_GRAY) + { + return CAIRO_INT_STATUS_UNSUPPORTED; + } + + if (op == CAIRO_OPERATOR_SATURATE) + return CAIRO_INT_STATUS_UNSUPPORTED; + + if (_glitz_ensure_target (dst->surface)) + return CAIRO_INT_STATUS_UNSUPPORTED; + /* Convert traps to pixman traps */ if (n_traps > ARRAY_LENGTH (stack_traps)) { pixman_traps = _cairo_malloc_ab (n_traps, sizeof (pixman_trapezoid_t)); @@ -1240,59 +1142,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, pixman_traps[i].right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y); } - if (antialias != CAIRO_ANTIALIAS_DEFAULT && - antialias != CAIRO_ANTIALIAS_GRAY) - { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto finish; - } - - if (dst->base.status) - { - status = dst->base.status; - goto finish; - } - - if (op == CAIRO_OPERATOR_SATURATE) - { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto finish; - } - - if (_glitz_ensure_target (dst->surface)) - { - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto finish; - } - - if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) - { - status = _cairo_pattern_init_copy (&tmp_src_pattern.base, pattern); - if (status) - goto finish; + status = _cairo_glitz_pattern_acquire_surface (pattern, dst, + src_x, src_y, + width, height, + &src, &attributes); + if (status) + goto FAIL; - status = _cairo_glitz_pattern_acquire_surface (&tmp_src_pattern.base, - dst, - src_x, src_y, - width, height, - &src, &attributes); - src_pattern = &tmp_src_pattern.base; - } - else - { - status = _cairo_glitz_pattern_acquire_surface (pattern, dst, - src_x, src_y, - width, height, - &src, &attributes); - src_pattern = pattern; - } alpha = 0xffff; - if (status) - goto finish; - - if (op == CAIRO_OPERATOR_ADD || n_traps <= 1) - { + if (op == CAIRO_OPERATOR_ADD || n_traps <= 1) { static const glitz_color_t clear_black = { 0, 0, 0, 0 }; glitz_color_t color; glitz_geometry_format_t format; @@ -1314,19 +1173,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, CAIRO_CONTENT_ALPHA, 2, 1); if (mask == NULL) { - _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes); - if (src_pattern == &tmp_src_pattern.base) - _cairo_pattern_fini (&tmp_src_pattern.base); - status = CAIRO_INT_STATUS_UNSUPPORTED; - goto finish; + status = CAIRO_INT_STATUS_UNSUPPORTED; + goto FAIL; } if (mask->base.status) { - _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes); - if (src_pattern == &tmp_src_pattern.base) - _cairo_pattern_fini (&tmp_src_pattern.base); - status = mask->base.status; - goto finish; + goto FAIL; } color.red = color.green = color.blue = color.alpha = 0xffff; @@ -1341,21 +1193,15 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, size *= format.vertex.bytes_per_vertex; - while (n_traps) - { - if (data_size < size) - { + while (n_traps) { + if (data_size < size) { void *p; + data_size = size; p = realloc (data, data_size); - if (!p) - { - _cairo_glitz_pattern_release_surface (src_pattern, src, - &attributes); - if (src_pattern == &tmp_src_pattern.base) - _cairo_pattern_fini (&tmp_src_pattern.base); + if (p == NULL) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto finish; + goto FAIL; } data = p; @@ -1363,14 +1209,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, glitz_buffer_destroy (buffer); buffer = glitz_buffer_create_for_data (data); - if (!buffer) { - free (data); - _cairo_glitz_pattern_release_surface (src_pattern, src, - &attributes); - if (src_pattern == &tmp_src_pattern.base) - _cairo_pattern_fini (&tmp_src_pattern.base); + if (buffer == NULL) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto finish; + free (data); + goto FAIL; } } @@ -1392,22 +1234,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, glitz_set_array (dst->surface, 0, 3, offset / format.vertex.bytes_per_vertex, 0, 0); - } - else - { + } else { cairo_image_surface_t *image; unsigned char *ptr; int stride; stride = (width + 3) & -4; data = calloc (stride, height); - if (!data) - { - _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes); - if (src_pattern == &tmp_src_pattern.base) - _cairo_pattern_fini (&tmp_src_pattern.base); + if (data == NULL) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto finish; + goto FAIL; } /* using negative stride */ @@ -1418,12 +1254,10 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, CAIRO_FORMAT_A8, width, height, -stride); - if (image->base.status) - { - cairo_surface_destroy (&src->base); + status = image->base.status; + if (status) { free (data); - status = image->base.status; - goto finish; + goto FAIL; } pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y, @@ -1433,21 +1267,20 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, _cairo_surface_create_similar_scratch (&dst->base, CAIRO_CONTENT_ALPHA, width, height); - if (mask->base.status) { - _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes); + status = mask->base.status; + if (status) { free (data); cairo_surface_destroy (&image->base); - status = mask->base.status; - goto finish; + goto FAIL; } status = _cairo_glitz_surface_set_image (mask, image, 0, 0, width, height, 0, 0); - cairo_surface_destroy(&image->base); + cairo_surface_destroy (&image->base); if (status) - goto finish; + goto FAIL; } _cairo_glitz_surface_set_attributes (src, &attributes); @@ -1474,18 +1307,16 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, free (data); - if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED) + if (glitz_surface_get_status (dst->surface) == GLITZ_STATUS_NOT_SUPPORTED) { status = CAIRO_INT_STATUS_UNSUPPORTED; + goto FAIL; + } - if (status == CAIRO_STATUS_SUCCESS && ! _cairo_operator_bounded_by_mask (op)) - { - int src_width, src_height; - - src_width = glitz_surface_get_width (src->surface); - src_height = glitz_surface_get_height (src->surface); + if (! _cairo_operator_bounded_by_mask (op)) { status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base, &attributes.base, - src_width, src_height, + glitz_surface_get_width (src->surface), + glitz_surface_get_height (src->surface), width, height, src_x, src_y, 0, 0, @@ -1493,14 +1324,12 @@ _cairo_glitz_surface_composite_trapezoids (cairo_operator_t op, width, height); } - _cairo_glitz_pattern_release_surface (src_pattern, src, &attributes); - if (src_pattern == &tmp_src_pattern.base) - _cairo_pattern_fini (&tmp_src_pattern.base); +FAIL: + _cairo_glitz_pattern_release_surface (pattern, src, &attributes); - if (mask) + if (mask != NULL) cairo_surface_destroy (&mask->base); -finish: if (pixman_traps != stack_traps) free (pixman_traps); @@ -1513,33 +1342,23 @@ _cairo_glitz_surface_set_clip_region (void *abstract_surface, { cairo_glitz_surface_t *surface = abstract_surface; - if (region) - { - glitz_box_t *box; - int n; + if (region != NULL) { cairo_status_t status; - status = _cairo_glitz_get_boxes_from_region (region, &box, &n); + status = _cairo_glitz_get_boxes_from_region (region, + &surface->clip_boxes, + &surface->num_clip_boxes); if (status) - return status; - - if (surface->has_clip) - free (surface->clip_boxes); - - glitz_surface_set_clip_region (surface->surface, 0, 0, box, n); + return status; + glitz_surface_set_clip_region (surface->surface, + 0, 0, + surface->clip_boxes, + surface->num_clip_boxes); surface->has_clip = TRUE; - surface->clip_boxes = box; - surface->num_clip_boxes = n; - } - else - { + } else { glitz_surface_set_clip_region (surface->surface, 0, 0, NULL, 0); - - if (surface->has_clip) { - free (surface->clip_boxes); - surface->has_clip = FALSE; - } + surface->has_clip = FALSE; } return CAIRO_STATUS_SUCCESS; @@ -1553,7 +1372,7 @@ _cairo_glitz_surface_get_extents (void *abstract_surface, rectangle->x = 0; rectangle->y = 0; - rectangle->width = glitz_surface_get_width (surface->surface); + rectangle->width = glitz_surface_get_width (surface->surface); rectangle->height = glitz_surface_get_height (surface->surface); return CAIRO_STATUS_SUCCESS; @@ -2474,6 +2293,8 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = { _cairo_glitz_surface_composite, _cairo_glitz_surface_fill_rectangles, _cairo_glitz_surface_composite_trapezoids, + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ _cairo_glitz_surface_set_clip_region, @@ -2535,14 +2356,17 @@ cairo_glitz_surface_create (glitz_surface_t *surface) format = glitz_surface_get_format (surface); _cairo_surface_init (&crsurface->base, &cairo_glitz_surface_backend, - _glitz_format_to_content(format)); + _glitz_format_to_content (format)); glitz_surface_reference (surface); crsurface->surface = surface; crsurface->format = format; - crsurface->has_clip = FALSE; - return (cairo_surface_t *) crsurface; + crsurface->has_clip = FALSE; + crsurface->clip_boxes = NULL; + crsurface->num_clip_boxes = 0; + + return &crsurface->base; } slim_hidden_def (cairo_glitz_surface_create); diff --git a/src/cairo-gstate-private.h b/src/cairo-gstate-private.h index 25900482..94043a1e 100644 --- a/src/cairo-gstate-private.h +++ b/src/cairo-gstate-private.h @@ -66,6 +66,9 @@ struct _cairo_gstate { cairo_pattern_t *source; struct _cairo_gstate *next; + + int n_damage_regions; + cairo_region_t *damage_regions; }; #endif /* CAIRO_GSTATE_PRIVATE_H */ diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c index 2c149677..cfea1a2c 100644 --- a/src/cairo-gstate.c +++ b/src/cairo-gstate.c @@ -105,6 +105,9 @@ _cairo_gstate_init (cairo_gstate_t *gstate, gstate->source = (cairo_pattern_t *) &_cairo_pattern_black.base; + gstate->n_damage_regions = 0; + gstate->damage_regions = NULL; + /* Now that the gstate is fully initialized and ready for the eventual * _cairo_gstate_fini(), we can check for errors (and not worry about * the resource deallocation). */ @@ -113,11 +116,11 @@ _cairo_gstate_init (cairo_gstate_t *gstate, return _cairo_error (CAIRO_STATUS_NULL_POINTER); status = target->status; - if (status) + if (unlikely (status)) return status; status = gstate->source->status; - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -142,7 +145,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) status = _cairo_stroke_style_init_copy (&gstate->stroke_style, &other->stroke_style); - if (status) + if (unlikely (status)) return status; gstate->fill_rule = other->fill_rule; @@ -155,7 +158,7 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other) _cairo_font_options_init_copy (&gstate->font_options , &other->font_options); status = _cairo_clip_init_copy (&gstate->clip, &other->clip); - if (status) { + if (unlikely (status)) { _cairo_stroke_style_fini (&gstate->stroke_style); cairo_font_face_destroy (gstate->font_face); cairo_scaled_font_destroy (gstate->scaled_font); @@ -221,13 +224,13 @@ _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist) top = *freelist; if (top == NULL) { top = malloc (sizeof (cairo_gstate_t)); - if (top == NULL) + if (unlikely (top == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } else *freelist = top->next; status = _cairo_gstate_init_copy (top, *gstate); - if (status) { + if (unlikely (status)) { top->next = *freelist; *freelist = top; return status; @@ -297,7 +300,7 @@ _cairo_gstate_redirect_target (cairo_gstate_t *gstate, cairo_surface_t *child) _cairo_clip_reset (&gstate->clip); status = _cairo_clip_init_deep_copy (&gstate->clip, &gstate->next->clip, child); - if (status) + if (unlikely (status)) return status; /* The clip is in surface backend coordinates for the previous target; @@ -512,7 +515,7 @@ _cairo_gstate_set_dash (cairo_gstate_t *gstate, const double *dash, int num_dash } gstate->stroke_style.dash = _cairo_malloc_ab (gstate->stroke_style.num_dashes, sizeof (double)); - if (gstate->stroke_style.dash == NULL) { + if (unlikely (gstate->stroke_style.dash == NULL)) { gstate->stroke_style.num_dashes = 0; return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -668,7 +671,7 @@ _cairo_gstate_transform (cairo_gstate_t *gstate, tmp = *matrix; status = cairo_matrix_invert (&tmp); - if (status) + if (unlikely (status)) return status; _cairo_gstate_unset_scaled_font (gstate); @@ -827,7 +830,7 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, if (_cairo_surface_has_device_transform (surface)) { status = _cairo_pattern_init_copy (*pattern, original); - if (status) + if (unlikely (status)) return status; have_copy = TRUE; @@ -839,7 +842,7 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate, if (! _cairo_matrix_is_identity (ctm_inverse)) { if (! have_copy) { status = _cairo_pattern_init_copy (*pattern, original); - if (status) + if (unlikely (status)) return status; have_copy = TRUE; @@ -884,12 +887,12 @@ _cairo_gstate_paint (cairo_gstate_t *gstate) return gstate->source->status; status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (status) + if (unlikely (status)) return status; pattern = &pattern_stack.base; status = _cairo_gstate_copy_transformed_source (gstate, &pattern); - if (status) + if (unlikely (status)) return status; status = _cairo_surface_paint (gstate->target, @@ -917,17 +920,17 @@ _cairo_gstate_mask (cairo_gstate_t *gstate, return gstate->source->status; status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (status) + if (unlikely (status)) return status; source_pattern = &source_pattern_stack.base; status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern); - if (status) + if (unlikely (status)) return status; mask_pattern = &mask_pattern_stack.base; status = _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern, mask); - if (status) + if (unlikely (status)) goto CLEANUP_SOURCE; status = _cairo_surface_mask (gstate->target, @@ -958,13 +961,13 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path) return CAIRO_STATUS_SUCCESS; status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (status) + if (unlikely (status)) return status; source_pattern = &source_pattern_stack.base; status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern); - if (status) + if (unlikely (status)) return status; status = _cairo_surface_stroke (gstate->target, @@ -1015,7 +1018,7 @@ _cairo_gstate_in_stroke (cairo_gstate_t *gstate, &gstate->ctm_inverse, gstate->tolerance, &traps); - if (status) + if (unlikely (status)) goto BAIL; *inside_ret = _cairo_traps_contain (&traps, x, y); @@ -1037,12 +1040,12 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path) return gstate->source->status; status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (status) + if (unlikely (status)) return status; pattern = &pattern_stack.base; status = _cairo_gstate_copy_transformed_source (gstate, &pattern); - if (status) + if (unlikely (status)) return status; status = _cairo_surface_fill (gstate->target, @@ -1323,7 +1326,7 @@ _cairo_gstate_int_clip_extents (cairo_gstate_t *gstate, cairo_status_t status; status = _cairo_surface_get_extents (gstate->target, extents); - if (status) + if (unlikely (status)) return status; status = _cairo_clip_intersect_to_rectangle (&gstate->clip, extents); @@ -1343,7 +1346,7 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate, cairo_status_t status; status = _cairo_gstate_int_clip_extents (gstate, &extents); - if (status) + if (unlikely (status)) return status; px1 = extents.x; @@ -1462,7 +1465,7 @@ _cairo_gstate_get_font_face (cairo_gstate_t *gstate, cairo_status_t status; status = _cairo_gstate_ensure_font_face (gstate); - if (status) + if (unlikely (status)) return status; *font_face = gstate->font_face; @@ -1477,7 +1480,7 @@ _cairo_gstate_get_scaled_font (cairo_gstate_t *gstate, cairo_status_t status; status = _cairo_gstate_ensure_scaled_font (gstate); - if (status) + if (unlikely (status)) return status; *scaled_font = gstate->scaled_font; @@ -1593,7 +1596,7 @@ _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate) return gstate->scaled_font->status; status = _cairo_gstate_ensure_font_face (gstate); - if (status) + if (unlikely (status)) return status; cairo_surface_get_font_options (gstate->target, &options); @@ -1605,7 +1608,7 @@ _cairo_gstate_ensure_scaled_font (cairo_gstate_t *gstate) &options); status = cairo_scaled_font_status (scaled_font); - if (status) + if (unlikely (status)) return status; gstate->scaled_font = scaled_font; @@ -1618,7 +1621,7 @@ _cairo_gstate_get_font_extents (cairo_gstate_t *gstate, cairo_font_extents_t *extents) { cairo_status_t status = _cairo_gstate_ensure_scaled_font (gstate); - if (status) + if (unlikely (status)) return status; cairo_scaled_font_extents (gstate->scaled_font, extents); @@ -1641,7 +1644,7 @@ _cairo_gstate_text_to_glyphs (cairo_gstate_t *gstate, cairo_status_t status; status = _cairo_gstate_ensure_scaled_font (gstate); - if (status) + if (unlikely (status)) return status; return cairo_scaled_font_text_to_glyphs (gstate->scaled_font, x, y, @@ -1678,7 +1681,7 @@ _cairo_gstate_glyph_extents (cairo_gstate_t *gstate, cairo_status_t status; status = _cairo_gstate_ensure_scaled_font (gstate); - if (status) + if (unlikely (status)) return status; cairo_scaled_font_glyph_extents (gstate->scaled_font, @@ -1708,18 +1711,18 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, return gstate->source->status; status = _cairo_surface_set_clip (gstate->target, &gstate->clip); - if (status) + if (unlikely (status)) return status; status = _cairo_gstate_ensure_scaled_font (gstate); - if (status) + if (unlikely (status)) return status; if (num_glyphs <= ARRAY_LENGTH (stack_transformed_glyphs)) { transformed_glyphs = stack_transformed_glyphs; } else { transformed_glyphs = cairo_glyph_allocate (num_glyphs); - if (transformed_glyphs == NULL) + if (unlikely (transformed_glyphs == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -1733,7 +1736,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate, source_pattern = &source_pattern_stack.base; status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern); - if (status) + if (unlikely (status)) goto CLEANUP_GLYPHS; /* Just in case */ @@ -1802,21 +1805,22 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)]; status = _cairo_gstate_ensure_scaled_font (gstate); - if (status) + if (unlikely (status)) return status; - if (num_glyphs < ARRAY_LENGTH (stack_transformed_glyphs)) + if (num_glyphs < ARRAY_LENGTH (stack_transformed_glyphs)) { transformed_glyphs = stack_transformed_glyphs; - else - transformed_glyphs = cairo_glyph_allocate (num_glyphs); - if (transformed_glyphs == NULL) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } else { + transformed_glyphs = cairo_glyph_allocate (num_glyphs); + if (unlikely (transformed_glyphs == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } status = _cairo_gstate_transform_glyphs_to_backend (gstate, glyphs, num_glyphs, transformed_glyphs, NULL); - if (status) + if (unlikely (status)) goto CLEANUP_GLYPHS; status = _cairo_scaled_font_glyph_path (gstate->scaled_font, @@ -1976,3 +1980,73 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate, return CAIRO_STATUS_SUCCESS; } + +static cairo_status_t +allocate_regions (cairo_gstate_t *gstate, + int n_regions) +{ + cairo_region_t *regions; + int pot = 1; + + while (pot <= n_regions && pot > 0) + pot *= 2; + + if (pot < 0) + return CAIRO_STATUS_NO_MEMORY; + + regions = _cairo_realloc_ab ( + gstate->damage_regions, pot, sizeof (cairo_region_t)); + + if (!regions) + return CAIRO_STATUS_NO_MEMORY; + + gstate->n_damage_regions = n_regions; + gstate->damage_regions = regions; + + return CAIRO_STATUS_SUCCESS; +} + +cairo_status_t +_cairo_gtate_begin_damage_tracking (cairo_gstate_t *gstate) +{ + int last = gstate->n_damage_regions; + cairo_status_t status; + + status = allocate_regions (gstate, last + 1); + if (status != CAIRO_STATUS_SUCCESS) + return status; + + _cairo_region_init (&(gstate->damage_regions[last])); + + return CAIRO_STATUS_SUCCESS; +} + +cairo_status_t +_cairo_gstate_end_damage_tracking (cairo_gstate_t *gstate, + int *n_rectangles, + cairo_rectangle_t **rectangles) +{ + int last = gstate->n_damage_regions - 1; + cairo_region_t result; + cairo_status_t status; + + if (last > 0) + { + status = _cairo_region_union (&gstate->damage_regions[last - 1], + &gstate->damage_regions[last - 1], + &gstate->damage_regions[last]); + + if (status != CAIRO_STATUS_SUCCESS) + return status; + } + + result = gstate->damage_regions[last]; + + allocate_regions (gstate, gstate->n_damage_regions - 1); + + /* FIXME - do something with result, such as turning it into + * a list of rectangles. + */ + return CAIRO_STATUS_SUCCESS; +} + diff --git a/src/cairo-hash.c b/src/cairo-hash.c index b3f43b05..973281d4 100644 --- a/src/cairo-hash.c +++ b/src/cairo-hash.c @@ -148,7 +148,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal) cairo_hash_table_t *hash_table; hash_table = malloc (sizeof (cairo_hash_table_t)); - if (hash_table == NULL) { + if (unlikely (hash_table == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return NULL; } @@ -159,7 +159,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal) hash_table->entries = calloc (hash_table->arrangement->size, sizeof(cairo_hash_entry_t *)); - if (hash_table->entries == NULL) { + if (unlikely (hash_table->entries == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); free (hash_table); return NULL; @@ -280,7 +280,7 @@ _cairo_hash_table_resize (cairo_hash_table_t *hash_table) new_size = tmp.arrangement->size; tmp.entries = calloc (new_size, sizeof (cairo_hash_entry_t*)); - if (tmp.entries == NULL) + if (unlikely (tmp.entries == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); for (i = 0; i < hash_table->arrangement->size; ++i) { diff --git a/src/cairo-hull.c b/src/cairo-hull.c index 008ba7fd..a699a524 100644 --- a/src/cairo-hull.c +++ b/src/cairo-hull.c @@ -200,7 +200,7 @@ _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices) if (num_hull > ARRAY_LENGTH (hull_stack)) { hull = _cairo_malloc_ab (num_hull, sizeof (cairo_hull_t)); - if (hull == NULL) + if (unlikely (hull == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } else { hull = hull_stack; diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index 5174f145..9b768e57 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -131,7 +131,7 @@ _cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image, cairo_image_surface_t *surface; surface = malloc (sizeof (cairo_image_surface_t)); - if (surface == NULL) + if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&surface->base, &_cairo_image_surface_backend, @@ -203,7 +203,7 @@ _pixman_format_from_masks (cairo_format_masks_t *masks, } /* A mask consisting of N bits set to 1. */ -#define MASK(N) ((1 << (N))-1) +#define MASK(N) ((1UL << (N))-1) void _pixman_format_to_masks (pixman_format_code_t format, @@ -327,7 +327,7 @@ _cairo_image_surface_create_with_pixman_format (unsigned char *data, pixman_image = pixman_image_create_bits (pixman_format, width, height, (uint32_t *) data, stride); - if (pixman_image == NULL) + if (unlikely (pixman_image == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); surface = _cairo_image_surface_create_for_pixman_image (pixman_image, @@ -867,7 +867,7 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface, status = _cairo_image_surface_set_matrix (surface, &attributes->matrix, xc, yc); - if (status) + if (unlikely (status)) return status; switch (attributes->extend) { @@ -886,7 +886,7 @@ _cairo_image_surface_set_attributes (cairo_image_surface_t *surface, } status = _cairo_image_surface_set_filter (surface, attributes->filter); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -965,13 +965,13 @@ _cairo_image_surface_composite (cairo_operator_t op, (cairo_surface_t **) &src, (cairo_surface_t **) &mask, &src_attr, &mask_attr); - if (status) + if (unlikely (status)) return status; status = _cairo_image_surface_set_attributes (src, &src_attr, dst_x + width / 2., dst_y + height / 2.); - if (status) + if (unlikely (status)) goto CLEANUP_SURFACES; if (mask) @@ -979,7 +979,7 @@ _cairo_image_surface_composite (cairo_operator_t op, status = _cairo_image_surface_set_attributes (mask, &mask_attr, dst_x + width / 2., dst_y + height / 2.); - if (status) + if (unlikely (status)) goto CLEANUP_SURFACES; pixman_image_composite (_pixman_operator (op), @@ -1048,7 +1048,7 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface, if (num_rects > ARRAY_LENGTH (stack_rects)) { pixman_rects = _cairo_malloc_ab (num_rects, sizeof (pixman_rectangle16_t)); - if (pixman_rects == NULL) + if (unlikely (pixman_rects == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -1075,6 +1075,15 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface, return status; } +static cairo_format_t +_cairo_mask_format_from_antialias (cairo_antialias_t antialias) +{ + if (antialias == CAIRO_ANTIALIAS_NONE) + return CAIRO_FORMAT_A1; + return CAIRO_FORMAT_A8; +} + + static cairo_int_status_t _cairo_image_surface_composite_trapezoids (cairo_operator_t op, const cairo_pattern_t *pattern, @@ -1092,13 +1101,10 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, cairo_surface_attributes_t attributes; cairo_image_surface_t *dst = abstract_dst; cairo_image_surface_t *src; - cairo_int_status_t status; - pixman_image_t *mask; - pixman_format_code_t format; - uint32_t *mask_data; + cairo_int_status_t status; + cairo_image_surface_t *mask = NULL; pixman_trapezoid_t stack_traps[CAIRO_STACK_ARRAY_LENGTH (pixman_trapezoid_t)]; pixman_trapezoid_t *pixman_traps = stack_traps; - int mask_stride; int i; if (height == 0 || width == 0) @@ -1107,7 +1113,7 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, /* Convert traps to pixman traps */ if (num_traps > ARRAY_LENGTH (stack_traps)) { pixman_traps = _cairo_malloc_ab (num_traps, sizeof (pixman_trapezoid_t)); - if (pixman_traps == NULL) + if (unlikely (pixman_traps == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -1153,49 +1159,28 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, src_x, src_y, width, height, (cairo_surface_t **) &src, &attributes); - if (status) + if (unlikely (status)) goto finish; status = _cairo_image_surface_set_attributes (src, &attributes, dst_x + width / 2., dst_y + height / 2.); - if (status) + if (unlikely (status)) goto CLEANUP_SOURCE; - switch (antialias) { - case CAIRO_ANTIALIAS_NONE: - format = PIXMAN_a1; - mask_stride = ((width + 31) / 8) & ~0x03; - break; - case CAIRO_ANTIALIAS_GRAY: - case CAIRO_ANTIALIAS_SUBPIXEL: - case CAIRO_ANTIALIAS_DEFAULT: - default: - format = PIXMAN_a8; - mask_stride = (width + 3) & ~3; - break; - } - - /* The image must be initially transparent */ - mask_data = calloc (mask_stride, height); - if (mask_data == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + mask = (cairo_image_surface_t *) + cairo_image_surface_create ( + _cairo_mask_format_from_antialias (antialias), + width, height); + if (cairo_surface_status (&mask->base) != CAIRO_STATUS_SUCCESS) goto CLEANUP_SOURCE; - } - mask = pixman_image_create_bits (format, width, height, - mask_data, mask_stride); - if (mask == NULL) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto CLEANUP_IMAGE_DATA; - } - - pixman_add_trapezoids (mask, - dst_x, - dst_y, + pixman_add_trapezoids (mask->pixman_image, - dst_x, - dst_y, num_traps, pixman_traps); pixman_image_composite (_pixman_operator (op), src->pixman_image, - mask, + mask->pixman_image, dst->pixman_image, src_x + attributes.x_offset, src_y + attributes.y_offset, @@ -1205,15 +1190,13 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, if (! _cairo_operator_bounded_by_mask (op)) status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base, - &attributes, src->width, src->height, + &attributes, + src->width, src->height, width, height, src_x, src_y, 0, 0, dst_x, dst_y, width, height); - pixman_image_unref (mask); - - CLEANUP_IMAGE_DATA: - free (mask_data); + cairo_surface_destroy (&mask->base); CLEANUP_SOURCE: _cairo_pattern_release_surface (pattern, &src->base, &attributes); @@ -1225,6 +1208,216 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op, return status; } +typedef struct _cairo_image_surface_span_renderer { + cairo_span_renderer_t base; + + cairo_operator_t op; + const cairo_pattern_t *pattern; + cairo_antialias_t antialias; + + cairo_image_surface_t *src; + cairo_surface_attributes_t src_attributes; + cairo_image_surface_t *mask; + cairo_image_surface_t *dst; + + cairo_composite_rectangles_t composite_rectangles; +} cairo_image_surface_span_renderer_t; + +static cairo_status_t +_cairo_image_surface_span_renderer_render_row ( + void *abstract_renderer, + int y, + const cairo_half_open_span_t *spans, + unsigned num_spans) +{ + cairo_image_surface_span_renderer_t *renderer = abstract_renderer; + int xmin = renderer->composite_rectangles.mask.x; + int xmax = xmin + renderer->composite_rectangles.width; + uint8_t *row; + int prev_x = xmin; + int prev_alpha = 0; + unsigned i; + + /* Make sure we're within y-range. */ + y -= renderer->composite_rectangles.mask.y; + if (y < 0 || y >= renderer->composite_rectangles.height) + return CAIRO_STATUS_SUCCESS; + + row = (uint8_t*)(renderer->mask->data) + y*(size_t)renderer->mask->stride - xmin; + + /* Find the first span within x-range. */ + for (i=0; i < num_spans && spans[i].x < xmin; i++) {} + if (i>0) + prev_alpha = spans[i-1].coverage; + + /* Set the intermediate spans. */ + for (; i < num_spans; i++) { + int x = spans[i].x; + + if (x >= xmax) + break; + + if (prev_alpha != 0) { + /* We implement setting rendering the most common single + * pixel wide span case to avoid the overhead of a memset + * call. Open coding setting longer spans didn't show a + * noticeable improvement over memset. */ + if (x == prev_x + 1) { + row[prev_x] = prev_alpha; + } + else { + memset(row + prev_x, prev_alpha, x - prev_x); + } + } + + prev_x = x; + prev_alpha = spans[i].coverage; + } + + if (prev_alpha != 0 && prev_x < xmax) { + memset(row + prev_x, prev_alpha, xmax - prev_x); + } + + return CAIRO_STATUS_SUCCESS; +} + +static void +_cairo_image_surface_span_renderer_destroy (void *abstract_renderer) +{ + cairo_image_surface_span_renderer_t *renderer = abstract_renderer; + if (!renderer) return; + + if (renderer->src != NULL) { + _cairo_pattern_release_surface (renderer->pattern, + &renderer->src->base, + &renderer->src_attributes); + } + + if (renderer->mask != NULL) + cairo_surface_destroy (&renderer->mask->base); + + free (renderer); +} + +static cairo_status_t +_cairo_image_surface_span_renderer_finish (void *abstract_renderer) +{ + cairo_image_surface_span_renderer_t *renderer = abstract_renderer; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + + if (renderer->src == NULL || renderer->mask == NULL) + return CAIRO_STATUS_SUCCESS; + + status = cairo_surface_status (&renderer->mask->base); + if (status == CAIRO_STATUS_SUCCESS) { + cairo_composite_rectangles_t *rects = &renderer->composite_rectangles; + cairo_image_surface_t *src = renderer->src; + cairo_image_surface_t *dst = renderer->dst; + cairo_surface_attributes_t *src_attributes = &renderer->src_attributes; + int width = rects->width; + int height = rects->height; + + pixman_image_composite (_pixman_operator (renderer->op), + src->pixman_image, + renderer->mask->pixman_image, + dst->pixman_image, + rects->src.x + src_attributes->x_offset, + rects->src.y + src_attributes->y_offset, + 0, 0, /* mask.x, mask.y */ + rects->dst.x, rects->dst.y, + width, height); + + if (! _cairo_operator_bounded_by_mask (renderer->op)) + status = _cairo_surface_composite_shape_fixup_unbounded ( + &dst->base, + src_attributes, + src->width, src->height, + rects->width, rects->height, + rects->src.x, rects->src.y, + 0, 0, /* mask.x, mask.y */ + rects->dst.x, rects->dst.y, + rects->width, rects->height); + } + if (status != CAIRO_STATUS_SUCCESS) + return _cairo_span_renderer_set_error (abstract_renderer, + status); + return CAIRO_STATUS_SUCCESS; +} + +static cairo_bool_t +_cairo_image_surface_check_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, + void *abstract_dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects) +{ + (void) op; + (void) pattern; + (void) abstract_dst; + (void) antialias; + (void) rects; + return TRUE; +} + +static cairo_span_renderer_t * +_cairo_image_surface_create_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, + void *abstract_dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects) +{ + cairo_image_surface_t *dst = abstract_dst; + cairo_image_surface_span_renderer_t *renderer + = calloc(1, sizeof(*renderer)); + cairo_status_t status; + int width = rects->width; + int height = rects->height; + + if (renderer == NULL) + return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY); + + renderer->base.destroy = _cairo_image_surface_span_renderer_destroy; + renderer->base.finish = _cairo_image_surface_span_renderer_finish; + renderer->base.render_row = + _cairo_image_surface_span_renderer_render_row; + renderer->op = op; + renderer->pattern = pattern; + renderer->antialias = antialias; + renderer->dst = dst; + + renderer->composite_rectangles = *rects; + + status = _cairo_pattern_acquire_surface ( + renderer->pattern, &renderer->dst->base, + rects->src.x, rects->src.y, + width, height, + (cairo_surface_t **) &renderer->src, + &renderer->src_attributes); + if (status) + goto unwind; + + status = _cairo_image_surface_set_attributes ( + renderer->src, &renderer->src_attributes, + rects->dst.x + width/2, rects->dst.y + height/2); + if (status) + goto unwind; + + /* TODO: support rendering to A1 surfaces (or: go add span + * compositing to pixman.) */ + renderer->mask = (cairo_image_surface_t *) + cairo_image_surface_create (CAIRO_FORMAT_A8, + width, height); + + status = cairo_surface_status (&renderer->mask->base); + + unwind: + if (status != CAIRO_STATUS_SUCCESS) { + _cairo_image_surface_span_renderer_destroy (renderer); + return _cairo_span_renderer_create_in_error (status); + } + return &renderer->base; +} + cairo_int_status_t _cairo_image_surface_set_clip_region (void *abstract_surface, cairo_region_t *region) @@ -1300,6 +1493,8 @@ const cairo_surface_backend_t _cairo_image_surface_backend = { _cairo_image_surface_composite, _cairo_image_surface_fill_rectangles, _cairo_image_surface_composite_trapezoids, + _cairo_image_surface_create_span_renderer, + _cairo_image_surface_check_span_renderer, NULL, /* copy_page */ NULL, /* show_page */ _cairo_image_surface_set_clip_region, @@ -1350,7 +1545,7 @@ _cairo_image_surface_clone (cairo_image_surface_t *surface, status = cairo_status (cr); cairo_destroy (cr); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (&clone->base); return (cairo_image_surface_t *) _cairo_surface_create_in_error (status); } diff --git a/src/cairo-lzw.c b/src/cairo-lzw.c index 1241225d..a4fdf738 100644 --- a/src/cairo-lzw.c +++ b/src/cairo-lzw.c @@ -73,7 +73,7 @@ _lzw_buf_init (lzw_buf_t *buf, int size) buf->pending_bits = 0; buf->data = malloc (size); - if (buf->data == NULL) { + if (unlikely (buf->data == NULL)) { buf->data_size = 0; buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); return; @@ -98,7 +98,7 @@ _lzw_buf_grow (lzw_buf_t *buf) if (new_size / 2 == buf->data_size) new_data = realloc (buf->data, new_size); - if (new_data == NULL) { + if (unlikely (new_data == NULL)) { free (buf->data); buf->data_size = 0; buf->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -137,7 +137,7 @@ _lzw_buf_store_bits (lzw_buf_t *buf, uint16_t value, int num_bits) while (buf->pending_bits >= 8) { if (buf->num_data >= buf->data_size) { status = _lzw_buf_grow (buf); - if (status) + if (unlikely (status)) return; } buf->data[buf->num_data++] = buf->pending >> (buf->pending_bits - 8); @@ -167,7 +167,7 @@ _lzw_buf_store_pending (lzw_buf_t *buf) if (buf->num_data >= buf->data_size) { status = _lzw_buf_grow (buf); - if (status) + if (unlikely (status)) return; } diff --git a/src/cairo-matrix.c b/src/cairo-matrix.c index 05589833..6dfe537f 100644 --- a/src/cairo-matrix.c +++ b/src/cairo-matrix.c @@ -879,6 +879,7 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix, *pixman_transform = pixman_identity_transform; } else { cairo_matrix_t inv; + unsigned max_iterations; pixman_transform->matrix[0][0] = _cairo_fixed_16_16_from_double (matrix->xx); pixman_transform->matrix[0][1] = _cairo_fixed_16_16_from_double (matrix->xy); @@ -913,6 +914,7 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix, /* find the pattern space coordinate that maps to (xc, yc) */ xc += .5; yc += .5; /* offset for the pixel centre */ + max_iterations = 5; do { double x,y; pixman_vector_t vector; @@ -942,6 +944,6 @@ _cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix, if (dx == 0 && dy == 0) break; - } while (TRUE); + } while (--max_iterations); } } diff --git a/src/cairo-meta-surface.c b/src/cairo-meta-surface.c index cfaaf304..0f6e6324 100644 --- a/src/cairo-meta-surface.c +++ b/src/cairo-meta-surface.c @@ -84,7 +84,7 @@ _cairo_meta_surface_create (cairo_content_t content, cairo_meta_surface_t *meta; meta = malloc (sizeof (cairo_meta_surface_t)); - if (meta == NULL) + if (unlikely (meta == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&meta->base, &cairo_meta_surface_backend, @@ -197,7 +197,7 @@ _cairo_meta_surface_acquire_source_image (void *abstract_surface, surface->height_pixels); status = _cairo_meta_surface_replay (&surface->base, image); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (image); return status; } @@ -227,7 +227,7 @@ _cairo_meta_surface_paint (void *abstract_surface, cairo_command_paint_t *command; command = malloc (sizeof (cairo_command_paint_t)); - if (command == NULL) + if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_PAINT; @@ -239,11 +239,11 @@ _cairo_meta_surface_paint (void *abstract_surface, command->op = op; status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (status) + if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_array_append (&meta->commands, &command); - if (status) + if (unlikely (status)) goto CLEANUP_SOURCE; /* An optimisation that takes care to not replay what was done @@ -273,7 +273,7 @@ _cairo_meta_surface_mask (void *abstract_surface, cairo_command_mask_t *command; command = malloc (sizeof (cairo_command_mask_t)); - if (command == NULL) + if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_MASK; @@ -285,15 +285,15 @@ _cairo_meta_surface_mask (void *abstract_surface, command->op = op; status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (status) + if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_pattern_init_snapshot (&command->mask.base, mask); - if (status) + if (unlikely (status)) goto CLEANUP_SOURCE; status = _cairo_array_append (&meta->commands, &command); - if (status) + if (unlikely (status)) goto CLEANUP_MASK; return CAIRO_STATUS_SUCCESS; @@ -324,7 +324,7 @@ _cairo_meta_surface_stroke (void *abstract_surface, cairo_command_stroke_t *command; command = malloc (sizeof (cairo_command_stroke_t)); - if (command == NULL) + if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_STROKE; @@ -336,15 +336,15 @@ _cairo_meta_surface_stroke (void *abstract_surface, command->op = op; status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (status) + if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_path_fixed_init_copy (&command->path, path); - if (status) + if (unlikely (status)) goto CLEANUP_SOURCE; status = _cairo_stroke_style_init_copy (&command->style, style); - if (status) + if (unlikely (status)) goto CLEANUP_PATH; command->ctm = *ctm; @@ -353,7 +353,7 @@ _cairo_meta_surface_stroke (void *abstract_surface, command->antialias = antialias; status = _cairo_array_append (&meta->commands, &command); - if (status) + if (unlikely (status)) goto CLEANUP_STYLE; return CAIRO_STATUS_SUCCESS; @@ -384,7 +384,7 @@ _cairo_meta_surface_fill (void *abstract_surface, cairo_command_fill_t *command; command = malloc (sizeof (cairo_command_fill_t)); - if (command == NULL) + if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_FILL; @@ -396,11 +396,11 @@ _cairo_meta_surface_fill (void *abstract_surface, command->op = op; status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (status) + if (unlikely (status)) goto CLEANUP_COMMAND; status = _cairo_path_fixed_init_copy (&command->path, path); - if (status) + if (unlikely (status)) goto CLEANUP_SOURCE; command->fill_rule = fill_rule; @@ -408,7 +408,7 @@ _cairo_meta_surface_fill (void *abstract_surface, command->antialias = antialias; status = _cairo_array_append (&meta->commands, &command); - if (status) + if (unlikely (status)) goto CLEANUP_PATH; return CAIRO_STATUS_SUCCESS; @@ -447,7 +447,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface, cairo_command_show_text_glyphs_t *command; command = malloc (sizeof (cairo_command_show_text_glyphs_t)); - if (command == NULL) + if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_SHOW_TEXT_GLYPHS; @@ -459,7 +459,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface, command->op = op; status = _cairo_pattern_init_snapshot (&command->source.base, source); - if (status) + if (unlikely (status)) goto CLEANUP_COMMAND; command->utf8 = NULL; @@ -471,7 +471,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface, if (utf8_len) { command->utf8 = malloc (utf8_len); - if (command->utf8 == NULL) { + if (unlikely (command->utf8 == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_ARRAYS; } @@ -479,7 +479,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface, } if (num_glyphs) { command->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (glyphs[0])); - if (command->glyphs == NULL) { + if (unlikely (command->glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_ARRAYS; } @@ -487,7 +487,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface, } if (num_clusters) { command->clusters = _cairo_malloc_ab (num_clusters, sizeof (clusters[0])); - if (command->clusters == NULL) { + if (unlikely (command->clusters == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_ARRAYS; } @@ -499,7 +499,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface, command->scaled_font = cairo_scaled_font_reference (scaled_font); status = _cairo_array_append (&meta->commands, &command); - if (status) + if (unlikely (status)) goto CLEANUP_SCALED_FONT; return CAIRO_STATUS_SUCCESS; @@ -537,7 +537,7 @@ _cairo_meta_surface_snapshot (void *abstract_other) cairo_meta_surface_t *meta; meta = malloc (sizeof (cairo_meta_surface_t)); - if (meta == NULL) + if (unlikely (meta == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&meta->base, &cairo_meta_surface_backend, @@ -567,7 +567,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst, cairo_status_t status; command = malloc (sizeof (cairo_command_intersect_clip_path_t)); - if (command == NULL) + if (unlikely (command == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); command->header.type = CAIRO_COMMAND_INTERSECT_CLIP_PATH; @@ -575,7 +575,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst, if (path) { status = _cairo_path_fixed_init_copy (&command->path, path); - if (status) { + if (unlikely (status)) { free (command); return status; } @@ -590,7 +590,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst, command->antialias = antialias; status = _cairo_array_append (&meta->commands, &command); - if (status) { + if (unlikely (status)) { if (path) _cairo_path_fixed_fini (&command->path); free (command); @@ -647,6 +647,8 @@ static const cairo_surface_backend_t cairo_meta_surface_backend = { 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 */ @@ -766,7 +768,7 @@ _cairo_meta_surface_get_path (cairo_surface_t *surface, ASSERT_NOT_REACHED; } - if (status) + if (unlikely (status)) break; } @@ -814,14 +816,14 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface, * ensure the current clip gets set on the surface. */ if (command->header.type != CAIRO_COMMAND_INTERSECT_CLIP_PATH) { status = _cairo_surface_set_clip (target, &clip); - if (status) + if (unlikely (status)) break; } dev_path = _cairo_command_get_path (command); if (dev_path && has_device_transform) { status = _cairo_path_fixed_init_copy (&path_copy, dev_path); - if (status) + if (unlikely (status)) break; _cairo_path_fixed_transform (&path_copy, device_transform); dev_path = &path_copy; @@ -930,7 +932,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface, * copy the array before handing it to the backend. */ dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (dev_glyphs == NULL) { + if (unlikely (dev_glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); break; } @@ -986,7 +988,7 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface, } } - if (status) + if (unlikely (status)) break; } diff --git a/src/cairo-misc.c b/src/cairo-misc.c index 397b0efe..6f707a66 100644 --- a/src/cairo-misc.c +++ b/src/cairo-misc.c @@ -287,7 +287,7 @@ _cairo_validate_text_clusters (const char *utf8, /* Make sure we've got valid UTF-8 for the cluster */ status = _cairo_utf8_to_ucs4 (utf8+n_bytes, cluster_bytes, NULL, NULL); - if (status) + if (unlikely (status)) return CAIRO_STATUS_INVALID_CLUSTERS; n_bytes += cluster_bytes ; @@ -714,14 +714,19 @@ _cairo_intern_string (const char **str_inout, int len) tmpl.string = (char *) str; CAIRO_MUTEX_LOCK (_cairo_intern_string_mutex); - if (_cairo_intern_string_ht == NULL) + if (_cairo_intern_string_ht == NULL) { _cairo_intern_string_ht = _cairo_hash_table_create (_intern_string_equal); + if (unlikely (_cairo_intern_string_ht == NULL)) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto BAIL; + } + } istring = _cairo_hash_table_lookup (_cairo_intern_string_ht, &tmpl.hash_entry); if (istring == NULL) { istring = malloc (sizeof (cairo_intern_string_t) + len + 1); - if (istring != NULL) { + if (likely (istring != NULL)) { istring->hash_entry.hash = tmpl.hash_entry.hash; istring->len = tmpl.len; istring->string = (char *) (istring + 1); @@ -730,17 +735,20 @@ _cairo_intern_string (const char **str_inout, int len) status = _cairo_hash_table_insert (_cairo_intern_string_ht, &istring->hash_entry); - if (status) + if (unlikely (status)) { free (istring); - } else + goto BAIL; + } + } else { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); + goto BAIL; + } } - CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex); - - if (status == CAIRO_STATUS_SUCCESS) - *str_inout = istring->string; + *str_inout = istring->string; + BAIL: + CAIRO_MUTEX_UNLOCK (_cairo_intern_string_mutex); return status; } diff --git a/src/cairo-os2-surface.c b/src/cairo-os2-surface.c index e4cef052..02840e33 100644 --- a/src/cairo-os2-surface.c +++ b/src/cairo-os2-surface.c @@ -1326,6 +1326,8 @@ static const cairo_surface_backend_t cairo_os2_surface_backend = { 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 */ diff --git a/src/cairo-output-stream.c b/src/cairo-output-stream.c index 9a58aac2..71154339 100644 --- a/src/cairo-output-stream.c +++ b/src/cairo-output-stream.c @@ -147,7 +147,7 @@ _cairo_output_stream_create (cairo_write_func_t write_func, cairo_output_stream_with_closure_t *stream; stream = malloc (sizeof (cairo_output_stream_with_closure_t)); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } @@ -173,7 +173,7 @@ _cairo_output_stream_create_in_error (cairo_status_t status) return (cairo_output_stream_t *) &_cairo_output_stream_nil_write_error; stream = malloc (sizeof (cairo_output_stream_t)); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } @@ -598,7 +598,7 @@ _cairo_output_stream_create_for_file (FILE *file) } stream = malloc (sizeof *stream); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } @@ -632,7 +632,7 @@ _cairo_output_stream_create_for_filename (const char *filename) } stream = malloc (sizeof *stream); - if (stream == NULL) { + if (unlikely (stream == NULL)) { fclose (file); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; @@ -676,7 +676,7 @@ _cairo_memory_stream_create (void) memory_stream_t *stream; stream = malloc (sizeof *stream); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } @@ -696,14 +696,14 @@ _cairo_memory_stream_destroy (cairo_output_stream_t *abstract_stream, cairo_status_t status; status = abstract_stream->status; - if (status) + if (unlikely (status)) return _cairo_output_stream_destroy (abstract_stream); stream = (memory_stream_t *) abstract_stream; *length_out = _cairo_array_num_elements (&stream->array); *data_out = malloc (*length_out); - if (*data_out == NULL) { + if (unlikely (*data_out == NULL)) { status = _cairo_output_stream_destroy (abstract_stream); assert (status == CAIRO_STATUS_SUCCESS); return _cairo_error (CAIRO_STATUS_NO_MEMORY); @@ -753,7 +753,7 @@ _cairo_null_stream_create (void) cairo_output_stream_t *stream; stream = malloc (sizeof *stream); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c index bb542ff0..ce4e4def 100644 --- a/src/cairo-paginated-surface.c +++ b/src/cairo-paginated-surface.c @@ -77,7 +77,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target, cairo_status_t status; surface = malloc (sizeof (cairo_paginated_surface_t)); - if (surface == NULL) { + if (unlikely (surface == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto FAIL; } @@ -99,7 +99,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target, surface->meta = _cairo_meta_surface_create (content, width, height); status = cairo_surface_status (surface->meta); - if (status) + if (unlikely (status)) goto FAIL_CLEANUP_SURFACE; surface->page_num = 1; @@ -151,7 +151,7 @@ _cairo_paginated_surface_set_size (cairo_surface_t *surface, paginated_surface->meta = _cairo_meta_surface_create (paginated_surface->content, width, height); status = cairo_surface_status (paginated_surface->meta); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); return CAIRO_STATUS_SUCCESS; @@ -215,7 +215,7 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface, cairo_rectangle_int_t extents; status = _cairo_surface_get_extents (surface->target, &extents); - if (status) + if (unlikely (status)) return status; image = _cairo_paginated_surface_create_image_surface (surface, @@ -223,7 +223,7 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface, extents.height); status = _cairo_meta_surface_replay (surface->meta, image); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (image); return status; } @@ -267,7 +267,7 @@ _paint_fallback_image (cairo_paginated_surface_t *surface, cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale); status = _cairo_meta_surface_replay (surface->meta, image); - if (status) + if (unlikely (status)) goto CLEANUP_IMAGE; _cairo_pattern_init_for_surface (&pattern, image); @@ -318,7 +318,7 @@ _paint_page (cairo_paginated_surface_t *surface) _cairo_analysis_surface_get_bounding_box (analysis, &bbox); status = surface->backend->set_bounding_box (surface->target, &bbox); - if (status) + if (unlikely (status)) goto FAIL; } @@ -327,7 +327,7 @@ _paint_page (cairo_paginated_surface_t *surface) status = surface->backend->set_fallback_images_required (surface->target, has_fallbacks); - if (status) + if (unlikely (status)) goto FAIL; } @@ -360,7 +360,7 @@ _paint_page (cairo_paginated_surface_t *surface) surface->target, CAIRO_META_REGION_NATIVE); assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (status) + if (unlikely (status)) goto FAIL; } @@ -375,7 +375,7 @@ _paint_page (cairo_paginated_surface_t *surface) box.p2.x = surface->width; box.p2.y = surface->height; status = _paint_fallback_image (surface, &box); - if (status) + if (unlikely (status)) goto FAIL; } @@ -393,19 +393,19 @@ _paint_page (cairo_paginated_surface_t *surface) CAIRO_FILL_RULE_WINDING, CAIRO_GSTATE_TOLERANCE_DEFAULT, CAIRO_ANTIALIAS_DEFAULT); - if (status) + if (unlikely (status)) goto FAIL; region = _cairo_analysis_surface_get_unsupported (analysis); num_boxes = 0; status = _cairo_region_get_boxes (region, &num_boxes, &boxes); - if (status) + if (unlikely (status)) goto FAIL; for (i = 0; i < num_boxes; i++) { status = _paint_fallback_image (surface, &boxes[i]); - if (status) { + if (unlikely (status)) { _cairo_region_boxes_fini (region, boxes); goto FAIL; } @@ -439,11 +439,11 @@ _cairo_paginated_surface_copy_page (void *abstract_surface) cairo_paginated_surface_t *surface = abstract_surface; status = _start_page (surface); - if (status) + if (unlikely (status)) return status; status = _paint_page (surface); - if (status) + if (unlikely (status)) return status; surface->page_num++; @@ -466,20 +466,20 @@ _cairo_paginated_surface_show_page (void *abstract_surface) cairo_paginated_surface_t *surface = abstract_surface; status = _start_page (surface); - if (status) + if (unlikely (status)) return status; status = _paint_page (surface); - if (status) + if (unlikely (status)) return status; cairo_surface_show_page (surface->target); status = cairo_surface_status (surface->target); - if (status) + if (unlikely (status)) return status; status = cairo_surface_status (surface->meta); - if (status) + if (unlikely (status)) return status; cairo_surface_destroy (surface->meta); @@ -488,7 +488,7 @@ _cairo_paginated_surface_show_page (void *abstract_surface) surface->width, surface->height); status = cairo_surface_status (surface->meta); - if (status) + if (unlikely (status)) return status; surface->page_num++; @@ -678,6 +678,8 @@ static const cairo_surface_backend_t cairo_paginated_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ _cairo_paginated_surface_copy_page, _cairo_paginated_surface_show_page, NULL, /* set_clip_region */ diff --git a/src/cairo-path-fill.c b/src/cairo-path-fill.c index a6dea083..7af91d20 100644 --- a/src/cairo-path-fill.c +++ b/src/cairo-path-fill.c @@ -177,18 +177,18 @@ _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, _cairo_filler_curve_to, _cairo_filler_close_path, &filler); - if (status) + if (unlikely (status)) goto BAIL; _cairo_polygon_close (&filler.polygon); status = _cairo_polygon_status (&filler.polygon); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_bentley_ottmann_tessellate_polygon (filler.traps, &filler.polygon, fill_rule); - if (status) + if (unlikely (status)) goto BAIL; BAIL: @@ -237,7 +237,7 @@ _cairo_path_fixed_fill_rectangle (cairo_path_fixed_t *path, * GdkRegion clip region during exposes. */ _cairo_path_fixed_iter_init (&iter, path); - while (_cairo_path_fixed_iter_is_box (&iter, &box)) { + while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) { cairo_status_t status; int cw = 0; diff --git a/src/cairo-path-fixed-private.h b/src/cairo-path-fixed-private.h index c995e2a9..0ade9880 100644 --- a/src/cairo-path-fixed-private.h +++ b/src/cairo-path-fixed-private.h @@ -54,9 +54,9 @@ typedef char cairo_path_op_t; typedef struct _cairo_path_buf { struct _cairo_path_buf *next, *prev; - int buf_size; - int num_ops; - int num_points; + unsigned int buf_size; + unsigned int num_ops; + unsigned int num_points; cairo_path_op_t *op; cairo_point_t *points; @@ -90,8 +90,8 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a, typedef struct _cairo_path_fixed_iter { cairo_path_buf_t *buf; - int n_op; - int n_point; + unsigned int n_op; + unsigned int n_point; } cairo_path_fixed_iter_t; cairo_private void @@ -99,8 +99,8 @@ _cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter, cairo_path_fixed_t *path); cairo_private cairo_bool_t -_cairo_path_fixed_iter_is_box (cairo_path_fixed_iter_t *_iter, - cairo_box_t *box); +_cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter, + cairo_box_t *box); cairo_private cairo_bool_t _cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter); diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c index ffaf58c1..dd25bb88 100644 --- a/src/cairo-path-fixed.c +++ b/src/cairo-path-fixed.c @@ -120,7 +120,7 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path, buf_size = MAX (num_ops, (num_points + 1) / 2); if (buf_size) { buf = _cairo_path_buf_create (buf_size); - if (buf == NULL) { + if (unlikely (buf == NULL)) { _cairo_path_fixed_fini (path); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -372,7 +372,7 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path, *last_move_to_point = point; } else { status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1); - if (status) + if (unlikely (status)) return status; } @@ -426,7 +426,7 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path, else status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1); - if (status) + if (unlikely (status)) return status; path->current_point = point; @@ -467,12 +467,12 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path, if (! path->has_current_point) { status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &point[0], 1); - if (status) + if (unlikely (status)) return status; } status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3); - if (status) + if (unlikely (status)) return status; path->current_point = point[2]; @@ -519,13 +519,13 @@ _cairo_path_fixed_close_path (cairo_path_fixed_t *path) return CAIRO_STATUS_SUCCESS; status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CLOSE_PATH, NULL, 0); - if (status) + if (unlikely (status)) return status; status = _cairo_path_fixed_move_to (path, path->last_move_point.x, path->last_move_point.y); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -557,7 +557,7 @@ _cairo_path_fixed_add (cairo_path_fixed_t *path, buf->num_points + num_points > 2 * buf->buf_size) { buf = _cairo_path_buf_create (buf->buf_size * 2); - if (buf == NULL) + if (unlikely (buf == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); _cairo_path_fixed_add_buf (path, buf); @@ -692,7 +692,7 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t *path, status = (*close_path) (closure); break; } - if (status) + if (unlikely (status)) return status; if (forward) { @@ -759,7 +759,7 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path, cairo_fixed_t scaley) { cairo_path_buf_t *buf = &path->buf_head.base; - int i; + unsigned int i; while (buf) { for (i = 0; i < buf->num_points; i++) { @@ -790,7 +790,7 @@ _cairo_path_fixed_transform (cairo_path_fixed_t *path, cairo_matrix_t *matrix) { cairo_path_buf_t *buf; - int i; + unsigned int i; double dx, dy; if (matrix->yx == 0.0 && matrix->xy == 0.0) { @@ -930,6 +930,15 @@ _cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path, { cpf_t flattener; + if (!path->has_curve_to) { + return _cairo_path_fixed_interpret (path, dir, + move_to, + line_to, + NULL, + close_path, + closure); + } + flattener.tolerance = tolerance; flattener.move_to = move_to; flattener.line_to = line_to; @@ -1058,7 +1067,7 @@ _cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter, static cairo_bool_t _cairo_path_fixed_iter_next_op (cairo_path_fixed_iter_t *iter) { - if (++iter->n_op == iter->buf->num_ops) { + if (++iter->n_op >= iter->buf->num_ops) { iter->buf = iter->buf->next; iter->n_op = 0; iter->n_point = 0; @@ -1068,8 +1077,8 @@ _cairo_path_fixed_iter_next_op (cairo_path_fixed_iter_t *iter) } cairo_bool_t -_cairo_path_fixed_iter_is_box (cairo_path_fixed_iter_t *_iter, - cairo_box_t *box) +_cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter, + cairo_box_t *box) { cairo_point_t points[5]; cairo_path_fixed_iter_t iter; @@ -1079,6 +1088,12 @@ _cairo_path_fixed_iter_is_box (cairo_path_fixed_iter_t *_iter, iter = *_iter; + if (iter.n_op == iter.buf->num_ops && + ! _cairo_path_fixed_iter_next_op (&iter)) + { + return FALSE; + } + /* Check whether the ops are those that would be used for a rectangle */ if (iter.buf->op[iter.n_op] != CAIRO_PATH_OP_MOVE_TO) return FALSE; @@ -1106,12 +1121,16 @@ _cairo_path_fixed_iter_is_box (cairo_path_fixed_iter_t *_iter, /* Now, there are choices. The rectangle might end with a LINE_TO * (to the original point), but this isn't required. If it - * doesn't, then it must end with a CLOSE_PATH. */ - if (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_LINE_TO) { + * doesn't, then it must end with a CLOSE_PATH (which may be implicit). */ + if (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_LINE_TO) + { points[4] = iter.buf->points[iter.n_point++]; if (points[4].x != points[0].x || points[4].y != points[0].y) return FALSE; - } else if (iter.buf->op[iter.n_op] != CAIRO_PATH_OP_CLOSE_PATH) { + } + else if (! (iter.buf->op[iter.n_op] == CAIRO_PATH_OP_CLOSE_PATH || + iter.buf->op[iter.n_op] == CAIRO_PATH_OP_MOVE_TO)) + { return FALSE; } if (! _cairo_path_fixed_iter_next_op (&iter)) @@ -1149,6 +1168,9 @@ _cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter) if (iter->buf == NULL) return TRUE; + if (iter->n_op == iter->buf->num_ops) + return TRUE; + if (iter->buf->op[iter->n_op] == CAIRO_PATH_OP_MOVE_TO && iter->buf->num_ops == iter->n_op + 1) { @@ -1157,3 +1179,99 @@ _cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter) return FALSE; } + +/* Closure for path region testing. Every move_to must be to integer + * coordinates, there must be no curves, and every line_to or + * close_path must represent an axis aligned line to an integer point. + * We're relying on the path interpreter always sending a single + * move_to at the start of any subpath, not receiving having any + * superfluous move_tos, and the path intepreter bailing with our + * first non-successful error. */ +typedef struct cairo_path_region_tester { + cairo_point_t last_move_point; + cairo_point_t current_point; +} cprt_t; + +static cairo_status_t +_cprt_line_to (void *closure, + cairo_point_t *p2) +{ + cprt_t *self = closure; + cairo_point_t *p1 = &self->current_point; + if (p2->x == p1->x) { + if (_cairo_fixed_is_integer(p2->y)) { + *p1 = *p2; + return CAIRO_STATUS_SUCCESS; + } + } + else if (p2->y == p1->y) { + if (_cairo_fixed_is_integer(p2->x)) { + *p1 = *p2; + return CAIRO_STATUS_SUCCESS; + } + } + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static cairo_status_t +_cprt_close_path (void *closure) +{ + cprt_t *self = closure; + return _cprt_line_to (closure, &self->last_move_point); +} + +static cairo_status_t +_cprt_move_to (void *closure, + cairo_point_t *p) +{ + cprt_t *self = closure; + cairo_status_t status = _cprt_close_path (closure); + if (status) return status; + if (_cairo_fixed_is_integer(p->x) && + _cairo_fixed_is_integer(p->y)) + { + self->current_point = *p; + self->last_move_point = *p; + return CAIRO_STATUS_SUCCESS; + } + return CAIRO_INT_STATUS_UNSUPPORTED; +} + +static cairo_status_t +_cprt_curve_to (void *closure, + cairo_point_t *p0, + cairo_point_t *p1, + cairo_point_t *p2) +{ + (void)closure; + (void)p0; + (void)p1; + (void)p2; + 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. + */ +cairo_bool_t +_cairo_path_fixed_is_region (cairo_path_fixed_t *path) +{ + cprt_t cprt; + cairo_status_t status; + if (path->has_curve_to) + return FALSE; + cprt.current_point.x = 0; + cprt.current_point.y = 0; + cprt.last_move_point.x = 0; + cprt.last_move_point.y = 0; + status = _cairo_path_fixed_interpret (path, + CAIRO_DIRECTION_FORWARD, + _cprt_move_to, + _cprt_line_to, + _cprt_curve_to, + _cprt_close_path, + &cprt); + return status == CAIRO_STATUS_SUCCESS; +} diff --git a/src/cairo-path-stroke.c b/src/cairo-path-stroke.c index 3c02a94c..8c3064ea 100644 --- a/src/cairo-path-stroke.c +++ b/src/cairo-path-stroke.c @@ -175,7 +175,7 @@ _cairo_stroker_init (cairo_stroker_t *stroker, status = _cairo_pen_init (&stroker->pen, stroke_style->line_width / 2.0, tolerance, ctm); - if (status) + if (unlikely (status)) return status; stroker->has_current_face = FALSE; @@ -658,22 +658,22 @@ _cairo_stroker_add_caps (cairo_stroker_t *stroker) _compute_face (&stroker->first_point, &slope, dx, dy, stroker, &face); status = _cairo_stroker_add_leading_cap (stroker, &face); - if (status) + if (unlikely (status)) return status; status = _cairo_stroker_add_trailing_cap (stroker, &face); - if (status) + if (unlikely (status)) return status; } if (stroker->has_first_face) { status = _cairo_stroker_add_leading_cap (stroker, &stroker->first_face); - if (status) + if (unlikely (status)) return status; } if (stroker->has_current_face) { status = _cairo_stroker_add_trailing_cap (stroker, &stroker->current_face); - if (status) + if (unlikely (status)) return status; } @@ -761,7 +761,7 @@ _cairo_stroker_move_to (void *closure, cairo_point_t *point) /* Cap the start and end of the previous sub path as needed */ status = _cairo_stroker_add_caps (stroker); - if (status) + if (unlikely (status)) return status; stroker->first_point = *point; @@ -806,13 +806,13 @@ _cairo_stroker_line_to (void *closure, cairo_point_t *point) _compute_normalized_device_slope (&slope_dx, &slope_dy, stroker->ctm_inverse, NULL); status = _cairo_stroker_add_sub_edge (stroker, p1, p2, &dev_slope, slope_dx, slope_dy, &start, &end); - if (status) + if (unlikely (status)) return status; if (stroker->has_current_face) { /* Join with final face from previous segment */ status = _cairo_stroker_join (stroker, &stroker->current_face, &start); - if (status) + if (unlikely (status)) return status; } else if (!stroker->has_first_face) { /* Save sub path's first face in case needed for closing join */ @@ -890,7 +890,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) &dev_slope, slope_dx, slope_dy, &sub_start, &sub_end); - if (status) + if (unlikely (status)) return status; if (stroker->has_current_face) { @@ -898,7 +898,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) status = _cairo_stroker_join (stroker, &stroker->current_face, &sub_start); - if (status) + if (unlikely (status)) return status; stroker->has_current_face = FALSE; @@ -909,14 +909,14 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) } else { /* Cap dash start if not connecting to a previous segment */ status = _cairo_stroker_add_leading_cap (stroker, &sub_start); - if (status) + if (unlikely (status)) return status; } if (remain) { /* Cap dash end if not at end of segment */ status = _cairo_stroker_add_trailing_cap (stroker, &sub_end); - if (status) + if (unlikely (status)) return status; } else { stroker->current_face = sub_end; @@ -927,7 +927,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) /* Cap final face from previous segment */ status = _cairo_stroker_add_trailing_cap (stroker, &stroker->current_face); - if (status) + if (unlikely (status)) return status; stroker->has_current_face = FALSE; @@ -955,7 +955,7 @@ _cairo_stroker_line_to_dashed (void *closure, cairo_point_t *point) status = _cairo_stroker_add_leading_cap (stroker, &stroker->current_face); - if (status) + if (unlikely (status)) return status; stroker->has_current_face = TRUE; @@ -986,7 +986,7 @@ _cairo_stroker_curve_to (void *closure, a, b, c, d); if (status == CAIRO_INT_STATUS_DEGENERATE) return _cairo_stroker_line_to (closure, d); - else if (status) + else if (unlikely (status)) return status; initial_slope_dx = _cairo_fixed_to_double (spline_pen.spline.initial_slope.dx); @@ -1014,7 +1014,7 @@ _cairo_stroker_curve_to (void *closure, if (stroker->has_current_face) { status = _cairo_stroker_join (stroker, &stroker->current_face, &start); - if (status) + if (unlikely (status)) goto CLEANUP_PEN; } else if (! stroker->has_first_face) { stroker->first_face = start; @@ -1037,7 +1037,7 @@ _cairo_stroker_curve_to (void *closure, extra_points[3].y -= end.point.y; status = _cairo_pen_add_points (&spline_pen.pen, extra_points, 4); - if (status) + if (unlikely (status)) goto CLEANUP_PEN; status = _cairo_pen_stroke_spline (&spline_pen, @@ -1121,18 +1121,18 @@ _cairo_stroker_close_path (void *closure) status = _cairo_stroker_line_to_dashed (stroker, &stroker->first_point); else status = _cairo_stroker_line_to (stroker, &stroker->first_point); - if (status) + if (unlikely (status)) return status; if (stroker->has_first_face && stroker->has_current_face) { /* Join first and final faces of sub path */ status = _cairo_stroker_join (stroker, &stroker->current_face, &stroker->first_face); - if (status) + if (unlikely (status)) return status; } else { /* Cap the start and end of the sub path as needed */ status = _cairo_stroker_add_caps (stroker); - if (status) + if (unlikely (status)) return status; } @@ -1175,7 +1175,7 @@ _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, status = _cairo_stroker_init (&stroker, stroke_style, ctm, ctm_inverse, tolerance, traps); - if (status) + if (unlikely (status)) return status; if (stroker.style->dash) @@ -1194,7 +1194,7 @@ _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, _cairo_stroker_curve_to, _cairo_stroker_close_path, &stroker); - if (status) + if (unlikely (status)) goto BAIL; /* Cap the start and end of the final sub path as needed */ @@ -1254,7 +1254,7 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker, if (stroker->segments == stroker->segments_embedded) { new_segments = _cairo_malloc_ab (new_size, sizeof (cairo_line_t)); - if (new_segments == NULL) + if (unlikely (new_segments == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memcpy (new_segments, stroker->segments, @@ -1262,7 +1262,7 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker, } else { new_segments = _cairo_realloc_ab (stroker->segments, new_size, sizeof (cairo_line_t)); - if (new_segments == NULL) + if (unlikely (new_segments == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -1386,7 +1386,7 @@ _cairo_rectilinear_stroker_emit_segments (cairo_rectilinear_stroker_t *stroker) } status = _cairo_traps_tessellate_rectangle (stroker->traps, a, b); - if (status) + if (unlikely (status)) return status; } @@ -1403,7 +1403,7 @@ _cairo_rectilinear_stroker_move_to (void *closure, cairo_status_t status; status = _cairo_rectilinear_stroker_emit_segments (stroker); - if (status) + if (unlikely (status)) return status; stroker->current_point = *point; @@ -1449,13 +1449,13 @@ _cairo_rectilinear_stroker_close_path (void *closure) status = _cairo_rectilinear_stroker_line_to (stroker, &stroker->first_point); - if (status) + if (unlikely (status)) return status; stroker->open_sub_path = FALSE; status = _cairo_rectilinear_stroker_emit_segments (stroker); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -1512,7 +1512,7 @@ _cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path, NULL, _cairo_rectilinear_stroker_close_path, &rectilinear_stroker); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_rectilinear_stroker_emit_segments (&rectilinear_stroker); @@ -1520,7 +1520,7 @@ _cairo_path_fixed_stroke_rectilinear (cairo_path_fixed_t *path, BAIL: _cairo_rectilinear_stroker_fini (&rectilinear_stroker); - if (status) + if (unlikely (status)) _cairo_traps_clear (traps); return status; diff --git a/src/cairo-path.c b/src/cairo-path.c index c6639f3f..84dfc0c4 100644 --- a/src/cairo-path.c +++ b/src/cairo-path.c @@ -127,7 +127,7 @@ _cairo_path_count (cairo_path_t *path, &cpc); } - if (status) + if (unlikely (status)) return -1; return cpc.count; @@ -283,7 +283,7 @@ _cairo_path_populate (cairo_path_t *path, &cpp); } - if (status) + if (unlikely (status)) return status; /* Sanity check the count */ @@ -302,7 +302,7 @@ _cairo_path_create_in_error (cairo_status_t status) return (cairo_path_t*) &_cairo_path_nil; path = malloc (sizeof (cairo_path_t)); - if (path == NULL) { + if (unlikely (path == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_path_t*) &_cairo_path_nil; } @@ -322,7 +322,7 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed, cairo_path_t *path; path = malloc (sizeof (cairo_path_t)); - if (path == NULL) { + if (unlikely (path == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_path_t*) &_cairo_path_nil; } @@ -337,8 +337,8 @@ _cairo_path_create_internal (cairo_path_fixed_t *path_fixed, if (path->num_data) { path->data = _cairo_malloc_ab (path->num_data, - sizeof (cairo_path_data_t)); - if (path->data == NULL) { + sizeof (cairo_path_data_t)); + if (unlikely (path->data == NULL)) { free (path); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_path_t*) &_cairo_path_nil; @@ -474,7 +474,7 @@ _cairo_path_append_to_context (const cairo_path_t *path, } status = cairo_status (cr); - if (status) + if (unlikely (status)) return status; } diff --git a/src/cairo-pattern.c b/src/cairo-pattern.c index bdcafe7c..aa580d55 100644 --- a/src/cairo-pattern.c +++ b/src/cairo-pattern.c @@ -140,7 +140,7 @@ _cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern, { pattern->stops = _cairo_malloc_ab (other->stops_size, sizeof (cairo_gradient_stop_t)); - if (pattern->stops == NULL) { + if (unlikely (pattern->stops == NULL)) { pattern->stops_size = 0; pattern->n_stops = 0; return _cairo_pattern_set_error (&pattern->base, CAIRO_STATUS_NO_MEMORY); @@ -181,7 +181,7 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern, cairo_status_t status; status = _cairo_gradient_pattern_init_copy (dst, src); - if (status) + if (unlikely (status)) return status; } break; @@ -203,7 +203,7 @@ _cairo_pattern_init_snapshot (cairo_pattern_t *pattern, /* We don't bother doing any fancy copy-on-write implementation * for the pattern's data. It's generally quite tiny. */ status = _cairo_pattern_init_copy (pattern, other); - if (status) + if (unlikely (status)) return status; /* But we do let the surface snapshot stuff be as fancy as it @@ -272,11 +272,11 @@ _cairo_pattern_create_copy (cairo_pattern_t **pattern, *pattern = malloc (sizeof (cairo_radial_pattern_t)); break; } - if (*pattern == NULL) + if (unlikely (*pattern == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _cairo_pattern_init_copy (*pattern, other); - if (status) { + if (unlikely (status)) { free (*pattern); return status; } @@ -379,18 +379,17 @@ _cairo_pattern_create_solid (const cairo_color_t *color, CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock); - if (pattern == NULL) { + if (unlikely (pattern == NULL)) { /* None cached, need to create a new pattern. */ pattern = malloc (sizeof (cairo_solid_pattern_t)); + if (unlikely (pattern == NULL)) { + _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); + return (cairo_pattern_t *) &_cairo_pattern_nil; + } } - if (pattern == NULL) { - _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); - pattern = (cairo_solid_pattern_t *) &_cairo_pattern_nil; - } else { - _cairo_pattern_init_solid (pattern, color, content); - CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1); - } + _cairo_pattern_init_solid (pattern, color, content); + CAIRO_REFERENCE_COUNT_INIT (&pattern->base.ref_count, 1); return &pattern->base; } @@ -535,7 +534,7 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface) return (cairo_pattern_t*) _cairo_pattern_create_in_error (surface->status); pattern = malloc (sizeof (cairo_surface_pattern_t)); - if (pattern == NULL) { + if (unlikely (pattern == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_pattern_t *)&_cairo_pattern_nil.base; } @@ -581,7 +580,7 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1) cairo_linear_pattern_t *pattern; pattern = malloc (sizeof (cairo_linear_pattern_t)); - if (pattern == NULL) { + if (unlikely (pattern == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_pattern_t *) &_cairo_pattern_nil.base; } @@ -629,7 +628,7 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0, cairo_radial_pattern_t *pattern; pattern = malloc (sizeof (cairo_radial_pattern_t)); - if (pattern == NULL) { + if (unlikely (pattern == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_pattern_t *) &_cairo_pattern_nil.base; } @@ -846,11 +845,11 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern) memcpy (new_stops, pattern->stops, old_size * sizeof (cairo_gradient_stop_t)); } else { new_stops = _cairo_realloc_ab (pattern->stops, - new_size, + new_size, sizeof (cairo_gradient_stop_t)); } - if (new_stops == NULL) + if (unlikely (new_stops == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); pattern->stops = new_stops; @@ -872,7 +871,7 @@ _cairo_pattern_add_color_stop (cairo_gradient_pattern_t *pattern, if (pattern->n_stops >= pattern->stops_size) { cairo_status_t status = _cairo_pattern_gradient_grow (pattern); - if (status) { + if (unlikely (status)) { status = _cairo_pattern_set_error (&pattern->base, status); return; } @@ -1063,7 +1062,7 @@ cairo_pattern_set_matrix (cairo_pattern_t *pattern, inverse = *matrix; status = cairo_matrix_invert (&inverse); - if (status) + if (unlikely (status)) status = _cairo_pattern_set_error (pattern, status); } slim_hidden_def (cairo_pattern_set_matrix); @@ -1255,8 +1254,9 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat cairo_matrix_t matrix = pattern->base.matrix; if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) { - pixman_stops = _cairo_malloc_ab (pattern->n_stops, sizeof(pixman_gradient_stop_t)); - if (pixman_stops == NULL) + pixman_stops = _cairo_malloc_ab (pattern->n_stops, + sizeof(pixman_gradient_stop_t)); + if (unlikely (pixman_stops == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -1340,7 +1340,7 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat if (pixman_stops != pixman_stops_static) free (pixman_stops); - if (pixman_image == NULL) + if (unlikely (pixman_image == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); if (_cairo_surface_is_image (dst)) @@ -1519,7 +1519,7 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt dst)) { status = _cairo_surface_reset (solid_surface_cache.cache[i].surface); - if (status) + if (unlikely (status)) goto UNLOCK; goto DONE; @@ -1531,7 +1531,7 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt dst)) { status = _cairo_surface_reset (solid_surface_cache.cache[i].surface); - if (status) + if (unlikely (status)) goto UNLOCK; goto DONE; @@ -1551,11 +1551,11 @@ _cairo_pattern_acquire_surface_for_solid (const cairo_solid_pattern_t *patt /* Reuse the surface instead of evicting */ status = _cairo_surface_reset (surface); - if (status) + if (unlikely (status)) goto EVICT; status = _cairo_surface_repaint_solid_pattern_surface (dst, surface, pattern); - if (status) + if (unlikely (status)) goto EVICT; cairo_surface_reference (surface); @@ -1839,14 +1839,14 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat int w, h; status = _cairo_surface_get_extents (surface, &extents); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_surface_clone_similar (dst, surface, extents.x, extents.y, extents.width, extents.height, &extents.x, &extents.y, &src); - if (status) + if (unlikely (status)) goto BAIL; w = 2 * extents.width; @@ -1914,14 +1914,14 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat cairo_surface_destroy (src); - if (status) + if (unlikely (status)) goto BAIL; attr->extend = CAIRO_EXTEND_REPEAT; } status = _cairo_surface_get_extents (surface, &extents); - if (status) + if (unlikely (status)) goto BAIL; /* We first transform the rectangle to the coordinate space of the @@ -1969,7 +1969,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat extents.x, extents.y, extents.width, extents.height, &x, &y, out); - if (status) + if (unlikely (status)) goto BAIL; if (x != 0 || y != 0) { @@ -2184,7 +2184,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, src_x, src_y, width, height, src_out, src_attributes); - if (status) + if (unlikely (status)) goto BAIL; if (mask == NULL) { @@ -2196,7 +2196,7 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src, mask_x, mask_y, width, height, mask_out, mask_attributes); - if (status) + if (unlikely (status)) _cairo_pattern_release_surface (src, *src_out, src_attributes); BAIL: @@ -2237,7 +2237,7 @@ _cairo_pattern_get_extents (const cairo_pattern_t *pattern, status = _cairo_surface_get_extents (surface, &surface_extents); if (status == CAIRO_INT_STATUS_UNSUPPORTED) goto UNBOUNDED; - if (status) + if (unlikely (status)) return status; /* The filter can effectively enlarge the extents of the diff --git a/src/cairo-pdf-operators.c b/src/cairo-pdf-operators.c index d363805f..ea5c5148 100644 --- a/src/cairo-pdf-operators.c +++ b/src/cairo-pdf-operators.c @@ -301,7 +301,7 @@ _word_wrap_stream_create (cairo_output_stream_t *output, int max_column) return _cairo_output_stream_create_in_error (output->status); stream = malloc (sizeof (word_wrap_stream_t)); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } @@ -447,7 +447,7 @@ _cairo_pdf_operators_emit_path (cairo_pdf_operators_t *pdf_operators, word_wrap = _word_wrap_stream_create (pdf_operators->stream, 72); status = _cairo_output_stream_get_status (word_wrap); - if (status) + if (unlikely (status)) return _cairo_output_stream_destroy (word_wrap); info.output = word_wrap; @@ -488,7 +488,7 @@ _cairo_pdf_operators_clip (cairo_pdf_operators_t *pdf_operators, path, &pdf_operators->cairo_to_pdf, CAIRO_LINE_CAP_ROUND); - if (status) + if (unlikely (status)) return status; } @@ -569,7 +569,7 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators, */ if (num_dashes % 2) { dash = _cairo_malloc_abc (num_dashes, 2, sizeof (double)); - if (dash == NULL) + if (unlikely (dash == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memcpy (dash, style->dash, num_dashes * sizeof (double)); @@ -585,7 +585,7 @@ _cairo_pdf_operators_emit_stroke_style (cairo_pdf_operators_t *pdf_operators, */ if (dash == style->dash) { dash = _cairo_malloc_ab (num_dashes, sizeof (double)); - if (dash == NULL) + if (unlikely (dash == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memcpy (dash, style->dash, num_dashes * sizeof (double)); } @@ -714,7 +714,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators, if (pdf_operators->in_text_object) { status = _cairo_pdf_operators_end_text (pdf_operators); - if (status) + if (unlikely (status)) return status; } @@ -753,7 +753,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators, _cairo_matrix_factor_out_scale (&m, &scale); path_transform = m; status = cairo_matrix_invert (&path_transform); - if (status) + if (unlikely (status)) return status; cairo_matrix_multiply (&m, &m, &pdf_operators->cairo_to_pdf); @@ -762,7 +762,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators, status = _cairo_pdf_operators_emit_stroke_style (pdf_operators, style, scale); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; if (has_ctm) { @@ -778,7 +778,7 @@ _cairo_pdf_operators_emit_stroke (cairo_pdf_operators_t *pdf_operators, path, &path_transform, style->line_cap); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (pdf_operators->stream, "%s", pdf_operator); @@ -815,7 +815,7 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators, if (pdf_operators->in_text_object) { status = _cairo_pdf_operators_end_text (pdf_operators); - if (status) + if (unlikely (status)) return status; } @@ -823,7 +823,7 @@ _cairo_pdf_operators_fill (cairo_pdf_operators_t *pdf_operators, path, &pdf_operators->cairo_to_pdf, CAIRO_LINE_CAP_ROUND); - if (status) + if (unlikely (status)) return status; switch (fill_rule) { @@ -964,7 +964,7 @@ _cairo_pdf_operators_flush_glyphs (cairo_pdf_operators_t *pdf_operators) word_wrap_stream = _word_wrap_stream_create (pdf_operators->stream, 72); status = _cairo_output_stream_get_status (word_wrap_stream); - if (status) + if (unlikely (status)) return _cairo_output_stream_destroy (word_wrap_stream); /* Check if glyph advance used to position every glyph */ @@ -1023,7 +1023,7 @@ _cairo_pdf_operators_set_text_matrix (cairo_pdf_operators_t *pdf_operators, /* We require the matrix to be invertable. */ inverse = *matrix; status = cairo_matrix_invert (&inverse); - if (status) + if (unlikely (status)) return status; pdf_operators->text_matrix = *matrix; @@ -1112,7 +1112,7 @@ _cairo_pdf_operators_set_font_subset (cairo_pdf_operators_t *pdf_ope status = pdf_operators->use_font_subset (subset_glyph->font_id, subset_glyph->subset_id, pdf_operators->use_font_subset_closure); - if (status) + if (unlikely (status)) return status; } pdf_operators->font_id = subset_glyph->font_id; @@ -1143,7 +1143,7 @@ _cairo_pdf_operators_end_text (cairo_pdf_operators_t *pdf_operators) cairo_status_t status; status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (pdf_operators->stream, "ET\n"); @@ -1177,7 +1177,7 @@ _cairo_pdf_operators_begin_actualtext (cairo_pdf_operators_t *pdf_operators, _cairo_output_stream_printf (pdf_operators->stream, "/Span << /ActualText <feff"); if (utf8_len) { status = _cairo_utf8_to_utf16 (utf8, utf8_len, &utf16, &utf16_len); - if (status) + if (unlikely (status)) return status; for (i = 0; i < utf16_len; i++) { @@ -1212,11 +1212,11 @@ _cairo_pdf_operators_emit_glyph (cairo_pdf_operators_t *pdf_operator pdf_operators->subset_id != subset_glyph->subset_id) { status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_set_font_subset (pdf_operators, subset_glyph); - if (status) + if (unlikely (status)) return status; pdf_operators->is_new_text_object = FALSE; @@ -1241,14 +1241,14 @@ _cairo_pdf_operators_emit_glyph (cairo_pdf_operators_t *pdf_operator fabs(y - pdf_operators->cur_y) > GLYPH_POSITION_TOLERANCE) { status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (status) + if (unlikely (status)) return status; x = glyph->x; y = glyph->y; cairo_matrix_transform_point (&pdf_operators->cairo_to_pdf, &x, &y); status = _cairo_pdf_operators_set_text_position (pdf_operators, x, y); - if (status) + if (unlikely (status)) return status; x = 0.0; @@ -1296,14 +1296,14 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators, utf8, utf8_len, &subset_glyph); - if (status) + if (unlikely (status)) return status; if (subset_glyph.utf8_is_mapped || utf8_len < 0) { status = _cairo_pdf_operators_emit_glyph (pdf_operators, glyphs, &subset_glyph); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -1313,11 +1313,11 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators, /* Fallback to using ActualText to map zero or more glyphs to a * unicode string. */ status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_begin_actualtext (pdf_operators, utf8, utf8_len); - if (status) + if (unlikely (status)) return status; cur_glyph = glyphs; @@ -1329,13 +1329,13 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators, cur_glyph->index, NULL, -1, &subset_glyph); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_emit_glyph (pdf_operators, cur_glyph, &subset_glyph); - if (status) + if (unlikely (status)) return status; if ((cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)) @@ -1344,7 +1344,7 @@ _cairo_pdf_operators_emit_cluster (cairo_pdf_operators_t *pdf_operators, cur_glyph++; } status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_end_actualtext (pdf_operators); @@ -1374,13 +1374,13 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators, status = cairo_matrix_invert (&pdf_operators->font_matrix_inverse); if (status == CAIRO_STATUS_INVALID_MATRIX) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; pdf_operators->is_new_text_object = FALSE; if (pdf_operators->in_text_object == FALSE) { status = _cairo_pdf_operators_begin_text (pdf_operators); - if (status) + if (unlikely (status)) return status; /* Force Tm and Tf to be emitted when starting a new text @@ -1401,7 +1401,7 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators, ! _cairo_matrix_scale_equal (&pdf_operators->text_matrix, &text_matrix)) { status = _cairo_pdf_operators_flush_glyphs (pdf_operators); - if (status) + if (unlikely (status)) return status; x = glyphs[0].x; @@ -1412,7 +1412,7 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators, status = _cairo_pdf_operators_set_text_matrix (pdf_operators, &text_matrix); if (status == CAIRO_STATUS_INVALID_MATRIX) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; } @@ -1432,7 +1432,7 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators, clusters[i].num_glyphs, cluster_flags, scaled_font); - if (status) + if (unlikely (status)) return status; cur_text += clusters[i].num_bytes; @@ -1448,7 +1448,7 @@ _cairo_pdf_operators_show_text_glyphs (cairo_pdf_operators_t *pdf_operators, 1, FALSE, scaled_font); - if (status) + if (unlikely (status)) return status; } } diff --git a/src/cairo-pdf-surface.c b/src/cairo-pdf-surface.c index 97902505..5862c4b5 100644 --- a/src/cairo-pdf-surface.c +++ b/src/cairo-pdf-surface.c @@ -207,7 +207,7 @@ _cairo_pdf_surface_new_object (cairo_pdf_surface_t *surface) object.offset = _cairo_output_stream_get_position (surface->output); status = _cairo_array_append (&surface->objects, &object); - if (status) { + if (unlikely (status)) { resource.id = 0; return resource; } @@ -249,7 +249,7 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output, cairo_status_t status, status_ignored; surface = malloc (sizeof (cairo_pdf_surface_t)); - if (surface == NULL) { + if (unlikely (surface == NULL)) { /* destroy stream on behalf of caller */ status = _cairo_output_stream_destroy (output); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); @@ -551,7 +551,7 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface, cairo_status_t status; status = _extract_pdf_surface (surface, &pdf_surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return; } @@ -562,7 +562,7 @@ cairo_pdf_surface_set_size (cairo_surface_t *surface, status = _cairo_paginated_surface_set_size (pdf_surface->paginated_surface, width_in_points, height_in_points); - if (status) + if (unlikely (status)) status = _cairo_surface_set_error (surface, status); } @@ -639,7 +639,7 @@ _cairo_pdf_surface_add_alpha (cairo_pdf_surface_t *surface, } status = _cairo_array_append (&res->alphas, &alpha); - if (status) + if (unlikely (status)) return status; *index = _cairo_array_num_elements (&res->alphas) - 1; @@ -702,7 +702,7 @@ _cairo_pdf_surface_add_font (unsigned int font_id, return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _cairo_array_append (&surface->fonts, &font); - if (status) + if (unlikely (status)) return status; return _cairo_array_append (&res->fonts, &font); @@ -817,7 +817,7 @@ _cairo_pdf_surface_create_smask_group (cairo_pdf_surface_t *surface) cairo_pdf_smask_group_t *group; group = calloc (1, sizeof (cairo_pdf_smask_group_t)); - if (group == NULL) { + if (unlikely (group == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return NULL; } @@ -898,7 +898,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface, } status = _cairo_pattern_create_copy (&pdf_pattern.pattern, pattern); - if (status) + if (unlikely (status)) return status; pdf_pattern.pattern_res = _cairo_pdf_surface_new_object (surface); @@ -936,7 +936,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface, *gstate_res = pdf_pattern.gstate_res; status = _cairo_array_append (&surface->patterns, &pdf_pattern); - if (status) { + if (unlikely (status)) { cairo_pattern_destroy (pdf_pattern.pattern); return status; } @@ -1022,7 +1022,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface) return CAIRO_STATUS_SUCCESS; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; if (surface->pdf_stream.compressed) { @@ -1151,7 +1151,7 @@ _cairo_pdf_surface_open_knockout_group (cairo_pdf_surface_t *surface) cairo_status_t status; status = _cairo_pdf_surface_open_group (surface, NULL); - if (status) + if (unlikely (status)) return status; surface->group_stream.is_knockout = TRUE; @@ -1169,7 +1169,7 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface, assert (surface->group_stream.active == TRUE); status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; if (surface->compress_content) { @@ -1237,7 +1237,7 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface, surface->compress_content, NULL); } - if (status) + if (unlikely (status)) return status; surface->content = surface->pdf_stream.self; @@ -1256,12 +1256,12 @@ _cairo_pdf_surface_close_content_stream (cairo_pdf_surface_t *surface) assert (surface->group_stream.active == FALSE); status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, "Q\n"); status = _cairo_pdf_surface_close_stream (surface); - if (status) + if (unlikely (status)) return status; _cairo_pdf_surface_update_object (surface, surface->content_resources); @@ -1414,7 +1414,7 @@ _cairo_pdf_surface_has_fallback_images (void *abstract_surface, surface->has_fallback_images = has_fallbacks; status = _cairo_pdf_surface_open_content_stream (surface, has_fallbacks); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -1461,7 +1461,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface, alpha = _cairo_malloc_ab (image->height, image->width); } - if (alpha == NULL) { + if (unlikely (alpha == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP; } @@ -1515,7 +1515,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface, " /BitsPerComponent %d\n", image->width, image->height, image->format == CAIRO_FORMAT_A1 ? 1 : 8); - if (status) + if (unlikely (status)) goto CLEANUP_ALPHA; *stream_ret = surface->pdf_stream.self; @@ -1557,7 +1557,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, rgb_size = image->height * image->width * 3; rgb = _cairo_malloc_abc (image->width, image->height, 3); - if (rgb == NULL) { + if (unlikely (rgb == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP; } @@ -1601,7 +1601,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, image->format == CAIRO_FORMAT_A8 || image->format == CAIRO_FORMAT_A1) { status = _cairo_pdf_surface_emit_smask (surface, image, &smask); - if (status) + if (unlikely (status)) goto CLEANUP_RGB; if (smask.id) @@ -1645,7 +1645,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface, IMAGE_DICTIONARY, image->width, image->height, interpolate); - if (status) + if (unlikely (status)) goto CLEANUP_RGB; #undef IMAGE_DICTIONARY @@ -1727,7 +1727,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface, return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length); - if (status) + if (unlikely (status)) return status; if (info.num_components != 1 && info.num_components != 3) @@ -1747,7 +1747,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface, info.height, info.num_components == 1 ? "/DeviceGray" : "/DeviceRGB", info.bits_per_component); - if (status) + if (unlikely (status)) return status; *res = surface->pdf_stream.self; @@ -1789,7 +1789,7 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface, return status; status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra); - if (status) + if (unlikely (status)) goto BAIL; pad_image = &image->base; @@ -1826,13 +1826,13 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface, rect.width, rect.height); _cairo_pattern_fini (&pad_pattern.base); - if (status) + if (unlikely (status)) goto BAIL; } status = _cairo_pdf_surface_emit_image (surface, (cairo_image_surface_t *)pad_image, resource, pattern->base.filter); - if (status) + if (unlikely (status)) goto BAIL; *width = ((cairo_image_surface_t *)pad_image)->width; @@ -1862,7 +1862,7 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface, int alpha = 0; status = _cairo_surface_get_extents (meta_surface, &meta_extents); - if (status) + if (unlikely (status)) return status; old_width = surface->width; @@ -1879,13 +1879,13 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface, surface->paginated_mode = CAIRO_PAGINATED_MODE_RENDER; _cairo_pdf_group_resources_clear (&surface->resources); status = _cairo_pdf_surface_open_content_stream (surface, TRUE); - if (status) + if (unlikely (status)) return status; *resource = surface->content; if (cairo_surface_get_content (meta_surface) == CAIRO_CONTENT_COLOR) { status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -1898,11 +1898,11 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface, status = _cairo_meta_surface_replay_region (meta_surface, &surface->base, CAIRO_META_REGION_NATIVE); assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (status) + if (unlikely (status)) return status; status = _cairo_surface_set_clip (&surface->base, old_clip); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_close_content_stream (surface); @@ -1940,11 +1940,11 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, status = _cairo_pdf_surface_emit_meta_surface (surface, meta_surface, &pattern_resource); - if (status) + if (unlikely (status)) return status; status = _cairo_surface_get_extents (meta_surface, &pattern_extents); - if (status) + if (unlikely (status)) return status; pattern_width = pattern_extents.width; @@ -1957,12 +1957,12 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, &pattern_height, &origin_x, &origin_y); - if (status) + if (unlikely (status)) return status; } status = _cairo_surface_get_extents (&surface->base, &surface_extents); - if (status) + if (unlikely (status)) return status; bbox_x = pattern_width; @@ -2074,7 +2074,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, pdf_p2d.x0, pdf_p2d.y0, pattern_resource.id, pattern_resource.id); - if (status) + if (unlikely (status)) return status; if (_cairo_surface_is_meta (pattern->surface)) { @@ -2112,7 +2112,7 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface, } status = _cairo_pdf_surface_close_stream (surface); - if (status) + if (unlikely (status)) return status; return _cairo_output_stream_get_status (surface->output); @@ -2244,14 +2244,14 @@ _cairo_pdf_surface_emit_stitched_colorgradient (cairo_pdf_surface_t *surface, &stops[i], &stops[i+1], &stops[i].resource); - if (status) + if (unlikely (status)) return status; } else { status = cairo_pdf_surface_emit_rgb_linear_function (surface, &stops[i], &stops[i+1], &stops[i].resource); - if (status) + if (unlikely (status)) return status; } } @@ -2333,7 +2333,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, alpha_function->id = 0; allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_pdf_color_stop_t)); - if (allstops == NULL) + if (unlikely (allstops == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); stops = &allstops[1]; @@ -2380,7 +2380,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, &stops[0], &stops[1], color_function); - if (status) + if (unlikely (status)) goto BAIL; if (emit_alpha) { @@ -2388,7 +2388,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, &stops[0], &stops[1], alpha_function); - if (status) + if (unlikely (status)) goto BAIL; } } else { @@ -2399,7 +2399,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, stops, FALSE, color_function); - if (status) + if (unlikely (status)) goto BAIL; if (emit_alpha) { @@ -2408,7 +2408,7 @@ _cairo_pdf_surface_emit_pattern_stops (cairo_pdf_surface_t *surface, stops, TRUE, alpha_function); - if (status) + if (unlikely (status)) goto BAIL; } } @@ -2510,7 +2510,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface, surface->height, gradient_mask.id, gradient_mask.id); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -2525,7 +2525,7 @@ cairo_pdf_surface_emit_transparency_group (cairo_pdf_surface_t *surface, surface->height); status = _cairo_pdf_surface_close_stream (surface); - if (status) + if (unlikely (status)) return status; smask_resource = _cairo_pdf_surface_new_object (surface); @@ -2648,7 +2648,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface, &pattern->base, &color_function, &alpha_function); - if (status) + if (unlikely (status)) return status; if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT || @@ -2658,7 +2658,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface, &color_function, repeat_begin, repeat_end); - if (status) + if (unlikely (status)) return status; if (alpha_function.id != 0) { @@ -2667,7 +2667,7 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface, &alpha_function, repeat_begin, repeat_end); - if (status) + if (unlikely (status)) return status; } } @@ -2747,13 +2747,13 @@ _cairo_pdf_surface_emit_linear_pattern (cairo_pdf_surface_t *surface, ">>\n" "endobj\n"); status = _cairo_pdf_surface_add_pattern (surface, mask_resource); - if (status) + if (unlikely (status)) return status; status = cairo_pdf_surface_emit_transparency_group (surface, pdf_pattern->gstate_res, mask_resource); - if (status) + if (unlikely (status)) return status; } @@ -2779,7 +2779,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface, &pattern->base, &color_function, &alpha_function); - if (status) + if (unlikely (status)) return status; pat_to_pdf = pattern->base.base.matrix; @@ -2870,7 +2870,7 @@ _cairo_pdf_surface_emit_radial_pattern (cairo_pdf_surface_t *surface, status = cairo_pdf_surface_emit_transparency_group (surface, pdf_pattern->gstate_res, mask_resource); - if (status) + if (unlikely (status)) return status; } @@ -2953,7 +2953,7 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface, surface->current_color_is_stroke != is_stroke) { status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -2977,11 +2977,11 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface, surface->current_color_alpha != solid_color->alpha) { status = _cairo_pdf_surface_add_alpha (surface, solid_color->alpha, &alpha); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -2993,15 +2993,15 @@ _cairo_pdf_surface_select_pattern (cairo_pdf_surface_t *surface, surface->current_pattern_is_solid_color = TRUE; } else { status = _cairo_pdf_surface_add_alpha (surface, 1.0, &alpha); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_add_pattern (surface, pattern_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; /* fill-stroke calls select_pattern twice. Don't save if the @@ -3035,7 +3035,7 @@ _cairo_pdf_surface_unselect_pattern (cairo_pdf_surface_t *surface) if (surface->select_pattern_gstate_saved) { status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, "Q\n"); @@ -3053,11 +3053,11 @@ _cairo_pdf_surface_show_page (void *abstract_surface) cairo_int_status_t status; status = _cairo_pdf_surface_close_content_stream (surface); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_write_page (surface); - if (status) + if (unlikely (status)) return status; _cairo_pdf_surface_clear (surface); @@ -3096,7 +3096,7 @@ _cairo_pdf_surface_intersect_clip_path (void *abstract_surface, if (path == NULL) { status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, "Q q\n"); @@ -3183,7 +3183,7 @@ _cairo_pdf_surface_emit_unicode_for_glyph (cairo_pdf_surface_t *surface, if (utf8 && *utf8) { status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len); - if (status) + if (unlikely (status)) return status; } @@ -3225,7 +3225,7 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface, NULL, surface->compress_content, NULL); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -3277,7 +3277,7 @@ _cairo_pdf_surface_emit_to_unicode_stream (cairo_pdf_surface_t *surface, } status = _cairo_pdf_surface_emit_unicode_for_glyph (surface, font_subset->utf8[i + 1]); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -3317,14 +3317,14 @@ _cairo_pdf_surface_emit_cff_font (cairo_pdf_surface_t *surface, NULL, TRUE, " /Subtype /CIDFontType0C\n"); - if (status) + if (unlikely (status)) return status; stream = surface->pdf_stream.self; _cairo_output_stream_write (surface->output, subset->data, subset->data_length); status = _cairo_pdf_surface_close_stream (surface); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_emit_to_unicode_stream (surface, @@ -3432,7 +3432,7 @@ _cairo_pdf_surface_emit_cff_font_subset (cairo_pdf_surface_t *surface, snprintf (name, sizeof name, "CairoFont-%d-%d", font_subset->font_id, font_subset->subset_id); status = _cairo_cff_subset_init (&subset, name, font_subset); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset); @@ -3453,7 +3453,7 @@ _cairo_pdf_surface_emit_cff_fallback_font (cairo_pdf_surface_t *surface, snprintf (name, sizeof name, "CairoFont-%d-%d", font_subset->font_id, font_subset->subset_id); status = _cairo_cff_fallback_init (&subset, name, font_subset); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_emit_cff_font (surface, font_subset, &subset); @@ -3490,13 +3490,13 @@ _cairo_pdf_surface_emit_type1_font (cairo_pdf_surface_t *surface, " /Length3 0\n", subset->header_length, subset->data_length); - if (status) + if (unlikely (status)) return status; stream = surface->pdf_stream.self; _cairo_output_stream_write (surface->output, subset->data, length); status = _cairo_pdf_surface_close_stream (surface); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_emit_to_unicode_stream (surface, @@ -3584,7 +3584,7 @@ _cairo_pdf_surface_emit_type1_font_subset (cairo_pdf_surface_t *surface, snprintf (name, sizeof name, "CairoFont-%d-%d", font_subset->font_id, font_subset->subset_id); status = _cairo_type1_subset_init (&subset, name, font_subset, FALSE); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset); @@ -3605,7 +3605,7 @@ _cairo_pdf_surface_emit_type1_fallback_font (cairo_pdf_surface_t *surface, snprintf (name, sizeof name, "CairoFont-%d-%d", font_subset->font_id, font_subset->subset_id); status = _cairo_type1_fallback_init_binary (&subset, name, font_subset); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_emit_type1_font (surface, font_subset, &subset); @@ -3634,7 +3634,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, return CAIRO_STATUS_SUCCESS; status = _cairo_truetype_subset_init (&subset, font_subset); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_open_stream (surface, @@ -3642,7 +3642,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, TRUE, " /Length1 %lu\n", subset.data_length); - if (status) { + if (unlikely (status)) { _cairo_truetype_subset_fini (&subset); return status; } @@ -3651,7 +3651,7 @@ _cairo_pdf_surface_emit_truetype_font_subset (cairo_pdf_surface_t *surface, _cairo_output_stream_write (surface->output, subset.data, subset.data_length); status = _cairo_pdf_surface_close_stream (surface); - if (status) { + if (unlikely (status)) { _cairo_truetype_subset_fini (&subset); return status; } @@ -3822,7 +3822,7 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su for (i = 0; i < font_subset->num_glyphs; i++) { status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface, font_subset->glyphs[i]); - if (status) + if (unlikely (status)) break; } @@ -3857,11 +3857,11 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, return CAIRO_STATUS_SUCCESS; glyphs = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (cairo_pdf_resource_t)); - if (glyphs == NULL) + if (unlikely (glyphs == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); widths = _cairo_malloc_ab (font_subset->num_glyphs, sizeof (double)); - if (widths == NULL) { + if (unlikely (widths == NULL)) { free (glyphs); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -3880,7 +3880,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, NULL, surface->compress_content, NULL); - if (status) + if (unlikely (status)) break; glyphs[i] = surface->pdf_stream.self; @@ -3889,11 +3889,11 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, font_subset->glyphs[i], &bbox, &widths[i]); - if (status) + if (unlikely (status)) break; status = _cairo_pdf_surface_close_stream (surface); - if (status) + if (unlikely (status)) break; if (i == 0) { @@ -3913,7 +3913,7 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface, } } cairo_surface_destroy (type3_surface); - if (status) { + if (unlikely (status)) { free (glyphs); free (widths); return status; @@ -4072,19 +4072,19 @@ _cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface) status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, _cairo_pdf_surface_analyze_user_font_subset, surface); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets, _cairo_pdf_surface_emit_unscaled_font_subset, surface); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets, _cairo_pdf_surface_emit_scaled_font_subset, surface); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, @@ -4159,36 +4159,36 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, /* Create mask group */ status = _cairo_pdf_surface_open_group (surface, NULL); - if (status) + if (unlikely (status)) return status; pattern_res.id = 0; gstate_res.id = 0; status = _cairo_pdf_surface_add_pdf_pattern (surface, group->mask, NULL, &pattern_res, &gstate_res); - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { smask_group = _cairo_pdf_surface_create_smask_group (surface); - if (smask_group == NULL) + if (unlikely (smask_group == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); smask_group->operation = PDF_PAINT; smask_group->source = cairo_pattern_reference (group->mask); smask_group->source_res = pattern_res; status = _cairo_pdf_surface_add_smask_group (surface, smask_group); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (smask_group); return status; } status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -4197,7 +4197,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, smask_group->group_res.id); } else { status = _cairo_pdf_surface_select_pattern (surface, group->mask, pattern_res, FALSE); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -4205,46 +4205,46 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, surface->width, surface->height); status = _cairo_pdf_surface_unselect_pattern (surface); - if (status) + if (unlikely (status)) return status; } status = _cairo_pdf_surface_close_group (surface, &mask_group); - if (status) + if (unlikely (status)) return status; /* Create source group */ status = _cairo_pdf_surface_open_group (surface, &group->source_res); - if (status) + if (unlikely (status)) return status; pattern_res.id = 0; gstate_res.id = 0; status = _cairo_pdf_surface_add_pdf_pattern (surface, group->source, NULL, &pattern_res, &gstate_res); - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { smask_group = _cairo_pdf_surface_create_smask_group (surface); - if (smask_group == NULL) + if (unlikely (smask_group == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); smask_group->operation = PDF_PAINT; smask_group->source = cairo_pattern_reference (group->source); smask_group->source_res = pattern_res; status = _cairo_pdf_surface_add_smask_group (surface, smask_group); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (smask_group); return status; } status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_add_xobject (surface, smask_group->group_res); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -4253,7 +4253,7 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, smask_group->group_res.id); } else { status = _cairo_pdf_surface_select_pattern (surface, group->source, pattern_res, FALSE); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -4261,12 +4261,12 @@ _cairo_pdf_surface_write_mask_group (cairo_pdf_surface_t *surface, surface->width, surface->height); status = _cairo_pdf_surface_unselect_pattern (surface); - if (status) + if (unlikely (status)) return status; } status = _cairo_pdf_surface_close_group (surface, NULL); - if (status) + if (unlikely (status)) return status; /* Create an smask based on the alpha component of mask_group */ @@ -4319,14 +4319,14 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface, return _cairo_pdf_surface_write_mask_group (surface, group); status = _cairo_pdf_surface_open_group (surface, &group->group_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_select_pattern (surface, group->source, group->source_res, group->operation == PDF_STROKE); - if (status) + if (unlikely (status)) return status; switch (group->operation) { @@ -4359,11 +4359,11 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface, group->scaled_font); break; } - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_unselect_pattern (surface); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_close_group (surface, NULL); @@ -4398,14 +4398,14 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface for (; group_index < _cairo_array_num_elements (&surface->smask_groups); group_index++) { _cairo_array_copy_element (&surface->smask_groups, group_index, &group); status = _cairo_pdf_surface_write_smask_group (surface, group); - if (status) + if (unlikely (status)) return status; } for (; pattern_index < _cairo_array_num_elements (&surface->patterns); pattern_index++) { _cairo_array_copy_element (&surface->patterns, pattern_index, &pattern); status = _cairo_pdf_surface_emit_pattern (surface, &pattern); - if (status) + if (unlikely (status)) return status; } } @@ -4423,7 +4423,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface) _cairo_pdf_group_resources_clear (&surface->resources); if (surface->has_fallback_images) { status = _cairo_pdf_surface_open_knockout_group (surface); - if (status) + if (unlikely (status)) return status; len = _cairo_array_num_elements (&surface->knockout_group); @@ -4433,34 +4433,34 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface) "/x%d Do\n", res.id); status = _cairo_pdf_surface_add_xobject (surface, res); - if (status) + if (unlikely (status)) return status; } _cairo_output_stream_printf (surface->output, "/x%d Do\n", surface->content.id); status = _cairo_pdf_surface_add_xobject (surface, surface->content); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_close_group (surface, &knockout); - if (status) + if (unlikely (status)) return status; _cairo_pdf_group_resources_clear (&surface->resources); status = _cairo_pdf_surface_open_content_stream (surface, FALSE); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, "/x%d Do\n", knockout.id); status = _cairo_pdf_surface_add_xobject (surface, knockout); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_close_content_stream (surface); - if (status) + if (unlikely (status)) return status; } @@ -4490,11 +4490,11 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface) surface->content_resources.id); status = _cairo_array_append (&surface->pages, &page); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_write_patterns_and_smask_groups (surface); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -4512,7 +4512,7 @@ _cairo_pdf_surface_analyze_surface_pattern_transparency (cairo_pdf_surface_t status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra); - if (status) + if (unlikely (status)) return status; if (image->base.status) @@ -4697,11 +4697,11 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface) cairo_status_t status; status = _cairo_pdf_surface_close_content_stream (surface); - if (status) + if (unlikely (status)) return status; status = _cairo_array_append (&surface->knockout_group, &surface->content); - if (status) + if (unlikely (status)) return status; _cairo_pdf_group_resources_clear (&surface->resources); @@ -4723,7 +4723,7 @@ _cairo_pdf_surface_paint (void *abstract_surface, return _cairo_pdf_surface_analyze_operation (surface, op, source); } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) { status = _cairo_pdf_surface_start_fallback (surface); - if (status) + if (unlikely (status)) return status; } @@ -4735,37 +4735,37 @@ _cairo_pdf_surface_paint (void *abstract_surface, &pattern_res, &gstate_res); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { group = _cairo_pdf_surface_create_smask_group (surface); - if (group == NULL) + if (unlikely (group == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); group->operation = PDF_PAINT; status = _cairo_pattern_create_copy (&group->source, source); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } group->source_res = pattern_res; status = _cairo_pdf_surface_add_smask_group (surface, group); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_add_xobject (surface, group->group_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -4774,7 +4774,7 @@ _cairo_pdf_surface_paint (void *abstract_surface, group->group_res.id); } else { status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -4782,7 +4782,7 @@ _cairo_pdf_surface_paint (void *abstract_surface, surface->width, surface->height); status = _cairo_pdf_surface_unselect_pattern (surface); - if (status) + if (unlikely (status)) return status; } @@ -4815,7 +4815,7 @@ _cairo_pdf_surface_mask (void *abstract_surface, mask_status); } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) { status = _cairo_pdf_surface_start_fallback (surface); - if (status) + if (unlikely (status)) return status; } @@ -4823,17 +4823,17 @@ _cairo_pdf_surface_mask (void *abstract_surface, assert (_cairo_pdf_surface_operation_supported (surface, op, mask)); group = _cairo_pdf_surface_create_smask_group (surface); - if (group == NULL) + if (unlikely (group == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); group->operation = PDF_MASK; status = _cairo_pattern_create_copy (&group->source, source); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } status = _cairo_pattern_create_copy (&group->mask, mask); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } @@ -4844,21 +4844,21 @@ _cairo_pdf_surface_mask (void *abstract_surface, } status = _cairo_pdf_surface_add_smask_group (surface, group); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } status = _cairo_pdf_surface_add_smask (surface, group->group_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_add_xobject (surface, group->source_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -4897,23 +4897,23 @@ _cairo_pdf_surface_stroke (void *abstract_surface, &pattern_res, &gstate_res); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { group = _cairo_pdf_surface_create_smask_group (surface); - if (group == NULL) + if (unlikely (group == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); group->operation = PDF_STROKE; status = _cairo_pattern_create_copy (&group->source, source); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } group->source_res = pattern_res; status = _cairo_path_fixed_init_copy (&group->path, path); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } @@ -4922,21 +4922,21 @@ _cairo_pdf_surface_stroke (void *abstract_surface, group->ctm = *ctm; group->ctm_inverse = *ctm_inverse; status = _cairo_pdf_surface_add_smask_group (surface, group); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_add_xobject (surface, group->group_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -4945,7 +4945,7 @@ _cairo_pdf_surface_stroke (void *abstract_surface, group->group_res.id); } else { status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, TRUE); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_stroke (&surface->pdf_operators, @@ -4953,11 +4953,11 @@ _cairo_pdf_surface_stroke (void *abstract_surface, style, ctm, ctm_inverse); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_unselect_pattern (surface); - if (status) + if (unlikely (status)) return status; } @@ -4983,7 +4983,7 @@ _cairo_pdf_surface_fill (void *abstract_surface, return _cairo_pdf_surface_analyze_operation (surface, op, source); } else if (surface->paginated_mode == CAIRO_PAGINATED_MODE_FALLBACK) { status = _cairo_pdf_surface_start_fallback (surface); - if (status) + if (unlikely (status)) return status; } @@ -4995,44 +4995,44 @@ _cairo_pdf_surface_fill (void *abstract_surface, &pattern_res, &gstate_res); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { group = _cairo_pdf_surface_create_smask_group (surface); - if (group == NULL) + if (unlikely (group == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); group->operation = PDF_FILL; status = _cairo_pattern_create_copy (&group->source, source); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } group->source_res = pattern_res; status = _cairo_path_fixed_init_copy (&group->path, path); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } group->fill_rule = fill_rule; status = _cairo_pdf_surface_add_smask_group (surface, group); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_add_xobject (surface, group->group_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -5041,17 +5041,17 @@ _cairo_pdf_surface_fill (void *abstract_surface, group->group_res.id); } else { status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_fill (&surface->pdf_operators, path, fill_rule); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_unselect_pattern (surface); - if (status) + if (unlikely (status)) return status; } @@ -5104,7 +5104,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, extents, &fill_pattern_res, &gstate_res); - if (status) + if (unlikely (status)) return status; assert (gstate_res.id == 0); @@ -5116,7 +5116,7 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, extents, &stroke_pattern_res, &gstate_res); - if (status) + if (unlikely (status)) return status; assert (gstate_res.id == 0); @@ -5125,12 +5125,12 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, * select both at the same time */ status = _cairo_pdf_surface_select_pattern (surface, fill_source, fill_pattern_res, FALSE); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_select_pattern (surface, stroke_source, stroke_pattern_res, TRUE); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_fill_stroke (&surface->pdf_operators, @@ -5139,11 +5139,11 @@ _cairo_pdf_surface_fill_stroke (void *abstract_surface, stroke_style, stroke_ctm, stroke_ctm_inverse); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_unselect_pattern (surface); - if (status) + if (unlikely (status)) return status; return _cairo_output_stream_get_status (surface->output); @@ -5185,17 +5185,17 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, &pattern_res, &gstate_res); if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; if (gstate_res.id != 0) { group = _cairo_pdf_surface_create_smask_group (surface); - if (group == NULL) + if (unlikely (group == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); group->operation = PDF_SHOW_GLYPHS; status = _cairo_pattern_create_copy (&group->source, source); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } @@ -5203,7 +5203,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, if (utf8_len) { group->utf8 = malloc (utf8_len); - if (group->utf8 == NULL) { + if (unlikely (group->utf8 == NULL)) { _cairo_pdf_smask_group_destroy (group); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -5213,7 +5213,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, if (num_glyphs) { group->glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); - if (group->glyphs == NULL) { + if (unlikely (group->glyphs == NULL)) { _cairo_pdf_smask_group_destroy (group); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -5223,7 +5223,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, if (num_clusters) { group->clusters = _cairo_malloc_ab (num_clusters, sizeof (cairo_text_cluster_t)); - if (group->clusters == NULL) { + if (unlikely (group->clusters == NULL)) { _cairo_pdf_smask_group_destroy (group); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -5233,21 +5233,21 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, group->scaled_font = cairo_scaled_font_reference (scaled_font); status = _cairo_pdf_surface_add_smask_group (surface, group); - if (status) { + if (unlikely (status)) { _cairo_pdf_smask_group_destroy (group); return status; } status = _cairo_pdf_surface_add_smask (surface, gstate_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_add_xobject (surface, group->group_res); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->output, @@ -5256,7 +5256,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, group->group_res.id); } else { status = _cairo_pdf_surface_select_pattern (surface, source, pattern_res, FALSE); - if (status) + if (unlikely (status)) return status; /* Each call to show_glyphs() with a transclucent pattern must @@ -5265,7 +5265,7 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, * each other. */ if (! _cairo_pattern_is_opaque (source)) { status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; } @@ -5275,11 +5275,11 @@ _cairo_pdf_surface_show_text_glyphs (void *abstract_surface, clusters, num_clusters, cluster_flags, scaled_font); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_surface_unselect_pattern (surface); - if (status) + if (unlikely (status)) return status; } @@ -5308,6 +5308,8 @@ static const cairo_surface_backend_t cairo_pdf_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* _cairo_pdf_surface_copy_page */ _cairo_pdf_surface_show_page, NULL, /* set_clip_region */ diff --git a/src/cairo-pen.c b/src/cairo-pen.c index 43d344a1..4158f175 100644 --- a/src/cairo-pen.c +++ b/src/cairo-pen.c @@ -65,7 +65,7 @@ _cairo_pen_init (cairo_pen_t *pen, if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) { pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t)); - if (pen->vertices == NULL) + if (unlikely (pen->vertices == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } else { pen->vertices = pen->vertices_embedded; @@ -112,7 +112,7 @@ _cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other) if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) { pen->vertices = _cairo_malloc_ab (pen->num_vertices, sizeof (cairo_pen_vertex_t)); - if (pen->vertices == NULL) + if (unlikely (pen->vertices == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -139,7 +139,7 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) if (pen->vertices == pen->vertices_embedded) { vertices = _cairo_malloc_ab (num_vertices, sizeof (cairo_pen_vertex_t)); - if (vertices == NULL) + if (unlikely (vertices == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memcpy (vertices, pen->vertices, @@ -148,7 +148,7 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) vertices = _cairo_realloc_ab (pen->vertices, num_vertices, sizeof (cairo_pen_vertex_t)); - if (vertices == NULL) + if (unlikely (vertices == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -162,7 +162,7 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points) pen->vertices[pen->num_vertices-num_points+i].point = point[i]; status = _cairo_hull_compute (pen->vertices, &pen->num_vertices); - if (status) + if (unlikely (status)) return status; _cairo_pen_compute_slopes (pen); @@ -491,7 +491,7 @@ _cairo_pen_stroke_spline (cairo_pen_stroke_spline_t *stroker, 1); status = _cairo_polygon_status (&stroker->polygon); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_bentley_ottmann_tessellate_polygon (traps, @@ -548,7 +548,7 @@ _cairo_pen_stroke_spline_init (cairo_pen_stroke_spline_t *stroker, } status = _cairo_pen_init_copy (&stroker->pen, pen); - if (status) { + if (unlikely (status)) { _cairo_spline_fini (&stroker->spline); return status; } diff --git a/src/cairo-png.c b/src/cairo-png.c index 5bb658cb..fd16c4dc 100644 --- a/src/cairo-png.c +++ b/src/cairo-png.c @@ -159,7 +159,7 @@ write_png (cairo_surface_t *surface, if (status == CAIRO_INT_STATUS_UNSUPPORTED) return _cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH); - else if (status) + else if (unlikely (status)) return status; /* PNG complains about "Image width or height is zero in IHDR" */ @@ -169,7 +169,7 @@ write_png (cairo_surface_t *surface, } rows = _cairo_malloc_ab (image->height, sizeof (png_byte*)); - if (rows == NULL) { + if (unlikely (rows == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto BAIL1; } @@ -180,13 +180,13 @@ write_png (cairo_surface_t *surface, png = png_create_write_struct (PNG_LIBPNG_VER_STRING, &status, png_simple_error_callback, png_simple_warning_callback); - if (png == NULL) { + if (unlikely (png == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto BAIL2; } info = png_create_info_struct (png); - if (info == NULL) { + if (unlikely (info == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto BAIL3; } @@ -361,7 +361,7 @@ stream_write_func (png_structp png, png_bytep data, png_size_t size) png_closure = png_get_io_ptr (png); status = png_closure->write_func (png_closure->closure, data, size); - if (status) { + if (unlikely (status)) { cairo_status_t *error = png_get_error_ptr (png); if (*error == CAIRO_STATUS_SUCCESS) *error = status; @@ -486,7 +486,7 @@ stream_read_func (png_structp png, png_bytep data, png_size_t size) png_closure = png_get_io_ptr (png); status = png_closure->read_func (png_closure->closure, data, size); - if (status) { + if (unlikely (status)) { cairo_status_t *error = png_get_error_ptr (png); if (*error == CAIRO_STATUS_SUCCESS) *error = status; @@ -512,23 +512,24 @@ read_png (struct png_read_closure_t *png_closure) unsigned char *mime_data; unsigned int mime_data_length; + png_closure->png_data = _cairo_memory_stream_create (); + /* XXX: Perhaps we'll want some other error handlers? */ png = png_create_read_struct (PNG_LIBPNG_VER_STRING, &status, png_simple_error_callback, png_simple_warning_callback); - if (png == NULL) { + if (unlikely (png == NULL)) { surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); goto BAIL; } info = png_create_info_struct (png); - if (info == NULL) { + if (unlikely (info == NULL)) { surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); goto BAIL; } - png_closure->png_data = _cairo_memory_stream_create (); png_set_read_fn (png, png_closure, stream_read_func); status = CAIRO_STATUS_SUCCESS; @@ -544,7 +545,7 @@ read_png (struct png_read_closure_t *png_closure) png_get_IHDR (png, info, &png_width, &png_height, &depth, &color_type, &interlace, NULL, NULL); - if (status) { /* catch any early warnings */ + if (unlikely (status)) { /* catch any early warnings */ surface = _cairo_surface_create_in_error (status); goto BAIL; } @@ -620,13 +621,13 @@ read_png (struct png_read_closure_t *png_closure) } data = _cairo_malloc_ab (png_height, stride); - if (data == NULL) { + if (unlikely (data == NULL)) { surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); goto BAIL; } row_pointers = _cairo_malloc_ab (png_height, sizeof (char *)); - if (row_pointers == NULL) { + if (unlikely (row_pointers == NULL)) { surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); goto BAIL; } @@ -637,7 +638,7 @@ read_png (struct png_read_closure_t *png_closure) png_read_image (png, row_pointers); png_read_end (png, info); - if (status) { /* catch any late warnings - probably hit an error already */ + if (unlikely (status)) { /* catch any late warnings - probably hit an error already */ surface = _cairo_surface_create_in_error (status); goto BAIL; } @@ -654,11 +655,12 @@ read_png (struct png_read_closure_t *png_closure) status = _cairo_memory_stream_destroy (png_closure->png_data, &mime_data, &mime_data_length); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (surface); surface = _cairo_surface_create_in_error (status); goto BAIL; } + png_closure->png_data = NULL; status = cairo_surface_set_mime_data (surface, CAIRO_MIME_TYPE_PNG, @@ -666,7 +668,7 @@ read_png (struct png_read_closure_t *png_closure) mime_data_length, free, mime_data); - if (status) { + if (unlikely (status)) { free (mime_data); cairo_surface_destroy (surface); surface = _cairo_surface_create_in_error (status); @@ -674,12 +676,17 @@ read_png (struct png_read_closure_t *png_closure) } BAIL: - if (row_pointers) + if (row_pointers != NULL) free (row_pointers); - if (data) + if (data != NULL) free (data); - if (png) + if (png != NULL) png_destroy_read_struct (&png, &info, NULL); + if (png_closure->png_data != NULL) { + cairo_status_t status_ignored; + + status_ignored = _cairo_output_stream_destroy (png_closure->png_data); + } return surface; } diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c index 95cadc9c..0b0fa991 100644 --- a/src/cairo-polygon.c +++ b/src/cairo-polygon.c @@ -73,7 +73,7 @@ _cairo_polygon_grow (cairo_polygon_t *polygon) new_size, sizeof (cairo_edge_t)); } - if (new_edges == NULL) { + if (unlikely (new_edges == NULL)) { polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); return FALSE; } diff --git a/src/cairo-ps-surface.c b/src/cairo-ps-surface.c index 0c9ef7f4..a13be1d8 100644 --- a/src/cairo-ps-surface.c +++ b/src/cairo-ps-surface.c @@ -262,7 +262,7 @@ _cairo_ps_surface_emit_type1_font_subset (cairo_ps_surface_t *surface, snprintf (name, sizeof name, "f-%d-%d", font_subset->font_id, font_subset->subset_id); status = _cairo_type1_subset_init (&subset, name, font_subset, TRUE); - if (status) + if (unlikely (status)) return status; /* FIXME: Figure out document structure convention for fonts */ @@ -293,7 +293,7 @@ _cairo_ps_surface_emit_type1_font_fallback (cairo_ps_surface_t *surface, snprintf (name, sizeof name, "f-%d-%d", font_subset->font_id, font_subset->subset_id); status = _cairo_type1_fallback_init_hex (&subset, name, font_subset); - if (status) + if (unlikely (status)) return status; /* FIXME: Figure out document structure convention for fonts */ @@ -322,7 +322,7 @@ _cairo_ps_surface_emit_truetype_font_subset (cairo_ps_surface_t *surface, unsigned int i, begin, end; status = _cairo_truetype_subset_init (&subset, font_subset); - if (status) + if (unlikely (status)) return status; /* FIXME: Figure out document structure convention for fonts */ @@ -463,7 +463,7 @@ _cairo_ps_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_sub for (i = 0; i < font_subset->num_glyphs; i++) { status = _cairo_type3_glyph_surface_analyze_glyph (type3_surface, font_subset->glyphs[i]); - if (status) + if (unlikely (status)) break; } @@ -527,7 +527,7 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, font_subset->glyphs[i], &bbox, &width); - if (status) + if (unlikely (status)) break; _cairo_output_stream_printf (surface->final_stream, @@ -549,7 +549,7 @@ _cairo_ps_surface_emit_type3_font_subset (cairo_ps_surface_t *surface, } } cairo_surface_destroy (type3_surface); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->final_stream, @@ -635,19 +635,19 @@ _cairo_ps_surface_emit_font_subsets (cairo_ps_surface_t *surface) status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, _cairo_ps_surface_analyze_user_font_subset, surface); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_scaled_font_subsets_foreach_unscaled (surface->font_subsets, _cairo_ps_surface_emit_unscaled_font_subset, surface); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_scaled_font_subsets_foreach_scaled (surface->font_subsets, _cairo_ps_surface_emit_scaled_font_subset, surface); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_scaled_font_subsets_foreach_user (surface->font_subsets, @@ -705,7 +705,7 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, cairo_ps_surface_t *surface; surface = malloc (sizeof (cairo_ps_surface_t)); - if (surface == NULL) { + if (unlikely (surface == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP; } @@ -730,11 +730,11 @@ _cairo_ps_surface_create_for_stream_internal (cairo_output_stream_t *stream, surface->stream = _cairo_output_stream_create_for_file (surface->tmpfile); status = _cairo_output_stream_get_status (surface->stream); - if (status) + if (unlikely (status)) goto CLEANUP_OUTPUT_STREAM; surface->font_subsets = _cairo_scaled_font_subsets_create_simple (); - if (surface->font_subsets == NULL) { + if (unlikely (surface->font_subsets == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_OUTPUT_STREAM; } @@ -935,7 +935,7 @@ cairo_ps_surface_restrict_to_level (cairo_surface_t *surface, cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return; } @@ -1010,7 +1010,7 @@ cairo_ps_surface_set_eps (cairo_surface_t *surface, cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return; } @@ -1035,7 +1035,7 @@ cairo_ps_surface_get_eps (cairo_surface_t *surface) cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return FALSE; } @@ -1069,7 +1069,7 @@ cairo_ps_surface_set_size (cairo_surface_t *surface, cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return; } @@ -1082,7 +1082,7 @@ cairo_ps_surface_set_size (cairo_surface_t *surface, status = _cairo_paginated_surface_set_size (ps_surface->paginated_surface, width_in_points, height_in_points); - if (status) + if (unlikely (status)) status = _cairo_surface_set_error (surface, status); } @@ -1183,7 +1183,7 @@ cairo_ps_surface_dsc_comment (cairo_surface_t *surface, char *comment_copy; status = _extract_ps_surface (surface, &ps_surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return; } @@ -1201,13 +1201,13 @@ cairo_ps_surface_dsc_comment (cairo_surface_t *surface, /* Then, copy the comment and store it in the appropriate array. */ comment_copy = strdup (comment); - if (comment_copy == NULL) { + if (unlikely (comment_copy == NULL)) { status = _cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY); return; } status = _cairo_array_append (ps_surface->dsc_comment_target, &comment_copy); - if (status) { + if (unlikely (status)) { free (comment_copy); status = _cairo_surface_set_error (surface, status); return; @@ -1237,7 +1237,7 @@ cairo_ps_surface_dsc_begin_setup (cairo_surface_t *surface) cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return; } @@ -1272,7 +1272,7 @@ cairo_ps_surface_dsc_begin_page_setup (cairo_surface_t *surface) cairo_status_t status; status = _extract_ps_surface (surface, &ps_surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return; } @@ -1304,11 +1304,11 @@ _cairo_ps_surface_finish (void *abstract_surface) _cairo_ps_surface_emit_header (surface); status = _cairo_ps_surface_emit_font_subsets (surface); - if (status) + if (unlikely (status)) goto CLEANUP; status = _cairo_ps_surface_emit_body (surface); - if (status) + if (unlikely (status)) goto CLEANUP; _cairo_ps_surface_emit_footer (surface); @@ -1362,7 +1362,7 @@ _cairo_ps_surface_end_page (cairo_ps_surface_t *surface) cairo_int_status_t status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->stream, @@ -1378,7 +1378,7 @@ _cairo_ps_surface_show_page (void *abstract_surface) cairo_int_status_t status; status = _cairo_ps_surface_end_page (surface); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->stream, "showpage\n"); @@ -1407,7 +1407,7 @@ _cairo_ps_surface_analyze_surface_pattern_transparency (cairo_ps_surface_t status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra); - if (status) + if (unlikely (status)) return status; if (image->base.status) @@ -1733,7 +1733,7 @@ _string_array_stream_create (cairo_output_stream_t *output) string_array_stream_t *stream; stream = malloc (sizeof (string_array_stream_t)); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } @@ -1760,7 +1760,7 @@ _base85_array_stream_create (cairo_output_stream_t *output) string_array_stream_t *stream; stream = malloc (sizeof (string_array_stream_t)); - if (stream == NULL) { + if (unlikely (stream == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_output_stream_t *) &_cairo_output_stream_nil; } @@ -1809,7 +1809,7 @@ _cairo_ps_surface_flatten_image_transparency (cairo_ps_surface_t *surface, background_color, 0, 0, image->width, image->height); - if (status) + if (unlikely (status)) goto fail; status = _cairo_surface_composite (CAIRO_OPERATOR_OVER, @@ -1821,7 +1821,7 @@ _cairo_ps_surface_flatten_image_transparency (cairo_ps_surface_t *surface, 0, 0, image->width, image->height); - if (status) + if (unlikely (status)) goto fail; _cairo_pattern_fini (&pattern.base); @@ -1851,12 +1851,12 @@ _cairo_ps_surface_emit_base85_string (cairo_ps_surface_t *surface, string_array_stream = _base85_array_stream_create (surface->stream); status = _cairo_output_stream_get_status (string_array_stream); - if (status) + if (unlikely (status)) return _cairo_output_stream_destroy (string_array_stream); base85_stream = _cairo_base85_stream_create (string_array_stream); status = _cairo_output_stream_get_status (base85_stream); - if (status) { + if (unlikely (status)) { status2 = _cairo_output_stream_destroy (string_array_stream); return _cairo_output_stream_destroy (base85_stream); } @@ -1918,7 +1918,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, status = _cairo_ps_surface_flatten_image_transparency (surface, image, &opaque_image); - if (status) + if (unlikely (status)) return status; use_mask = FALSE; @@ -1940,7 +1940,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, data_size = image->height * image->width * 3; } data = malloc (data_size); - if (data == NULL) { + if (unlikely (data == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto bail1; } @@ -1989,7 +1989,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, * instead. */ data_compressed_size = data_size; data_compressed = _cairo_lzw_compress (data, &data_compressed_size); - if (data_compressed == NULL) { + if (unlikely (data_compressed == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto bail2; } @@ -2004,7 +2004,7 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface, data_compressed, data_compressed_size, TRUE); - if (status) + if (unlikely (status)) goto bail3; _cairo_output_stream_printf (surface->stream, @@ -2138,7 +2138,7 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface, return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_image_info_get_jpeg_info (&info, mime_data, mime_data_length); - if (status) + if (unlikely (status)) return status; if (info.num_components != 1 && info.num_components != 3) @@ -2154,7 +2154,7 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface, mime_data, mime_data_length, TRUE); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->stream, @@ -2219,7 +2219,7 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface, cairo_status_t status; status = _cairo_surface_get_extents (meta_surface, &meta_extents); - if (status) + if (unlikely (status)) return status; old_content = surface->content; @@ -2251,11 +2251,11 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface, status = _cairo_meta_surface_replay_region (meta_surface, &surface->base, CAIRO_META_REGION_NATIVE); assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->stream, @@ -2267,7 +2267,7 @@ _cairo_ps_surface_emit_meta_surface (cairo_ps_surface_t *surface, _cairo_pdf_operators_reset (&surface->pdf_operators); surface->cairo_to_ps = old_cairo_to_ps; status = _cairo_surface_set_clip (&surface->base, old_clip); - if (status) + if (unlikely (status)) return status; _cairo_pdf_operators_set_cairo_to_pdf_matrix (&surface->pdf_operators, @@ -2337,7 +2337,7 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface, cairo_rectangle_int_t pattern_extents; status = _cairo_surface_get_extents (meta_surface, &pattern_extents); - if (status) + if (unlikely (status)) return status; *width = pattern_extents.width; @@ -2346,7 +2346,7 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface, status = _cairo_surface_acquire_source_image (pattern->surface, &surface->acquired_image, &surface->image_extra); - if (status) + if (unlikely (status)) return status; pad_image = &surface->acquired_image->base; @@ -2383,7 +2383,7 @@ _cairo_ps_surface_acquire_surface (cairo_ps_surface_t *surface, rect.width, rect.height); _cairo_pattern_fini (&pad_pattern.base); - if (status) + if (unlikely (status)) goto BAIL; } @@ -2458,7 +2458,7 @@ _cairo_ps_surface_paint_surface (cairo_ps_surface_t *surface, extents, &width, &height, &origin_x, &origin_y); - if (status) + if (unlikely (status)) return status; cairo_p2d = pattern->base.matrix; @@ -2540,7 +2540,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, extents, &pattern_width, &pattern_height, &origin_x, &origin_y); - if (status) + if (unlikely (status)) return status; switch (pattern->base.extend) { @@ -2602,7 +2602,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, } status = _cairo_ps_surface_emit_surface (surface, pattern, op, pattern_width, pattern_height); - if (status) + if (unlikely (status)) return status; surface->use_string_datasource = old_use_string_datasource; @@ -2649,7 +2649,7 @@ _cairo_ps_surface_emit_surface_pattern (cairo_ps_surface_t *surface, ">>\n"); status = _cairo_surface_get_extents (&surface->base, &surface_extents); - if (status) + if (unlikely (status)) return status; cairo_p2d = pattern->base.matrix; @@ -2749,7 +2749,7 @@ _cairo_ps_surface_emit_pattern_stops (cairo_ps_surface_t *surface, unsigned int i, n_stops; allstops = _cairo_malloc_ab ((pattern->n_stops + 2), sizeof (cairo_ps_color_stop_t)); - if (allstops == NULL) + if (unlikely (allstops == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); stops = &allstops[1]; @@ -2955,7 +2955,7 @@ _cairo_ps_surface_emit_linear_pattern (cairo_ps_surface_t *surface, status = _cairo_ps_surface_emit_pattern_stops (surface, &pattern->base); - if (status) + if (unlikely (status)) return status; if (pattern->base.base.extend == CAIRO_EXTEND_REPEAT || @@ -2964,7 +2964,7 @@ _cairo_ps_surface_emit_linear_pattern (cairo_ps_surface_t *surface, &pattern->base, repeat_begin, repeat_end); - if (status) + if (unlikely (status)) return status; } @@ -3042,7 +3042,7 @@ _cairo_ps_surface_emit_radial_pattern (cairo_ps_surface_t *surface, r2 = _cairo_fixed_to_double (pattern->r2); status = _cairo_ps_surface_emit_pattern_stops (surface, &pattern->base); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->stream, @@ -3092,7 +3092,7 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, ! _cairo_color_equal (&surface->current_color, &solid->color)) { status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_ps_surface_emit_solid_pattern (surface, (cairo_solid_pattern_t *) pattern); @@ -3106,7 +3106,7 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, surface->current_pattern_is_solid_color = FALSE; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; switch (pattern->type) { @@ -3120,21 +3120,21 @@ _cairo_ps_surface_emit_pattern (cairo_ps_surface_t *surface, (cairo_surface_pattern_t *) pattern, extents, op); - if (status) + if (unlikely (status)) return status; break; case CAIRO_PATTERN_TYPE_LINEAR: status = _cairo_ps_surface_emit_linear_pattern (surface, (cairo_linear_pattern_t *) pattern); - if (status) + if (unlikely (status)) return status; break; case CAIRO_PATTERN_TYPE_RADIAL: status = _cairo_ps_surface_emit_radial_pattern (surface, (cairo_radial_pattern_t *) pattern); - if (status) + if (unlikely (status)) return status; break; } @@ -3163,7 +3163,7 @@ _cairo_ps_surface_intersect_clip_path (void *abstract_surface, if (path == NULL) { status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (stream, "Q q\n"); @@ -3230,11 +3230,11 @@ _cairo_ps_surface_paint (void *abstract_surface, #endif status = _cairo_surface_get_extents (&surface->base, &extents); - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; if (source->type == CAIRO_PATTERN_TYPE_SURFACE && @@ -3248,7 +3248,7 @@ _cairo_ps_surface_paint (void *abstract_surface, status = _cairo_ps_surface_paint_surface (surface, (cairo_surface_pattern_t *) source, paint_extents, op); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (stream, "Q\n"); @@ -3257,7 +3257,7 @@ _cairo_ps_surface_paint (void *abstract_surface, if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (stream, "0 0 %d %d rectfill\n", @@ -3332,7 +3332,7 @@ _cairo_ps_surface_fill (void *abstract_surface, source->extend == CAIRO_EXTEND_PAD)) { status = _cairo_pdf_operators_flush (&surface->pdf_operators); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->stream, "q\n"); @@ -3340,13 +3340,13 @@ _cairo_ps_surface_fill (void *abstract_surface, status = _cairo_pdf_operators_clip (&surface->pdf_operators, path, fill_rule); - if (status) + if (unlikely (status)) return status; status = _cairo_ps_surface_paint_surface (surface, (cairo_surface_pattern_t *) source, extents, op); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->stream, "Q\n"); @@ -3356,7 +3356,7 @@ _cairo_ps_surface_fill (void *abstract_surface, if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; status = _cairo_pdf_operators_fill (&surface->pdf_operators, @@ -3397,7 +3397,7 @@ _cairo_ps_surface_show_glyphs (void *abstract_surface, if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; - if (status) + if (unlikely (status)) return status; return _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators, @@ -3503,6 +3503,8 @@ static const cairo_surface_backend_t cairo_ps_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* cairo_ps_surface_copy_page */ _cairo_ps_surface_show_page, NULL, /* set_clip_region */ diff --git a/src/cairo-quartz-image-surface.c b/src/cairo-quartz-image-surface.c index 3eee2c11..3bfd9e21 100644 --- a/src/cairo-quartz-image-surface.c +++ b/src/cairo-quartz-image-surface.c @@ -163,6 +163,8 @@ static const cairo_surface_backend_t cairo_quartz_image_surface_backend = { 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 */ diff --git a/src/cairo-quartz-surface.c b/src/cairo-quartz-surface.c index 19160b4b..34661853 100644 --- a/src/cairo-quartz-surface.c +++ b/src/cairo-quartz-surface.c @@ -680,15 +680,21 @@ ComputeGradientValue (void *info, const float *in, float *out) } static CGFunctionRef -CreateGradientFunction (cairo_gradient_pattern_t *gpat) +CreateGradientFunction (const cairo_gradient_pattern_t *gpat) { + cairo_pattern_t *pat; float input_value_range[2] = { 0.f, 1.f }; float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f }; CGFunctionCallbacks callbacks = { 0, ComputeGradientValue, (CGFunctionReleaseInfoCallback) cairo_pattern_destroy }; - return CGFunctionCreate (cairo_pattern_reference (&gpat->base), + if (_cairo_pattern_create_copy (&pat, &gpat->base)) + /* quartz doesn't deal very well with malloc failing, so there's + * not much point in us trying either */ + return NULL; + + return CGFunctionCreate (pat, 1, input_value_range, 4, @@ -698,10 +704,11 @@ CreateGradientFunction (cairo_gradient_pattern_t *gpat) static CGFunctionRef CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface, - cairo_gradient_pattern_t *gpat, + const cairo_gradient_pattern_t *gpat, CGPoint *start, CGPoint *end, CGAffineTransform matrix) { + cairo_pattern_t *pat; float input_value_range[2]; float output_value_ranges[8] = { 0.f, 1.f, 0.f, 1.f, 0.f, 1.f, 0.f, 1.f }; CGFunctionCallbacks callbacks = { @@ -766,7 +773,12 @@ CreateRepeatingGradientFunction (cairo_quartz_surface_t *surface, input_value_range[0] = 0.0 - 1.0 * rep_start; input_value_range[1] = 1.0 + 1.0 * rep_end; - return CGFunctionCreate (cairo_pattern_reference (&gpat->base), + if (_cairo_pattern_create_copy (&pat, &gpat->base)) + /* quartz doesn't deal very well with malloc failing, so there's + * not much point in us trying either */ + return NULL; + + return CGFunctionCreate (pat, 1, input_value_range, 4, @@ -1013,7 +1025,7 @@ typedef enum { static cairo_quartz_action_t _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface, - cairo_pattern_t *source) + const cairo_pattern_t *source) { CGRect clipBox = CGContextGetClipBoundingBox (surface->cgContext); CGAffineTransform ctm; @@ -1022,6 +1034,7 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface, cairo_surface_t *fallback; cairo_t *fallback_cr; CGImageRef img; + cairo_pattern_t *source_copy; cairo_status_t status; @@ -1050,7 +1063,13 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface, /* Paint the source onto our temporary */ fallback_cr = cairo_create (fallback); cairo_set_operator (fallback_cr, CAIRO_OPERATOR_SOURCE); - cairo_set_source (fallback_cr, source); + + /* Use a copy of the pattern because it is const and could be allocated + * on the stack */ + status = _cairo_pattern_create_copy (&source_copy, source); + cairo_set_source (fallback_cr, source_copy); + cairo_pattern_destroy (source_copy); + cairo_paint (fallback_cr); cairo_destroy (fallback_cr); @@ -1070,9 +1089,9 @@ _cairo_quartz_setup_fallback_source (cairo_quartz_surface_t *surface, static cairo_quartz_action_t _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface, - cairo_linear_pattern_t *lpat) + const cairo_linear_pattern_t *lpat) { - cairo_pattern_t *abspat = (cairo_pattern_t *) lpat; + const cairo_pattern_t *abspat = &lpat->base.base; cairo_matrix_t mat; CGPoint start, end; CGFunctionRef gradFunc; @@ -1085,7 +1104,7 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface, return DO_SOLID; } - cairo_pattern_get_matrix (abspat, &mat); + mat = abspat->matrix; cairo_matrix_invert (&mat); _cairo_quartz_cairo_matrix_to_quartz (&mat, &surface->sourceTransform); @@ -1099,10 +1118,10 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface, if (abspat->extend == CAIRO_EXTEND_NONE || abspat->extend == CAIRO_EXTEND_PAD) { - gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) lpat); + gradFunc = CreateGradientFunction (&lpat->base); } else { gradFunc = CreateRepeatingGradientFunction (surface, - (cairo_gradient_pattern_t*) lpat, + &lpat->base, &start, &end, surface->sourceTransform); } @@ -1119,9 +1138,9 @@ _cairo_quartz_setup_linear_source (cairo_quartz_surface_t *surface, static cairo_quartz_action_t _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface, - cairo_radial_pattern_t *rpat) + const cairo_radial_pattern_t *rpat) { - cairo_pattern_t *abspat = (cairo_pattern_t *)rpat; + const cairo_pattern_t *abspat = &rpat->base.base; cairo_matrix_t mat; CGPoint start, end; CGFunctionRef gradFunc; @@ -1142,10 +1161,10 @@ _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface, * Radial shadings). So, instead, let's just render an image * for pixman to draw the shading into, and use that. */ - return _cairo_quartz_setup_fallback_source (surface, (cairo_pattern_t*) rpat); + return _cairo_quartz_setup_fallback_source (surface, &rpat->base.base); } - cairo_pattern_get_matrix (abspat, &mat); + mat = abspat->matrix; cairo_matrix_invert (&mat); _cairo_quartz_cairo_matrix_to_quartz (&mat, &surface->sourceTransform); @@ -1156,7 +1175,7 @@ _cairo_quartz_setup_radial_source (cairo_quartz_surface_t *surface, end = CGPointMake (_cairo_fixed_to_double (rpat->c2.x), _cairo_fixed_to_double (rpat->c2.y)); - gradFunc = CreateGradientFunction ((cairo_gradient_pattern_t*) rpat); + gradFunc = CreateGradientFunction (&rpat->base); surface->sourceShading = CGShadingCreateRadial (rgb, start, @@ -1199,13 +1218,13 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface, } if (source->type == CAIRO_PATTERN_TYPE_LINEAR) { - cairo_linear_pattern_t *lpat = (cairo_linear_pattern_t *)source; + const cairo_linear_pattern_t *lpat = (const cairo_linear_pattern_t *)source; return _cairo_quartz_setup_linear_source (surface, lpat); } if (source->type == CAIRO_PATTERN_TYPE_RADIAL) { - cairo_radial_pattern_t *rpat = (cairo_radial_pattern_t *)source; + const cairo_radial_pattern_t *rpat = (const cairo_radial_pattern_t *)source; return _cairo_quartz_setup_radial_source (surface, rpat); } @@ -1213,7 +1232,7 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface, if (source->type == CAIRO_PATTERN_TYPE_SURFACE && (source->extend == CAIRO_EXTEND_NONE || (CGContextDrawTiledImagePtr && source->extend == CAIRO_EXTEND_REPEAT))) { - cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source; + const cairo_surface_pattern_t *spat = (const cairo_surface_pattern_t *) source; cairo_surface_t *pat_surf = spat->surface; CGImageRef img; cairo_matrix_t m = spat->base.matrix; @@ -2259,7 +2278,7 @@ _cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface, cairo_t *gradient_surf_cr = NULL; cairo_surface_pattern_t surface_pattern; - cairo_pattern_t *mask_copy = NULL; + cairo_pattern_t *mask_copy; cairo_int_status_t status; /* Render the gradient to a surface */ @@ -2271,13 +2290,13 @@ _cairo_quartz_surface_mask_with_generic (cairo_quartz_surface_t *surface, /* make a copy of the pattern because because cairo_set_source doesn't take * a 'const cairo_pattern_t *' */ _cairo_pattern_create_copy (&mask_copy, mask); - cairo_set_source (gradient_surf_cr, mask_copy); + cairo_pattern_destroy (mask_copy); + cairo_set_operator (gradient_surf_cr, CAIRO_OPERATOR_SOURCE); cairo_paint (gradient_surf_cr); status = cairo_status (gradient_surf_cr); cairo_destroy (gradient_surf_cr); - cairo_pattern_destroy (mask_copy); if (status) goto BAIL; @@ -2404,6 +2423,8 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = { 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 */ diff --git a/src/cairo-rectangle.c b/src/cairo-rectangle.c index 2143f0c6..9a68409c 100644 --- a/src/cairo-rectangle.c +++ b/src/cairo-rectangle.c @@ -223,3 +223,24 @@ _cairo_box_contains_point (cairo_box_t *box, cairo_point_t *point) return FALSE; return TRUE; } + +void +_cairo_composite_rectangles_init( + cairo_composite_rectangles_t *rects, + int all_x, + int all_y, + int width, + int height) +{ + rects->src.x = all_x; + rects->src.y = all_y; + rects->mask.x = all_x; + rects->mask.y = all_y; + rects->clip.x = all_x; + rects->clip.y = all_y; + rects->dst.x = all_x; + rects->dst.y = all_y; + + rects->width = width; + rects->height = height; +} diff --git a/src/cairo-region-private.h b/src/cairo-region-private.h index 588762e5..1f4cfb47 100644 --- a/src/cairo-region-private.h +++ b/src/cairo-region-private.h @@ -96,6 +96,11 @@ _cairo_region_intersect (cairo_region_t *dst, cairo_region_t *b); cairo_private cairo_int_status_t +_cairo_region_union (cairo_region_t *dst, + cairo_region_t *a, + cairo_region_t *b); + +cairo_private cairo_int_status_t _cairo_region_union_rect (cairo_region_t *dst, cairo_region_t *src, cairo_rectangle_int_t *rect); diff --git a/src/cairo-region.c b/src/cairo-region.c index 146ae60b..376dbc84 100644 --- a/src/cairo-region.c +++ b/src/cairo-region.c @@ -64,7 +64,7 @@ _cairo_region_init_boxes (cairo_region_t *region, if (count > ARRAY_LENGTH (stack_pboxes)) { pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t)); - if (pboxes == NULL) + if (unlikely (pboxes == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -181,6 +181,17 @@ _cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t return CAIRO_STATUS_SUCCESS; } +cairo_private cairo_int_status_t +_cairo_region_union (cairo_region_t *dst, + cairo_region_t *a, + cairo_region_t *b) +{ + if (!pixman_region_union (&dst->rgn, &a->rgn, &b->rgn)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + return CAIRO_STATUS_SUCCESS; +} + cairo_int_status_t _cairo_region_union_rect (cairo_region_t *dst, cairo_region_t *src, diff --git a/src/cairo-scaled-font-subsets.c b/src/cairo-scaled-font-subsets.c index d8771bba..c802c314 100644 --- a/src/cairo-scaled-font-subsets.c +++ b/src/cairo-scaled-font-subsets.c @@ -163,7 +163,7 @@ _cairo_sub_font_glyph_create (unsigned long scaled_font_glyph_index, cairo_sub_font_glyph_t *sub_font_glyph; sub_font_glyph = malloc (sizeof (cairo_sub_font_glyph_t)); - if (sub_font_glyph == NULL) { + if (unlikely (sub_font_glyph == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return NULL; } @@ -267,7 +267,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, cairo_scaled_font_subsets_glyph_t subset_glyph; sub_font = malloc (sizeof (cairo_sub_font_t)); - if (sub_font == NULL) + if (unlikely (sub_font == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); sub_font->is_scaled = is_scaled; @@ -284,7 +284,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, sub_font->max_glyphs_per_subset = max_glyphs_per_subset; sub_font->sub_font_glyphs = _cairo_hash_table_create (_cairo_sub_font_glyphs_equal); - if (sub_font->sub_font_glyphs == NULL) { + if (unlikely (sub_font->sub_font_glyphs == NULL)) { free (sub_font); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -294,7 +294,7 @@ _cairo_sub_font_create (cairo_scaled_font_subsets_t *parent, * Type 3 fonts */ if (! _cairo_font_face_is_user (scaled_font->font_face)) { status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &subset_glyph); - if (status) { + if (unlikely (status)) { _cairo_hash_table_destroy (sub_font->sub_font_glyphs); free (sub_font); return status; @@ -349,7 +349,7 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph, status = scaled_font->backend->index_to_ucs4 (scaled_font, scaled_font_glyph_index, &unicode); - if (status) + if (unlikely (status)) return status; } @@ -360,7 +360,7 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph, len = _cairo_ucs4_to_utf8 (unicode, buf); if (len > 0) { sub_font_glyph->utf8 = malloc (len + 1); - if (sub_font_glyph->utf8 == NULL) + if (unlikely (sub_font_glyph->utf8 == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memcpy (sub_font_glyph->utf8, buf, len); @@ -466,7 +466,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, * except for Type 3 fonts */ if (! _cairo_font_face_is_user (sub_font->scaled_font->font_face)) { status = _cairo_sub_font_map_glyph (sub_font, 0, NULL, -1, &tmp_subset_glyph); - if (status) + if (unlikely (status)) return status; } } @@ -477,7 +477,7 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); assert (status != CAIRO_INT_STATUS_UNSUPPORTED); - if (status) { + if (unlikely (status)) { _cairo_scaled_font_thaw_cache (sub_font->scaled_font); return status; } @@ -489,19 +489,19 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font, scaled_glyph->metrics.y_advance); _cairo_scaled_font_thaw_cache (sub_font->scaled_font); - if (sub_font_glyph == NULL) + if (unlikely (sub_font_glyph == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _cairo_sub_font_glyph_lookup_unicode (sub_font_glyph, sub_font->scaled_font, scaled_font_glyph_index); - if (status) { + if (unlikely (status)) { _cairo_sub_font_glyph_destroy (sub_font_glyph); return status; } status = _cairo_hash_table_insert (sub_font->sub_font_glyphs, &sub_font_glyph->base); - if (status) { + if (unlikely (status)) { _cairo_sub_font_glyph_destroy (sub_font_glyph); return status; } @@ -596,8 +596,8 @@ _cairo_scaled_font_subsets_create_internal (cairo_subsets_type_t type) { cairo_scaled_font_subsets_t *subsets; - subsets = malloc (sizeof (cairo_scaled_font_subsets_t)); - if (subsets == NULL) { + subsets = malloc (sizeof (cairo_scaled_font_subsets_t)); + if (unlikely (subsets == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return NULL; } @@ -744,7 +744,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, &identity, &identity, &font_options); - if (unscaled_font->status) + if (unlikely (unscaled_font->status)) return unscaled_font->status; subset_glyph->is_scaled = FALSE; @@ -768,7 +768,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, subset_glyph->is_composite, &sub_font); - if (status) { + if (unlikely (status)) { cairo_scaled_font_destroy (unscaled_font); return status; } @@ -776,7 +776,7 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, status = _cairo_hash_table_insert (subsets->unscaled_sub_fonts, &sub_font->base); - if (status) { + if (unlikely (status)) { _cairo_sub_font_destroy (sub_font); return status; } @@ -808,14 +808,14 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets, subset_glyph->is_scaled, subset_glyph->is_composite, &sub_font); - if (status) { + if (unlikely (status)) { cairo_scaled_font_destroy (scaled_font); return status; } status = _cairo_hash_table_insert (subsets->scaled_sub_fonts, &sub_font->base); - if (status) { + if (unlikely (status)) { _cairo_sub_font_destroy (sub_font); return status; } @@ -866,7 +866,7 @@ _cairo_scaled_font_subsets_foreach_internal (cairo_scaled_font_subsets_t collection.glyphs = _cairo_malloc_ab (collection.glyphs_size, sizeof(unsigned long)); collection.utf8 = _cairo_malloc_ab (collection.glyphs_size, sizeof(char *)); - if (collection.glyphs == NULL || collection.utf8 == NULL) { + if (unlikely (collection.glyphs == NULL || collection.utf8 == NULL)) { if (collection.glyphs != NULL) free (collection.glyphs); if (collection.utf8 != NULL) @@ -957,7 +957,7 @@ static cairo_status_t create_string_entry (char *s, cairo_string_entry_t **entry) { *entry = malloc (sizeof (cairo_string_entry_t)); - if (*entry == NULL) + if (unlikely (*entry == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); _cairo_string_init_key (*entry, s); @@ -985,11 +985,11 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset cairo_status_t status = CAIRO_STATUS_SUCCESS; names = _cairo_hash_table_create (_cairo_string_equal); - if (names == NULL) + if (unlikely (names == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); subset->glyph_names = calloc (subset->num_glyphs, sizeof (char *)); - if (subset->glyph_names == NULL) { + if (unlikely (subset->glyph_names == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } @@ -997,17 +997,17 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset i = 0; if (! _cairo_font_face_is_user (subset->scaled_font->font_face)) { subset->glyph_names[0] = strdup (".notdef"); - if (subset->glyph_names[0] == NULL) { + if (unlikely (subset->glyph_names[0] == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } status = create_string_entry (subset->glyph_names[0], &entry); - if (status) + if (unlikely (status)) goto CLEANUP_HASH; status = _cairo_hash_table_insert (names, &entry->base); - if (status) { + if (unlikely (status)) { free (entry); goto CLEANUP_HASH; } @@ -1020,7 +1020,7 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset utf16_len = 0; if (utf8 && *utf8) { status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len); - if (status) + if (unlikely (status)) return status; /* FIXME */ } @@ -1037,17 +1037,17 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset free (utf16); subset->glyph_names[i] = strdup (buf); - if (subset->glyph_names[i] == NULL) { + if (unlikely (subset->glyph_names[i] == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_HASH; } status = create_string_entry (subset->glyph_names[i], &entry); - if (status) + if (unlikely (status)) goto CLEANUP_HASH; status = _cairo_hash_table_insert (names, &entry->base); - if (status) { + if (unlikely (status)) { free (entry); goto CLEANUP_HASH; } diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 8b749940..ca86f512 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -321,14 +321,14 @@ _cairo_scaled_font_map_lock (void) if (cairo_scaled_font_map == NULL) { cairo_scaled_font_map = malloc (sizeof (cairo_scaled_font_map_t)); - if (cairo_scaled_font_map == NULL) + if (unlikely (cairo_scaled_font_map == NULL)) goto CLEANUP_MUTEX_LOCK; cairo_scaled_font_map->mru_scaled_font = NULL; cairo_scaled_font_map->hash_table = _cairo_hash_table_create (_cairo_scaled_font_keys_equal); - if (cairo_scaled_font_map->hash_table == NULL) + if (unlikely (cairo_scaled_font_map->hash_table == NULL)) goto CLEANUP_SCALED_FONT_MAP; cairo_scaled_font_map->num_holdovers = 0; @@ -360,7 +360,7 @@ _cairo_scaled_font_map_destroy (void) CAIRO_MUTEX_LOCK (_cairo_scaled_font_map_mutex); font_map = cairo_scaled_font_map; - if (font_map == NULL) { + if (unlikely (font_map == NULL)) { goto CLEANUP_MUTEX_LOCK; } @@ -425,11 +425,11 @@ _cairo_scaled_font_register_placeholder_and_unlock_font_map (cairo_scaled_font_t assert (CAIRO_MUTEX_IS_LOCKED (_cairo_scaled_font_map_mutex)); status = scaled_font->status; - if (status) + if (unlikely (status)) return status; placeholder_scaled_font = malloc (sizeof (cairo_scaled_font_t)); - if (placeholder_scaled_font == NULL) + if (unlikely (placeholder_scaled_font == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); /* full initialization is wasteful, but who cares... */ @@ -439,14 +439,14 @@ _cairo_scaled_font_register_placeholder_and_unlock_font_map (cairo_scaled_font_t &scaled_font->ctm, &scaled_font->options, NULL); - if (status) + if (unlikely (status)) goto FREE_PLACEHOLDER; placeholder_scaled_font->placeholder = TRUE; status = _cairo_hash_table_insert (cairo_scaled_font_map->hash_table, &placeholder_scaled_font->hash_entry); - if (status) + if (unlikely (status)) goto FINI_PLACEHOLDER; CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_map_mutex); @@ -599,7 +599,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, cairo_status_t status; status = cairo_font_options_status ((cairo_font_options_t *) options); - if (status) + if (unlikely (status)) return status; _cairo_scaled_font_init_key (scaled_font, font_face, @@ -613,7 +613,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, fabs (scaled_font->scale.yx) + fabs (scaled_font->scale.yy)); scaled_font->scale_inverse = scaled_font->scale; status = cairo_matrix_invert (&scaled_font->scale_inverse); - if (status) { + if (unlikely (status)) { /* If the font scale matrix is rank 0, just using an all-zero inverse matrix * makes everything work correctly. This make font size 0 work without * producing an error. @@ -638,7 +638,7 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font, scaled_font->glyphs = _cairo_cache_create (_cairo_scaled_glyph_keys_equal, _cairo_scaled_glyph_destroy, MAX_GLYPHS_CACHED_PER_FONT); - if (scaled_font->glyphs == NULL) + if (unlikely (scaled_font->glyphs == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); CAIRO_REFERENCE_COUNT_INIT (&scaled_font->ref_count, 1); @@ -697,7 +697,7 @@ _cairo_scaled_font_set_metrics (cairo_scaled_font_t *scaled_font, status = _cairo_matrix_compute_basis_scale_factors (&scaled_font->font_matrix, &font_scale_x, &font_scale_y, 1); - if (status) + if (unlikely (status)) return status; /* @@ -782,7 +782,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, return _cairo_scaled_font_create_in_error (font_face->status); status = cairo_font_options_status ((cairo_font_options_t *) options); - if (status) + if (unlikely (status)) return _cairo_scaled_font_create_in_error (status); /* Note that degenerate ctm or font_matrix *are* allowed. @@ -791,13 +791,13 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, if (font_face->backend->get_implementation != NULL) { /* indirect implementation, lookup the face that is used for the key */ status = font_face->backend->get_implementation (font_face, &impl_face); - if (status) + if (unlikely (status)) return _cairo_scaled_font_create_in_error (status); } else impl_face = font_face; font_map = _cairo_scaled_font_map_lock (); - if (font_map == NULL) + if (unlikely (font_map == NULL)) return _cairo_scaled_font_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_scaled_font_init_key (&key, impl_face, @@ -889,7 +889,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, /* Otherwise create it and insert it into the hash table. */ status = font_face->backend->scaled_font_create (font_face, font_matrix, ctm, options, &scaled_font); - if (status) { + if (unlikely (status)) { _cairo_scaled_font_map_unlock (); status = _cairo_font_face_set_error (font_face, status); return _cairo_scaled_font_create_in_error (status); @@ -905,7 +905,7 @@ cairo_scaled_font_create (cairo_font_face_t *font_face, _cairo_scaled_font_map_unlock (); - if (status) { + if (unlikely (status)) { /* We can't call _cairo_scaled_font_destroy here since it expects * that the font has already been successfully inserted into the * hash table. */ @@ -935,9 +935,9 @@ _cairo_scaled_font_create_in_error (cairo_status_t status) CAIRO_MUTEX_LOCK (_cairo_scaled_font_error_mutex); scaled_font = _cairo_scaled_font_nil_objects[status]; - if (scaled_font == NULL) { + if (unlikely (scaled_font == NULL)) { scaled_font = malloc (sizeof (cairo_scaled_font_t)); - if (scaled_font == NULL) { + if (unlikely (scaled_font == NULL)) { CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_error_mutex); _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return (cairo_scaled_font_t *) &_cairo_scaled_font_nil; @@ -1221,7 +1221,7 @@ cairo_scaled_font_text_extents (cairo_scaled_font_t *scaled_font, &glyphs, &num_glyphs, NULL, NULL, NULL); - if (status) { + if (unlikely (status)) { status = _cairo_scaled_font_set_error (scaled_font, status); goto ZERO_EXTENTS; } @@ -1304,7 +1304,7 @@ cairo_scaled_font_glyph_extents (cairo_scaled_font_t *scaled_font, glyphs[i].index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); - if (status) { + if (unlikely (status)) { status = _cairo_scaled_font_set_error (scaled_font, status); goto UNLOCK; } @@ -1521,7 +1521,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, cairo_text_cluster_t *orig_clusters; status = scaled_font->status; - if (status) + if (unlikely (status)) return status; /* A slew of sanity checks */ @@ -1584,7 +1584,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, /* validate input so backend does not have to */ status = _cairo_utf8_to_ucs4 (utf8, utf8_len, NULL, &num_chars); - if (status) + if (unlikely (status)) goto BAIL; _cairo_scaled_font_freeze_cache (scaled_font); @@ -1642,7 +1642,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, if (*num_glyphs < num_chars) { *glyphs = cairo_glyph_allocate (num_chars); - if (*glyphs == NULL) { + if (unlikely (*glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto DONE; } @@ -1652,7 +1652,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, if (clusters) { if (*num_clusters < num_chars) { *clusters = cairo_text_cluster_allocate (num_chars); - if (*clusters == NULL) { + if (unlikely (*clusters == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto DONE; } @@ -1682,7 +1682,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, (*glyphs)[i].index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); - if (status) { + if (unlikely (status)) { goto DONE; } @@ -1693,7 +1693,7 @@ cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, DONE: /* error that should be logged on scaled_font happened */ _cairo_scaled_font_thaw_cache (scaled_font); - if (status) { + if (unlikely (status)) { *num_glyphs = 0; if (*glyphs != orig_glyphs) { cairo_glyph_free (*glyphs); @@ -1752,7 +1752,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font, glyphs[i].index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); - if (status) + if (unlikely (status)) break; /* XXX glyph images are snapped to pixel locations */ @@ -1771,7 +1771,7 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font, } _cairo_scaled_font_thaw_cache (scaled_font); - if (status) + if (unlikely (status)) return _cairo_scaled_font_set_error (scaled_font, status); if (min.x < max.x && min.y < max.y) { @@ -1853,7 +1853,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); - if (status) + if (unlikely (status)) goto CLEANUP_MASK; glyph_surface = scaled_glyph->surface; @@ -1864,10 +1864,9 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, mask_format = glyph_surface->format; mask = cairo_image_surface_create (mask_format, width, height); - if (mask->status) { - status = mask->status; + status = mask->status; + if (unlikely (status)) goto CLEANUP_MASK; - } } /* If we have glyphs of different formats, we "upgrade" the mask @@ -1912,7 +1911,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, _cairo_pattern_fini (&mask_pattern.base); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (new_mask); goto CLEANUP_MASK; } @@ -1940,7 +1939,7 @@ _cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font, _cairo_pattern_fini (&glyph_pattern.base); - if (status) + if (unlikely (status)) goto CLEANUP_MASK; } @@ -2027,29 +2026,29 @@ _add_unit_rectangle_to_path (cairo_path_fixed_t *path, int x, int y) status = _cairo_path_fixed_move_to (path, _cairo_fixed_from_int (x), _cairo_fixed_from_int (y)); - if (status) + if (unlikely (status)) return status; status = _cairo_path_fixed_rel_line_to (path, _cairo_fixed_from_int (1), _cairo_fixed_from_int (0)); - if (status) + if (unlikely (status)) return status; status = _cairo_path_fixed_rel_line_to (path, _cairo_fixed_from_int (0), _cairo_fixed_from_int (1)); - if (status) + if (unlikely (status)) return status; status = _cairo_path_fixed_rel_line_to (path, _cairo_fixed_from_int (-1), _cairo_fixed_from_int (0)); - if (status) + if (unlikely (status)) return status; status = _cairo_path_fixed_close_path (path); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -2089,7 +2088,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask, a1_mask = _cairo_image_surface_clone (mask, CAIRO_FORMAT_A1); status = cairo_surface_status (&a1_mask->base); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (&a1_mask->base); return status; } @@ -2104,7 +2103,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask, if (byte & (1 << bit)) { status = _add_unit_rectangle_to_path (path, x - xoff, y - yoff); - if (status) + if (unlikely (status)) goto BAIL; } } @@ -2129,7 +2128,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, cairo_path_fixed_t *glyph_path; status = scaled_font->status; - if (status) + if (unlikely (status)) return status; closure.path = path; @@ -2153,17 +2152,17 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, glyphs[i].index, CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); - if (status) + if (unlikely (status)) goto BAIL; glyph_path = _cairo_path_fixed_create (); - if (glyph_path == NULL) { + if (unlikely (glyph_path == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto BAIL; } status = _trace_mask_to_path (scaled_glyph->surface, glyph_path); - if (status) { + if (unlikely (status)) { _cairo_path_fixed_destroy (glyph_path); goto BAIL; } @@ -2182,7 +2181,7 @@ _cairo_scaled_font_glyph_path (cairo_scaled_font_t *scaled_font, if (glyph_path != scaled_glyph->path) _cairo_path_fixed_destroy (glyph_path); - if (status) + if (unlikely (status)) goto BAIL; } BAIL: @@ -2361,7 +2360,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, * On miss, create glyph and insert into cache */ scaled_glyph = malloc (sizeof (cairo_scaled_glyph_t)); - if (scaled_glyph == NULL) { + if (unlikely (scaled_glyph == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP; } @@ -2377,7 +2376,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, /* ask backend to initialize metrics and shape fields */ status = (*scaled_font->backend-> scaled_glyph_init) (scaled_font, scaled_glyph, info); - if (status) { + if (unlikely (status)) { _cairo_scaled_glyph_destroy (scaled_glyph); goto CLEANUP; } @@ -2385,7 +2384,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, /* on success, the cache takes ownership of the scaled_glyph */ status = _cairo_cache_insert (scaled_font->glyphs, &scaled_glyph->cache_entry); - if (status) { + if (unlikely (status)) { _cairo_scaled_glyph_destroy (scaled_glyph); goto CLEANUP; } @@ -2410,7 +2409,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, if (need_info) { status = (*scaled_font->backend-> scaled_glyph_init) (scaled_font, scaled_glyph, need_info); - if (status) + if (unlikely (status)) goto CLEANUP; /* Don't trust the scaled_glyph_init() return value, the font @@ -2438,7 +2437,7 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font, } CLEANUP: - if (status) { + if (unlikely (status)) { /* It's not an error for the backend to not support the info we want. */ if (status != CAIRO_INT_STATUS_UNSUPPORTED) status = _cairo_scaled_font_set_error (scaled_font, status); diff --git a/src/cairo-script-surface.c b/src/cairo-script-surface.c index 9118d66d..cf2809f5 100644 --- a/src/cairo-script-surface.c +++ b/src/cairo-script-surface.c @@ -186,7 +186,7 @@ _bitmap_next_id (struct _bitmap *b, } while (b != NULL); bb = malloc (sizeof (struct _bitmap)); - if (bb == NULL) + if (unlikely (bb == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); *prev = bb; @@ -335,7 +335,7 @@ _emit_context (cairo_script_surface_t *surface) status = _bitmap_next_id (&surface->ctx->surface_id, &surface->id); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->ctx->stream, @@ -586,25 +586,25 @@ _emit_stroke_style (cairo_script_surface_t *surface, assert (_cairo_script_surface_owns_context (surface)); status = _emit_line_width (surface, style->line_width, force); - if (status) + if (unlikely (status)) return status; status = _emit_line_cap (surface, style->line_cap); - if (status) + if (unlikely (status)) return status; status = _emit_line_join (surface, style->line_join); - if (status) + if (unlikely (status)) return status; status = _emit_miter_limit (surface, style->miter_limit, force); - if (status) + if (unlikely (status)) return status; status = _emit_dash (surface, style->dash, style->num_dashes, style->dash_offset, force); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -750,13 +750,13 @@ _emit_meta_surface_pattern (cairo_script_surface_t *surface, cairo_surface_destroy (null_surface); status = analysis_surface->status; - if (status) + if (unlikely (status)) return status; status = _cairo_meta_surface_replay (source, analysis_surface); _cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox); cairo_surface_destroy (analysis_surface); - if (status) + if (unlikely (status)) return status; similar = cairo_surface_create_similar (&surface->base, @@ -767,13 +767,13 @@ _emit_meta_surface_pattern (cairo_script_surface_t *surface, return similar->status; status = _cairo_meta_surface_replay (source, similar); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (similar); return status; } status = _emit_context (surface); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (similar); return status; } @@ -852,7 +852,7 @@ _write_image_surface (cairo_output_stream_t *output, #else if (stride > ARRAY_LENGTH (row_stack)) { rowdata = malloc (stride); - if (rowdata == NULL) + if (unlikely (rowdata == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } else rowdata = row_stack; @@ -936,7 +936,7 @@ _emit_png_surface (cairo_script_surface_t *surface, base85_stream = _cairo_base85_stream_create (surface->ctx->stream); _cairo_output_stream_write (base85_stream, mime_data, mime_data_length); status = _cairo_output_stream_destroy (base85_stream); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, @@ -979,7 +979,7 @@ _emit_image_surface (cairo_script_surface_t *surface, status2 = _cairo_output_stream_destroy (base85_stream); if (status == CAIRO_STATUS_SUCCESS) status = status2; - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, @@ -1006,7 +1006,7 @@ _emit_image_surface (cairo_script_surface_t *surface, base85_stream = _cairo_base85_stream_create (surface->ctx->stream); _cairo_output_stream_write (base85_stream, mime_data, mime_data_length); status = _cairo_output_stream_destroy (base85_stream); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, @@ -1034,7 +1034,7 @@ _emit_image_surface_pattern (cairo_script_surface_t *surface, /* XXX snapshot-cow */ status = _cairo_surface_acquire_source_image (source, &image, &image_extra); - if (status) + if (unlikely (status)) return status; status = _emit_image_surface (surface, image); @@ -1089,7 +1089,7 @@ _emit_pattern (cairo_script_surface_t *surface, ASSERT_NOT_REACHED; status = CAIRO_INT_STATUS_UNSUPPORTED; } - if (status) + if (unlikely (status)) return status; if (! _cairo_matrix_is_identity (&pattern->matrix)) { @@ -1151,15 +1151,15 @@ _emit_source (cairo_script_surface_t *surface, cairo_pattern_destroy (surface->cr.current_source); status = _cairo_pattern_create_copy (&surface->cr.current_source, source); - if (status) + if (unlikely (status)) return status; status = _emit_identity (surface, &matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_pattern (surface, source); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, @@ -1242,7 +1242,7 @@ _emit_path (cairo_script_surface_t *surface, double y2 = _cairo_fixed_to_double (box.p2.y); status = _cairo_path_fixed_init_copy (&surface->cr.current_path, path); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->ctx->stream, @@ -1252,7 +1252,7 @@ _emit_path (cairo_script_surface_t *surface, cairo_status_t status; status = _cairo_path_fixed_init_copy (&surface->cr.current_path, path); - if (status) + if (unlikely (status)) return status; status = _cairo_path_fixed_interpret (path, @@ -1262,7 +1262,7 @@ _emit_path (cairo_script_surface_t *surface, _path_curve_to, _path_close, surface->ctx->stream); - if (status) + if (unlikely (status)) return status; } @@ -1356,7 +1356,7 @@ _cairo_script_surface_create_similar (void *abstract_surface, status = _bitmap_next_id (&ctx->surface_id, &other->id); - if (status) + if (unlikely (status)) return _cairo_surface_create_in_error (status); _cairo_output_stream_printf (ctx->stream, @@ -1378,7 +1378,7 @@ _cairo_script_surface_create_similar (void *abstract_surface, status = _bitmap_next_id (&ctx->surface_id, &surface->id); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (&surface->base); return _cairo_surface_create_in_error (status); } @@ -1455,7 +1455,7 @@ _cairo_script_surface_copy_page (void *abstract_surface) cairo_status_t status; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, "copy_page\n"); @@ -1470,7 +1470,7 @@ _cairo_script_surface_show_page (void *abstract_surface) cairo_status_t status; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, "show_page\n"); @@ -1490,7 +1490,7 @@ _cairo_script_surface_intersect_clip_path (void *abstract_surface, cairo_status_t status; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; if (path == NULL) { @@ -1499,23 +1499,23 @@ _cairo_script_surface_intersect_clip_path (void *abstract_surface, } status = _emit_identity (surface, &matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_fill_rule (surface, fill_rule); - if (status) + if (unlikely (status)) return status; status = _emit_tolerance (surface, tolerance, matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_antialias (surface, antialias); - if (status) + if (unlikely (status)) return status; status = _emit_path (surface, path); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, "clip+\n"); @@ -1533,15 +1533,15 @@ _cairo_script_surface_paint (void *abstract_surface, cairo_status_t status; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; status = _emit_operator (surface, op); - if (status) + if (unlikely (status)) return status; status = _emit_source (surface, op, source); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, @@ -1561,19 +1561,19 @@ _cairo_script_surface_mask (void *abstract_surface, cairo_status_t status; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; status = _emit_operator (surface, op); - if (status) + if (unlikely (status)) return status; status = _emit_source (surface, op, source); - if (status) + if (unlikely (status)) return status; status = _emit_pattern (surface, mask); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, @@ -1599,39 +1599,39 @@ _cairo_script_surface_stroke (void *abstract_surface, cairo_status_t status; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; status = _emit_identity (surface, &matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_path (surface, path); - if (status) + if (unlikely (status)) return status; status = _emit_source (surface, op, source); - if (status) + if (unlikely (status)) return status; status = _emit_matrix (surface, ctm, &matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_operator (surface, op); - if (status) + if (unlikely (status)) return status; status = _emit_stroke_style (surface, style, matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_tolerance (surface, tolerance, matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_antialias (surface, antialias); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, "stroke+\n"); @@ -1654,35 +1654,35 @@ _cairo_script_surface_fill (void *abstract_surface, cairo_status_t status; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; status = _emit_operator (surface, op); - if (status) + if (unlikely (status)) return status; status = _emit_identity (surface, &matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_source (surface, op, source); - if (status) + if (unlikely (status)) return status; status = _emit_fill_rule (surface, fill_rule); - if (status) + if (unlikely (status)) return status; status = _emit_tolerance (surface, tolerance, matrix_updated); - if (status) + if (unlikely (status)) return status; status = _emit_antialias (surface, antialias); - if (status) + if (unlikely (status)) return status; status = _emit_path (surface, path); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_puts (surface->ctx->stream, "fill+\n"); @@ -1828,15 +1828,15 @@ _emit_type42_font (cairo_script_surface_t *surface, size = 0; status = backend->load_truetype_table (scaled_font, 0, 0, NULL, &size); - if (status) + if (unlikely (status)) return status; buf = malloc (size); - if (buf == NULL) + if (unlikely (buf == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = backend->load_truetype_table (scaled_font, 0, 0, buf, NULL); - if (status) { + if (unlikely (status)) { free (buf); return status; } @@ -1882,7 +1882,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface, cairo_status_t status; font_private = malloc (sizeof (cairo_script_surface_font_private_t)); - if (font_private == NULL) + if (unlikely (font_private == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font_private->ctx = surface->ctx; @@ -1898,7 +1898,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface, status = _bitmap_next_id (&surface->ctx->font_id, &font_private->id); - if (status) { + if (unlikely (status)) { free (font_private); return status; } @@ -1907,7 +1907,7 @@ _emit_scaled_font_init (cairo_script_surface_t *surface, scaled_font->surface_backend = &_cairo_script_surface_backend; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; status = _emit_type42_font (surface, scaled_font); @@ -1943,7 +1943,7 @@ _emit_scaled_font (cairo_script_surface_t *surface, cairo_scaled_font_get_ctm (scaled_font, &matrix); status = _emit_matrix (surface, &matrix, &matrix_updated); - if (status) + if (unlikely (status)) return status; if (! matrix_updated && surface->cr.current_scaled_font == scaled_font) @@ -1951,12 +1951,12 @@ _emit_scaled_font (cairo_script_surface_t *surface, cairo_scaled_font_get_font_matrix (scaled_font, &matrix); status = _emit_font_matrix (surface, &matrix); - if (status) + if (unlikely (status)) return status; cairo_scaled_font_get_font_options (scaled_font, &options); status = _emit_font_options (surface, &options); - if (status) + if (unlikely (status)) return status; surface->cr.current_scaled_font = scaled_font; @@ -1967,11 +1967,11 @@ _emit_scaled_font (cairo_script_surface_t *surface, font_private = scaled_font->surface_private; if (font_private == NULL) { status = _emit_scaled_font_init (surface, scaled_font); - if (status) + if (unlikely (status)) return status; } else { status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->ctx->stream, @@ -2059,7 +2059,7 @@ _emit_scaled_glyph_bitmap (cairo_script_surface_t *surface, scaled_glyph->fs_metrics.y_bearing); status = _emit_image_surface (surface, scaled_glyph->surface); - if (status) + if (unlikely (status)) return status; if (! _cairo_matrix_is_identity (&scaled_font->font_matrix)) { @@ -2121,7 +2121,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface, glyphs[n].index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); - if (status) + if (unlikely (status)) break; if (scaled_glyph->surface_private != NULL) @@ -2137,7 +2137,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface, if (status == CAIRO_STATUS_SUCCESS) { if (! have_glyph_prologue) { status = _emit_scaled_glyph_prologue (surface, scaled_font); - if (status) + if (unlikely (status)) break; have_glyph_prologue = TRUE; @@ -2146,7 +2146,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface, status = _emit_scaled_glyph_vector (surface, scaled_font, scaled_glyph); - if (status) + if (unlikely (status)) break; continue; @@ -2162,7 +2162,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface, if (status == CAIRO_STATUS_SUCCESS) { if (! have_glyph_prologue) { status = _emit_scaled_glyph_prologue (surface, scaled_font); - if (status) + if (unlikely (status)) break; have_glyph_prologue = TRUE; @@ -2171,7 +2171,7 @@ _emit_scaled_glyphs (cairo_script_surface_t *surface, status = _emit_scaled_glyph_bitmap (surface, scaled_font, scaled_glyph); - if (status) + if (unlikely (status)) break; continue; @@ -2210,23 +2210,23 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, cairo_output_stream_t *base85_stream = NULL; status = _emit_context (surface); - if (status) + if (unlikely (status)) return status; status = _emit_operator (surface, op); - if (status) + if (unlikely (status)) return status; status = _emit_source (surface, op, source); - if (status) + if (unlikely (status)) return status; status = _emit_scaled_font (surface, scaled_font); - if (status) + if (unlikely (status)) return status; status = _emit_scaled_glyphs (surface, scaled_font, glyphs, num_glyphs); - if (status) + if (unlikely (status)) return status; /* (utf8) [cx cy [glyphs]] [clusters] backward show_text_glyphs */ @@ -2264,7 +2264,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, glyphs[n].index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); - if (status) { + if (unlikely (status)) { _cairo_scaled_font_thaw_cache (scaled_font); return status; } @@ -2284,7 +2284,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, glyphs[n].index, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); - if (status) + if (unlikely (status)) break; if (fabs (glyphs[n].x - x) > 1e-5 || fabs (glyphs[n].y - y) > 1e-5) { @@ -2295,7 +2295,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, iy -= scaled_font->font_matrix.y0; if (base85_stream != NULL) { status = _cairo_output_stream_destroy (base85_stream); - if (status) { + if (unlikely (status)) { base85_stream = NULL; break; } @@ -2345,7 +2345,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, } else { _cairo_output_stream_puts (surface->ctx->stream, " ]"); } - if (status) + if (unlikely (status)) return status; if (utf8 != NULL && clusters != NULL) { @@ -2378,7 +2378,7 @@ _cairo_script_surface_show_text_glyphs (void *abstract_surface, _cairo_output_stream_write (base85_stream, c, 2); } status = _cairo_output_stream_destroy (base85_stream); - if (status) + if (unlikely (status)) return status; } @@ -2423,6 +2423,8 @@ _cairo_script_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ _cairo_script_surface_copy_page, _cairo_script_surface_show_page, NULL, /* set_clip_region */ @@ -2466,7 +2468,7 @@ _cairo_script_vmcontext_create (cairo_output_stream_t *stream) cairo_script_vmcontext_t *ctx; ctx = malloc (sizeof (cairo_script_vmcontext_t)); - if (ctx == NULL) + if (unlikely (ctx == NULL)) return NULL; memset (ctx, 0, sizeof (cairo_script_vmcontext_t)); @@ -2500,11 +2502,11 @@ _cairo_script_surface_create_internal (cairo_script_vmcontext_t *ctx, { cairo_script_surface_t *surface; - if (ctx == NULL) + if (unlikely (ctx == NULL)) return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); surface = malloc (sizeof (cairo_script_surface_t)); - if (surface == NULL) + if (unlikely (surface == NULL)) return (cairo_script_surface_t *) _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&surface->base, diff --git a/src/cairo-sdl-surface.c b/src/cairo-sdl-surface.c index 18f13eaf..1f97fb47 100644 --- a/src/cairo-sdl-surface.c +++ b/src/cairo-sdl-surface.c @@ -52,7 +52,7 @@ _cairo_sdl_surface_create_internal (SDL_Surface *sdl, cairo_sdl_surface_t *surface; surface = malloc (sizeof (cairo_sdl_surface_t)); - if (surface == NULL) + if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&surface->base, @@ -240,7 +240,7 @@ _cairo_sdl_surface_composite (cairo_operator_t op, src_x, src_y, width, height, (cairo_surface_t **) &src, &src_attr); - if (status) + if (unlikely (status)) return status; is_integer_translation = @@ -324,7 +324,7 @@ _cairo_sdl_surface_flush (void *abstract_surface) n_boxes = 0; status = _cairo_region_get_boxes (&surface->update, &n_boxes, &boxes); - if (status) + if (unlikely (status)) return status; if (n_boxes == 0) return CAIRO_STATUS_SUCCESS; @@ -357,6 +357,8 @@ static const cairo_surface_backend_t _cairo_sdl_surface_backend = { _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, diff --git a/src/cairo-skiplist.c b/src/cairo-skiplist.c index b08453b0..d03a6bfc 100644 --- a/src/cairo-skiplist.c +++ b/src/cairo-skiplist.c @@ -91,20 +91,22 @@ _cairo_skip_list_fini (cairo_skip_list_t *list) static int random_level (void) { - int level = 0; /* tricky bit -- each bit is '1' 75% of the time. * This works because we only use the lower MAX_LEVEL * bits, and MAX_LEVEL < 16 */ uint32_t bits = hars_petruska_f54_1_random (); - bits |= bits >> 16; - - while (++level < MAX_LEVEL) - { - if (bits & 1) - break; +#if HAVE_FFS + return ffs (-(1<<MAX_LEVEL) | bits | bits >> 16); +#else + int level = 1; + + bits |= -(1<<MAX_LEVEL) | bits >> 16; + while ((bits & 1) == 0) { + level++; bits >>= 1; } return level; +#endif } static void * @@ -181,7 +183,7 @@ _cairo_skip_list_insert (cairo_skip_list_t *list, void *data, int unique) } data_and_elt = alloc_node_for_level (list, level); - if (data_and_elt == NULL) { + if (unlikely (data_and_elt == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return NULL; } diff --git a/src/cairo-spans-private.h b/src/cairo-spans-private.h new file mode 100644 index 00000000..c285f949 --- /dev/null +++ b/src/cairo-spans-private.h @@ -0,0 +1,144 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ +/* cairo - a vector graphics library with display and print output + * + * Copyright (c) 2008 M Joonas Pihlaja + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef CAIRO_SPANS_PRIVATE_H +#define CAIRO_SPANS_PRIVATE_H +#include "cairo-types-private.h" +#include "cairo-compiler-private.h" + +/* Number of bits of precision used for alpha. */ +#define CAIRO_SPANS_UNIT_COVERAGE_BITS 8 +#define CAIRO_SPANS_UNIT_COVERAGE ((1 << CAIRO_SPANS_UNIT_COVERAGE_BITS)-1) + +/* A structure representing an open-ended horizontal span of constant + * pixel coverage. */ +typedef struct _cairo_half_open_span { + /* The inclusive x-coordinate of the start of the span. */ + int x; + + /* The pixel coverage for the pixels to the right. */ + int coverage; +} cairo_half_open_span_t; + +/* Span renderer interface. Instances of renderers are provided by + * surfaces if they want to composite spans instead of trapezoids. */ +typedef struct _cairo_span_renderer cairo_span_renderer_t; +struct _cairo_span_renderer { + /* Called to destroy the renderer. */ + cairo_destroy_func_t destroy; + + /* Render the spans on row y of the source by whatever compositing + * method is required. The function should ignore spans outside + * the bounding box set by the init() function. */ + cairo_status_t (*render_row)( + void *abstract_renderer, + int y, + const cairo_half_open_span_t *coverages, + unsigned num_coverages); + + /* Called after all rows have been rendered to perform whatever + * final rendering step is required. This function is called just + * once before the renderer is destroyed. */ + cairo_status_t (*finish)( + void *abstract_renderer); + + /* Private status variable. */ + cairo_status_t status; +}; + +/* Scan converter interface. */ +typedef struct _cairo_scan_converter cairo_scan_converter_t; +struct _cairo_scan_converter { + /* Destroy this scan converter. */ + cairo_destroy_func_t destroy; + + /* Add an edge to the converter. */ + cairo_status_t + (*add_edge)( + void *abstract_converter, + cairo_fixed_t x1, + cairo_fixed_t y1, + cairo_fixed_t x2, + cairo_fixed_t y2); + + /* Generates coverage spans for rows for the added edges and calls + * the renderer function for each row. After generating spans the + * only valid thing to do with the converter is to destroy it. */ + cairo_status_t + (*generate)( + void *abstract_converter, + cairo_span_renderer_t *renderer); + + /* Private status. Read with _cairo_scan_converter_status(). */ + cairo_status_t status; +}; + +/* Scan converter constructors. */ + +cairo_private cairo_scan_converter_t * +_cairo_tor_scan_converter_create( + int xmin, + int ymin, + int xmax, + int ymax, + cairo_fill_rule_t fill_rule); + +/* cairo-spans.c: */ + +cairo_private cairo_scan_converter_t * +_cairo_scan_converter_create_in_error (cairo_status_t error); + +cairo_private cairo_status_t +_cairo_scan_converter_status (void *abstract_converter); + +cairo_private cairo_status_t +_cairo_scan_converter_set_error (void *abstract_converter, + cairo_status_t error); + +cairo_private cairo_span_renderer_t * +_cairo_span_renderer_create_in_error (cairo_status_t error); + +cairo_private cairo_status_t +_cairo_span_renderer_status (void *abstract_renderer); + +/* Set the renderer into an error state. This sets all the method + * pointers except ->destroy() of the renderer to no-op + * implementations that just return the error status. */ +cairo_private cairo_status_t +_cairo_span_renderer_set_error (void *abstract_renderer, + cairo_status_t error); + +cairo_private cairo_status_t +_cairo_path_fixed_fill_using_spans ( + cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_path_fixed_t *path, + cairo_surface_t *dst, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects); +#endif /* CAIRO_SPANS_PRIVATE_H */ diff --git a/src/cairo-spans.c b/src/cairo-spans.c new file mode 100644 index 00000000..e441143b --- /dev/null +++ b/src/cairo-spans.c @@ -0,0 +1,395 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ +/* cairo - a vector graphics library with display and print output + * + * Copyright (c) 2008 M Joonas Pihlaja + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "cairoint.h" + +typedef struct { + cairo_scan_converter_t *converter; + cairo_point_t current_point; + cairo_point_t first_point; +} scan_converter_filler_t; + +static void +scan_converter_filler_init ( + scan_converter_filler_t *filler, + cairo_scan_converter_t *converter) +{ + filler->converter = converter; + filler->current_point.x = 0; + filler->current_point.y = 0; + filler->first_point = filler->current_point; +} + +static cairo_status_t +scan_converter_filler_move_to ( + void *closure, + cairo_point_t *p) +{ + scan_converter_filler_t *filler = closure; + filler->current_point.x = p->x; + filler->current_point.y = p->y; + filler->first_point = filler->current_point; + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +scan_converter_filler_line_to ( + void *closure, + cairo_point_t *p) +{ + scan_converter_filler_t *filler = closure; + cairo_status_t status; + cairo_point_t to; + + to.x = p->x; + to.y = p->y; + + status = filler->converter->add_edge ( + filler->converter, + filler->current_point.x, filler->current_point.y, + to.x, to.y); + + filler->current_point = to; + + return status; +} + +static cairo_status_t +scan_converter_filler_close_path ( + void *closure) +{ + scan_converter_filler_t *filler = closure; + cairo_status_t status; + + if (filler->first_point.x == filler->current_point.x && + filler->first_point.y == filler->current_point.y) + { + return CAIRO_STATUS_SUCCESS; + } + + status = filler->converter->add_edge ( + filler->converter, + filler->current_point.x, filler->current_point.y, + filler->first_point.x, filler->first_point.y); + + filler->current_point = filler->first_point; + + return status; +} + +static cairo_status_t +_cairo_path_fixed_fill_to_scan_converter ( + cairo_path_fixed_t *path, + double tolerance, + cairo_scan_converter_t *converter) +{ + scan_converter_filler_t filler; + cairo_status_t status; + + scan_converter_filler_init (&filler, converter); + + status = _cairo_path_fixed_interpret_flat ( + path, CAIRO_DIRECTION_FORWARD, + scan_converter_filler_move_to, + scan_converter_filler_line_to, + scan_converter_filler_close_path, + &filler, tolerance); + if (status) + return status; + + return scan_converter_filler_close_path (&filler); +} + +static cairo_scan_converter_t * +_create_scan_converter (cairo_fill_rule_t fill_rule, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects) +{ + if (antialias == CAIRO_ANTIALIAS_NONE) { + ASSERT_NOT_REACHED; + return _cairo_scan_converter_create_in_error ( + CAIRO_INT_STATUS_UNSUPPORTED); + } + else { + return _cairo_tor_scan_converter_create ( + rects->mask.x, + rects->mask.y, + rects->mask.x + rects->width, + rects->mask.y + rects->height, + fill_rule); + } +} + +cairo_status_t +_cairo_path_fixed_fill_using_spans ( + cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_path_fixed_t *path, + cairo_surface_t *dst, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects) +{ + cairo_status_t status; + cairo_span_renderer_t *renderer = _cairo_surface_create_span_renderer ( + op, pattern, dst, antialias, rects); + cairo_scan_converter_t *converter = _create_scan_converter ( + fill_rule, antialias, rects); + + status = _cairo_path_fixed_fill_to_scan_converter ( + path, tolerance, converter); + if (status) + goto BAIL; + + status = converter->generate (converter, renderer); + if (status) + goto BAIL; + + status = renderer->finish (renderer); + if (status) + goto BAIL; + + BAIL: + renderer->destroy (renderer); + converter->destroy (converter); + return status; +} + +static void +_cairo_nil_destroy (void *abstract) +{ + (void) abstract; +} + +static cairo_status_t +_cairo_nil_scan_converter_add_edge (void *abstract_converter, + cairo_fixed_t x1, + cairo_fixed_t y1, + cairo_fixed_t x2, + cairo_fixed_t y2) +{ + (void) abstract_converter; + (void) x1; + (void) y1; + (void) x2; + (void) y2; + return _cairo_scan_converter_status (abstract_converter); +} + +static cairo_status_t +_cairo_nil_scan_converter_generate (void *abstract_converter, + cairo_span_renderer_t *renderer) +{ + (void) abstract_converter; + (void) renderer; + return _cairo_scan_converter_status (abstract_converter); +} + +cairo_status_t +_cairo_scan_converter_status (void *abstract_converter) +{ + cairo_scan_converter_t *converter = abstract_converter; + return converter->status; +} + +cairo_status_t +_cairo_scan_converter_set_error (void *abstract_converter, + cairo_status_t error) +{ + cairo_scan_converter_t *converter = abstract_converter; + if (error == CAIRO_STATUS_SUCCESS) + ASSERT_NOT_REACHED; + if (converter->status == CAIRO_STATUS_SUCCESS) { + converter->add_edge = _cairo_nil_scan_converter_add_edge; + converter->generate = _cairo_nil_scan_converter_generate; + converter->status = error; + } + return converter->status; +} + +static void +_cairo_nil_scan_converter_init (cairo_scan_converter_t *converter, + cairo_status_t status) +{ + converter->destroy = _cairo_nil_destroy; + converter->status = CAIRO_STATUS_SUCCESS; + status = _cairo_scan_converter_set_error (converter, status); +} + +cairo_scan_converter_t * +_cairo_scan_converter_create_in_error (cairo_status_t status) +{ +#define RETURN_NIL {\ + static cairo_scan_converter_t nil;\ + _cairo_nil_scan_converter_init (&nil, status);\ + return &nil;\ + } + switch (status) { + case CAIRO_STATUS_SUCCESS: + ASSERT_NOT_REACHED; + break; + case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL; + case CAIRO_STATUS_INVALID_POP_GROUP: RETURN_NIL; + case CAIRO_STATUS_NO_CURRENT_POINT: RETURN_NIL; + case CAIRO_STATUS_INVALID_MATRIX: RETURN_NIL; + case CAIRO_STATUS_INVALID_STATUS: RETURN_NIL; + case CAIRO_STATUS_NULL_POINTER: RETURN_NIL; + case CAIRO_STATUS_INVALID_STRING: RETURN_NIL; + case CAIRO_STATUS_INVALID_PATH_DATA: RETURN_NIL; + case CAIRO_STATUS_READ_ERROR: RETURN_NIL; + case CAIRO_STATUS_WRITE_ERROR: RETURN_NIL; + case CAIRO_STATUS_SURFACE_FINISHED: RETURN_NIL; + case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: RETURN_NIL; + case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: RETURN_NIL; + case CAIRO_STATUS_INVALID_CONTENT: RETURN_NIL; + case CAIRO_STATUS_INVALID_FORMAT: RETURN_NIL; + case CAIRO_STATUS_INVALID_VISUAL: RETURN_NIL; + case CAIRO_STATUS_FILE_NOT_FOUND: RETURN_NIL; + case CAIRO_STATUS_INVALID_DASH: RETURN_NIL; + case CAIRO_STATUS_INVALID_DSC_COMMENT: RETURN_NIL; + case CAIRO_STATUS_INVALID_INDEX: RETURN_NIL; + case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: RETURN_NIL; + case CAIRO_STATUS_TEMP_FILE_ERROR: RETURN_NIL; + case CAIRO_STATUS_INVALID_STRIDE: RETURN_NIL; + case CAIRO_STATUS_FONT_TYPE_MISMATCH: RETURN_NIL; + case CAIRO_STATUS_USER_FONT_IMMUTABLE: RETURN_NIL; + case CAIRO_STATUS_USER_FONT_ERROR: RETURN_NIL; + case CAIRO_STATUS_NEGATIVE_COUNT: RETURN_NIL; + case CAIRO_STATUS_INVALID_CLUSTERS: RETURN_NIL; + case CAIRO_STATUS_INVALID_SLANT: RETURN_NIL; + case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL; + case CAIRO_STATUS_NO_MEMORY: RETURN_NIL; + default: + break; + } + status = CAIRO_STATUS_NO_MEMORY; + RETURN_NIL; +#undef RETURN_NIL +} + +static cairo_status_t +_cairo_nil_span_renderer_render_row ( + void *abstract_renderer, + int y, + const cairo_half_open_span_t *coverages, + unsigned num_coverages) +{ + (void) y; + (void) coverages; + (void) num_coverages; + return _cairo_span_renderer_status (abstract_renderer); +} + +static cairo_status_t +_cairo_nil_span_renderer_finish (void *abstract_renderer) +{ + return _cairo_span_renderer_status (abstract_renderer); +} + +cairo_status_t +_cairo_span_renderer_status (void *abstract_renderer) +{ + cairo_span_renderer_t *renderer = abstract_renderer; + return renderer->status; +} + +cairo_status_t +_cairo_span_renderer_set_error ( + void *abstract_renderer, + cairo_status_t error) +{ + cairo_span_renderer_t *renderer = abstract_renderer; + if (error == CAIRO_STATUS_SUCCESS) { + ASSERT_NOT_REACHED; + } + if (renderer->status == CAIRO_STATUS_SUCCESS) { + renderer->render_row = _cairo_nil_span_renderer_render_row; + renderer->finish = _cairo_nil_span_renderer_finish; + renderer->status = error; + } + return renderer->status; +} + +static void +_cairo_nil_span_renderer_init (cairo_span_renderer_t *renderer, + cairo_status_t status) +{ + renderer->destroy = _cairo_nil_destroy; + renderer->status = CAIRO_STATUS_SUCCESS; + status = _cairo_span_renderer_set_error (renderer, status); +} + +cairo_span_renderer_t * +_cairo_span_renderer_create_in_error (cairo_status_t status) +{ +#define RETURN_NIL {\ + static cairo_span_renderer_t nil;\ + _cairo_nil_span_renderer_init (&nil, status);\ + return &nil;\ + } + switch (status) { + case CAIRO_STATUS_SUCCESS: + ASSERT_NOT_REACHED; + break; + case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL; + case CAIRO_STATUS_INVALID_POP_GROUP: RETURN_NIL; + case CAIRO_STATUS_NO_CURRENT_POINT: RETURN_NIL; + case CAIRO_STATUS_INVALID_MATRIX: RETURN_NIL; + case CAIRO_STATUS_INVALID_STATUS: RETURN_NIL; + case CAIRO_STATUS_NULL_POINTER: RETURN_NIL; + case CAIRO_STATUS_INVALID_STRING: RETURN_NIL; + case CAIRO_STATUS_INVALID_PATH_DATA: RETURN_NIL; + case CAIRO_STATUS_READ_ERROR: RETURN_NIL; + case CAIRO_STATUS_WRITE_ERROR: RETURN_NIL; + case CAIRO_STATUS_SURFACE_FINISHED: RETURN_NIL; + case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: RETURN_NIL; + case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: RETURN_NIL; + case CAIRO_STATUS_INVALID_CONTENT: RETURN_NIL; + case CAIRO_STATUS_INVALID_FORMAT: RETURN_NIL; + case CAIRO_STATUS_INVALID_VISUAL: RETURN_NIL; + case CAIRO_STATUS_FILE_NOT_FOUND: RETURN_NIL; + case CAIRO_STATUS_INVALID_DASH: RETURN_NIL; + case CAIRO_STATUS_INVALID_DSC_COMMENT: RETURN_NIL; + case CAIRO_STATUS_INVALID_INDEX: RETURN_NIL; + case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: RETURN_NIL; + case CAIRO_STATUS_TEMP_FILE_ERROR: RETURN_NIL; + case CAIRO_STATUS_INVALID_STRIDE: RETURN_NIL; + case CAIRO_STATUS_FONT_TYPE_MISMATCH: RETURN_NIL; + case CAIRO_STATUS_USER_FONT_IMMUTABLE: RETURN_NIL; + case CAIRO_STATUS_USER_FONT_ERROR: RETURN_NIL; + case CAIRO_STATUS_NEGATIVE_COUNT: RETURN_NIL; + case CAIRO_STATUS_INVALID_CLUSTERS: RETURN_NIL; + case CAIRO_STATUS_INVALID_SLANT: RETURN_NIL; + case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL; + case CAIRO_STATUS_NO_MEMORY: RETURN_NIL; + default: + break; + } + status = CAIRO_STATUS_NO_MEMORY; + RETURN_NIL; +#undef RETURN_NIL +} diff --git a/src/cairo-stroke-style.c b/src/cairo-stroke-style.c index 3bc234e9..edc4f889 100644 --- a/src/cairo-stroke-style.c +++ b/src/cairo-stroke-style.c @@ -63,7 +63,7 @@ _cairo_stroke_style_init_copy (cairo_stroke_style_t *style, style->dash = NULL; } else { style->dash = _cairo_malloc_ab (style->num_dashes, sizeof (double)); - if (style->dash == NULL) + if (unlikely (style->dash == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); memcpy (style->dash, other->dash, diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c index 2dcaa58e..88975e9a 100644 --- a/src/cairo-surface-fallback.c +++ b/src/cairo-surface-fallback.c @@ -79,7 +79,7 @@ _fallback_init (fallback_state_t *state, status = _cairo_surface_acquire_dest_image (dst, &state->extents, &state->image, &state->image_rect, &state->image_extra); - if (status) + if (unlikely (status)) return status; /* XXX: This NULL value tucked away in state->image is a rather @@ -131,7 +131,7 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern, NULL, mask, extents->x, extents->y, extents); - if (status) + if (unlikely (status)) goto CLEANUP_SURFACE; if (clip && clip->surface) @@ -139,7 +139,7 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern, mask, extents->x, extents->y, extents); - if (status) + if (unlikely (status)) goto CLEANUP_SURFACE; _cairo_pattern_init_for_surface (mask_pattern, mask); @@ -169,7 +169,7 @@ _clip_and_composite_with_mask (cairo_clip_t *clip, clip, draw_func, draw_closure, dst, extents); - if (status) + if (unlikely (status)) return status; status = _cairo_surface_composite (op, @@ -226,14 +226,14 @@ _clip_and_composite_combine (cairo_clip_t *clip, _cairo_pattern_fini (&dst_pattern.base); - if (status) + if (unlikely (status)) goto CLEANUP_SURFACE; status = (*draw_func) (draw_closure, op, src, intermediate, extents->x, extents->y, extents); - if (status) + if (unlikely (status)) goto CLEANUP_SURFACE; /* Combine that with the clip @@ -242,7 +242,7 @@ _clip_and_composite_combine (cairo_clip_t *clip, intermediate, extents->x, extents->y, extents); - if (status) + if (unlikely (status)) goto CLEANUP_SURFACE; /* Punch the clip out of the destination @@ -251,7 +251,7 @@ _clip_and_composite_combine (cairo_clip_t *clip, dst, 0, 0, extents); - if (status) + if (unlikely (status)) goto CLEANUP_SURFACE; /* Now add the two results together @@ -293,7 +293,7 @@ _clip_and_composite_source (cairo_clip_t *clip, clip, draw_func, draw_closure, dst, extents); - if (status) + if (unlikely (status)) return status; /* Compute dest' = dest OUT (mask IN clip) @@ -305,7 +305,7 @@ _clip_and_composite_source (cairo_clip_t *clip, extents->x, extents->y, extents->width, extents->height); - if (status) + if (unlikely (status)) goto CLEANUP_MASK_PATTERN; /* Now compute (src IN (mask IN clip)) ADD dest' @@ -439,7 +439,7 @@ _composite_trap_region (cairo_clip_t *clip, status = _cairo_surface_set_clip_region (dst, trap_region, clip_serial); - if (status) + if (unlikely (status)) return status; } @@ -531,7 +531,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, return CAIRO_STATUS_SUCCESS; status = _cairo_surface_get_extents (dst, &extents); - if (status) + if (unlikely (status)) return status; status = _cairo_traps_extract_region (traps, &trap_region); @@ -548,7 +548,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, if (has_trap_region) { status = _cairo_clip_intersect_to_region (clip, &trap_region); - if (status) + if (unlikely (status)) goto out; _cairo_region_get_extents (&trap_region, &trap_extents); @@ -564,7 +564,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, } status = _cairo_clip_intersect_to_rectangle (clip, &extents); - if (status) + if (unlikely (status)) goto out; } else { cairo_surface_t *clip_surface = clip ? clip->surface : NULL; @@ -579,13 +579,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, has_clear_region = TRUE; status = _cairo_clip_intersect_to_region (clip, &clear_region); - if (status) + if (unlikely (status)) goto out; _cairo_region_get_extents (&clear_region, &extents); status = _cairo_region_subtract (&clear_region, &clear_region, &trap_region); - if (status) + if (unlikely (status)) goto out; if (!_cairo_region_not_empty (&clear_region)) { @@ -597,7 +597,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src, } } - if (status) + if (unlikely (status)) goto out; if (has_trap_region) { @@ -670,6 +670,53 @@ out: return status; } +typedef struct { + cairo_path_fixed_t *path; + cairo_fill_rule_t fill_rule; + double tolerance; + cairo_antialias_t antialias; +} cairo_composite_spans_fill_info_t; + +static cairo_status_t +_composite_spans_fill_func (void *closure, + cairo_operator_t op, + const cairo_pattern_t *src, + cairo_surface_t *dst, + int dst_x, + int dst_y, + const cairo_rectangle_int_t *extents) +{ + cairo_composite_rectangles_t rects; + cairo_composite_spans_fill_info_t *info = closure; + cairo_pattern_union_t pattern; + cairo_status_t status = CAIRO_STATUS_SUCCESS; + + _cairo_composite_rectangles_init ( + &rects, extents->x, extents->y, + extents->width, extents->height); + + /* The incoming dst_x/y are where we're pretending the origin of + * the dst surface is -- *not* the offset of a rectangle where + * we'd like to place the result. */ + rects.dst.x -= dst_x; + rects.dst.y -= dst_y; + + /* We're called without a source pattern from + * _create_composite_mask_pattern(). */ + _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE, + CAIRO_CONTENT_COLOR); + if (src == NULL) + src = &pattern.base; + + status = _cairo_path_fixed_fill_using_spans ( + op, src, info->path, dst, + info->fill_rule, info->tolerance, info->antialias, + &rects); + + _cairo_pattern_fini (&pattern.base); + return status; +} + cairo_status_t _cairo_surface_fallback_paint (cairo_surface_t *surface, cairo_operator_t op, @@ -681,14 +728,14 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface, cairo_traps_t traps; status = _cairo_surface_get_extents (surface, &extents); - if (status) + if (unlikely (status)) return status; if (_cairo_operator_bounded_by_source (op)) { cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; if (! _cairo_rectangle_intersect (&extents, &source_extents)) @@ -696,7 +743,7 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface, } status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (status) + if (unlikely (status)) return status; _cairo_box_from_rectangle (&box, &extents); @@ -752,12 +799,12 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface, cairo_rectangle_int_t extents, source_extents, mask_extents; status = _cairo_surface_get_extents (surface, &extents); - if (status) + if (unlikely (status)) return status; if (_cairo_operator_bounded_by_source (op)) { status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; if (! _cairo_rectangle_intersect (&extents, &source_extents)) @@ -766,7 +813,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface, if (_cairo_operator_bounded_by_mask (op)) { status = _cairo_pattern_get_extents (mask, &mask_extents); - if (status) + if (unlikely (status)) return status; if (! _cairo_rectangle_intersect (&extents, &mask_extents)) @@ -774,7 +821,7 @@ _cairo_surface_fallback_mask (cairo_surface_t *surface, } status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (status) + if (unlikely (status)) return status; status = _clip_and_composite (surface->clip, op, @@ -804,13 +851,13 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface, cairo_rectangle_int_t extents; status = _cairo_surface_get_extents (surface, &extents); - if (status) + if (unlikely (status)) return status; if (_cairo_operator_bounded_by_source (op)) { cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; if (! _cairo_rectangle_intersect (&extents, &source_extents)) @@ -818,7 +865,7 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface, } status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (status) + if (unlikely (status)) return status; if (extents.width == 0 || extents.height == 0) @@ -834,7 +881,7 @@ _cairo_surface_fallback_stroke (cairo_surface_t *surface, ctm, ctm_inverse, tolerance, &traps); - if (status) + if (unlikely (status)) goto FAIL; status = _clip_and_composite_trapezoids (source, @@ -865,14 +912,14 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, cairo_rectangle_int_t extents; status = _cairo_surface_get_extents (surface, &extents); - if (status) + if (unlikely (status)) return status; if (_cairo_operator_bounded_by_source (op)) { cairo_rectangle_int_t source_extents; status = _cairo_pattern_get_extents (source, &source_extents); - if (status) + if (unlikely (status)) return status; if (! _cairo_rectangle_intersect (&extents, &source_extents)) @@ -880,14 +927,51 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, } status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (status) + if (unlikely (status)) return status; if (extents.width == 0 || extents.height == 0) return CAIRO_STATUS_SUCCESS; - _cairo_box_from_rectangle (&box, &extents); + /* Ask if the surface would like to render this combination of + * op/source/dst/antialias with spans or not, but don't actually + * make a renderer yet. We'll try to hit the region optimisations + * in _clip_and_composite_trapezoids() if it looks like the path + * is a region. */ + /* TODO: Until we have a mono scan converter we won't even try + * to use spans for CAIRO_ANTIALIAS_NONE. */ + /* TODO: The region filling code should be lifted from + * _clip_and_composite_trapezoids() and given first priority + * explicitly before deciding between spans and trapezoids. */ + if (antialias != CAIRO_ANTIALIAS_NONE && + !_cairo_path_fixed_is_box (path, &box) && + !_cairo_path_fixed_is_region (path) && + _cairo_surface_check_span_renderer ( + op, source, surface, antialias, NULL)) + { + cairo_composite_spans_fill_info_t info; + info.path = path; + info.fill_rule = fill_rule; + info.tolerance = tolerance; + info.antialias = antialias; + + if (_cairo_operator_bounded_by_mask (op)) { + cairo_rectangle_int_t path_extents; + _cairo_path_fixed_approximate_extents (path, &path_extents); + if (! _cairo_rectangle_intersect (&extents, &path_extents)) + return CAIRO_STATUS_SUCCESS; + } + return _clip_and_composite ( + surface->clip, op, source, + _composite_spans_fill_func, + &info, + surface, + &extents); + } + + /* Fall back to trapezoid fills. */ + _cairo_box_from_rectangle (&box, &extents); _cairo_traps_init (&traps); _cairo_traps_limit (&traps, &box); @@ -895,7 +979,7 @@ _cairo_surface_fallback_fill (cairo_surface_t *surface, fill_rule, tolerance, &traps); - if (status) { + if (unlikely (status)) { _cairo_traps_fini (&traps); return status; } @@ -992,7 +1076,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface, cairo_show_glyphs_info_t glyph_info; status = _cairo_surface_get_extents (surface, &extents); - if (status) + if (unlikely (status)) return status; if (_cairo_operator_bounded_by_mask (op)) { @@ -1002,7 +1086,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface, glyphs, num_glyphs, &glyph_extents); - if (status) + if (unlikely (status)) return status; if (! _cairo_rectangle_intersect (&extents, &glyph_extents)) @@ -1010,7 +1094,7 @@ _cairo_surface_fallback_show_glyphs (cairo_surface_t *surface, } status = _cairo_clip_intersect_to_rectangle (surface->clip, &extents); - if (status) + if (unlikely (status)) return status; glyph_info.font = scaled_font; @@ -1045,7 +1129,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) status = _cairo_surface_acquire_source_image (surface, &image, &image_extra); - if (status) + if (unlikely (status)) return _cairo_surface_create_in_error (status); snapshot = cairo_image_surface_create (image->format, @@ -1073,7 +1157,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) _cairo_surface_release_source_image (surface, image, image_extra); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (snapshot); return _cairo_surface_create_in_error (status); } @@ -1083,7 +1167,7 @@ _cairo_surface_fallback_snapshot (cairo_surface_t *surface) for (mime_type = mime_types; *mime_type; mime_type++) { status = _cairo_surface_copy_mime_data (snapshot, surface, *mime_type); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (snapshot); return _cairo_surface_create_in_error (status); } @@ -1112,7 +1196,7 @@ _cairo_surface_fallback_composite (cairo_operator_t op, cairo_status_t status; status = _fallback_init (&state, dst, dst_x, dst_y, width, height); - if (status) { + if (unlikely (status)) { if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; return status; @@ -1173,7 +1257,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface, } status = _fallback_init (&state, surface, x1, y1, x2 - x1, y2 - y1); - if (status) { + if (unlikely (status)) { if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; return status; @@ -1183,7 +1267,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface, if (state.image_rect.x != 0 || state.image_rect.y != 0) { offset_rects = _cairo_malloc_ab (num_rects, sizeof (cairo_rectangle_int_t)); - if (offset_rects == NULL) { + if (unlikely (offset_rects == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto DONE; } @@ -1229,7 +1313,7 @@ _cairo_surface_fallback_composite_trapezoids (cairo_operator_t op, cairo_status_t status; status = _fallback_init (&state, dst, dst_x, dst_y, width, height); - if (status) { + if (unlikely (status)) { if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) return CAIRO_STATUS_SUCCESS; return status; diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 4c10f958..077af5b4 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -237,7 +237,7 @@ _cairo_surface_create_similar_scratch (cairo_surface_t *other, } /* If any error occurred, then return the nil surface we received. */ - if (surface->status) + if (unlikely (surface->status)) return surface; if (other->has_font_options || other->backend != surface->backend) { @@ -322,7 +322,7 @@ _cairo_surface_create_similar_solid (cairo_surface_t *other, _cairo_pattern_fini (&solid_pattern.base); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (surface); return _cairo_surface_create_in_error (status); } @@ -455,7 +455,7 @@ _cairo_surface_reset (cairo_surface_t *surface) if (surface->backend->reset != NULL) { cairo_status_t status = surface->backend->reset (surface); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); } @@ -523,7 +523,7 @@ cairo_surface_finish (cairo_surface_t *surface) /* call finish even if in error mode */ if (surface->backend->finish) { status = surface->backend->finish (surface); - if (status) + if (unlikely (status)) status = _cairo_surface_set_error (surface, status); } @@ -608,7 +608,7 @@ cairo_surface_get_mime_data (cairo_surface_t *surface, return; status = _cairo_intern_string (&mime_type, -1); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (surface, status); return; } @@ -672,12 +672,12 @@ cairo_surface_set_mime_data (cairo_surface_t *surface, return surface->status; status = _cairo_intern_string (&mime_type, -1); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); if (data != NULL) { mime_data = malloc (sizeof (cairo_mime_data_t)); - if (mime_data == NULL) + if (unlikely (mime_data == NULL)) return _cairo_surface_set_error (surface, _cairo_error (CAIRO_STATUS_NO_MEMORY)); CAIRO_REFERENCE_COUNT_INIT (&mime_data->ref_count, 1); @@ -693,7 +693,7 @@ cairo_surface_set_mime_data (cairo_surface_t *surface, (cairo_user_data_key_t *) mime_type, mime_data, _cairo_mime_data_destroy); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); return CAIRO_STATUS_SUCCESS; @@ -715,7 +715,7 @@ _cairo_surface_copy_mime_data (cairo_surface_t *dst, return _cairo_surface_set_error (dst, src->status); status = _cairo_intern_string (&mime_type, -1); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (dst, status); mime_data = _cairo_user_data_array_get_data (&src->user_data, @@ -729,7 +729,7 @@ _cairo_surface_copy_mime_data (cairo_surface_t *dst, (cairo_user_data_key_t *) mime_type, mime_data, _cairo_mime_data_destroy); - if (status) { + if (unlikely (status)) { _cairo_mime_data_destroy (mime_data); return _cairo_surface_set_error (dst, status); } @@ -839,7 +839,7 @@ cairo_surface_flush (cairo_surface_t *surface) if (surface->backend->flush) { status = surface->backend->flush (surface); - if (status) + if (unlikely (status)) status = _cairo_surface_set_error (surface, status); } } @@ -917,7 +917,7 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface, y + surface->device_transform.y0, width, height); - if (status) + if (unlikely (status)) status = _cairo_surface_set_error (surface, status); } } @@ -1355,7 +1355,7 @@ _cairo_surface_clone_similar (cairo_surface_t *surface, clone_out); /* We should never get UNSUPPORTED here, so if we have an error, bail. */ - if (status) + if (unlikely (status)) return status; /* Update the clone's device_transform (which the underlying surface @@ -1562,7 +1562,7 @@ _cairo_surface_fill_region (cairo_surface_t *surface, if (num_boxes > 1) { num_boxes = sizeof (stack_rects) / sizeof (cairo_box_int_t); status = _cairo_region_get_boxes (region, &num_boxes, &boxes); - if (status) + if (unlikely (status)) return status; if (num_boxes > ARRAY_LENGTH (stack_rects)) { @@ -1661,7 +1661,7 @@ _cairo_surface_paint (cairo_surface_t *surface, status = _cairo_surface_copy_pattern_for_destination (&source, surface, &dev_source.base); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); if (surface->backend->paint) { @@ -1698,13 +1698,13 @@ _cairo_surface_mask (cairo_surface_t *surface, status = _cairo_surface_copy_pattern_for_destination (&source, surface, &dev_source.base); - if (status) + if (unlikely (status)) goto FINISH; status = _cairo_surface_copy_pattern_for_destination (&mask, surface, &dev_mask.base); - if (status) + if (unlikely (status)) goto CLEANUP_SOURCE; if (surface->backend->mask) { @@ -1757,13 +1757,13 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface, status = _cairo_surface_copy_pattern_for_destination (&stroke_source, surface, &dev_stroke_source.base); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); status = _cairo_surface_copy_pattern_for_destination (&fill_source, surface, &dev_fill_source.base); - if (status) { + if (unlikely (status)) { if (stroke_source == &dev_stroke_source.base) _cairo_pattern_fini (&dev_stroke_source.base); @@ -1792,13 +1792,13 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface, status = _cairo_surface_fill (surface, fill_op, fill_source, path, fill_rule, fill_tolerance, fill_antialias, NULL); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); status = _cairo_surface_stroke (surface, stroke_op, stroke_source, path, stroke_style, stroke_ctm, stroke_ctm_inverse, stroke_tolerance, stroke_antialias, NULL); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); return CAIRO_STATUS_SUCCESS; @@ -1831,7 +1831,7 @@ _cairo_surface_stroke (cairo_surface_t *surface, status = _cairo_surface_copy_pattern_for_destination (&source, surface, &dev_source.base); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); if (surface->backend->stroke) { @@ -1880,7 +1880,7 @@ _cairo_surface_fill (cairo_surface_t *surface, status = _cairo_surface_copy_pattern_for_destination (&source, surface, &dev_source.base); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); if (surface->backend->fill) { @@ -1953,6 +1953,59 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, traps, num_traps)); } +cairo_span_renderer_t * +_cairo_surface_create_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_surface_t *dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects) +{ + assert (! dst->is_snapshot); + + if (dst->status) + return _cairo_span_renderer_create_in_error (dst->status); + + if (dst->finished) + return _cairo_span_renderer_create_in_error (CAIRO_STATUS_SURFACE_FINISHED); + + if (dst->backend->create_span_renderer) { + return dst->backend->create_span_renderer (op, + pattern, dst, + antialias, + rects); + } + ASSERT_NOT_REACHED; + return _cairo_span_renderer_create_in_error (CAIRO_INT_STATUS_UNSUPPORTED); +} + +cairo_bool_t +_cairo_surface_check_span_renderer (cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_surface_t *dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects) +{ + cairo_int_status_t status; + + assert (! dst->is_snapshot); + + if (dst->status) + return FALSE; + + if (dst->finished) { + status = _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED); + return FALSE; + } + + if (dst->backend->check_span_renderer) { + return dst->backend->check_span_renderer (op, + pattern, dst, + antialias, + rects); + } + return FALSE; +} + /** * cairo_surface_copy_page: * @surface: a #cairo_surface_t @@ -2097,13 +2150,13 @@ _cairo_surface_reset_clip (cairo_surface_t *surface) CAIRO_FILL_RULE_WINDING, 0, CAIRO_ANTIALIAS_DEFAULT); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); } if (surface->backend->set_clip_region != NULL) { status = surface->backend->set_clip_region (surface, NULL); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); } @@ -2181,7 +2234,7 @@ _cairo_surface_set_clip_path_recursive (cairo_surface_t *surface, return CAIRO_STATUS_SUCCESS; status = _cairo_surface_set_clip_path_recursive (surface, clip_path->prev); - if (status) + if (unlikely (status)) return status; return _cairo_surface_intersect_clip_path (surface, @@ -2220,11 +2273,11 @@ _cairo_surface_set_clip_path (cairo_surface_t *surface, CAIRO_FILL_RULE_WINDING, 0, CAIRO_ANTIALIAS_DEFAULT); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); status = _cairo_surface_set_clip_path_recursive (surface, clip_path); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); surface->current_clip_serial = serial; @@ -2458,7 +2511,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface, status = _cairo_surface_copy_pattern_for_destination (&source, surface, &dev_source.base); - if (status) + if (unlikely (status)) return _cairo_surface_set_error (surface, status); if (_cairo_surface_has_device_transform (surface) && @@ -2477,7 +2530,7 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface, &font_options); } status = cairo_scaled_font_status (dev_scaled_font); - if (status) { + if (unlikely (status)) { if (source == &dev_source.base) _cairo_pattern_fini (&dev_source.base); @@ -2644,7 +2697,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst, status = _cairo_region_subtract (&clear_region, &clear_region, &drawn_region); - if (status) + if (unlikely (status)) goto CLEANUP_REGIONS; EMPTY: @@ -2833,7 +2886,7 @@ _cairo_surface_copy_pattern_for_destination (const cairo_pattern_t **pattern, return CAIRO_STATUS_SUCCESS; status = _cairo_pattern_init_copy (pattern_copy, *pattern); - if (status) + if (unlikely (status)) return status; _cairo_pattern_transform (pattern_copy, diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c index ab2e4b94..cfd9a2d5 100644 --- a/src/cairo-svg-surface.c +++ b/src/cairo-svg-surface.c @@ -285,7 +285,7 @@ cairo_svg_surface_restrict_to_version (cairo_surface_t *abstract_surface, cairo_status_t status; status = _extract_svg_surface (abstract_surface, &surface); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (abstract_surface, status); return; } @@ -347,7 +347,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, cairo_status_t status, status_ignored; surface = malloc (sizeof (cairo_svg_surface_t)); - if (surface == NULL) + if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&surface->base, &cairo_svg_surface_backend, @@ -366,7 +366,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, surface->xml_node = _cairo_memory_stream_create (); status = _cairo_output_stream_get_status (surface->xml_node); - if (status) + if (unlikely (status)) goto CLEANUP; _cairo_array_init (&surface->page_set, sizeof (cairo_svg_page_t)); @@ -378,7 +378,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document, "fill:rgb(0,0,0);\"/>\n", width, height); status = _cairo_output_stream_get_status (surface->xml_node); - if (status) + if (unlikely (status)) goto CLEANUP; } @@ -421,7 +421,7 @@ _cairo_svg_surface_create_for_stream_internal (cairo_output_stream_t *stream, status = _cairo_svg_document_create (stream, width, height, version, &document); - if (status) { + if (unlikely (status)) { surface = _cairo_surface_create_in_error (status); /* consume the output stream on behalf of caller */ status = _cairo_output_stream_destroy (stream); @@ -482,7 +482,7 @@ _cairo_svg_surface_copy_page (void *abstract_surface) cairo_svg_page_t *page; page = _cairo_svg_surface_store_page (surface); - if (page == NULL) + if (unlikely (page == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); _cairo_memory_stream_copy (page->xml_node, surface->xml_node); @@ -496,7 +496,7 @@ _cairo_svg_surface_show_page (void *abstract_surface) { cairo_svg_surface_t *surface = abstract_surface; - if (_cairo_svg_surface_store_page (surface) == NULL) + if (unlikely (_cairo_svg_surface_store_page (surface) == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); return CAIRO_STATUS_SUCCESS; @@ -614,7 +614,7 @@ _cairo_svg_surface_emit_path (cairo_output_stream_t *output, _cairo_svg_path_curve_to, _cairo_svg_path_close_path, &info); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (output, "\""); @@ -635,14 +635,14 @@ _cairo_svg_document_emit_outline_glyph_data (cairo_svg_document_t *document, CAIRO_SCALED_GLYPH_INFO_METRICS| CAIRO_SCALED_GLYPH_INFO_PATH, &scaled_glyph); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (document->xml_node_glyphs, "<path style=\"stroke:none;\" "); status = _cairo_svg_surface_emit_path (document->xml_node_glyphs, scaled_glyph->path, NULL); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (document->xml_node_glyphs, @@ -668,7 +668,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document, CAIRO_SCALED_GLYPH_INFO_METRICS| CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); - if (status) + if (unlikely (status)) return status; image = scaled_glyph->surface; @@ -724,7 +724,7 @@ _cairo_svg_document_emit_glyph (cairo_svg_document_t *document, status = _cairo_svg_document_emit_bitmap_glyph_data (document, scaled_font, scaled_font_glyph_index); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (document->xml_node_glyphs, "</symbol>\n"); @@ -746,7 +746,7 @@ _cairo_svg_document_emit_font_subset (cairo_scaled_font_subset_t *font_subset, font_subset->scaled_font, font_subset->glyphs[i], font_subset->font_id, i); - if (status) + if (unlikely (status)) break; } _cairo_scaled_font_thaw_cache (font_subset->scaled_font); @@ -762,7 +762,7 @@ _cairo_svg_document_emit_font_subsets (cairo_svg_document_t *document) status = _cairo_scaled_font_subsets_foreach_scaled (document->font_subsets, _cairo_svg_document_emit_font_subset, document); - if (status) + if (unlikely (status)) goto FAIL; status = _cairo_scaled_font_subsets_foreach_user (document->font_subsets, @@ -992,7 +992,7 @@ _cairo_surface_base64_encode_jpeg (cairo_surface_t *surface, return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_image_info_get_jpeg_info (&image_info, mime_data, mime_data_length); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (output, "data:image/jpeg;base64,"); @@ -1002,7 +1002,7 @@ _cairo_surface_base64_encode_jpeg (cairo_surface_t *surface, info.trailing = 0; status = base64_write_func (&info, mime_data, mime_data_length); - if (status) + if (unlikely (status)) return status; if (info.in_mem > 0) { @@ -1036,7 +1036,7 @@ _cairo_surface_base64_encode_png (cairo_surface_t *surface, info.trailing = 0; status = base64_write_func (&info, mime_data, mime_data_length); - if (status) + if (unlikely (status)) return status; if (info.in_mem > 0) { @@ -1073,7 +1073,7 @@ _cairo_surface_base64_encode (cairo_surface_t *surface, status = cairo_surface_write_to_png_stream (surface, base64_write_func, (void *) &info); - if (status) + if (unlikely (status)) return status; if (info.in_mem > 0) { @@ -1126,7 +1126,7 @@ _cairo_svg_surface_emit_composite_image_pattern (cairo_output_stream_t *output cairo_matrix_t p2u; status = _cairo_surface_get_extents (pattern->surface, &extents); - if (status) + if (unlikely (status)) return status; p2u = pattern->base.matrix; @@ -1214,7 +1214,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, document->owner->y_fallback_resolution); status = _cairo_meta_surface_replay (&meta->base, paginated_surface); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (&meta->base); cairo_surface_destroy (paginated_surface); return status; @@ -1222,7 +1222,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, cairo_surface_show_page (paginated_surface); status = cairo_surface_status (paginated_surface); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (&meta->base); cairo_surface_destroy (paginated_surface); return status; @@ -1231,7 +1231,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, new_snapshot.meta = meta; new_snapshot.id = svg_surface->id; status = _cairo_array_append (&document->meta_snapshots, &new_snapshot); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (&meta->base); cairo_surface_destroy (paginated_surface); return status; @@ -1268,7 +1268,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document, page_set = &svg_surface->page_set; if (_cairo_memory_stream_length (contents) > 0) { - if (_cairo_svg_surface_store_page (svg_surface) == NULL) { + if (unlikely (_cairo_svg_surface_store_page (svg_surface) == NULL)) { cairo_surface_destroy (paginated_surface); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -1321,7 +1321,7 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output, meta_surface = (cairo_meta_surface_t *) pattern->surface; status = _cairo_svg_surface_emit_meta_surface (document, meta_surface, &id); - if (status) + if (unlikely (status)) return status; if (pattern_id != invalid_pattern_id) { @@ -1407,7 +1407,7 @@ _cairo_svg_surface_emit_surface_pattern (cairo_svg_surface_t *surface, status = _cairo_svg_surface_emit_composite_pattern (document->xml_node_defs, surface, CAIRO_OPERATOR_SOURCE, pattern, pattern_id, parent_matrix, NULL); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (style, @@ -1449,7 +1449,7 @@ _cairo_svg_surface_emit_pattern_stops (cairo_output_stream_t *output, if (emulate_reflect || reverse_stops) { n_stops = emulate_reflect ? pattern->n_stops * 2 - 2: pattern->n_stops; stops = _cairo_malloc_ab (n_stops, sizeof (cairo_gradient_stop_t)); - if (stops == NULL) + if (unlikely (stops == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); for (i = 0; i < pattern->n_stops; i++) { @@ -1634,7 +1634,7 @@ _cairo_svg_surface_emit_linear_pattern (cairo_svg_surface_t *surface, status = _cairo_svg_surface_emit_pattern_stops (document->xml_node_defs, &pattern->base, 0.0, FALSE, FALSE); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (document->xml_node_defs, @@ -1812,7 +1812,7 @@ _cairo_svg_surface_emit_radial_pattern (cairo_svg_surface_t *surface, &pattern->base, offset, reverse_stops, emulate_reflect); - if (status) + if (unlikely (status)) return status; if (pattern->base.base.extend == CAIRO_EXTEND_NONE) @@ -1927,7 +1927,7 @@ _cairo_svg_surface_emit_stroke_style (cairo_output_stream_t *output, line_join); status = _cairo_svg_surface_emit_pattern (surface, source, output, TRUE, parent_matrix); - if (status) + if (unlikely (status)) return status; _cairo_svg_surface_emit_operator_for_style (output, surface, op); @@ -1979,18 +1979,18 @@ _cairo_svg_surface_fill_stroke (void *abstract_surface, _cairo_output_stream_printf (surface->xml_node, "<path style=\""); status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, fill_op, fill_source, fill_rule, stroke_ctm_inverse); - if (status) + if (unlikely (status)) return status; status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, stroke_op, stroke_source, stroke_style, stroke_ctm_inverse); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->xml_node, "\" "); status = _cairo_svg_surface_emit_path (surface->xml_node, path, stroke_ctm_inverse); - if (status) + if (unlikely (status)) return status; _cairo_svg_surface_emit_transform (surface->xml_node, " transform", stroke_ctm, NULL); @@ -2019,13 +2019,13 @@ _cairo_svg_surface_fill (void *abstract_surface, _cairo_output_stream_printf (surface->xml_node, "<path style=\" stroke:none;"); status = _cairo_svg_surface_emit_fill_style (surface->xml_node, surface, op, source, fill_rule, NULL); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->xml_node, "\" "); status = _cairo_svg_surface_emit_path (surface->xml_node, path, NULL); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->xml_node, "/>\n"); @@ -2079,7 +2079,7 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output, surface->width, surface->height); _cairo_svg_surface_emit_operator_for_style (output, surface, op); status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, NULL); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (output, "stroke:none;\""); @@ -2116,7 +2116,7 @@ _cairo_svg_surface_paint (void *abstract_surface, * and an optimization in meta surface. */ if (surface->clip_level == 0 && op == CAIRO_OPERATOR_CLEAR) { status = _cairo_output_stream_destroy (surface->xml_node); - if (status) { + if (unlikely (status)) { surface->xml_node = NULL; return status; } @@ -2204,7 +2204,7 @@ _cairo_svg_surface_mask (void *abstract_surface, mask_id, discard_filter ? "" : " <g filter=\"url(#alpha)\">\n"); status = _cairo_svg_surface_emit_paint (mask_stream, surface, CAIRO_OPERATOR_OVER, mask, source, NULL); - if (status) { + if (unlikely (status)) { cairo_status_t ignore = _cairo_output_stream_destroy (mask_stream); return status; (void) ignore; @@ -2217,13 +2217,13 @@ _cairo_svg_surface_mask (void *abstract_surface, _cairo_memory_stream_copy (mask_stream, document->xml_node_defs); status = _cairo_output_stream_destroy (mask_stream); - if (status) + if (unlikely (status)) return status; snprintf (buffer, sizeof buffer, "mask=\"url(#mask%d)\"", mask_id); status = _cairo_svg_surface_emit_paint (surface->xml_node, surface, op, source, 0, buffer); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -2252,13 +2252,13 @@ _cairo_svg_surface_stroke (void *abstract_dst, _cairo_output_stream_printf (surface->xml_node, "<path style=\"fill:none;"); status = _cairo_svg_surface_emit_stroke_style (surface->xml_node, surface, op, source, stroke_style, ctm_inverse); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->xml_node, "\" "); status = _cairo_svg_surface_emit_path (surface->xml_node, path, ctm_inverse); - if (status) + if (unlikely (status)) return status; _cairo_svg_surface_emit_transform (surface->xml_node, " transform", ctm, NULL); @@ -2301,7 +2301,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface, _cairo_output_stream_printf (surface->xml_node, "<g style=\""); status = _cairo_svg_surface_emit_pattern (surface, pattern, surface->xml_node, FALSE, NULL); - if (status) + if (unlikely (status)) return status; _cairo_svg_surface_emit_operator_for_style (surface->xml_node, surface, op); @@ -2321,7 +2321,7 @@ _cairo_svg_surface_show_glyphs (void *abstract_surface, goto FALLBACK; } - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (surface->xml_node, @@ -2341,7 +2341,7 @@ FALLBACK: status = _cairo_scaled_font_glyph_path (scaled_font,(cairo_glyph_t *) glyphs, num_glyphs, &path); - if (status) { + if (unlikely (status)) { _cairo_path_fixed_fini (&path); return status; } @@ -2379,7 +2379,7 @@ _cairo_svg_surface_intersect_clip_path (void *dst, " <path ", document->clip_id); status = _cairo_svg_surface_emit_path (document->xml_node_defs, path, NULL); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_printf (document->xml_node_defs, @@ -2422,6 +2422,8 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = { NULL, /* _cairo_svg_surface_composite, */ NULL, /* _cairo_svg_surface_fill_rectangles, */ NULL, /* _cairo_svg_surface_composite_trapezoids,*/ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ _cairo_svg_surface_copy_page, _cairo_svg_surface_show_page, NULL, /* set_clip_region */ @@ -2458,12 +2460,12 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream, return output_stream->status; document = malloc (sizeof (cairo_svg_document_t)); - if (document == NULL) + if (unlikely (document == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); /* The use of defs for font glyphs imposes no per-subset limit. */ document->font_subsets = _cairo_scaled_font_subsets_create_scaled (); - if (document->font_subsets == NULL) { + if (unlikely (document->font_subsets == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto CLEANUP_DOCUMENT; } @@ -2485,12 +2487,12 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream, document->xml_node_defs = _cairo_memory_stream_create (); status = _cairo_output_stream_get_status (document->xml_node_defs); - if (status) + if (unlikely (status)) goto CLEANUP_NODE_DEFS; document->xml_node_glyphs = _cairo_memory_stream_create (); status = _cairo_output_stream_get_status (document->xml_node_glyphs); - if (status) + if (unlikely (status)) goto CLEANUP_NODE_GLYPHS; document->alpha_filter = FALSE; @@ -2607,7 +2609,7 @@ _cairo_svg_document_finish (cairo_svg_document_t *document) surface = (cairo_svg_surface_t *) _cairo_paginated_surface_get_target (document->owner); if (surface->xml_node != NULL && _cairo_memory_stream_length (surface->xml_node) > 0) { - if (_cairo_svg_surface_store_page (surface) == NULL) { + if (unlikely (_cairo_svg_surface_store_page (surface) == NULL)) { if (status == CAIRO_STATUS_SUCCESS) status = _cairo_error (CAIRO_STATUS_NO_MEMORY); } diff --git a/src/cairo-tor-scan-converter.c b/src/cairo-tor-scan-converter.c new file mode 100644 index 00000000..20104a7f --- /dev/null +++ b/src/cairo-tor-scan-converter.c @@ -0,0 +1,2003 @@ +/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */ +/* glitter-paths - polygon scan converter + * + * Copyright (c) 2008 M Joonas Pihlaja + * Copyright (c) 2007 David Turner + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/* This is the Glitter paths scan converter incorporated into cairo. + * The source is from commit 734c53237a867a773640bd5b64816249fa1730f8 + * of + * + * http://gitweb.freedesktop.org/?p=users/joonas/glitter-paths + */ +/* Glitter-paths is a stand alone polygon rasteriser derived from + * David Turner's reimplementation of Tor Anderssons's 15x17 + * supersampling rasteriser from the Apparition graphics library. The + * main new feature here is cheaply choosing per-scan line between + * doing fully analytical coverage computation for an entire row at a + * time vs. using a supersampling approach. + * + * David Turner's code can be found at + * + * http://david.freetype.org/rasterizer-shootout/raster-comparison-20070813.tar.bz2 + * + * In particular this file incorporates large parts of ftgrays_tor10.h + * from raster-comparison-20070813.tar.bz2 + */ +/* Overview + * + * A scan converter's basic purpose to take polygon edges and convert + * them into an RLE compressed A8 mask. This one works in two phases: + * gathering edges and generating spans. + * + * 1) As the user feeds the scan converter edges they are vertically + * clipped and bucketted into a _polygon_ data structure. The edges + * are also snapped from the user's coordinates to the subpixel grid + * coordinates used during scan conversion. + * + * user + * | + * | edges + * V + * polygon buckets + * + * 2) Generating spans works by performing a vertical sweep of pixel + * rows from top to bottom and maintaining an _active_list_ of edges + * that intersect the row. From the active list the fill rule + * determines which edges are the left and right edges of the start of + * each span, and their contribution is then accumulated into a pixel + * coverage list (_cell_list_) as coverage deltas. Once the coverage + * deltas of all edges are known we can form spans of constant pixel + * coverage by summing the deltas during a traversal of the cell list. + * At the end of a pixel row the cell list is sent to a coverage + * blitter for rendering to some target surface. + * + * The pixel coverages are computed by either supersampling the row + * and box filtering a mono rasterisation, or by computing the exact + * coverages of edges in the active list. The supersampling method is + * used whenever some edge starts or stops within the row or there are + * edge intersections in the row. + * + * polygon bucket for \ + * current pixel row | + * | | + * | activate new edges | Repeat GRID_Y times if we + * V \ are supersampling this row, + * active list / or just once if we're computing + * | | analytical coverage. + * | coverage deltas | + * V | + * pixel coverage list / + * | + * V + * coverage blitter + */ +#include "cairoint.h" +#include "cairo-spans-private.h" + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +/*------------------------------------------------------------------------- + * cairo specific config + */ +#define I static + +/* Prefer cairo's status type. */ +#define GLITTER_HAVE_STATUS_T 1 +#define GLITTER_STATUS_SUCCESS CAIRO_STATUS_SUCCESS +#define GLITTER_STATUS_NO_MEMORY CAIRO_STATUS_NO_MEMORY +typedef cairo_status_t glitter_status_t; + +/* The input coordinate scale and the rasterisation grid scales. */ +#define GLITTER_INPUT_BITS CAIRO_FIXED_FRAC_BITS +#define GRID_X_BITS CAIRO_FIXED_FRAC_BITS +#define GRID_Y 15 + +/* Set glitter up to use a cairo span renderer to do the coverage + * blitting. */ +struct pool; +struct cell_list; + +static glitter_status_t +blit_with_span_renderer( + struct cell_list *coverages, + cairo_span_renderer_t *span_renderer, + struct pool *span_pool, + int y, + int xmin, + int xmax); + +#define GLITTER_BLIT_COVERAGES_ARGS \ + cairo_span_renderer_t *span_renderer, \ + struct pool *span_pool + +#define GLITTER_BLIT_COVERAGES(cells, y, xmin, xmax) do { \ + cairo_status_t status = blit_with_span_renderer (cells, \ + span_renderer, \ + span_pool, \ + y, xmin, xmax); \ + if (unlikely (status)) \ + return status; \ +} while (0) + +/*------------------------------------------------------------------------- + * glitter-paths.h + */ + +/* "Input scaled" numbers are fixed precision reals with multiplier + * 2**GLITTER_INPUT_BITS. Input coordinates are given to glitter as + * pixel scaled numbers. These get converted to the internal grid + * scaled numbers as soon as possible. Internal overflow is possible + * if GRID_X/Y inside glitter-paths.c is larger than + * 1<<GLITTER_INPUT_BITS. */ +#ifndef GLITTER_INPUT_BITS +# define GLITTER_INPUT_BITS 8 +#endif +#define GLITTER_INPUT_SCALE (1<<GLITTER_INPUT_BITS) +typedef int glitter_input_scaled_t; + +#if !GLITTER_HAVE_STATUS_T +typedef enum { + GLITTER_STATUS_SUCCESS = 0, + GLITTER_STATUS_NO_MEMORY +} glitter_status_t; +#endif + +#ifndef I +# define I /*static*/ +#endif + +/* Opaque type for scan converting. */ +typedef struct glitter_scan_converter glitter_scan_converter_t; + +/* Reset a scan converter to accept polygon edges and set the clip box + * in pixels. Allocates O(ymax-ymin) bytes of memory. The clip box + * is set to integer pixel coordinates xmin <= x < xmax, ymin <= y < + * ymax. */ +I glitter_status_t +glitter_scan_converter_reset( + glitter_scan_converter_t *converter, + int xmin, int ymin, + int xmax, int ymax); + +/* Add a new polygon edge from pixel (x1,y1) to (x2,y2) to the scan + * converter. The coordinates represent pixel positions scaled by + * 2**GLITTER_PIXEL_BITS. If this function fails then the scan + * converter should be reset or destroyed. Dir must be +1 or -1, + * with the latter reversing the orientation of the edge. */ +I glitter_status_t +glitter_scan_converter_add_edge( + glitter_scan_converter_t *converter, + glitter_input_scaled_t x1, glitter_input_scaled_t y1, + glitter_input_scaled_t x2, glitter_input_scaled_t y2, + int dir); + +/* Render the polygon in the scan converter to the given A8 format + * image raster. Only the pixels accessible as pixels[y*stride+x] for + * x,y inside the clip box are written to, where xmin <= x < xmax, + * ymin <= y < ymax. The image is assumed to be clear on input. + * + * If nonzero_fill is true then the interior of the polygon is + * computed with the non-zero fill rule. Otherwise the even-odd fill + * rule is used. + * + * The scan converter must be reset or destroyed after this call. */ +#ifndef GLITTER_BLIT_COVERAGES_ARGS +# define GLITTER_BLIT_COVERAGES_ARGS unsigned char *raster_pixels, long raster_stride +#endif +I glitter_status_t +glitter_scan_converter_render( + glitter_scan_converter_t *converter, + int nonzero_fill, + GLITTER_BLIT_COVERAGES_ARGS); + +/*------------------------------------------------------------------------- + * glitter-paths.c: Implementation internal types + */ +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +/* All polygon coordinates are snapped onto a subsample grid. "Grid + * scaled" numbers are fixed precision reals with multiplier GRID_X or + * GRID_Y. */ +typedef int grid_scaled_t; +typedef int grid_scaled_x_t; +typedef int grid_scaled_y_t; + +/* Default x/y scale factors. + * You can either define GRID_X/Y_BITS to get a power-of-two scale + * or define GRID_X/Y separately. */ +#if !defined(GRID_X) && !defined(GRID_X_BITS) +# define GRID_X_BITS 8 +#endif +#if !defined(GRID_Y) && !defined(GRID_Y_BITS) +# define GRID_Y 15 +#endif + +/* Use GRID_X/Y_BITS to define GRID_X/Y if they're available. */ +#ifdef GRID_X_BITS +# define GRID_X (1 << GRID_X_BITS) +#endif +#ifdef GRID_Y_BITS +# define GRID_Y (1 << GRID_Y_BITS) +#endif + +/* The GRID_X_TO_INT_FRAC macro splits a grid scaled coordinate into + * integer and fractional parts. The integer part is floored. */ +#if defined(GRID_X_TO_INT_FRAC) + /* do nothing */ +#elif defined(GRID_X_BITS) +# define GRID_X_TO_INT_FRAC(x, i, f) \ + _GRID_TO_INT_FRAC_shift(x, i, f, GRID_X_BITS) +#else +# define GRID_X_TO_INT_FRAC(x, i, f) \ + _GRID_TO_INT_FRAC_general(x, i, f, GRID_X) +#endif + +#define _GRID_TO_INT_FRAC_general(t, i, f, m) do { \ + (i) = (t) / (m); \ + (f) = (t) % (m); \ + if ((f) < 0) { \ + --(i); \ + (f) += (m); \ + } \ +} while (0) + +#define _GRID_TO_INT_FRAC_shift(t, i, f, b) do { \ + (f) = (t) & ((1 << (b)) - 1); \ + (i) = (t) >> (b); \ +} while (0) + +/* A grid area is a real in [0,1] scaled by 2*GRID_X*GRID_Y. We want + * to be able to represent exactly areas of subpixel trapezoids whose + * vertices are given in grid scaled coordinates. The scale factor + * comes from needing to accurately represent the area 0.5*dx*dy of a + * triangle with base dx and height dy in grid scaled numbers. */ +typedef int grid_area_t; +#define GRID_XY (2*GRID_X*GRID_Y) /* Unit area on the grid. */ + +/* GRID_AREA_TO_ALPHA(area): map [0,GRID_XY] to [0,255]. */ +#if GRID_XY == 510 +# define GRID_AREA_TO_ALPHA(c) (((c)+1) >> 1) +#elif GRID_XY == 255 +# define GRID_AREA_TO_ALPHA(c) (c) +#elif GRID_XY == 64 +# define GRID_AREA_TO_ALPHA(c) (((c) << 2) | -(((c) & 0x40) >> 6)) +#elif GRID_XY == 128 +# define GRID_AREA_TO_ALPHA(c) ((((c) << 1) | -((c) >> 7)) & 255) +#elif GRID_XY == 256 +# define GRID_AREA_TO_ALPHA(c) (((c) | -((c) >> 8)) & 255) +#elif GRID_XY == 15 +# define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c)) +#elif GRID_XY == 2*256*15 +# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4)) >> 9) +#else +# define GRID_AREA_TO_ALPHA(c) ((c)*255 / GRID_XY) /* tweak me for rounding */ +#endif + +#define UNROLL3(x) x x x + +struct quorem { + int quo; + int rem; +}; + +/* Header for a chunk of memory in a memory pool. */ +struct _pool_chunk { + /* # bytes used in this chunk. */ + size_t size; + + /* # bytes total in this chunk */ + size_t capacity; + + /* Pointer to the previous chunk or %NULL if this is the sentinel + * chunk in the pool header. */ + 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 + * within some other structure. It may optionally be followed by an + * embedded array from which requests are fulfilled until + * malloc needs to be called to allocate a first real chunk. */ +struct pool { + /* Chunk we're allocating from. */ + struct _pool_chunk *current; + + /* Free list of previously allocated chunks. All have >= default + * capacity. */ + struct _pool_chunk *first_free; + + /* The default capacity of a chunk. */ + size_t default_capacity; + + /* Header for the sentinel chunk. Directly following the pool + * struct should be some space for embedded elements from which + * the sentinel chunk allocates from. */ + struct _pool_chunk sentinel[1]; +}; + +/* A polygon edge. */ +struct edge { + /* Next in y-bucket or active list. */ + struct edge *next; + + /* Current x coordinate while the edge is on the active + * list. Initialised to the x coordinate of the top of the + * edge. The quotient is in grid_scaled_x_t units and the + * remainder is mod dy in grid_scaled_y_t units.*/ + struct quorem x; + + /* Advance of the current x when moving down a subsample line. */ + struct quorem dxdy; + + /* Advance of the current x when moving down a full pixel + * row. Only initialised when the height of the edge is large + * enough that there's a chance the edge could be stepped by a + * full row's worth of subsample rows at a time. */ + struct quorem dxdy_full; + + /* The clipped y of the top of the edge. */ + grid_scaled_y_t ytop; + + /* y2-y1 after orienting the edge downwards. */ + grid_scaled_y_t dy; + + /* Number of subsample rows remaining to scan convert of this + * edge. */ + grid_scaled_y_t height_left; + + /* Original sign of the edge: +1 for downwards, -1 for upwards + * edges. */ + int dir; +}; + +/* Number of subsample rows per y-bucket. Must be GRID_Y. */ +#define EDGE_Y_BUCKET_HEIGHT GRID_Y + +#define EDGE_Y_BUCKET_INDEX(y, ymin) (((y) - (ymin))/EDGE_Y_BUCKET_HEIGHT) + +/* A collection of sorted and vertically clipped edges of the polygon. + * Edges are moved from the polygon to an active list while scan + * converting. */ +struct polygon { + /* The vertical clip extents. */ + grid_scaled_y_t ymin, ymax; + + /* Array of edges all starting in the same bucket. An edge is put + * into bucket EDGE_BUCKET_INDEX(edge->ytop, polygon->ymin) when + * it is added to the polygon. */ + struct edge **y_buckets; + + struct { + struct pool base[1]; + struct edge embedded[32]; + } edge_pool; +}; + +/* A cell records the effect on pixel coverage of polygon edges + * passing through a pixel. It contains two accumulators of pixel + * coverage. + * + * Consider the effects of a polygon edge on the coverage of a pixel + * it intersects and that of the following one. The coverage of the + * following pixel is the height of the edge multiplied by the width + * of the pixel, and the coverage of the pixel itself is the area of + * the trapezoid formed by the edge and the right side of the pixel. + * + * +-----------------------+-----------------------+ + * | | | + * | | | + * |_______________________|_______________________| + * | \...................|.......................|\ + * | \..................|.......................| | + * | \.................|.......................| | + * | \....covered.....|.......................| | + * | \....area.......|.......................| } covered height + * | \..............|.......................| | + * |uncovered\.............|.......................| | + * | area \............|.......................| | + * |___________\...........|.......................|/ + * | | | + * | | | + * | | | + * +-----------------------+-----------------------+ + * + * Since the coverage of the following pixel will always be a multiple + * of the width of the pixel, we can store the height of the covered + * area instead. The coverage of the pixel itself is the total + * coverage minus the area of the uncovered area to the left of the + * edge. As it's faster to compute the uncovered area we only store + * that and subtract it from the total coverage later when forming + * spans to blit. + * + * The heights and areas are signed, with left edges of the polygon + * having positive sign and right edges having negative sign. When + * two edges intersect they swap their left/rightness so their + * contribution above and below the intersection point must be + * computed separately. */ +struct cell { + struct cell *next; + int x; + grid_area_t uncovered_area; + grid_scaled_y_t covered_height; +}; + +/* A cell list represents the scan line sparsely as cells ordered by + * ascending x. It is geared towards scanning the cells in order + * using an internal cursor. */ +struct cell_list { + /* Points to the left-most cell in the scan line. */ + struct cell *head; + + /* Cursor state for iterating through the cell list. Points to + * a pointer to the current cell: either &cell_list->head or the next + * field of the previous cell. */ + struct cell **cursor; + + /* Cells in the cell list are owned by the cell list and are + * allocated from this pool. */ + struct { + struct pool base[1]; + struct cell embedded[32]; + } cell_pool; +}; + +struct cell_pair { + struct cell *cell1; + struct cell *cell2; +}; + +/* The active list contains edges in the current scan line ordered by + * the x-coordinate of the intercept of the edge and the scan line. */ +struct active_list { + /* Leftmost edge on the current scan line. */ + struct edge *head; + + /* A lower bound on the height of the active edges is used to + * estimate how soon some active edge ends. We can't advance the + * scan conversion by a full pixel row if an edge ends somewhere + * within it. */ + grid_scaled_y_t min_height; +}; + +struct glitter_scan_converter { + struct polygon polygon[1]; + struct active_list active[1]; + struct cell_list coverages[1]; + + /* Clip box. */ + grid_scaled_x_t xmin, xmax; + grid_scaled_y_t ymin, ymax; +}; + +/* Compute the floored division a/b. Assumes / and % perform symmetric + * division. */ +inline static struct quorem +floored_divrem(int a, int b) +{ + struct quorem qr; + qr.quo = a/b; + qr.rem = a%b; + if ((a^b)<0 && qr.rem) { + qr.quo -= 1; + qr.rem += b; + } + return qr; +} + +/* Compute the floored division (x*a)/b. Assumes / and % perform symmetric + * division. */ +static struct quorem +floored_muldivrem(int x, int a, int b) +{ + struct quorem qr; + long long xa = (long long)x*a; + qr.quo = xa/b; + qr.rem = xa%b; + if ((xa>=0) != (b>=0) && qr.rem) { + qr.quo -= 1; + qr.rem += b; + } + return qr; +} + +static void +_pool_chunk_init( + struct _pool_chunk *p, + struct _pool_chunk *prev_chunk, + size_t capacity) +{ + p->prev_chunk = prev_chunk; + p->size = 0; + p->capacity = capacity; +} + +static struct _pool_chunk * +_pool_chunk_create( + struct _pool_chunk *prev_chunk, + size_t size) +{ + struct _pool_chunk *p; + size_t size_with_head = size + sizeof(struct _pool_chunk); + if (size_with_head < size) + return NULL; + p = malloc(size_with_head); + if (p) + _pool_chunk_init(p, prev_chunk, size); + return p; +} + +static void +pool_init( + struct pool *pool, + size_t default_capacity, + size_t embedded_capacity) +{ + pool->current = pool->sentinel; + pool->first_free = NULL; + pool->default_capacity = default_capacity; + _pool_chunk_init(pool->sentinel, NULL, embedded_capacity); +} + +static void +pool_fini(struct pool *pool) +{ + struct _pool_chunk *p = pool->current; + do { + while (NULL != p) { + struct _pool_chunk *prev = p->prev_chunk; + if (p != pool->sentinel) + free(p); + p = prev; + } + p = pool->first_free; + pool->first_free = NULL; + } while (NULL != p); + pool_init(pool, 0, 0); +} + +/* Satisfy an allocation by first allocating a new large enough chunk + * and adding it to the head of the pool's chunk list. This function + * is called as a fallback if pool_alloc() couldn't do a quick + * allocation from the current chunk in the pool. */ +static void * +_pool_alloc_from_new_chunk( + struct pool *pool, + size_t size) +{ + struct _pool_chunk *chunk; + void *obj; + size_t capacity; + + /* If the allocation is smaller than the default chunk size then + * try getting a chunk off the free list. Force alloc of a new + * chunk for large requests. */ + capacity = size; + chunk = NULL; + if (size < pool->default_capacity) { + capacity = pool->default_capacity; + chunk = pool->first_free; + if (chunk) { + pool->first_free = chunk->prev_chunk; + _pool_chunk_init(chunk, pool->current, chunk->capacity); + } + } + + if (NULL == chunk) { + chunk = _pool_chunk_create( + pool->current, + capacity); + if (NULL == chunk) + return NULL; + } + pool->current = chunk; + + obj = &chunk->data[chunk->size]; + chunk->size += size; + return obj; +} + +/* Allocate size bytes from the pool. The first allocated address + * returned from a pool is aligned to sizeof(void*). Subsequent + * addresses will maintain alignment as long as multiples of void* are + * allocated. Returns the address of a new memory area or %NULL on + * allocation failures. The pool retains ownership of the returned + * memory. */ +inline static void * +pool_alloc( + struct pool *pool, + size_t size) +{ + struct _pool_chunk *chunk = pool->current; + + if (size <= chunk->capacity - chunk->size) { + void *obj = &chunk->data[chunk->size]; + chunk->size += size; + return obj; + } + else { + return _pool_alloc_from_new_chunk(pool, size); + } +} + +/* Relinquish all pool_alloced memory back to the pool. */ +static void +pool_reset(struct pool *pool) +{ + /* Transfer all used chunks to the chunk free list. */ + struct _pool_chunk *chunk = pool->current; + if (chunk != pool->sentinel) { + while (chunk->prev_chunk != pool->sentinel) { + chunk = chunk->prev_chunk; + } + chunk->prev_chunk = pool->first_free; + pool->first_free = pool->current; + } + /* Reset the sentinel as the current chunk. */ + pool->current = pool->sentinel; + pool->sentinel->size = 0; +} + +/* Rewinds the cell list's cursor to the beginning. After rewinding + * we're good to cell_list_find() the cell any x coordinate. */ +inline static void +cell_list_rewind(struct cell_list *cells) +{ + cells->cursor = &cells->head; +} + +/* Rewind the cell list if its cursor has been advanced past x. */ +inline static void +cell_list_maybe_rewind(struct cell_list *cells, int x) +{ + struct cell *tail = *cells->cursor; + if (tail && tail->x > x) { + cell_list_rewind(cells); + } +} + +static void +cell_list_init(struct cell_list *cells) +{ + pool_init(cells->cell_pool.base, + 256*sizeof(struct cell), + sizeof(cells->cell_pool.embedded)); + cells->head = NULL; + cell_list_rewind(cells); +} + +static void +cell_list_fini(struct cell_list *cells) +{ + pool_fini(cells->cell_pool.base); + cell_list_init(cells); +} + +/* Empty the cell list. This is called at the start of every pixel + * row. */ +inline static void +cell_list_reset(struct cell_list *cells) +{ + cell_list_rewind(cells); + cells->head = NULL; + pool_reset(cells->cell_pool.base); +} + +/* Find a cell at the given x-coordinate. Returns %NULL if a new cell + * needed to be allocated but couldn't be. Cells must be found with + * non-decreasing x-coordinate until the cell list is rewound using + * cell_list_rewind(). Ownership of the returned cell is retained by + * the cell list. */ +inline static struct cell * +cell_list_find(struct cell_list *cells, int x) +{ + struct cell **cursor = cells->cursor; + struct cell *tail; + + while (1) { + UNROLL3({ + tail = *cursor; + if (NULL == tail || tail->x >= x) { + break; + } + cursor = &tail->next; + }); + } + cells->cursor = cursor; + if (tail && tail->x == x) { + return tail; + } else { + struct cell *cell = pool_alloc( + cells->cell_pool.base, + sizeof(struct cell)); + if (NULL == cell) + return NULL; + *cursor = cell; + cell->next = tail; + cell->x = x; + cell->uncovered_area = 0; + cell->covered_height = 0; + return cell; + } +} + +/* Find two cells at x1 and x2. This is exactly equivalent + * to + * + * pair.cell1 = cell_list_find(cells, x1); + * pair.cell2 = cell_list_find(cells, x2); + * + * except with less function call overhead. */ +inline static struct cell_pair +cell_list_find2(struct cell_list *cells, int x1, int x2) +{ + struct cell_pair pair; + struct cell **cursor = cells->cursor; + struct cell *cell1; + struct cell *cell2; + struct cell *newcell; + + /* Find first cell at x1. */ + while (1) { + UNROLL3({ + cell1 = *cursor; + if (NULL == cell1 || cell1->x > x1) + break; + if (cell1->x == x1) + goto found_first; + cursor = &cell1->next; + }); + } + + /* New first cell at x1. */ + newcell = pool_alloc( + cells->cell_pool.base, + sizeof(struct cell)); + if (NULL != newcell) { + *cursor = newcell; + newcell->next = cell1; + newcell->x = x1; + newcell->uncovered_area = 0; + newcell->covered_height = 0; + } + cell1 = newcell; + found_first: + + /* Find second cell at x2. */ + while (1) { + UNROLL3({ + cell2 = *cursor; + if (NULL == cell2 || cell2->x > x2) + break; + if (cell2->x == x2) + goto found_second; + cursor = &cell2->next; + }); + } + + /* New second cell at x2. */ + newcell = pool_alloc( + cells->cell_pool.base, + sizeof(struct cell)); + if (NULL != newcell) { + *cursor = newcell; + newcell->next = cell2; + newcell->x = x2; + newcell->uncovered_area = 0; + newcell->covered_height = 0; + } + cell2 = newcell; + found_second: + + cells->cursor = cursor; + pair.cell1 = cell1; + pair.cell2 = cell2; + return pair; +} + +/* Add an unbounded subpixel span covering subpixels >= x to the + * coverage cells. */ +static glitter_status_t +cell_list_add_unbounded_subspan( + struct cell_list *cells, + grid_scaled_x_t x) +{ + struct cell *cell; + int ix, fx; + + GRID_X_TO_INT_FRAC(x, ix, fx); + + cell = cell_list_find(cells, ix); + if (cell) { + cell->uncovered_area += 2*fx; + cell->covered_height++; + return GLITTER_STATUS_SUCCESS; + } + return GLITTER_STATUS_NO_MEMORY; +} + +/* Add a subpixel span covering [x1, x2) to the coverage cells. */ +inline static glitter_status_t +cell_list_add_subspan( + struct cell_list *cells, + grid_scaled_x_t x1, + grid_scaled_x_t x2) +{ + int ix1, fx1; + int ix2, fx2; + + GRID_X_TO_INT_FRAC(x1, ix1, fx1); + GRID_X_TO_INT_FRAC(x2, ix2, fx2); + + if (ix1 != ix2) { + struct cell_pair p; + p = cell_list_find2(cells, ix1, ix2); + if (p.cell1 && p.cell2) { + p.cell1->uncovered_area += 2*fx1; + ++p.cell1->covered_height; + p.cell2->uncovered_area -= 2*fx2; + --p.cell2->covered_height; + return GLITTER_STATUS_SUCCESS; + } + } + else { + struct cell *cell = cell_list_find(cells, ix1); + if (cell) { + cell->uncovered_area += 2*(fx1-fx2); + return GLITTER_STATUS_SUCCESS; + } + } + return GLITTER_STATUS_NO_MEMORY; +} + +/* Adds the analytical coverage of an edge crossing the current pixel + * row to the coverage cells and advances the edge's x position to the + * following row. + * + * This function is only called when we know that during this pixel row: + * + * 1) The relative order of all edges on the active list doesn't + * change. In particular, no edges intersect within this row to pixel + * precision. + * + * 2) No new edges start in this row. + * + * 3) No existing edges end mid-row. + * + * This function depends on being called with all edges from the + * active list in the order they appear on the list (i.e. with + * non-decreasing x-coordinate.) */ +static glitter_status_t +cell_list_render_edge( + struct cell_list *cells, + struct edge *edge, + int sign) +{ + struct quorem x1 = edge->x; + struct quorem x2 = x1; + grid_scaled_y_t y1, y2, dy; + grid_scaled_x_t dx; + int ix1, ix2; + grid_scaled_x_t fx1, fx2; + + x2.quo += edge->dxdy_full.quo; + x2.rem += edge->dxdy_full.rem; + if (x2.rem >= 0) { + ++x2.quo; + x2.rem -= edge->dy; + } + edge->x = x2; + + GRID_X_TO_INT_FRAC(x1.quo, ix1, fx1); + GRID_X_TO_INT_FRAC(x2.quo, ix2, fx2); + + /* Edge is entirely within a column? */ + if (ix1 == ix2) { + /* We always know that ix1 is >= the cell list cursor in this + * case due to the no-intersections precondition. */ + struct cell *cell = cell_list_find(cells, ix1); + if (NULL == cell) + return GLITTER_STATUS_NO_MEMORY; + cell->covered_height += sign*GRID_Y; + cell->uncovered_area += sign*(fx1 + fx2)*GRID_Y; + return GLITTER_STATUS_SUCCESS; + } + + /* Orient the edge left-to-right. */ + dx = x2.quo - x1.quo; + if (dx >= 0) { + y1 = 0; + y2 = GRID_Y; + } else { + int tmp; + tmp = ix1; ix1 = ix2; ix2 = tmp; + tmp = fx1; fx1 = fx2; fx2 = tmp; + dx = -dx; + sign = -sign; + y1 = GRID_Y; + y2 = 0; + } + dy = y2 - y1; + + /* Add coverage for all pixels [ix1,ix2] on this row crossed + * by the edge. */ + { + struct cell_pair pair; + struct quorem y = floored_divrem((GRID_X - fx1)*dy, dx); + + /* When rendering a previous edge on the active list we may + * advance the cell list cursor past the leftmost pixel of the + * current edge even though the two edges don't intersect. + * e.g. consider two edges going down and rightwards: + * + * --\_+---\_+-----+-----+---- + * \_ \_ | | + * | \_ | \_ | | + * | \_| \_| | + * | \_ \_ | + * ----+-----+-\---+-\---+---- + * + * The left edge touches cells past the starting cell of the + * right edge. Fortunately such cases are rare. + * + * The rewinding is never necessary if the current edge stays + * within a single column because we've checked before calling + * this function that the active list order won't change. */ + cell_list_maybe_rewind(cells, ix1); + + pair = cell_list_find2(cells, ix1, ix1+1); + if (!pair.cell1 || !pair.cell2) + return GLITTER_STATUS_NO_MEMORY; + + pair.cell1->uncovered_area += sign*y.quo*(GRID_X + fx1); + pair.cell1->covered_height += sign*y.quo; + y.quo += y1; + + if (ix1+1 < ix2) { + struct quorem dydx_full = floored_divrem(GRID_X*dy, dx); + struct cell *cell = pair.cell2; + + ++ix1; + do { + grid_scaled_y_t y_skip = dydx_full.quo; + y.rem += dydx_full.rem; + if (y.rem >= dx) { + ++y_skip; + y.rem -= dx; + } + + y.quo += y_skip; + + y_skip *= sign; + cell->uncovered_area += y_skip*GRID_X; + cell->covered_height += y_skip; + + ++ix1; + cell = cell_list_find(cells, ix1); + if (NULL == cell) + return GLITTER_STATUS_NO_MEMORY; + } while (ix1 != ix2); + + pair.cell2 = cell; + } + pair.cell2->uncovered_area += sign*(y2 - y.quo)*fx2; + pair.cell2->covered_height += sign*(y2 - y.quo); + } + + return GLITTER_STATUS_SUCCESS; +} + +static void +polygon_init(struct polygon *polygon) +{ + polygon->ymin = polygon->ymax = 0; + polygon->y_buckets = NULL; + pool_init(polygon->edge_pool.base, + (8192 - sizeof(struct _pool_chunk))/sizeof(struct edge), + sizeof(polygon->edge_pool.embedded)); +} + +static void +polygon_fini(struct polygon *polygon) +{ + free(polygon->y_buckets); + pool_fini(polygon->edge_pool.base); + polygon_init(polygon); +} + +static void * +realloc_and_clear(void *p, size_t a, size_t b) +{ + size_t total = a*b; + if (b && total / b != a) + return NULL; + p = realloc(p, total); + if (p) + memset(p, 0, total); + return p; +} + +/* Empties the polygon of all edges. The polygon is then prepared to + * receive new edges and clip them to the vertical range + * [ymin,ymax). */ +static glitter_status_t +polygon_reset( + struct polygon *polygon, + grid_scaled_y_t ymin, + grid_scaled_y_t ymax) +{ + void *p; + unsigned h = ymax - ymin; + unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax + EDGE_Y_BUCKET_HEIGHT-1, + ymin); + + pool_reset(polygon->edge_pool.base); + + if (h > 0x7FFFFFFFU - EDGE_Y_BUCKET_HEIGHT) + goto bail_no_mem; /* even if you could, you wouldn't want to. */ + + if (num_buckets > 0) { + p = realloc_and_clear( + polygon->y_buckets, + num_buckets, + sizeof(struct edge*)); + if (NULL == p) + goto bail_no_mem; + } + else { + free(polygon->y_buckets); + p = NULL; + } + polygon->y_buckets = p; + + polygon->ymin = ymin; + polygon->ymax = ymax; + return GLITTER_STATUS_SUCCESS; + + bail_no_mem: + free(polygon->y_buckets); + polygon->y_buckets = NULL; + polygon->ymin = 0; + polygon->ymax = 0; + return GLITTER_STATUS_NO_MEMORY; +} + +static void +_polygon_insert_edge_into_its_y_bucket( + struct polygon *polygon, + struct edge *e) +{ + unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin); + struct edge **ptail = &polygon->y_buckets[ix]; + e->next = *ptail; + *ptail = e; +} + +inline static glitter_status_t +polygon_add_edge( + struct polygon *polygon, + int x0, int y0, + int x1, int y1, + int dir) +{ + struct edge *e; + grid_scaled_x_t dx; + grid_scaled_y_t dy; + grid_scaled_y_t ytop, ybot; + grid_scaled_y_t ymin = polygon->ymin; + grid_scaled_y_t ymax = polygon->ymax; + + if (y0 == y1) + return GLITTER_STATUS_SUCCESS; + + if (y0 > y1) { + int tmp; + tmp = x0; x0 = x1; x1 = tmp; + tmp = y0; y0 = y1; y1 = tmp; + dir = -dir; + } + + if (y0 >= ymax || y1 <= ymin) + return GLITTER_STATUS_SUCCESS; + + e = pool_alloc(polygon->edge_pool.base, + sizeof(struct edge)); + if (NULL == e) + return GLITTER_STATUS_NO_MEMORY; + + dx = x1 - x0; + dy = y1 - y0; + e->dy = dy; + e->dxdy = floored_divrem(dx, dy); + + if (ymin <= y0) { + ytop = y0; + e->x.quo = x0; + e->x.rem = 0; + } + else { + ytop = ymin; + e->x = floored_muldivrem(ymin - y0, dx, dy); + e->x.quo += x0; + } + + e->dir = dir; + e->ytop = ytop; + ybot = y1 < ymax ? y1 : ymax; + e->height_left = ybot - ytop; + + if (e->height_left >= GRID_Y) { + e->dxdy_full = floored_muldivrem(GRID_Y, dx, dy); + } + else { + e->dxdy_full.quo = 0; + e->dxdy_full.rem = 0; + } + + _polygon_insert_edge_into_its_y_bucket(polygon, e); + + e->x.rem -= dy; /* Bias the remainder for faster + * edge advancement. */ + return GLITTER_STATUS_SUCCESS; +} + +static void +active_list_reset( + struct active_list *active) +{ + active->head = NULL; + active->min_height = 0; +} + +static void +active_list_init(struct active_list *active) +{ + active_list_reset(active); +} + +static void +active_list_fini( + struct active_list *active) +{ + active_list_reset(active); +} + +/* Merge the edges in an unsorted list of edges into a sorted + * list. The sort order is edges ascending by edge->x.quo. Returns + * the new head of the sorted list. */ +static struct edge * +merge_unsorted_edges(struct edge *sorted_head, struct edge *unsorted_head) +{ + struct edge *head = unsorted_head; + struct edge **cursor = &sorted_head; + int x; + + while (NULL != head) { + struct edge *prev = *cursor; + struct edge *next = head->next; + x = head->x.quo; + + if (NULL == prev || x < prev->x.quo) { + cursor = &sorted_head; + } + + while (1) { + UNROLL3({ + prev = *cursor; + if (NULL == prev || prev->x.quo >= x) + break; + cursor = &prev->next; + }); + } + + head->next = *cursor; + *cursor = head; + + head = next; + } + return sorted_head; +} + +/* Test if the edges on the active list can be safely advanced by a + * full row without intersections or any edges ending. */ +inline static int +active_list_can_step_full_row( + struct active_list *active) +{ + /* Recomputes the minimum height of all edges on the active + * list if we have been dropping edges. */ + if (active->min_height <= 0) { + struct edge *e = active->head; + int min_height = INT_MAX; + + while (NULL != e) { + if (e->height_left < min_height) + min_height = e->height_left; + e = e->next; + } + + active->min_height = min_height; + } + + /* Check for intersections only if no edges end during the next + * row. */ + if (active->min_height >= GRID_Y) { + grid_scaled_x_t prev_x = INT_MIN; + struct edge *e = active->head; + while (NULL != e) { + struct quorem x = e->x; + + x.quo += e->dxdy_full.quo; + x.rem += e->dxdy_full.rem; + if (x.rem >= 0) + ++x.quo; + + if (x.quo <= prev_x) + return 0; + prev_x = x.quo; + e = e->next; + } + return 1; + } + return 0; +} + +/* Merges edges on the given subpixel row from the polygon to the + * active_list. */ +inline static void +active_list_merge_edges_from_polygon( + struct active_list *active, + grid_scaled_y_t y, + struct polygon *polygon) +{ + /* Split off the edges on the current subrow and merge them into + * the active list. */ + unsigned ix = EDGE_Y_BUCKET_INDEX(y, polygon->ymin); + int min_height = active->min_height; + struct edge *subrow_edges = NULL; + struct edge **ptail = &polygon->y_buckets[ix]; + + while (1) { + struct edge *tail = *ptail; + if (NULL == tail) break; + + if (y == tail->ytop) { + *ptail = tail->next; + tail->next = subrow_edges; + subrow_edges = tail; + if (tail->height_left < min_height) + min_height = tail->height_left; + } + else { + ptail = &tail->next; + } + } + active->head = merge_unsorted_edges(active->head, subrow_edges); + active->min_height = min_height; +} + +/* Advance the edges on the active list by one subsample row by + * updating their x positions. Drop edges from the list that end. */ +inline static void +active_list_substep_edges( + struct active_list *active) +{ + struct edge **cursor = &active->head; + grid_scaled_x_t prev_x = INT_MIN; + struct edge *unsorted = NULL; + + while (1) { + struct edge *edge; + + UNROLL3({ + edge = *cursor; + if (NULL == edge) + break; + + if (0 != --edge->height_left) { + edge->x.quo += edge->dxdy.quo; + edge->x.rem += edge->dxdy.rem; + if (edge->x.rem >= 0) { + ++edge->x.quo; + edge->x.rem -= edge->dy; + } + + if (edge->x.quo < prev_x) { + *cursor = edge->next; + edge->next = unsorted; + unsorted = edge; + } else { + prev_x = edge->x.quo; + cursor = &edge->next; + } + + } else { + *cursor = edge->next; + } + }); + } + + if (unsorted) + active->head = merge_unsorted_edges(active->head, unsorted); +} + +inline static glitter_status_t +apply_nonzero_fill_rule_for_subrow( + struct active_list *active, + struct cell_list *coverages) +{ + struct edge *edge = active->head; + int winding = 0; + int xstart; + int xend; + int status; + + cell_list_rewind(coverages); + + while (NULL != edge) { + xstart = edge->x.quo; + winding = edge->dir; + while (1) { + edge = edge->next; + if (NULL == edge) { + return cell_list_add_unbounded_subspan( + coverages, xstart); + } + winding += edge->dir; + if (0 == winding) + break; + } + + xend = edge->x.quo; + status = cell_list_add_subspan(coverages, xstart, xend); + if (status) + return status; + + edge = edge->next; + } + + return GLITTER_STATUS_SUCCESS; +} + +static glitter_status_t +apply_evenodd_fill_rule_for_subrow( + struct active_list *active, + struct cell_list *coverages) +{ + struct edge *edge = active->head; + int xstart; + int xend; + int status; + + cell_list_rewind(coverages); + + while (NULL != edge) { + xstart = edge->x.quo; + + edge = edge->next; + if (NULL == edge) { + return cell_list_add_unbounded_subspan( + coverages, xstart); + } + + xend = edge->x.quo; + status = cell_list_add_subspan(coverages, xstart, xend); + if (status) + return status; + + edge = edge->next; + } + + return GLITTER_STATUS_SUCCESS; +} + +static glitter_status_t +apply_nonzero_fill_rule_and_step_edges( + struct active_list *active, + struct cell_list *coverages) +{ + struct edge **cursor = &active->head; + struct edge *left_edge; + int status; + + left_edge = *cursor; + while (NULL != left_edge) { + struct edge *right_edge; + int winding = left_edge->dir; + + left_edge->height_left -= GRID_Y; + if (left_edge->height_left) { + cursor = &left_edge->next; + } + else { + *cursor = left_edge->next; + } + + while (1) { + right_edge = *cursor; + + if (NULL == right_edge) { + return cell_list_render_edge( + coverages, left_edge, +1); + } + + right_edge->height_left -= GRID_Y; + if (right_edge->height_left) { + cursor = &right_edge->next; + } + else { + *cursor = right_edge->next; + } + + winding += right_edge->dir; + if (0 == winding) + break; + + right_edge->x.quo += right_edge->dxdy_full.quo; + right_edge->x.rem += right_edge->dxdy_full.rem; + if (right_edge->x.rem >= 0) { + ++right_edge->x.quo; + right_edge->x.rem -= right_edge->dy; + } + } + + status = cell_list_render_edge( + coverages, left_edge, +1); + if (status) + return status; + status = cell_list_render_edge( + coverages, right_edge, -1); + if (status) + return status; + + left_edge = *cursor; + } + + return GLITTER_STATUS_SUCCESS; +} + +static glitter_status_t +apply_evenodd_fill_rule_and_step_edges( + struct active_list *active, + struct cell_list *coverages) +{ + struct edge **cursor = &active->head; + struct edge *left_edge; + int status; + + left_edge = *cursor; + while (NULL != left_edge) { + struct edge *right_edge; + + left_edge->height_left -= GRID_Y; + if (left_edge->height_left) { + cursor = &left_edge->next; + } + else { + *cursor = left_edge->next; + } + + right_edge = *cursor; + + if (NULL == right_edge) { + return cell_list_render_edge( + coverages, left_edge, +1); + } + + right_edge->height_left -= GRID_Y; + if (right_edge->height_left) { + cursor = &right_edge->next; + } + else { + *cursor = right_edge->next; + } + + status = cell_list_render_edge( + coverages, left_edge, +1); + if (status) + return status; + status = cell_list_render_edge( + coverages, right_edge, -1); + if (status) + return status; + + left_edge = *cursor; + } + + return GLITTER_STATUS_SUCCESS; +} + +/* If the user hasn't configured a coverage blitter, use a default one + * that blits spans directly to an A8 raster. */ +#ifndef GLITTER_BLIT_COVERAGES + +inline static void +blit_span( + unsigned char *row_pixels, + int x, unsigned len, + grid_area_t coverage) +{ + int alpha = GRID_AREA_TO_ALPHA(coverage); + if (1 == len) { + row_pixels[x] = alpha; + } + else { + memset(row_pixels + x, alpha, len); + } +} + +#define GLITTER_BLIT_COVERAGES(coverages, y, xmin, xmax) \ + blit_cells(coverages, raster_pixels + (y)*raster_stride, xmin, xmax) + +static void +blit_cells( + struct cell_list *cells, + unsigned char *row_pixels, + int xmin, int xmax) +{ + struct cell *cell = cells->head; + int prev_x = xmin; + int coverage = 0; + if (NULL == cell) + return; + + while (NULL != cell && cell->x < xmin) { + coverage += cell->covered_height; + cell = cell->next; + } + coverage *= GRID_X*2; + + for (; NULL != cell; cell = cell->next) { + int x = cell->x; + int area; + if (x >= xmax) + break; + if (x > prev_x && 0 != coverage) { + blit_span(row_pixels, prev_x, x - prev_x, coverage); + } + + coverage += cell->covered_height * GRID_X*2; + area = coverage - cell->uncovered_area; + if (area) { + blit_span(row_pixels, x, 1, area); + } + prev_x = x+1; + } + + if (0 != coverage && prev_x < xmax) { + blit_span(row_pixels, prev_x, xmax - prev_x, coverage); + } +} +#endif /* GLITTER_BLIT_COVERAGES */ + +static void +_glitter_scan_converter_init(glitter_scan_converter_t *converter) +{ + polygon_init(converter->polygon); + active_list_init(converter->active); + cell_list_init(converter->coverages); + converter->xmin=0; + converter->ymin=0; + converter->xmax=0; + converter->ymax=0; +} + +static void +_glitter_scan_converter_fini(glitter_scan_converter_t *converter) +{ + polygon_fini(converter->polygon); + active_list_fini(converter->active); + cell_list_fini(converter->coverages); + converter->xmin=0; + converter->ymin=0; + converter->xmax=0; + converter->ymax=0; +} + +static grid_scaled_t +int_to_grid_scaled(int i, int scale) +{ + /* Clamp to max/min representable scaled number. */ + if (i >= 0) { + if (i >= INT_MAX/scale) + i = INT_MAX/scale; + } + else { + if (i <= INT_MIN/scale) + i = INT_MIN/scale; + } + return i*scale; +} + +#define int_to_grid_scaled_x(x) int_to_grid_scaled((x), GRID_X) +#define int_to_grid_scaled_y(x) int_to_grid_scaled((x), GRID_Y) + +I glitter_status_t +glitter_scan_converter_reset( + glitter_scan_converter_t *converter, + int xmin, int ymin, + int xmax, int ymax) +{ + glitter_status_t status; + + converter->xmin = 0; converter->xmax = 0; + converter->ymin = 0; converter->ymax = 0; + + xmin = int_to_grid_scaled_x(xmin); + ymin = int_to_grid_scaled_y(ymin); + xmax = int_to_grid_scaled_x(xmax); + ymax = int_to_grid_scaled_y(ymax); + + active_list_reset(converter->active); + cell_list_reset(converter->coverages); + status = polygon_reset(converter->polygon, ymin, ymax); + if (status) + return status; + + converter->xmin = xmin; + converter->xmax = xmax; + converter->ymin = ymin; + converter->ymax = ymax; + return GLITTER_STATUS_SUCCESS; +} + +/* INPUT_TO_GRID_X/Y (in_coord, out_grid_scaled, grid_scale) + * These macros convert an input coordinate in the client's + * device space to the rasterisation grid. + */ +/* Gah.. this bit of ugly defines INPUT_TO_GRID_X/Y so as to use + * shifts if possible, and something saneish if not. + */ +#if !defined(INPUT_TO_GRID_Y) && defined(GRID_Y_BITS) && GRID_Y_BITS <= GLITTER_INPUT_BITS +# define INPUT_TO_GRID_Y(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_Y_BITS) +#else +# define INPUT_TO_GRID_Y(in, out) INPUT_TO_GRID_general(in, out, GRID_Y) +#endif + +#if !defined(INPUT_TO_GRID_X) && defined(GRID_X_BITS) && GRID_X_BITS <= GLITTER_INPUT_BITS +# define INPUT_TO_GRID_X(in, out) (out) = (in) >> (GLITTER_INPUT_BITS - GRID_X_BITS) +#else +# define INPUT_TO_GRID_X(in, out) INPUT_TO_GRID_general(in, out, GRID_X) +#endif + +#define INPUT_TO_GRID_general(in, out, grid_scale) do { \ + long long tmp__ = (long long)(grid_scale) * (in); \ + tmp__ >>= GLITTER_INPUT_BITS; \ + (out) = tmp__; \ +} while (0) + +I glitter_status_t +glitter_scan_converter_add_edge( + glitter_scan_converter_t *converter, + glitter_input_scaled_t x1, glitter_input_scaled_t y1, + glitter_input_scaled_t x2, glitter_input_scaled_t y2, + int dir) +{ + /* XXX: possible overflows if GRID_X/Y > 2**GLITTER_INPUT_BITS */ + grid_scaled_y_t sx1, sy1; + grid_scaled_y_t sx2, sy2; + + INPUT_TO_GRID_Y(y1, sy1); + INPUT_TO_GRID_Y(y2, sy2); + if (sy1 == sy2) + return GLITTER_STATUS_SUCCESS; + + INPUT_TO_GRID_X(x1, sx1); + INPUT_TO_GRID_X(x2, sx2); + + return polygon_add_edge( + converter->polygon, sx1, sy1, sx2, sy2, dir); +} + +#ifndef GLITTER_BLIT_COVERAGES_BEGIN +# define GLITTER_BLIT_COVERAGES_BEGIN +#endif + +#ifndef GLITTER_BLIT_COVERAGES_END +# define GLITTER_BLIT_COVERAGES_END +#endif + +#ifndef GLITTER_BLIT_COVERAGES_EMPTY +# define GLITTER_BLIT_COVERAGES_EMPTY(y, xmin, xmax) +#endif + +I glitter_status_t +glitter_scan_converter_render( + glitter_scan_converter_t *converter, + int nonzero_fill, + GLITTER_BLIT_COVERAGES_ARGS) +{ + int i; + int ymax_i = converter->ymax / GRID_Y; + int ymin_i = converter->ymin / GRID_Y; + int xmin_i, xmax_i; + int h = ymax_i - ymin_i; + struct polygon *polygon = converter->polygon; + struct cell_list *coverages = converter->coverages; + struct active_list *active = converter->active; + + xmin_i = converter->xmin / GRID_X; + xmax_i = converter->xmax / GRID_X; + if (xmin_i >= xmax_i) + return GLITTER_STATUS_SUCCESS; + + /* Let the coverage blitter initialise itself. */ + GLITTER_BLIT_COVERAGES_BEGIN; + + /* Render each pixel row. */ + for (i=0; i<h; i++) { + int do_full_step = 0; + glitter_status_t status = 0; + + /* Determine if we can ignore this row or use the full pixel + * stepper. */ + if (GRID_Y == EDGE_Y_BUCKET_HEIGHT + && !polygon->y_buckets[i]) + { + if (!active->head) { + GLITTER_BLIT_COVERAGES_EMPTY(i+ymin_i, xmin_i, xmax_i); + continue; + } + do_full_step = active_list_can_step_full_row(active); + } + + cell_list_reset(coverages); + + if (do_full_step) { + /* Step by a full pixel row's worth. */ + if (nonzero_fill) { + status = apply_nonzero_fill_rule_and_step_edges( + active, coverages); + } + else { + status = apply_evenodd_fill_rule_and_step_edges( + active, coverages); + } + } + else { + /* Subsample this row. */ + grid_scaled_y_t suby; + for (suby = 0; suby < GRID_Y; suby++) { + grid_scaled_y_t y = (i+ymin_i)*GRID_Y + suby; + + active_list_merge_edges_from_polygon( + active, y, polygon); + + if (nonzero_fill) + status |= apply_nonzero_fill_rule_for_subrow( + active, coverages); + else + status |= apply_evenodd_fill_rule_for_subrow( + active, coverages); + + active_list_substep_edges(active); + } + } + + if (status) + return status; + + GLITTER_BLIT_COVERAGES(coverages, i+ymin_i, xmin_i, xmax_i); + + if (!active->head) { + active->min_height = INT_MAX; + } + else { + active->min_height -= GRID_Y; + } + } + + /* Clean up the coverage blitter. */ + GLITTER_BLIT_COVERAGES_END; + + return GLITTER_STATUS_SUCCESS; +} + +/*------------------------------------------------------------------------- + * cairo specific implementation: the coverage blitter and + * scan converter subclass. */ + +static glitter_status_t +blit_with_span_renderer( + struct cell_list *cells, + cairo_span_renderer_t *renderer, + struct pool *span_pool, + int y, + int xmin, + int xmax) +{ + struct cell *cell = cells->head; + int prev_x = xmin; + int cover = 0; + cairo_half_open_span_t *spans; + unsigned num_spans; + if (cell == NULL) + return CAIRO_STATUS_SUCCESS; + + /* Skip cells to the left of the clip region. */ + while (cell != NULL && cell->x < xmin) { + cover += cell->covered_height; + cell = cell->next; + } + cover *= GRID_X*2; + + /* Count number of cells remaining. */ + { + struct cell *next = cell; + num_spans = 0; + while (next) { + next = next->next; + ++num_spans; + } + num_spans = 2*num_spans + 1; + } + + /* Allocate enough spans for the row. */ + pool_reset (span_pool); + spans = pool_alloc (span_pool, sizeof(spans[0])*num_spans); + if (spans == NULL) + return GLITTER_STATUS_NO_MEMORY; + + num_spans = 0; + + /* Form the spans from the coverages and areas. */ + for (; cell != NULL; cell = cell->next) { + int x = cell->x; + int area; + if (x >= xmax) + break; + + if (x > prev_x) { + spans[num_spans].x = prev_x; + spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); + ++num_spans; + } + + cover += cell->covered_height*GRID_X*2; + area = cover - cell->uncovered_area; + + spans[num_spans].x = x; + spans[num_spans].coverage = GRID_AREA_TO_ALPHA (area); + ++num_spans; + + prev_x = x+1; + } + + if (prev_x < xmax) { + spans[num_spans].x = prev_x; + spans[num_spans].coverage = GRID_AREA_TO_ALPHA (cover); + ++num_spans; + } + + /* Dump them into the renderer. */ + return renderer->render_row (renderer, y, spans, num_spans); +} + +struct _cairo_tor_scan_converter { + cairo_scan_converter_t base; + glitter_scan_converter_t converter[1]; + cairo_fill_rule_t fill_rule; + + struct { + struct pool base[1]; + cairo_half_open_span_t embedded[32]; + } span_pool; +}; + +typedef struct _cairo_tor_scan_converter cairo_tor_scan_converter_t; + +static void +_cairo_tor_scan_converter_destroy(void *abstract_converter) +{ + cairo_tor_scan_converter_t *self = abstract_converter; + if (self == NULL) { + return; + } + _glitter_scan_converter_fini (self->converter); + pool_fini (self->span_pool.base); + free(self); +} + +static cairo_status_t +_cairo_tor_scan_converter_add_edge( + void *abstract_converter, + cairo_fixed_t x1, + cairo_fixed_t y1, + cairo_fixed_t x2, + cairo_fixed_t y2) +{ + cairo_tor_scan_converter_t *self = abstract_converter; + cairo_status_t status; + status = glitter_scan_converter_add_edge ( + self->converter, + x1, y1, x2, y2, +1); + if (status) { + return _cairo_scan_converter_set_error (self, + _cairo_error (status)); + } + return CAIRO_STATUS_SUCCESS; +} + +static cairo_status_t +_cairo_tor_scan_converter_generate( + void *abstract_converter, + cairo_span_renderer_t *renderer) +{ + cairo_tor_scan_converter_t *self = abstract_converter; + cairo_status_t status = glitter_scan_converter_render ( + self->converter, + self->fill_rule == CAIRO_FILL_RULE_WINDING, + renderer, + self->span_pool.base); + if (status) { + return _cairo_scan_converter_set_error (self, + _cairo_error (status)); + } + return CAIRO_STATUS_SUCCESS; +} + +cairo_scan_converter_t * +_cairo_tor_scan_converter_create( + int xmin, + int ymin, + int xmax, + int ymax, + cairo_fill_rule_t fill_rule) +{ + cairo_status_t status; + cairo_tor_scan_converter_t *self = + calloc (1, sizeof(struct _cairo_tor_scan_converter)); + if (self == NULL) + goto bail_nomem; + + self->base.destroy = &_cairo_tor_scan_converter_destroy; + self->base.add_edge = &_cairo_tor_scan_converter_add_edge; + self->base.generate = &_cairo_tor_scan_converter_generate; + + pool_init (self->span_pool.base, + 250 * sizeof(self->span_pool.embedded[0]), + sizeof(self->span_pool.embedded)); + + _glitter_scan_converter_init (self->converter); + status = glitter_scan_converter_reset ( + self->converter, xmin, ymin, xmax, ymax); + if (status != CAIRO_STATUS_SUCCESS) + goto bail; + + self->fill_rule = fill_rule; + + return &self->base; + + bail: + self->base.destroy(&self->base); + bail_nomem: + return _cairo_scan_converter_create_in_error (CAIRO_STATUS_NO_MEMORY); +} diff --git a/src/cairo-traps.c b/src/cairo-traps.c index 5cf13d9c..2494696c 100644 --- a/src/cairo-traps.c +++ b/src/cairo-traps.c @@ -140,7 +140,7 @@ _cairo_traps_grow (cairo_traps_t *traps) new_size, sizeof (cairo_trapezoid_t)); } - if (new_traps == NULL) { + if (unlikely (new_traps == NULL)) { traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY); return FALSE; } @@ -690,7 +690,7 @@ _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 (boxes == NULL) + if (unlikely (boxes == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -721,7 +721,7 @@ _cairo_traps_extract_region (const cairo_traps_t *traps, if (boxes != stack_boxes) free (boxes); - if (status) + if (unlikely (status)) _cairo_region_fini (region); return status; @@ -760,15 +760,15 @@ _cairo_traps_path (const cairo_traps_t *traps, _sanitize_trap (&trap); status = _cairo_path_fixed_move_to (path, trap.left.p1.x, trap.top); - if (status) return status; + if (unlikely (status)) return status; status = _cairo_path_fixed_line_to (path, trap.right.p1.x, trap.top); - if (status) return status; + if (unlikely (status)) return status; status = _cairo_path_fixed_line_to (path, trap.right.p2.x, trap.bottom); - if (status) return status; + if (unlikely (status)) return status; status = _cairo_path_fixed_line_to (path, trap.left.p2.x, trap.bottom); - if (status) return status; + if (unlikely (status)) return status; status = _cairo_path_fixed_close_path (path); - if (status) return status; + if (unlikely (status)) return status; } return CAIRO_STATUS_SUCCESS; diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c index e8be4b44..4662eaa3 100644 --- a/src/cairo-truetype-subset.c +++ b/src/cairo-truetype-subset.c @@ -146,7 +146,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, TT_TAG_head, 0, (unsigned char *) &head, &size); - if (status) + if (unlikely (status)) return status; size = sizeof (tt_maxp_t); @@ -154,7 +154,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, TT_TAG_maxp, 0, (unsigned char *) &maxp, &size); - if (status) + if (unlikely (status)) return status; size = sizeof (tt_hhea_t); @@ -162,7 +162,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, TT_TAG_hhea, 0, (unsigned char *) &hhea, &size); - if (status) + if (unlikely (status)) return status; size = 0; @@ -170,22 +170,22 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, TT_TAG_name, 0, NULL, &size); - if (status) + if (unlikely (status)) return status; - name = malloc(size); - if (name == NULL) + name = malloc (size); + if (unlikely (name == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = backend->load_truetype_table (scaled_font_subset->scaled_font, TT_TAG_name, 0, (unsigned char *) name, &size); - if (status) + if (unlikely (status)) goto fail0; font = malloc (sizeof (cairo_truetype_font_t)); - if (font == NULL) { + if (unlikely (font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail0; } @@ -198,17 +198,17 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, font->last_boundary = 0; _cairo_array_init (&font->output, sizeof (char)); status = _cairo_array_grow_by (&font->output, 4096); - if (status) + if (unlikely (status)) goto fail1; font->glyphs = calloc (font->num_glyphs_in_face + 1, sizeof (subset_glyph_t)); - if (font->glyphs == NULL) { + if (unlikely (font->glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail1; } font->parent_to_subset = calloc (font->num_glyphs_in_face, sizeof (int)); - if (font->parent_to_subset == NULL) { + if (unlikely (font->parent_to_subset == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } @@ -252,7 +252,7 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, if (font->base.base_font == NULL) { font->base.base_font = malloc (30); - if (font->base.base_font == NULL) { + if (unlikely (font->base.base_font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } @@ -270,14 +270,14 @@ _cairo_truetype_font_create (cairo_scaled_font_subset_t *scaled_font_subset, font->base.base_font[i] = '\0'; font->base.widths = calloc (font->num_glyphs_in_face, sizeof (int)); - if (font->base.widths == NULL) { + if (unlikely (font->base.widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail4; } _cairo_array_init (&font->string_offsets, sizeof (unsigned long)); status = _cairo_array_grow_by (&font->string_offsets, 10); - if (status) + if (unlikely (status)) goto fail5; font->status = CAIRO_STATUS_SUCCESS; @@ -328,7 +328,7 @@ cairo_truetype_font_allocate_write_buffer (cairo_truetype_font_t *font, return font->status; status = _cairo_array_allocate (&font->output, length, (void **) buffer); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); return CAIRO_STATUS_SUCCESS; @@ -345,7 +345,7 @@ cairo_truetype_font_write (cairo_truetype_font_t *font, return; status = _cairo_array_append_multiple (&font->output, data, length); - if (status) + if (unlikely (status)) status = _cairo_truetype_font_set_error (font, status); } @@ -391,7 +391,7 @@ cairo_truetype_font_align_output (cairo_truetype_font_t *font, status = cairo_truetype_font_allocate_write_buffer (font, pad, &padding); - if (status) + if (unlikely (status)) return status; memset (padding, 0, pad); @@ -413,7 +413,7 @@ cairo_truetype_font_check_boundary (cairo_truetype_font_t *font, { status = _cairo_array_append (&font->string_offsets, &font->last_boundary); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); font->last_offset = font->last_boundary; @@ -486,16 +486,16 @@ cairo_truetype_font_write_generic_table (cairo_truetype_font_t *font, size = 0; status = font->backend->load_truetype_table(font->scaled_font_subset->scaled_font, tag, 0, NULL, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, tag, 0, buffer, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); return CAIRO_STATUS_SUCCESS; @@ -533,7 +533,7 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font, flags = be16_to_cpu (composite_glyph->flags); has_more_components = flags & TT_MORE_COMPONENTS; status = cairo_truetype_font_use_glyph (font, be16_to_cpu (composite_glyph->index), &index); - if (status) + if (unlikely (status)) return status; composite_glyph->index = cpu_to_be16 (index); @@ -575,21 +575,21 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font, status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_head, 0, (unsigned char*) &header, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); - + if (be16_to_cpu (header.index_to_loc_format) == 0) size = sizeof (int16_t) * (font->num_glyphs_in_face + 1); else size = sizeof (int32_t) * (font->num_glyphs_in_face + 1); u.bytes = malloc (size); - if (u.bytes == NULL) + if (unlikely (u.bytes == NULL)) return _cairo_truetype_font_set_error (font, CAIRO_STATUS_NO_MEMORY); status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_loca, 0, u.bytes, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); start_offset = _cairo_array_num_elements (&font->output); @@ -612,33 +612,33 @@ cairo_truetype_font_write_glyf_table (cairo_truetype_font_t *font, size = end - begin; status = cairo_truetype_font_align_output (font, &next); - if (status) + if (unlikely (status)) goto FAIL; status = cairo_truetype_font_check_boundary (font, next); - if (status) + if (unlikely (status)) goto FAIL; font->glyphs[i].location = next - start_offset; status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (status) + if (unlikely (status)) goto FAIL; if (size != 0) { status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_glyf, begin, buffer, &size); - if (status) + if (unlikely (status)) goto FAIL; status = cairo_truetype_font_remap_composite_glyph (font, buffer, size); - if (status) + if (unlikely (status)) goto FAIL; } } status = cairo_truetype_font_align_output (font, &next); - if (status) + if (unlikely (status)) goto FAIL; font->glyphs[i].location = next - start_offset; @@ -664,17 +664,17 @@ cairo_truetype_font_write_head_table (cairo_truetype_font_t *font, size = 0; status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, tag, 0, NULL, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); font->checksum_index = _cairo_array_num_elements (&font->output) + 8; status = cairo_truetype_font_allocate_write_buffer (font, size, &buffer); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, tag, 0, buffer, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); /* set checkSumAdjustment to 0 for table checksum calcualtion */ @@ -695,12 +695,12 @@ cairo_truetype_font_write_hhea_table (cairo_truetype_font_t *font, unsigned long size = sizeof (tt_hhea_t); status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &hhea); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, tag, 0, (unsigned char *) hhea, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); hhea->num_hmetrics = cpu_to_be16 ((uint16_t)(font->base.num_glyphs)); @@ -728,7 +728,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_hhea, 0, (unsigned char*) &hhea, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); num_hmetrics = be16_to_cpu(hhea.num_hmetrics); @@ -739,7 +739,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, status = cairo_truetype_font_allocate_write_buffer (font, long_entry_size, (unsigned char **) &p); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); if (font->glyphs[i].parent_index < num_hmetrics) { @@ -747,7 +747,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, TT_TAG_hmtx, font->glyphs[i].parent_index * long_entry_size, (unsigned char *) p, &long_entry_size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); } else @@ -756,7 +756,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, TT_TAG_hmtx, (num_hmetrics - 1) * long_entry_size, (unsigned char *) p, &short_entry_size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, @@ -764,7 +764,7 @@ cairo_truetype_font_write_hmtx_table (cairo_truetype_font_t *font, num_hmetrics * long_entry_size + (font->glyphs[i].parent_index - num_hmetrics) * short_entry_size, (unsigned char *) (p + 1), &short_entry_size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); } font->base.widths[i] = be16_to_cpu (p[0]); @@ -789,7 +789,7 @@ cairo_truetype_font_write_loca_table (cairo_truetype_font_t *font, status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, TT_TAG_head, 0, (unsigned char*) &header, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); if (be16_to_cpu (header.index_to_loc_format) == 0) @@ -817,12 +817,12 @@ cairo_truetype_font_write_maxp_table (cairo_truetype_font_t *font, size = sizeof (tt_maxp_t); status = cairo_truetype_font_allocate_write_buffer (font, size, (unsigned char **) &maxp); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); status = font->backend->load_truetype_table (font->scaled_font_subset->scaled_font, tag, 0, (unsigned char *) maxp, &size); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); maxp->num_glyphs = cpu_to_be16 (font->base.num_glyphs); @@ -862,7 +862,7 @@ cairo_truetype_font_write_offset_table (cairo_truetype_font_t *font) table_buffer_length = font->num_tables * 16; status = cairo_truetype_font_allocate_write_buffer (font, table_buffer_length, &table_buffer); - if (status) + if (unlikely (status)) return _cairo_truetype_font_set_error (font, status); return CAIRO_STATUS_SUCCESS; @@ -920,28 +920,28 @@ cairo_truetype_font_generate (cairo_truetype_font_t *font, return font->status; status = cairo_truetype_font_write_offset_table (font); - if (status) + if (unlikely (status)) goto FAIL; status = cairo_truetype_font_align_output (font, &start); - if (status) + if (unlikely (status)) goto FAIL; end = 0; for (i = 0; i < font->num_tables; i++) { status = font->truetype_tables[i].write (font, font->truetype_tables[i].tag); - if (status) + if (unlikely (status)) goto FAIL; end = _cairo_array_num_elements (&font->output); status = cairo_truetype_font_align_output (font, &next); - if (status) + if (unlikely (status)) goto FAIL; cairo_truetype_font_update_entry (font, font->truetype_tables[i].pos, font->truetype_tables[i].tag, start, end); status = cairo_truetype_font_check_boundary (font, next); - if (status) + if (unlikely (status)) goto FAIL; start = next; @@ -1081,24 +1081,24 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, unsigned long num_strings = 0; status = _cairo_truetype_font_create (font_subset, &font); - if (status) + if (unlikely (status)) return status; for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { unsigned short parent_glyph = font->scaled_font_subset->glyphs[i]; status = cairo_truetype_font_use_glyph (font, parent_glyph, &parent_glyph); - if (status) + if (unlikely (status)) goto fail1; } cairo_truetype_font_create_truetype_table_list (font); status = cairo_truetype_font_generate (font, &data, &length, &string_offsets, &num_strings); - if (status) + if (unlikely (status)) goto fail1; truetype_subset->base_font = strdup (font->base.base_font); - if (truetype_subset->base_font == NULL) { + if (unlikely (truetype_subset->base_font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail1; } @@ -1108,7 +1108,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, * font_subset->num_glyphs are omitted. */ truetype_subset->widths = calloc (sizeof (double), font->scaled_font_subset->num_glyphs); - if (truetype_subset->widths == NULL) { + if (unlikely (truetype_subset->widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } @@ -1124,7 +1124,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, if (length) { truetype_subset->data = malloc (length); - if (truetype_subset->data == NULL) { + if (unlikely (truetype_subset->data == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } @@ -1137,7 +1137,7 @@ _cairo_truetype_subset_init (cairo_truetype_subset_t *truetype_subset, if (num_strings) { offsets_length = num_strings * sizeof (unsigned long); truetype_subset->string_offsets = malloc (offsets_length); - if (truetype_subset->string_offsets == NULL) { + if (unlikely (truetype_subset->string_offsets == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail4; } @@ -1199,7 +1199,7 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font, TT_TAG_cmap, table_offset, (unsigned char *) &buf, &size); - if (status) + if (unlikely (status)) return status; /* All table formats have the same first two words */ @@ -1209,14 +1209,14 @@ _cairo_truetype_reverse_cmap (cairo_scaled_font_t *scaled_font, size = be16_to_cpu (map->length); map = malloc (size); - if (map == NULL) + if (unlikely (map == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = backend->load_truetype_table (scaled_font, TT_TAG_cmap, table_offset, (unsigned char *) map, &size); - if (status) + if (unlikely (status)) goto fail; num_segments = be16_to_cpu (map->segCountX2)/2; @@ -1299,21 +1299,21 @@ _cairo_truetype_index_to_ucs4 (cairo_scaled_font_t *scaled_font, TT_TAG_cmap, 0, (unsigned char *) &buf, &size); - if (status) + if (unlikely (status)) return status; cmap = (tt_cmap_t *) buf; num_tables = be16_to_cpu (cmap->num_tables); size = 4 + num_tables*sizeof(tt_cmap_index_t); cmap = _cairo_malloc_ab_plus_c (num_tables, sizeof (tt_cmap_index_t), 4); - if (cmap == NULL) + if (unlikely (cmap == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = backend->load_truetype_table (scaled_font, TT_TAG_cmap, 0, (unsigned char *) cmap, &size); - if (status) + if (unlikely (status)) goto cleanup; /* Find a table with Unicode mapping */ diff --git a/src/cairo-type1-fallback.c b/src/cairo-type1-fallback.c index 1f39a3f0..91c00542 100644 --- a/src/cairo-type1-fallback.c +++ b/src/cairo-type1-fallback.c @@ -85,12 +85,11 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset, cairo_status_t status; font = calloc (1, sizeof (cairo_type1_font_t)); - if (font == NULL) + if (unlikely (font == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); - font->widths = calloc (scaled_font_subset->num_glyphs, - sizeof (int)); - if (font->widths == NULL) { + font->widths = calloc (scaled_font_subset->num_glyphs, sizeof (int)); + if (unlikely (font->widths == NULL)) { free (font); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -112,7 +111,7 @@ cairo_type1_font_create (cairo_scaled_font_subset_t *scaled_font_subset, &ctm, &font_options); status = font->type1_scaled_font->status; - if (status) + if (unlikely (status)) goto fail; _cairo_array_init (&font->contents, sizeof (unsigned char)); @@ -227,7 +226,7 @@ _charstring_move_to (void *closure, cairo_status_t status; status = _cairo_array_grow_by (path_info->data, 12); - if (status) + if (unlikely (status)) return status; dx = _cairo_fixed_integer_part (point->x) - path_info->current_x; @@ -251,7 +250,7 @@ _charstring_line_to (void *closure, cairo_status_t status; status = _cairo_array_grow_by (path_info->data, 12); - if (status) + if (unlikely (status)) return status; dx = _cairo_fixed_integer_part (point->x) - path_info->current_x; @@ -277,7 +276,7 @@ _charstring_curve_to (void *closure, cairo_status_t status; status = _cairo_array_grow_by (path_info->data, 32); - if (status) + if (unlikely (status)) return status; dx1 = _cairo_fixed_integer_part (point1->x) - path_info->current_x; @@ -309,7 +308,7 @@ _charstring_close_path (void *closure) return CAIRO_STATUS_SUCCESS; status = _cairo_array_grow_by (path_info->data, 2); - if (status) + if (unlikely (status)) return status; charstring_encode_command (path_info->data, CHARSTRING_closepath); @@ -363,7 +362,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font, CAIRO_SCALED_GLYPH_INFO_METRICS, &scaled_glyph); } - if (status) + if (unlikely (status)) return status; metrics = &scaled_glyph->metrics; @@ -385,7 +384,7 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font, font->widths[subset_index] = metrics->x_advance; status = _cairo_array_grow_by (data, 30); - if (status) + if (unlikely (status)) return status; if (type == CAIRO_CHARSTRING_TYPE1) { @@ -413,12 +412,12 @@ cairo_type1_font_create_charstring (cairo_type1_font_t *font, _charstring_curve_to, _charstring_close_path, &path_info); - if (status) + if (unlikely (status)) return status; } status = _cairo_array_grow_by (data, 1); - if (status) + if (unlikely (status)) return status; charstring_encode_command (path_info.data, CHARSTRING_endchar); @@ -437,7 +436,7 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, _cairo_array_init (&data, sizeof (unsigned char)); status = _cairo_array_grow_by (&data, 1024); - if (status) + if (unlikely (status)) goto fail; _cairo_output_stream_printf (encrypted_output, @@ -449,14 +448,14 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font, _cairo_array_truncate (&data, 0); /* four "random" bytes required by encryption algorithm */ status = _cairo_array_append_multiple (&data, zeros, 4); - if (status) + if (unlikely (status)) goto fail; status = cairo_type1_font_create_charstring (font, i, font->scaled_font_subset->glyphs[i], CAIRO_CHARSTRING_TYPE1, &data); - if (status) + if (unlikely (status)) goto fail; charstring_encrypt (&data); @@ -599,7 +598,7 @@ cairo_type1_font_write_private_dict (cairo_type1_font_t *font, "/password 5839 def\n"); status = cairo_type1_font_write_charstrings (font, encrypted_output); - if (status) + if (unlikely (status)) goto fail; _cairo_output_stream_printf (encrypted_output, @@ -651,7 +650,7 @@ cairo_type1_font_write (cairo_type1_font_t *font, font->header_size = _cairo_output_stream_get_position (font->output); status = cairo_type1_font_write_private_dict (font, name); - if (status) + if (unlikely (status)) return status; font->data_size = _cairo_output_stream_get_position (font->output) - @@ -671,7 +670,7 @@ cairo_type1_font_generate (cairo_type1_font_t *font, const char *name) cairo_int_status_t status; status = _cairo_array_grow_by (&font->contents, 4096); - if (status) + if (unlikely (status)) return status; font->output = _cairo_output_stream_create (cairo_type1_write_stream, NULL, font); @@ -679,7 +678,7 @@ cairo_type1_font_generate (cairo_type1_font_t *font, const char *name) return _cairo_output_stream_destroy (font->output); status = cairo_type1_font_write (font, name); - if (status) + if (unlikely (status)) return status; font->data = _cairo_array_index (&font->contents, 0); @@ -714,21 +713,21 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset, unsigned int i, len; status = cairo_type1_font_create (scaled_font_subset, &font, hex_encode); - if (status) + if (unlikely (status)) return status; status = cairo_type1_font_generate (font, name); - if (status) + if (unlikely (status)) goto fail1; type1_subset->base_font = strdup (name); - if (type1_subset->base_font == NULL) { + if (unlikely (type1_subset->base_font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail1; } type1_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs); - if (type1_subset->widths == NULL) { + if (unlikely (type1_subset->widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } @@ -745,7 +744,7 @@ _cairo_type1_fallback_init_internal (cairo_type1_subset_t *type1_subset, length = font->header_size + font->data_size + font->trailer_size; type1_subset->data = malloc (length); - if (type1_subset->data == NULL) { + if (unlikely (type1_subset->data == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } @@ -816,13 +815,13 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset, cairo_array_t charstring; status = cairo_type1_font_create (scaled_font_subset, &font, FALSE); - if (status) + if (unlikely (status)) return status; _cairo_array_init (&type2_subset->charstrings, sizeof (cairo_array_t)); type2_subset->widths = calloc (sizeof (int), font->scaled_font_subset->num_glyphs); - if (type2_subset->widths == NULL) { + if (unlikely (type2_subset->widths == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail1; } @@ -831,18 +830,18 @@ _cairo_type2_charstrings_init (cairo_type2_charstrings_t *type2_subset, for (i = 0; i < font->scaled_font_subset->num_glyphs; i++) { _cairo_array_init (&charstring, sizeof (unsigned char)); status = _cairo_array_grow_by (&charstring, 32); - if (status) + if (unlikely (status)) goto fail2; status = cairo_type1_font_create_charstring (font, i, font->scaled_font_subset->glyphs[i], CAIRO_CHARSTRING_TYPE2, &charstring); - if (status) + if (unlikely (status)) goto fail2; status = _cairo_array_append (&type2_subset->charstrings, &charstring); - if (status) + if (unlikely (status)) goto fail2; } _cairo_scaled_font_thaw_cache (font->type1_scaled_font); diff --git a/src/cairo-type1-subset.c b/src/cairo-type1-subset.c index e5557585..fe74dc6c 100644 --- a/src/cairo-type1-subset.c +++ b/src/cairo-type1-subset.c @@ -126,7 +126,7 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font, ft_unscaled_font = (cairo_ft_unscaled_font_t *) unscaled_font; face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font); - if (face == NULL) + if (unlikely (face == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); if (FT_Get_PS_Font_Info(face, &font_info) != 0) { @@ -154,7 +154,7 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font, if (face->family_name) { font->base.base_font = strdup (face->family_name); - if (font->base.base_font == NULL) { + if (unlikely (font->base.base_font == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail2; } @@ -167,7 +167,7 @@ _cairo_type1_font_subset_init (cairo_type1_font_subset_t *font, } font->glyphs = calloc (face->num_glyphs, sizeof font->glyphs[0]); - if (font->glyphs == NULL) { + if (unlikely (font->glyphs == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail3; } @@ -467,7 +467,7 @@ cairo_type1_font_subset_decrypt_eexec_segment (cairo_type1_font_subset_t *font) end = (unsigned char *) in + font->eexec_segment_size; font->cleartext = malloc (font->eexec_segment_size); - if (font->cleartext == NULL) + if (unlikely (font->cleartext == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); out = font->cleartext; @@ -573,7 +573,7 @@ cairo_type1_font_subset_get_glyph_names_and_widths (cairo_type1_font_subset_t *f } font->glyphs[i].name = strdup (buffer); - if (font->glyphs[i].name == NULL) + if (unlikely (font->glyphs[i].name == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -838,7 +838,7 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font, int command; charstring = malloc (encrypted_charstring_length); - if (charstring == NULL) + if (unlikely (charstring == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); cairo_type1_font_subset_decrypt_charstring ((const unsigned char *) @@ -866,11 +866,11 @@ cairo_type1_font_subset_look_for_seac(cairo_type1_font_subset_t *font, * make sure those glyphs are present in the subset * under their standard names. */ status = use_standard_encoding_glyph (font, stack[3]); - if (status) + if (unlikely (status)) return status; status = use_standard_encoding_glyph (font, stack[4]); - if (status) + if (unlikely (status)) return status; sp = 0; @@ -906,18 +906,18 @@ write_used_glyphs (cairo_type1_font_subset_t *font, "/%.*s %d %s ", name_length, name, charstring_length, font->rd); status = cairo_type1_font_subset_write_encrypted (font, buffer, length); - if (status) + if (unlikely (status)) return status; status = cairo_type1_font_subset_write_encrypted (font, charstring, charstring_length); - if (status) + if (unlikely (status)) return status; length = snprintf (buffer, sizeof buffer, "%s\n", font->nd); status = cairo_type1_font_subset_write_encrypted (font, buffer, length); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -983,7 +983,7 @@ cairo_type1_font_subset_for_each_glyph (cairo_type1_font_subset_t *font, cairo_status_t status = func (font, name, name_length, charstring, charstring_length); - if (status) + if (unlikely (status)) return status; } } @@ -1040,7 +1040,7 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font, dict_start = p; status = cairo_type1_font_subset_get_glyph_names_and_widths (font); - if (status) + if (unlikely (status)) return status; /* Now that we have the private dictionary broken down in @@ -1052,7 +1052,7 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font, font->cleartext_end, cairo_type1_font_subset_look_for_seac, &p); - if (status) + if (unlikely (status)) return status; closefile_token = find_token (p, font->cleartext_end, "closefile"); @@ -1060,13 +1060,13 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font, return CAIRO_INT_STATUS_UNSUPPORTED; status = cairo_type1_font_subset_get_glyph_names_and_widths (font); - if (status) + if (unlikely (status)) return status; /* We're ready to start outputting. First write the header, * i.e. the public part of the font dict.*/ status = cairo_type1_font_subset_write_header (font, name); - if (status) + if (unlikely (status)) return status; font->base.header_size = _cairo_output_stream_get_position (font->output); @@ -1076,21 +1076,21 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font, * to the /CharStrings token. */ status = cairo_type1_font_subset_write_encrypted (font, font->cleartext, charstrings - font->cleartext); - if (status) + if (unlikely (status)) return status; /* Write out new charstring count */ length = snprintf (buffer, sizeof buffer, "/CharStrings %d", font->num_glyphs); status = cairo_type1_font_subset_write_encrypted (font, buffer, length); - if (status) + if (unlikely (status)) return status; /* Write out text between the charstring count and the first * charstring definition */ status = cairo_type1_font_subset_write_encrypted (font, glyph_count_end, dict_start - glyph_count_end); - if (status) + if (unlikely (status)) return status; /* Write out the charstring definitions for each of the glyphs in @@ -1100,14 +1100,14 @@ cairo_type1_font_subset_write_private_dict (cairo_type1_font_subset_t *font, font->cleartext_end, write_used_glyphs, &p); - if (status) + if (unlikely (status)) return status; /* Output what's left between the end of the glyph definitions and * the end of the private dict to the output. */ status = cairo_type1_font_subset_write_encrypted (font, p, closefile_token - p + strlen ("closefile") + 1); - if (status) + if (unlikely (status)) return status; _cairo_output_stream_write (font->output, "\n", 1); @@ -1158,11 +1158,11 @@ cairo_type1_font_subset_write (cairo_type1_font_subset_t *font, cairo_status_t status; status = cairo_type1_font_subset_find_segments (font); - if (status) + if (unlikely (status)) return status; status = cairo_type1_font_subset_decrypt_eexec_segment (font); - if (status) + if (unlikely (status)) return status; /* Determine which glyph definition delimiters to use. */ @@ -1181,14 +1181,14 @@ cairo_type1_font_subset_write (cairo_type1_font_subset_t *font, font->hex_column = 0; status = cairo_type1_font_subset_write_private_dict (font, name); - if (status) + if (unlikely (status)) return status; font->base.data_size = _cairo_output_stream_get_position (font->output) - font->base.header_size; status = cairo_type1_font_subset_write_trailer (font); - if (status) + if (unlikely (status)) return status; font->base.trailer_size = @@ -1210,12 +1210,12 @@ cairo_type1_font_subset_generate (void *abstract_font, ft_unscaled_font = (cairo_ft_unscaled_font_t *) font->base.unscaled_font; font->face = _cairo_ft_unscaled_font_lock_face (ft_unscaled_font); - if (font->face == NULL) + if (unlikely (font->face == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font->type1_length = font->face->stream->size; font->type1_data = malloc (font->type1_length); - if (font->type1_data == NULL) { + if (unlikely (font->type1_data == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto fail; } @@ -1239,7 +1239,7 @@ cairo_type1_font_subset_generate (void *abstract_font, } status = _cairo_array_grow_by (&font->contents, 4096); - if (status) + if (unlikely (status)) goto fail; font->output = _cairo_output_stream_create (type1_font_write, NULL, font); @@ -1249,7 +1249,7 @@ cairo_type1_font_subset_generate (void *abstract_font, } status = cairo_type1_font_subset_write (font, name); - if (status) + if (unlikely (status)) goto fail; font->base.data = _cairo_array_index (&font->contents, 0); @@ -1306,7 +1306,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset, unscaled_font = _cairo_ft_scaled_font_get_unscaled_font (scaled_font_subset->scaled_font); status = _cairo_type1_font_subset_init (&font, unscaled_font, hex_encode); - if (status) + if (unlikely (status)) return status; for (i = 0; i < scaled_font_subset->num_glyphs; i++) { @@ -1315,7 +1315,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset, } status = cairo_type1_font_subset_generate (&font, name); - if (status) + if (unlikely (status)) goto fail1; if (font.base.base_font) { @@ -1325,11 +1325,11 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset, scaled_font_subset->font_id, scaled_font_subset->subset_id); type1_subset->base_font = strdup (buf); } - if (type1_subset->base_font == NULL) + if (unlikely (type1_subset->base_font == NULL)) goto fail1; type1_subset->widths = calloc (sizeof (int), font.num_glyphs); - if (type1_subset->widths == NULL) + if (unlikely (type1_subset->widths == NULL)) goto fail2; for (i = 0; i < font.base.num_glyphs; i++) { if (font.glyphs[i].subset_index < 0) @@ -1349,7 +1349,7 @@ _cairo_type1_subset_init (cairo_type1_subset_t *type1_subset, font.base.data_size + font.base.trailer_size; type1_subset->data = malloc (length); - if (type1_subset->data == NULL) + if (unlikely (type1_subset->data == NULL)) goto fail3; memcpy (type1_subset->data, diff --git a/src/cairo-type3-glyph-surface.c b/src/cairo-type3-glyph-surface.c index 6f9eb43e..b3a48313 100644 --- a/src/cairo-type3-glyph-surface.c +++ b/src/cairo-type3-glyph-surface.c @@ -55,7 +55,7 @@ _cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font, cairo_matrix_t invert_y_axis; surface = malloc (sizeof (cairo_type3_glyph_surface_t)); - if (surface == NULL) + if (unlikely (surface == NULL)) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); _cairo_surface_init (&surface->base, &cairo_type3_glyph_surface_backend, @@ -96,7 +96,7 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface, } else { image_mask = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1); status = cairo_surface_status (&image->base); - if (status) + if (unlikely (status)) return status; } @@ -196,7 +196,7 @@ _cairo_type3_glyph_surface_paint (void *abstract_surface, pattern = (const cairo_surface_pattern_t *) source; status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra); - if (status) + if (unlikely (status)) goto fail; status = _cairo_type3_glyph_surface_emit_image_pattern (surface, @@ -282,7 +282,7 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface, /* We require the matrix to be invertable. */ ctm_inverse = scaled_font->ctm; status = cairo_matrix_invert (&ctm_inverse); - if (status) + if (unlikely (status)) return CAIRO_INT_STATUS_IMAGE_FALLBACK; cairo_matrix_multiply (&new_ctm, &scaled_font->ctm, &ctm_inverse); @@ -315,6 +315,8 @@ static const cairo_surface_backend_t cairo_type3_glyph_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* cairo_type3_glyph_surface_copy_page */ NULL, /* _cairo_type3_glyph_surface_show_page */ NULL, /* set_clip_region */ @@ -357,7 +359,7 @@ _cairo_type3_glyph_surface_emit_fallback_image (cairo_type3_glyph_surface_t *sur CAIRO_SCALED_GLYPH_INFO_METRICS | CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); - if (status) + if (unlikely (status)) return status; image = scaled_glyph->surface; @@ -419,7 +421,7 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface, status = _cairo_meta_surface_replay (scaled_glyph->meta_surface, &surface->base); - if (status) + if (unlikely (status)) goto cleanup; status2 = _cairo_pdf_operators_flush (&surface->pdf_operators); diff --git a/src/cairo-types-private.h b/src/cairo-types-private.h index 6f1354d6..d8d5a2c0 100644 --- a/src/cairo-types-private.h +++ b/src/cairo-types-private.h @@ -252,6 +252,30 @@ typedef struct _cairo_box_int { 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 + * source pattern, mask, clip and destination surface take part in a + * general composite operation. The idea is that the pixels at + * + * (i,j)+(src.x, src.y) of the source, + * (i,j)+(mask.x, mask.y) of the mask, + * (i,j)+(clip.x, clip.y) of the clip and + * (i,j)+(dst.x, dst.y) of the destination + * + * all combine together to form the result at (i,j)+(dst.x,dst.y), + * for i,j ranging in [0,width) and [0,height) respectively. + */ +typedef struct _cairo_composite_rectangles { + cairo_point_int_t src; + cairo_point_int_t mask; + cairo_point_int_t clip; + cairo_point_int_t dst; + int width; + int height; +} cairo_composite_rectangles_t; + typedef enum _cairo_direction { CAIRO_DIRECTION_FORWARD, CAIRO_DIRECTION_REVERSE diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c index c272966a..6670b536 100644 --- a/src/cairo-user-font.c +++ b/src/cairo-user-font.c @@ -127,7 +127,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font, cairo_destroy (cr); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (meta_surface); return status; } @@ -152,7 +152,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font, analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1); cairo_surface_destroy (null_surface); status = analysis_surface->status; - if (status) + if (unlikely (status)) return status; _cairo_analysis_surface_set_ctm (analysis_surface, @@ -162,7 +162,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font, _cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox); cairo_surface_destroy (analysis_surface); - if (status) + if (unlikely (status)) return status; _cairo_box_to_doubles (&bbox, &x1, &y1, &x2, &y2); @@ -215,7 +215,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font, - _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y)); status = _cairo_meta_surface_replay (meta_surface, surface); - if (status) { + if (unlikely (status)) { cairo_surface_destroy(surface); return status; } @@ -232,7 +232,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font, status = _cairo_meta_surface_get_path (meta_surface, path); - if (status) { + if (unlikely (status)) { _cairo_path_fixed_destroy (path); return status; } @@ -355,7 +355,7 @@ _cairo_user_scaled_font_get_implementation (cairo_toy_font_face_t *toy_face, face, (cairo_destroy_func_t) cairo_font_face_destroy); - if (status) { + if (unlikely (status)) { cairo_font_face_destroy (face); return status; } @@ -376,7 +376,7 @@ _cairo_user_scaled_font_create_toy (cairo_toy_font_face_t *toy_face, cairo_status_t status; status = _cairo_user_scaled_font_get_implementation (toy_face, &face); - if (status) + if (unlikely (status)) return status; status = _cairo_user_font_face_scaled_font_create (face, @@ -384,7 +384,7 @@ _cairo_user_scaled_font_create_toy (cairo_toy_font_face_t *toy_face, ctm, font_options, font); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -420,7 +420,7 @@ _cairo_user_font_face_scaled_font_create (void *abstract_ font_face->immutable = TRUE; user_scaled_font = malloc (sizeof (cairo_user_scaled_font_t)); - if (user_scaled_font == NULL) + if (unlikely (user_scaled_font == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); status = _cairo_scaled_font_init (&user_scaled_font->base, @@ -428,7 +428,7 @@ _cairo_user_font_face_scaled_font_create (void *abstract_ font_matrix, ctm, options, &_cairo_user_scaled_font_backend); - if (status) { + if (unlikely (status)) { free (user_scaled_font); return status; } diff --git a/src/cairo-win32-printing-surface.c b/src/cairo-win32-printing-surface.c index 41330198..94927aeb 100644 --- a/src/cairo-win32-printing-surface.c +++ b/src/cairo-win32-printing-surface.c @@ -1752,6 +1752,8 @@ static const cairo_surface_backend_t cairo_win32_printing_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ _cairo_win32_printing_surface_show_page, NULL, /* set_clip_region */ diff --git a/src/cairo-win32-surface.c b/src/cairo-win32-surface.c index 863f9d52..03a8f61a 100644 --- a/src/cairo-win32-surface.c +++ b/src/cairo-win32-surface.c @@ -872,6 +872,9 @@ _cairo_win32_surface_composite_inner (cairo_win32_surface_t *src, return CAIRO_STATUS_SUCCESS; } +/* from pixman-private.h */ +#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b)) + static cairo_int_status_t _cairo_win32_surface_composite (cairo_operator_t op, const cairo_pattern_t *pattern, @@ -1153,8 +1156,8 @@ _cairo_win32_surface_composite (cairo_operator_t op, uint32_t rendered_width = 0, rendered_height = 0; uint32_t to_render_height, to_render_width; int32_t piece_x, piece_y; - int32_t src_start_x = src_r.x % src_extents.width; - int32_t src_start_y = src_r.y % src_extents.height; + int32_t src_start_x = MOD(src_r.x, src_extents.width); + int32_t src_start_y = MOD(src_r.y, src_extents.height); if (needs_scale) goto UNSUPPORTED; @@ -1979,6 +1982,8 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = { _cairo_win32_surface_composite, _cairo_win32_surface_fill_rectangles, NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ _cairo_win32_surface_set_clip_region, diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c index 999f7d54..6f246f80 100644 --- a/src/cairo-xcb-surface.c +++ b/src/cairo-xcb-surface.c @@ -1684,6 +1684,8 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = { _cairo_xcb_surface_composite, _cairo_xcb_surface_fill_rectangles, _cairo_xcb_surface_composite_trapezoids, + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ _cairo_xcb_surface_set_clip_region, diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c index 2823e5dc..e85174b7 100644 --- a/src/cairo-xlib-display.c +++ b/src/cairo-xlib-display.c @@ -248,7 +248,7 @@ _cairo_xlib_display_get (Display *dpy, } display = malloc (sizeof (cairo_xlib_display_t)); - if (display == NULL) { + if (unlikely (display == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto UNLOCK; } @@ -262,7 +262,7 @@ _cairo_xlib_display_get (Display *dpy, XRenderQueryVersion (dpy, &render_major, &render_minor); codes = XAddExtension (dpy); - if (codes == NULL) { + if (unlikely (codes == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); free (display); display = NULL; diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c index 9dd411ed..3b1ae2e1 100644 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@ -352,7 +352,7 @@ _cairo_xlib_screen_info_get (cairo_xlib_display_t *display, info = _cairo_xlib_screen_info_reference (info); } else { info = malloc (sizeof (cairo_xlib_screen_info_t)); - if (info == NULL) + if (unlikely (info == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); CAIRO_REFERENCE_COUNT_INIT (&info->ref_count, 2); /* Add one for display cache */ @@ -485,7 +485,7 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info, XScreenNumberOfScreen (info->screen), visual->visualid, &ret); - if (status) + if (unlikely (status)) return status; CAIRO_MUTEX_LOCK (info->mutex); @@ -506,7 +506,7 @@ _cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info, status = _cairo_array_append (&info->visuals, &ret); CAIRO_MUTEX_UNLOCK (info->mutex); - if (status) { + if (unlikely (status)) { _cairo_xlib_visual_info_destroy (dpy, ret); return status; } diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c index 136e5546..68d81922 100644 --- a/src/cairo-xlib-surface.c +++ b/src/cairo-xlib-surface.c @@ -147,9 +147,8 @@ _cairo_xlib_surface_create_similar_with_format (void *abstract_src, if (! CAIRO_SURFACE_RENDER_HAS_COMPOSITE (src)) return NULL; - xrender_format = _cairo_xlib_display_get_xrender_format ( - src->display, - format); + xrender_format = _cairo_xlib_display_get_xrender_format (src->display, + format); if (xrender_format == NULL) return NULL; @@ -672,7 +671,7 @@ _get_image_surface (cairo_xlib_surface_t *surface, Pixmap pixmap; status = _cairo_xlib_surface_ensure_gc (surface); - if (status) + if (unlikely (status)) return status; pixmap = XCreatePixmap (surface->dpy, @@ -717,7 +716,7 @@ _get_image_surface (cairo_xlib_surface_t *surface, ximage->height, ximage->bytes_per_line); status = image->base.status; - if (status) + if (unlikely (status)) goto BAIL; /* Let the surface take ownership of the data */ @@ -778,14 +777,14 @@ _get_image_surface (cairo_xlib_surface_t *surface, status = _cairo_xlib_screen_get_visual_info (surface->screen_info, surface->visual, &visual_info); - if (status) + if (unlikely (status)) goto BAIL; } image = (cairo_image_surface_t *) cairo_image_surface_create (format, ximage->width, ximage->height); status = image->base.status; - if (status) + if (unlikely (status)) goto BAIL; data = cairo_image_surface_get_data (&image->base); @@ -822,7 +821,7 @@ _get_image_surface (cairo_xlib_surface_t *surface, BAIL: XDestroyImage (ximage); - if (status) { + if (unlikely (status)) { if (image) { cairo_surface_destroy (&image->base); image = NULL; @@ -910,7 +909,7 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface) gcv.graphics_exposures = False; surface->gc = XCreateGC (surface->dpy, surface->drawable, GCGraphicsExposures, &gcv); - if (!surface->gc) + if (unlikely (surface->gc == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } } @@ -990,7 +989,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface, ximage.bits_per_pixel); ximage.bytes_per_line = stride; ximage.data = _cairo_malloc_ab (stride, ximage.height); - if (ximage.data == NULL) + if (unlikely (ximage.data == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); own_data = TRUE; @@ -1014,7 +1013,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface, status = _cairo_xlib_screen_get_visual_info (surface->screen_info, surface->visual, &visual_info); - if (status) + if (unlikely (status)) goto BAIL; } @@ -1071,7 +1070,7 @@ _draw_image_surface (cairo_xlib_surface_t *surface, } status = _cairo_xlib_surface_ensure_gc (surface); - if (status) + if (unlikely (status)) goto BAIL; XPutImage(surface->dpy, surface->drawable, surface->gc, @@ -1097,7 +1096,7 @@ _cairo_xlib_surface_acquire_source_image (void *abstract_surf _cairo_xlib_display_notify (surface->display); status = _get_image_surface (surface, NULL, &image, NULL); - if (status) + if (unlikely (status)) return status; *image_out = image; @@ -1128,7 +1127,7 @@ _cairo_xlib_surface_acquire_dest_image (void *abstract_surfac _cairo_xlib_display_notify (surface->display); status = _get_image_surface (surface, interest_rect, &image, image_rect_out); - if (status) + if (unlikely (status)) return status; *image_out = image; @@ -1217,7 +1216,7 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface, src_x, src_y, width, height, 0, 0); - if (status) { + if (unlikely (status)) { cairo_surface_destroy (&clone->base); return status; } @@ -1264,7 +1263,7 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac _cairo_image_surface_create_with_content (solid_pattern->content, width, height); status = image->base.status; - if (status) + if (unlikely (status)) goto BAIL; pixmap = XCreatePixmap (other->dpy, @@ -1280,26 +1279,26 @@ _cairo_xlib_surface_create_solid_pattern_surface (void *abstrac width, height, other->depth); status = surface->base.status; - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_surface_paint (&image->base, CAIRO_OPERATOR_SOURCE, &solid_pattern->base, NULL); - if (status) + if (unlikely (status)) goto BAIL; status = _draw_image_surface (surface, image, 0, 0, width, height, 0, 0); - if (status) + if (unlikely (status)) goto BAIL; BAIL: cairo_surface_destroy (&image->base); - if (status) { + if (unlikely (status)) { if (pixmap != None) XFreePixmap (other->dpy, pixmap); cairo_surface_destroy (&surface->base); @@ -1426,7 +1425,7 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface, status = _cairo_xlib_surface_set_matrix (surface, &attributes->matrix, xc, yc); - if (status) + if (unlikely (status)) return status; switch (attributes->extend) { @@ -1443,7 +1442,7 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface, } status = _cairo_xlib_surface_set_filter (surface, attributes->filter); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -1728,7 +1727,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op, (cairo_surface_t **) &src, (cairo_surface_t **) &mask, &src_attr, &mask_attr); - if (status) + if (unlikely (status)) return status; /* check for fallback surfaces that we cannot handle ... */ @@ -1757,7 +1756,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op, status = _cairo_xlib_surface_set_attributes (src, &src_attr, dst_x + width / 2., dst_y + height / 2.); - if (status) + if (unlikely (status)) goto BAIL; _cairo_xlib_surface_ensure_dst_picture (dst); @@ -1765,7 +1764,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op, status = _cairo_xlib_surface_set_attributes (mask, &mask_attr, dst_x + width / 2., dst_y + height/ 2.); - if (status) + if (unlikely (status)) goto BAIL; XRenderComposite (dst->dpy, @@ -1796,7 +1795,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op, case DO_XCOPYAREA: status = _cairo_xlib_surface_ensure_gc (dst); - if (status) + if (unlikely (status)) goto BAIL; is_integer_translation = _cairo_matrix_is_integer_translation (&src_attr.matrix, @@ -1824,7 +1823,7 @@ _cairo_xlib_surface_composite (cairo_operator_t op, */ status = _cairo_xlib_surface_ensure_gc (dst); - if (status) + if (unlikely (status)) goto BAIL; is_integer_translation = _cairo_matrix_is_integer_translation (&src_attr.matrix, &itx, &ity); @@ -1879,7 +1878,7 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface, _cairo_pattern_init_solid (&solid, color, CAIRO_CONTENT_COLOR); status = _cairo_xlib_surface_ensure_gc (surface); - if (status) + if (unlikely (status)) return status; status = _cairo_pattern_acquire_surface (&solid.base, &surface->base, @@ -1888,7 +1887,7 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface, ARRAY_LENGTH (dither_pattern), &solid_surface, &attrs); - if (status) + if (unlikely (status)) return status; if (! _cairo_surface_is_xlib (solid_surface)) { @@ -1964,7 +1963,7 @@ _cairo_xlib_surface_fill_rectangles (void *abstract_surface, if (num_rects > ARRAY_LENGTH (static_xrects)) { xrects = _cairo_malloc_ab (num_rects, sizeof (XRectangle)); - if (xrects == NULL) + if (unlikely (xrects == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -2136,7 +2135,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, src_x, src_y, width, height, (cairo_surface_t **) &src, &attributes); - if (status) + if (unlikely (status)) return status; operation = _recategorize_composite_operation (dst, op, src, @@ -2177,7 +2176,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, status = _cairo_xlib_surface_set_attributes (src, &attributes, dst_x + width / 2., dst_y + height / 2.); - if (status) + if (unlikely (status)) goto BAIL; if (!_cairo_operator_bounded_by_mask (op)) { @@ -2225,7 +2224,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op, if (num_traps > ARRAY_LENGTH (xtraps_stack)) { xtraps = _cairo_malloc_ab (num_traps, sizeof (XTrapezoid)); - if (xtraps == NULL) { + if (unlikely (xtraps == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto BAIL; } @@ -2300,7 +2299,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, _cairo_region_init_rect (&bound, &rect); _cairo_region_init (&bounded); status = _cairo_region_intersect (&bounded, &bound, region); - if (status) { + if (unlikely (status)) { _cairo_region_fini (&bound); _cairo_region_fini (&bounded); return status; @@ -2309,7 +2308,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, 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 (status) { + if (unlikely (status)) { _cairo_region_fini (&bound); _cairo_region_fini (&bounded); return status; @@ -2317,7 +2316,7 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface, if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) { rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle)); - if (rects == NULL) { + if (unlikely (rects == NULL)) { _cairo_region_boxes_fini (&bounded, boxes); _cairo_region_fini (&bound); _cairo_region_fini (&bounded); @@ -2429,7 +2428,7 @@ _cairo_xlib_surface_reset (void *abstract_surface) cairo_status_t status; status = _cairo_xlib_surface_set_clip_region (surface, NULL); - if (status) + if (unlikely (status)) return status; return CAIRO_STATUS_SUCCESS; @@ -2447,6 +2446,8 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = { _cairo_xlib_surface_composite, _cairo_xlib_surface_fill_rectangles, _cairo_xlib_surface_composite_trapezoids, + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ _cairo_xlib_surface_set_clip_region, @@ -2564,17 +2565,17 @@ _cairo_xlib_surface_create_internal (Display *dpy, return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL)); status = _cairo_xlib_display_get (dpy, &display); - if (status) + if (unlikely (status)) return _cairo_surface_create_in_error (status); status = _cairo_xlib_screen_info_get (display, screen, &screen_info); - if (status) { + if (unlikely (status)) { _cairo_xlib_display_destroy (display); return _cairo_surface_create_in_error (status); } surface = malloc (sizeof (cairo_xlib_surface_t)); - if (surface == NULL) { + if (unlikely (surface == NULL)) { _cairo_xlib_screen_info_destroy (screen_info); _cairo_xlib_display_destroy (display); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); @@ -2903,7 +2904,7 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface, surface->display, XRenderFreePicture, surface->dst_picture); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (&surface->base, status); return; } @@ -2916,7 +2917,7 @@ cairo_xlib_surface_set_drawable (cairo_surface_t *abstract_surface, surface->display, XRenderFreePicture, surface->src_picture); - if (status) { + if (unlikely (status)) { status = _cairo_surface_set_error (&surface->base, status); return; } @@ -3168,12 +3169,12 @@ _cairo_xlib_surface_font_init (Display *dpy, int i; font_private = malloc (sizeof (cairo_xlib_surface_font_private_t)); - if (font_private == NULL) + if (unlikely (font_private == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); font_private->scaled_font = scaled_font; status = _cairo_xlib_display_get (dpy, &font_private->display); - if (status) { + if (unlikely (status)) { free (font_private); return status; } @@ -3289,7 +3290,7 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph, to_free, free); /* XXX cannot propagate failure */ - if (status) + if (unlikely (status)) free (to_free); to_free = glyphset_info->pending_free_glyphs = NULL; @@ -3297,7 +3298,7 @@ _cairo_xlib_surface_scaled_glyph_fini (cairo_scaled_glyph_t *scaled_glyph, if (to_free == NULL) { to_free = malloc (sizeof (cairo_xlib_font_glyphset_free_glyphs_t)); - if (to_free == NULL) { + if (unlikely (to_free == NULL)) { _cairo_error_throw (CAIRO_STATUS_NO_MEMORY); return; /* XXX cannot propagate failure */ } @@ -3445,7 +3446,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy, CAIRO_SCALED_GLYPH_INFO_METRICS | CAIRO_SCALED_GLYPH_INFO_SURFACE, pscaled_glyph); - if (status) + if (unlikely (status)) return status; scaled_glyph = *pscaled_glyph; @@ -3457,7 +3458,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy, if (scaled_font->surface_private == NULL) { status = _cairo_xlib_surface_font_init (dpy, scaled_font); - if (status) + if (unlikely (status)) return status; } @@ -3484,7 +3485,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy, tmp_surface = cairo_image_surface_create (glyphset_info->format, 1, 1); status = tmp_surface->status; - if (status) + if (unlikely (status)) goto BAIL; cr = cairo_create (tmp_surface); @@ -3498,7 +3499,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy, glyph_surface = (cairo_image_surface_t *) tmp_surface; - if (status) + if (unlikely (status)) goto BAIL; } @@ -3514,7 +3515,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy, glyph_surface->width, glyph_surface->height); status = tmp_surface->status; - if (status) + if (unlikely (status)) goto BAIL; tmp_surface->device_transform = glyph_surface->base.device_transform; @@ -3529,7 +3530,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy, glyph_surface = (cairo_image_surface_t *) tmp_surface; - if (status) + if (unlikely (status)) goto BAIL; } @@ -3579,7 +3580,7 @@ _cairo_xlib_surface_add_glyph (Display *dpy, unsigned char *new, *n; new = malloc (c); - if (new == NULL) { + if (unlikely (new == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto BAIL; } @@ -3723,7 +3724,7 @@ _emit_glyphs_chunk (cairo_xlib_surface_t *dst, elts = stack_elts; } else { elts = _cairo_malloc_ab (num_elts, sizeof (XGlyphElt8)); - if (elts == NULL) + if (unlikely (elts == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); } @@ -3864,7 +3865,7 @@ _cairo_xlib_surface_emit_glyphs (cairo_xlib_surface_t *dst, status = _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, &scaled_glyph); - if (status) { + if (unlikely (status)) { if (status == CAIRO_INT_STATUS_UNSUPPORTED) /* Break so we flush glyphs so far and let fallback code * handle the rest */ @@ -4055,7 +4056,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, 0, 0, 1, 1, (cairo_surface_t **) &src, &attributes); - if (status) + if (unlikely (status)) goto BAIL0; } else { cairo_rectangle_int_t glyph_extents; @@ -4064,7 +4065,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, glyphs, num_glyphs, &glyph_extents); - if (status) + if (unlikely (status)) goto BAIL0; status = _cairo_pattern_acquire_surface (src_pattern, &dst->base, @@ -4072,7 +4073,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, glyph_extents.width, glyph_extents.height, (cairo_surface_t **) &src, &attributes); - if (status) + if (unlikely (status)) goto BAIL0; } @@ -4084,7 +4085,7 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst, } status = _cairo_xlib_surface_set_attributes (src, &attributes, 0, 0); - if (status) + if (unlikely (status)) goto BAIL1; _cairo_scaled_font_freeze_cache (scaled_font); diff --git a/src/cairo-xlib-visual.c b/src/cairo-xlib-visual.c index f6eb1ee9..7dbe86c2 100644 --- a/src/cairo-xlib-visual.c +++ b/src/cairo-xlib-visual.c @@ -78,7 +78,7 @@ _cairo_xlib_visual_info_create (Display *dpy, ramp_index_to_short[i] = (0xffff * i + ((RAMP_SIZE-1)>>1)) / (RAMP_SIZE-1); info = malloc (sizeof (cairo_xlib_visual_info_t)); - if (info == NULL) + if (unlikely (info == NULL)) return _cairo_error (CAIRO_STATUS_NO_MEMORY); info->visualid = visualid; diff --git a/src/cairo.c b/src/cairo.c index 1fbf62dd..60988782 100644 --- a/src/cairo.c +++ b/src/cairo.c @@ -152,7 +152,7 @@ cairo_create (cairo_surface_t *target) return (cairo_t *) &_cairo_nil; cr = malloc (sizeof (cairo_t)); - if (cr == NULL) { + if (unlikely (cr == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_t *) &_cairo_nil; } @@ -168,7 +168,7 @@ cairo_create (cairo_surface_t *target) cr->gstate_freelist = NULL; status = _cairo_gstate_init (cr->gstate, target); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); return cr; @@ -349,7 +349,7 @@ cairo_save (cairo_t *cr) return; status = _cairo_gstate_save (&cr->gstate, &cr->gstate_freelist); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_save); @@ -371,7 +371,7 @@ cairo_restore (cairo_t *cr) return; status = _cairo_gstate_restore (&cr->gstate, &cr->gstate_freelist); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_restore); @@ -458,10 +458,10 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content) parent_surface = _cairo_gstate_get_target (cr->gstate); /* Get the extents that we'll use in creating our new group surface */ status = _cairo_surface_get_extents (parent_surface, &extents); - if (status) + if (unlikely (status)) goto bail; status = _cairo_clip_intersect_to_rectangle (_cairo_gstate_get_clip (cr->gstate), &extents); - if (status) + if (unlikely (status)) goto bail; group_surface = cairo_surface_create_similar (_cairo_gstate_get_target (cr->gstate), @@ -469,7 +469,7 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content) extents.width, extents.height); status = cairo_surface_status (group_surface); - if (status) + if (unlikely (status)) goto bail; /* Set device offsets on the new surface so that logically it appears at @@ -490,7 +490,7 @@ cairo_push_group_with_content (cairo_t *cr, cairo_content_t content) bail: cairo_surface_destroy (group_surface); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_push_group_with_content); @@ -628,7 +628,7 @@ cairo_set_operator (cairo_t *cr, cairo_operator_t op) return; status = _cairo_gstate_set_operator (cr->gstate, op); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_operator); @@ -790,7 +790,7 @@ cairo_set_source (cairo_t *cr, cairo_pattern_t *source) } status = _cairo_gstate_set_source (cr->gstate, source); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_source); @@ -838,7 +838,7 @@ cairo_set_tolerance (cairo_t *cr, double tolerance) _cairo_restrict_value (&tolerance, CAIRO_TOLERANCE_MINIMUM, tolerance); status = _cairo_gstate_set_tolerance (cr->gstate, tolerance); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_tolerance); @@ -865,7 +865,7 @@ cairo_set_antialias (cairo_t *cr, cairo_antialias_t antialias) return; status = _cairo_gstate_set_antialias (cr->gstate, antialias); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -891,7 +891,7 @@ cairo_set_fill_rule (cairo_t *cr, cairo_fill_rule_t fill_rule) return; status = _cairo_gstate_set_fill_rule (cr->gstate, fill_rule); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -932,7 +932,7 @@ cairo_set_line_width (cairo_t *cr, double width) _cairo_restrict_value (&width, 0.0, width); status = _cairo_gstate_set_line_width (cr->gstate, width); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_line_width); @@ -962,7 +962,7 @@ cairo_set_line_cap (cairo_t *cr, cairo_line_cap_t line_cap) return; status = _cairo_gstate_set_line_cap (cr->gstate, line_cap); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_line_cap); @@ -992,7 +992,7 @@ cairo_set_line_join (cairo_t *cr, cairo_line_join_t line_join) return; status = _cairo_gstate_set_line_join (cr->gstate, line_join); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_line_join); @@ -1042,7 +1042,7 @@ cairo_set_dash (cairo_t *cr, status = _cairo_gstate_set_dash (cr->gstate, dashes, num_dashes, offset); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -1132,7 +1132,7 @@ cairo_set_miter_limit (cairo_t *cr, double limit) return; status = _cairo_gstate_set_miter_limit (cr->gstate, limit); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -1157,7 +1157,7 @@ cairo_translate (cairo_t *cr, double tx, double ty) return; status = _cairo_gstate_translate (cr->gstate, tx, ty); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -1181,7 +1181,7 @@ cairo_scale (cairo_t *cr, double sx, double sy) return; status = _cairo_gstate_scale (cr->gstate, sx, sy); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_scale); @@ -1207,7 +1207,7 @@ cairo_rotate (cairo_t *cr, double angle) return; status = _cairo_gstate_rotate (cr->gstate, angle); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -1230,7 +1230,7 @@ cairo_transform (cairo_t *cr, return; status = _cairo_gstate_transform (cr->gstate, matrix); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -1252,7 +1252,7 @@ cairo_set_matrix (cairo_t *cr, return; status = _cairo_gstate_set_matrix (cr->gstate, matrix); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_matrix); @@ -1393,7 +1393,7 @@ cairo_move_to (cairo_t *cr, double x, double y) y_fixed = _cairo_fixed_from_double (y); status = _cairo_path_fixed_move_to (cr->path, x_fixed, y_fixed); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_move_to); @@ -1452,7 +1452,7 @@ cairo_line_to (cairo_t *cr, double x, double y) y_fixed = _cairo_fixed_from_double (y); status = _cairo_path_fixed_line_to (cr->path, x_fixed, y_fixed); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_line_to); @@ -1507,7 +1507,7 @@ cairo_curve_to (cairo_t *cr, x1_fixed, y1_fixed, x2_fixed, y2_fixed, x3_fixed, y3_fixed); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_curve_to); @@ -1641,7 +1641,7 @@ cairo_arc_to (cairo_t *cr, x1, y1, x2, y2, radius); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } */ @@ -1677,7 +1677,7 @@ cairo_rel_move_to (cairo_t *cr, double dx, double dy) dy_fixed = _cairo_fixed_from_double (dy); status = _cairo_path_fixed_rel_move_to (cr->path, dx_fixed, dy_fixed); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -1714,7 +1714,7 @@ cairo_rel_line_to (cairo_t *cr, double dx, double dy) dy_fixed = _cairo_fixed_from_double (dy); status = _cairo_path_fixed_rel_line_to (cr->path, dx_fixed, dy_fixed); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_rel_line_to); @@ -1775,7 +1775,7 @@ cairo_rel_curve_to (cairo_t *cr, dx1_fixed, dy1_fixed, dx2_fixed, dy2_fixed, dx3_fixed, dy3_fixed); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -1827,7 +1827,7 @@ cairo_stroke_to_path (cairo_t *cr) /* The code in _cairo_meta_surface_get_path has a poorman's stroke_to_path */ status = _cairo_gstate_stroke_path (cr->gstate); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } #endif @@ -1867,7 +1867,7 @@ cairo_close_path (cairo_t *cr) return; status = _cairo_path_fixed_close_path (cr->path); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_close_path); @@ -1941,7 +1941,7 @@ cairo_paint (cairo_t *cr) return; status = _cairo_gstate_paint (cr->gstate); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_paint); @@ -1980,7 +1980,7 @@ cairo_paint_with_alpha (cairo_t *cr, _cairo_pattern_init_solid (&pattern, &color, CAIRO_CONTENT_ALPHA); status = _cairo_gstate_mask (cr->gstate, &pattern.base); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); _cairo_pattern_fini (&pattern.base); @@ -2016,7 +2016,7 @@ cairo_mask (cairo_t *cr, } status = _cairo_gstate_mask (cr->gstate, pattern); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_mask); @@ -2118,7 +2118,7 @@ cairo_stroke_preserve (cairo_t *cr) return; status = _cairo_gstate_stroke (cr->gstate, cr->path); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_stroke_preserve); @@ -2161,7 +2161,7 @@ cairo_fill_preserve (cairo_t *cr) return; status = _cairo_gstate_fill (cr->gstate, cr->path); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_fill_preserve); @@ -2187,7 +2187,7 @@ cairo_copy_page (cairo_t *cr) return; status = _cairo_gstate_copy_page (cr->gstate); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2210,7 +2210,7 @@ cairo_show_page (cairo_t *cr) return; status = _cairo_gstate_show_page (cr->gstate); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2244,7 +2244,7 @@ cairo_in_stroke (cairo_t *cr, double x, double y) status = _cairo_gstate_in_stroke (cr->gstate, cr->path, x, y, &inside); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); return inside; @@ -2290,8 +2290,11 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status) return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; list = malloc (sizeof (cairo_rectangle_list_t)); - if (list == NULL) + if (unlikely (list == NULL)) { + status = _cairo_error (CAIRO_STATUS_NO_MEMORY); return (cairo_rectangle_list_t*) &_cairo_rectangles_nil; + } + list->status = status; list->rectangles = NULL; list->num_rectangles = 0; @@ -2411,7 +2414,7 @@ cairo_stroke_extents (cairo_t *cr, status = _cairo_gstate_stroke_extents (cr->gstate, cr->path, x1, y1, x2, y2); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2462,7 +2465,7 @@ cairo_fill_extents (cairo_t *cr, status = _cairo_gstate_fill_extents (cr->gstate, cr->path, x1, y1, x2, y2); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2527,7 +2530,7 @@ cairo_clip_preserve (cairo_t *cr) return; status = _cairo_gstate_clip (cr->gstate, cr->path); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def(cairo_clip_preserve); @@ -2557,7 +2560,7 @@ cairo_reset_clip (cairo_t *cr) return; status = _cairo_gstate_reset_clip (cr->gstate); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2595,7 +2598,7 @@ cairo_clip_extents (cairo_t *cr, } status = _cairo_gstate_clip_extents (cr->gstate, x1, y1, x2, y2); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2681,7 +2684,7 @@ cairo_select_font_face (cairo_t *cr, return; status = _cairo_gstate_select_font_face (cr->gstate, family, slant, weight); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2709,7 +2712,7 @@ cairo_font_extents (cairo_t *cr, return; status = _cairo_gstate_get_font_extents (cr->gstate, extents); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2732,7 +2735,7 @@ cairo_set_font_face (cairo_t *cr, return; status = _cairo_gstate_set_font_face (cr->gstate, font_face); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2764,7 +2767,7 @@ cairo_get_font_face (cairo_t *cr) return (cairo_font_face_t*) &_cairo_font_face_nil; status = _cairo_gstate_get_font_face (cr->gstate, &font_face); - if (status) { + if (unlikely (status)) { _cairo_set_error (cr, status); return (cairo_font_face_t*) &_cairo_font_face_nil; } @@ -2796,7 +2799,7 @@ cairo_set_font_size (cairo_t *cr, double size) return; status = _cairo_gstate_set_font_size (cr->gstate, size); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } slim_hidden_def (cairo_set_font_size); @@ -2824,7 +2827,7 @@ cairo_set_font_matrix (cairo_t *cr, return; status = _cairo_gstate_set_font_matrix (cr->gstate, matrix); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -2868,7 +2871,7 @@ cairo_set_font_options (cairo_t *cr, return; status = cairo_font_options_status ((cairo_font_options_t *) options); - if (status) { + if (unlikely (status)) { _cairo_set_error (cr, status); return; } @@ -2932,15 +2935,15 @@ cairo_set_scaled_font (cairo_t *cr, } status = scaled_font->status; - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_gstate_set_font_face (cr->gstate, scaled_font->font_face); - if (status) + if (unlikely (status)) goto BAIL; status = _cairo_gstate_set_font_matrix (cr->gstate, &scaled_font->font_matrix); - if (status) + if (unlikely (status)) goto BAIL; _cairo_gstate_set_font_options (cr->gstate, &scaled_font->options); @@ -2981,7 +2984,7 @@ cairo_get_scaled_font (cairo_t *cr) return _cairo_scaled_font_create_in_error (cr->status); status = _cairo_gstate_get_scaled_font (cr->gstate, &scaled_font); - if (status) { + if (unlikely (status)) { _cairo_set_error (cr, status); return _cairo_scaled_font_create_in_error (status); } @@ -3047,7 +3050,7 @@ cairo_text_extents (cairo_t *cr, extents); cairo_glyph_free (glyphs); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -3102,7 +3105,7 @@ cairo_glyph_extents (cairo_t *cr, status = _cairo_gstate_glyph_extents (cr->gstate, glyphs, num_glyphs, extents); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -3172,7 +3175,7 @@ cairo_show_text (cairo_t *cr, const char *utf8) &glyphs, &num_glyphs, has_show_text_glyphs ? &clusters : NULL, &num_clusters, &cluster_flags); - if (status) + if (unlikely (status)) goto BAIL; if (num_glyphs == 0) @@ -3183,14 +3186,14 @@ cairo_show_text (cairo_t *cr, const char *utf8) glyphs, num_glyphs, clusters, num_clusters, cluster_flags); - if (status) + if (unlikely (status)) goto BAIL; last_glyph = &glyphs[num_glyphs - 1]; status = _cairo_gstate_glyph_extents (cr->gstate, last_glyph, 1, &extents); - if (status) + if (unlikely (status)) goto BAIL; x = last_glyph->x + extents.x_advance; @@ -3203,7 +3206,7 @@ cairo_show_text (cairo_t *cr, const char *utf8) if (clusters != stack_clusters) cairo_text_cluster_free (clusters); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -3243,7 +3246,7 @@ cairo_show_glyphs (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) glyphs, num_glyphs, NULL, 0, FALSE); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -3346,7 +3349,7 @@ cairo_show_text_glyphs (cairo_t *cr, utf8, utf8_len, glyphs, num_glyphs, clusters, num_clusters, cluster_flags); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -3398,7 +3401,7 @@ cairo_text_path (cairo_t *cr, const char *utf8) NULL, NULL, NULL); - if (status) + if (unlikely (status)) goto BAIL; if (num_glyphs == 0) @@ -3408,7 +3411,7 @@ cairo_text_path (cairo_t *cr, const char *utf8) glyphs, num_glyphs, cr->path); - if (status) + if (unlikely (status)) goto BAIL; last_glyph = &glyphs[num_glyphs - 1]; @@ -3416,7 +3419,7 @@ cairo_text_path (cairo_t *cr, const char *utf8) last_glyph, 1, &extents); - if (status) + if (unlikely (status)) goto BAIL; x = last_glyph->x + extents.x_advance; @@ -3426,7 +3429,7 @@ cairo_text_path (cairo_t *cr, const char *utf8) BAIL: cairo_glyph_free (glyphs); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -3464,7 +3467,7 @@ cairo_glyph_path (cairo_t *cr, const cairo_glyph_t *glyphs, int num_glyphs) status = _cairo_gstate_glyph_path (cr->gstate, glyphs, num_glyphs, cr->path); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } @@ -3884,7 +3887,7 @@ cairo_append_path (cairo_t *cr, } status = _cairo_path_append_to_context (path, cr); - if (status) + if (unlikely (status)) _cairo_set_error (cr, status); } diff --git a/src/cairoint.h b/src/cairoint.h index 18f5a560..611f07ec 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -234,6 +234,7 @@ be32_to_cpu(uint32_t v) #include "cairo-types-private.h" #include "cairo-cache-private.h" #include "cairo-reference-count-private.h" +#include "cairo-spans-private.h" cairo_private void _cairo_box_from_doubles (cairo_box_t *box, @@ -263,6 +264,13 @@ _cairo_box_intersects_line_segment (cairo_box_t *box, cairo_line_t *line); cairo_private cairo_bool_t _cairo_box_contains_point (cairo_box_t *box, cairo_point_t *point); +cairo_private void +_cairo_composite_rectangles_init (cairo_composite_rectangles_t *rects, + int all_x, + int all_y, + int width, + int height); + /* cairo-array.c structures and functions */ cairo_private void @@ -626,6 +634,20 @@ struct _cairo_surface_backend { cairo_trapezoid_t *traps, int num_traps); + cairo_warn cairo_span_renderer_t * + (*create_span_renderer) (cairo_operator_t op, + const cairo_pattern_t *pattern, + void *dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects); + + cairo_warn cairo_bool_t + (*check_span_renderer) (cairo_operator_t op, + const cairo_pattern_t *pattern, + void *dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects); + cairo_warn cairo_int_status_t (*copy_page) (void *surface); @@ -1299,6 +1321,20 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate, int num_glyphs, cairo_path_fixed_t *path); +cairo_private cairo_status_t +_cairo_gtate_begin_damage_tracking (cairo_gstate_t *gstate); + +cairo_private cairo_status_t +_cairo_gstate_end_damage_tracking (cairo_gstate_t *gstate, + int *n_rectangles, + cairo_rectangle_t **rectangles); +cairo_private cairo_status_t +_cairo_gstate_set_antialias (cairo_gstate_t *gstate, + cairo_antialias_t antialias); + +cairo_private cairo_antialias_t +_cairo_gstate_get_antialias (cairo_gstate_t *gstate); + cairo_private cairo_bool_t _cairo_operator_bounded_by_mask (cairo_operator_t op) cairo_pure; @@ -1545,6 +1581,9 @@ cairo_private cairo_bool_t _cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path, cairo_box_t *box); +cairo_private cairo_bool_t +_cairo_path_fixed_is_region (cairo_path_fixed_t *path); + /* cairo-path-in-fill.c */ cairo_private void _cairo_path_fixed_in_fill (cairo_path_fixed_t *path, @@ -1861,6 +1900,22 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op, cairo_trapezoid_t *traps, int ntraps); +cairo_private cairo_span_renderer_t * +_cairo_surface_create_span_renderer ( + cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_surface_t *dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects); + +cairo_private cairo_bool_t +_cairo_surface_check_span_renderer ( + cairo_operator_t op, + const cairo_pattern_t *pattern, + cairo_surface_t *dst, + cairo_antialias_t antialias, + const cairo_composite_rectangles_t *rects); + cairo_private cairo_status_t _cairo_surface_acquire_source_image (cairo_surface_t *surface, cairo_image_surface_t **image_out, @@ -2452,13 +2507,6 @@ _cairo_pattern_equal (const cairo_pattern_t *a, cairo_private void _cairo_pattern_reset_static_data (void); -cairo_private cairo_status_t -_cairo_gstate_set_antialias (cairo_gstate_t *gstate, - cairo_antialias_t antialias); - -cairo_private cairo_antialias_t -_cairo_gstate_get_antialias (cairo_gstate_t *gstate); - /* cairo-region.c */ #include "cairo-region-private.h" diff --git a/src/check-doc-syntax.sh b/src/check-doc-syntax.sh index abf526da..a5c84628 100755 --- a/src/check-doc-syntax.sh +++ b/src/check-doc-syntax.sh @@ -64,7 +64,7 @@ if echo $FILES | xargs grep . /dev/null | sed -e '/<programlisting>/,/<\/program echo " '$func_regexp'" fi >&2 -note_regexp='NOTE' +note_regexp='\<NOTE\>' if echo $FILES | xargs grep "$note_regexp" /dev/null; then stat=1 echo Error: some source files contain the string 'NOTE'. diff --git a/src/test-fallback-surface.c b/src/test-fallback-surface.c index 883941df..8acd91ee 100644 --- a/src/test-fallback-surface.c +++ b/src/test-fallback-surface.c @@ -79,7 +79,7 @@ _cairo_test_fallback_surface_create (cairo_content_t content, return backing; surface = malloc (sizeof (test_fallback_surface_t)); - if (surface == NULL) { + if (unlikely (surface == NULL)) { cairo_surface_destroy (backing); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); } @@ -214,6 +214,8 @@ static const cairo_surface_backend_t test_fallback_surface_backend = { 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 */ diff --git a/src/test-meta-surface.c b/src/test-meta-surface.c index 71700bdd..42bf6b0c 100644 --- a/src/test-meta-surface.c +++ b/src/test-meta-surface.c @@ -77,7 +77,7 @@ _cairo_test_meta_surface_create (cairo_content_t content, cairo_status_t status; surface = malloc (sizeof (test_meta_surface_t)); - if (surface == NULL) { + if (unlikely (surface == NULL)) { status = _cairo_error (CAIRO_STATUS_NO_MEMORY); goto FAIL; } @@ -313,6 +313,8 @@ static const cairo_surface_backend_t test_meta_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ _test_meta_surface_show_page, NULL, /* set_clip_region */ diff --git a/src/test-paginated-surface.c b/src/test-paginated-surface.c index cfb87f33..4c566470 100644 --- a/src/test-paginated-surface.c +++ b/src/test-paginated-surface.c @@ -80,7 +80,7 @@ _cairo_test_paginated_surface_create_for_data (unsigned char *data, return target; surface = malloc (sizeof (test_paginated_surface_t)); - if (surface == NULL) { + if (unlikely (surface == NULL)) { cairo_surface_destroy (target); return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); } @@ -298,6 +298,8 @@ static const cairo_surface_backend_t test_paginated_surface_backend = { NULL, /* composite */ NULL, /* fill_rectangles */ NULL, /* composite_trapezoids */ + NULL, /* create_span_renderer */ + NULL, /* check_span_renderer */ NULL, /* copy_page */ NULL, /* show_page */ _test_paginated_surface_set_clip_region, diff --git a/test/Makefile.am b/test/Makefile.am index 3afac519..de9f9c47 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -13,8 +13,10 @@ test_sources = \ 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 \ @@ -212,7 +214,11 @@ test_sources += ft-text-vertical-layout-type3.c test_sources += ft-text-antialias-none.c endif -# Need to add win32-surface-source, quartz-surface-source +# Need to add quartz-surface-source +if CAIRO_HAS_QUARTZ_SURFACE +test_sources += quartz-surface-source.c +endif + if CAIRO_HAS_GLITZ_SURFACE test_sources += glitz-surface-source.c endif @@ -294,6 +300,10 @@ 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 @@ -318,13 +328,16 @@ REFERENCE_IMAGES = \ bilevel-image.ref.png \ bitmap-font.ref.png \ bitmap-font.rgb24.ref.png \ + caps.ref.png \ + caps.ps.ref.png \ caps-joins-alpha.quartz.ref.png \ caps-joins-alpha.ref.png \ caps-joins-alpha.svg12.ref.png \ caps-joins-alpha.svg11.ref.png \ + caps-joins-curve.ref.png \ + caps-joins-curve.ps.ref.png \ caps-joins.ref.png \ - caps-joins.ps2.ref.png \ - caps-joins.ps3.ref.png \ + caps-joins.ps.ref.png \ caps-sub-paths.ref.png \ clip-all.ref.png \ clip-empty.ref.png \ diff --git a/test/cairo-test-runner.c b/test/cairo-test-runner.c index 4fb0cbea..aec90ff7 100644 --- a/test/cairo-test-runner.c +++ b/test/cairo-test-runner.c @@ -33,6 +33,10 @@ #undef CAIRO_VERSION_MICRO #include "../cairo-version.h" +#if CAIRO_HAS_SDL_SURFACE +#include <SDL_main.h> +#endif + #include <pixman.h> /* for version information */ #if HAVE_FORK && HAVE_WAITPID diff --git a/test/caps-joins-curve.c b/test/caps-joins-curve.c new file mode 100644 index 00000000..1b2fc7f0 --- /dev/null +++ b/test/caps-joins-curve.c @@ -0,0 +1,111 @@ +/* + * Copyright © 2008 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 <chris@chris-wilson.co.uk> + */ + +#include "cairo-test.h" + +#define LINE_WIDTH 10. +#define SIZE (5 * LINE_WIDTH) +#define PAD (3 * LINE_WIDTH) + +static void +make_path (cairo_t *cr) +{ + cairo_move_to (cr, 0, 0); + cairo_rel_curve_to (cr, + -SIZE/4, SIZE/3, + -SIZE/4, SIZE/3, + 0, SIZE); + cairo_rel_curve_to (cr, + SIZE/3, -SIZE/4, + SIZE/3, -SIZE/4, + SIZE, 0); + cairo_close_path (cr); + + cairo_move_to (cr, 5 * LINE_WIDTH, 3 * LINE_WIDTH); + cairo_rel_curve_to (cr, + 0, -3 * LINE_WIDTH, + 0, -3 * LINE_WIDTH, + -3 * LINE_WIDTH, -3 * LINE_WIDTH); +} + +static void +draw_caps_joins (cairo_t *cr) +{ + cairo_save (cr); + + cairo_translate (cr, PAD, PAD); + + make_path (cr); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL); + cairo_stroke (cr); + + cairo_translate (cr, SIZE + PAD, 0.); + + make_path (cr); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + cairo_stroke (cr); + + cairo_translate (cr, SIZE + PAD, 0.); + + make_path (cr); + cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); + cairo_stroke (cr); + + cairo_restore (cr); +} + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + /* We draw in the default black, so paint white first. */ + cairo_save (cr); + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ + cairo_paint (cr); + cairo_restore (cr); + + cairo_set_line_width (cr, LINE_WIDTH); + + draw_caps_joins (cr); + + /* and reflect to generate the opposite vertex ordering */ + cairo_translate (cr, 0, height); + cairo_scale (cr, 1, -1); + + draw_caps_joins (cr); + + return CAIRO_TEST_SUCCESS; +} + +CAIRO_TEST (caps_joins_curve, + "Test caps and joins on curves", + "stroke cap join", /* keywords */ + NULL, /* requirements */ + 3 * (PAD + SIZE) + PAD, + 2 * (PAD + SIZE) + PAD, + NULL, draw) + diff --git a/test/caps-joins-curve.ps.ref.png b/test/caps-joins-curve.ps.ref.png Binary files differnew file mode 100644 index 00000000..1f7e2000 --- /dev/null +++ b/test/caps-joins-curve.ps.ref.png diff --git a/test/caps-joins-curve.ref.png b/test/caps-joins-curve.ref.png Binary files differnew file mode 100644 index 00000000..9f763013 --- /dev/null +++ b/test/caps-joins-curve.ref.png diff --git a/test/caps-joins.c b/test/caps-joins.c index 5ec6a817..9d1c2a88 100644 --- a/test/caps-joins.c +++ b/test/caps-joins.c @@ -37,21 +37,15 @@ make_path (cairo_t *cr) cairo_rel_line_to (cr, SIZE, 0.); cairo_close_path (cr); - cairo_move_to (cr, 2 * LINE_WIDTH, 0.); - cairo_rel_line_to (cr, 3 * LINE_WIDTH, 0.); - cairo_rel_line_to (cr, 0., 3 * LINE_WIDTH); + cairo_move_to (cr, 5 * LINE_WIDTH, 3 * LINE_WIDTH); + cairo_rel_line_to (cr, 0., -3 * LINE_WIDTH); + cairo_rel_line_to (cr, -3 * LINE_WIDTH, 0.); } -static cairo_test_status_t -draw (cairo_t *cr, int width, int height) +static void +draw_caps_joins (cairo_t *cr) { - /* We draw in the default black, so paint white first. */ cairo_save (cr); - cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ - cairo_paint (cr); - cairo_restore (cr); - - cairo_set_line_width (cr, LINE_WIDTH); cairo_translate (cr, PAD, PAD); @@ -74,6 +68,28 @@ draw (cairo_t *cr, int width, int height) cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); cairo_stroke (cr); + cairo_restore (cr); +} + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + /* We draw in the default black, so paint white first. */ + cairo_save (cr); + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ + cairo_paint (cr); + cairo_restore (cr); + + cairo_set_line_width (cr, LINE_WIDTH); + + draw_caps_joins (cr); + + /* and reflect to generate the opposite vertex ordering */ + cairo_translate (cr, 0, height); + cairo_scale (cr, 1, -1); + + draw_caps_joins (cr); + return CAIRO_TEST_SUCCESS; } @@ -82,6 +98,6 @@ CAIRO_TEST (caps_joins, "stroke", /* keywords */ NULL, /* requirements */ 3 * (PAD + SIZE) + PAD, - PAD + SIZE + PAD, + 2 * (PAD + SIZE) + PAD, NULL, draw) diff --git a/test/caps-joins.ps.ref.png b/test/caps-joins.ps.ref.png Binary files differnew file mode 100644 index 00000000..e61aafce --- /dev/null +++ b/test/caps-joins.ps.ref.png diff --git a/test/caps-joins.ps2.ref.png b/test/caps-joins.ps2.ref.png Binary files differdeleted file mode 100644 index 1d473ac7..00000000 --- a/test/caps-joins.ps2.ref.png +++ /dev/null diff --git a/test/caps-joins.ps3.ref.png b/test/caps-joins.ps3.ref.png Binary files differdeleted file mode 100644 index 1d473ac7..00000000 --- a/test/caps-joins.ps3.ref.png +++ /dev/null diff --git a/test/caps-joins.ref.png b/test/caps-joins.ref.png Binary files differindex 9297ac4d..d83f9561 100644 --- a/test/caps-joins.ref.png +++ b/test/caps-joins.ref.png diff --git a/test/caps.c b/test/caps.c new file mode 100644 index 00000000..7f561179 --- /dev/null +++ b/test/caps.c @@ -0,0 +1,87 @@ +/* + * Copyright © 2008 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 <chris@chris-wilson.co.uk> + */ + +#include "cairo-test.h" + +#define LINE_WIDTH 10. +#define SIZE (5 * LINE_WIDTH) +#define PAD (2 * LINE_WIDTH) + +static void +make_path (cairo_t *cr) +{ + int i; + + cairo_save (cr); + for (i = 0; i <= 3; i++) { + cairo_new_sub_path (cr); + cairo_move_to (cr, -SIZE / 2, 0.); + cairo_line_to (cr, SIZE / 2, 0.); + cairo_rotate (cr, M_PI / 4.); + } + cairo_restore (cr); +} + +static cairo_test_status_t +draw (cairo_t *cr, int width, int height) +{ + cairo_save (cr); + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* white */ + cairo_paint (cr); + cairo_restore (cr); + + cairo_set_line_width (cr, LINE_WIDTH); + cairo_translate (cr, PAD + SIZE / 2., PAD + SIZE / 2.); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL); + make_path (cr); + cairo_stroke (cr); + + cairo_translate (cr, 0, SIZE + PAD); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND); + make_path (cr); + cairo_stroke (cr); + + cairo_translate (cr, 0, SIZE + PAD); + + cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); + cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); + make_path (cr); + cairo_stroke (cr); + + return CAIRO_TEST_SUCCESS; +} + +CAIRO_TEST (caps, + "Test caps", + "stroke caps", /* keywords */ + NULL, /* requirements */ + PAD + SIZE + PAD, + 3 * (PAD + SIZE) + PAD, + NULL, draw) + diff --git a/test/caps.ps.ref.png b/test/caps.ps.ref.png Binary files differnew file mode 100644 index 00000000..b1f4a72a --- /dev/null +++ b/test/caps.ps.ref.png diff --git a/test/caps.ref.png b/test/caps.ref.png Binary files differnew file mode 100644 index 00000000..a46e0366 --- /dev/null +++ b/test/caps.ref.png diff --git a/test/clip-fill-rule.pdf.argb32.ref.png b/test/clip-fill-rule.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0d9938e7 --- /dev/null +++ b/test/clip-fill-rule.pdf.argb32.ref.png diff --git a/test/clip-fill-rule.rgb24.ref.png b/test/clip-fill-rule.rgb24.ref.png Binary files differindex a969e367..050bd666 100644 --- a/test/clip-fill-rule.rgb24.ref.png +++ b/test/clip-fill-rule.rgb24.ref.png diff --git a/test/clip-fill-rule.test-fallback.rgb24.ref.png b/test/clip-fill-rule.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d21472dc --- /dev/null +++ b/test/clip-fill-rule.test-fallback.rgb24.ref.png diff --git a/test/clip-fill-rule.test-paginated.rgb24.ref.png b/test/clip-fill-rule.test-paginated.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d21472dc --- /dev/null +++ b/test/clip-fill-rule.test-paginated.rgb24.ref.png diff --git a/test/clip-fill-rule.xlib.rgb24.ref.png b/test/clip-fill-rule.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..a969e367 --- /dev/null +++ b/test/clip-fill-rule.xlib.rgb24.ref.png diff --git a/test/clip-nesting.pdf.argb32.ref.png b/test/clip-nesting.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..78ae6e08 --- /dev/null +++ b/test/clip-nesting.pdf.argb32.ref.png diff --git a/test/clip-nesting.rgb24.ref.png b/test/clip-nesting.rgb24.ref.png Binary files differindex e2488f34..a014763d 100644 --- a/test/clip-nesting.rgb24.ref.png +++ b/test/clip-nesting.rgb24.ref.png diff --git a/test/clip-nesting.test-fallback.rgb24.ref.png b/test/clip-nesting.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d087ab6c --- /dev/null +++ b/test/clip-nesting.test-fallback.rgb24.ref.png diff --git a/test/clip-nesting.test-paginated.rgb24.ref.png b/test/clip-nesting.test-paginated.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d087ab6c --- /dev/null +++ b/test/clip-nesting.test-paginated.rgb24.ref.png diff --git a/test/clip-nesting.xlib.rgb24.ref.png b/test/clip-nesting.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..e2488f34 --- /dev/null +++ b/test/clip-nesting.xlib.rgb24.ref.png diff --git a/test/clip-operator.pdf.argb32.ref.png b/test/clip-operator.pdf.argb32.ref.png Binary files differindex b3ee1437..e2fdc8d1 100644 --- a/test/clip-operator.pdf.argb32.ref.png +++ b/test/clip-operator.pdf.argb32.ref.png diff --git a/test/clip-operator.pdf.rgb24.ref.png b/test/clip-operator.pdf.rgb24.ref.png Binary files differindex b420f385..6590dd88 100644 --- a/test/clip-operator.pdf.rgb24.ref.png +++ b/test/clip-operator.pdf.rgb24.ref.png diff --git a/test/clip-operator.ps2.rgb24.ref.png b/test/clip-operator.ps2.rgb24.ref.png Binary files differindex 6ed9fc45..52452993 100644 --- a/test/clip-operator.ps2.rgb24.ref.png +++ b/test/clip-operator.ps2.rgb24.ref.png diff --git a/test/clip-operator.ps3.argb32.ref.png b/test/clip-operator.ps3.argb32.ref.png Binary files differnew file mode 100644 index 00000000..cd207d92 --- /dev/null +++ b/test/clip-operator.ps3.argb32.ref.png diff --git a/test/clip-operator.ps3.rgb24.ref.png b/test/clip-operator.ps3.rgb24.ref.png Binary files differindex 6ed9fc45..52452993 100644 --- a/test/clip-operator.ps3.rgb24.ref.png +++ b/test/clip-operator.ps3.rgb24.ref.png diff --git a/test/clip-operator.ref.png b/test/clip-operator.ref.png Binary files differindex 4ea1842e..3a685f5e 100644 --- a/test/clip-operator.ref.png +++ b/test/clip-operator.ref.png diff --git a/test/clip-operator.rgb24.ref.png b/test/clip-operator.rgb24.ref.png Binary files differindex 7ab964c3..0a4d4c09 100644 --- a/test/clip-operator.rgb24.ref.png +++ b/test/clip-operator.rgb24.ref.png diff --git a/test/clip-operator.test-fallback.argb32.ref.png b/test/clip-operator.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..f53e4921 --- /dev/null +++ b/test/clip-operator.test-fallback.argb32.ref.png diff --git a/test/clip-operator.test-fallback.rgb24.ref.png b/test/clip-operator.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..7579ae69 --- /dev/null +++ b/test/clip-operator.test-fallback.rgb24.ref.png diff --git a/test/clip-operator.test-paginated.argb32.ref.png b/test/clip-operator.test-paginated.argb32.ref.png Binary files differnew file mode 100644 index 00000000..22e080a2 --- /dev/null +++ b/test/clip-operator.test-paginated.argb32.ref.png diff --git a/test/clip-operator.xlib-fallback.rgb24.ref.png b/test/clip-operator.xlib-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..4a05f7ba --- /dev/null +++ b/test/clip-operator.xlib-fallback.rgb24.ref.png diff --git a/test/clip-operator.xlib.ref.png b/test/clip-operator.xlib.ref.png Binary files differnew file mode 100644 index 00000000..4ea1842e --- /dev/null +++ b/test/clip-operator.xlib.ref.png diff --git a/test/clip-operator.xlib.rgb24.ref.png b/test/clip-operator.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..7ab964c3 --- /dev/null +++ b/test/clip-operator.xlib.rgb24.ref.png diff --git a/test/clip-twice.pdf.argb32.ref.png b/test/clip-twice.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..2a7541fe --- /dev/null +++ b/test/clip-twice.pdf.argb32.ref.png diff --git a/test/clip-twice.ref.png b/test/clip-twice.ref.png Binary files differindex 8dc86f30..4aafc9ac 100644 --- a/test/clip-twice.ref.png +++ b/test/clip-twice.ref.png diff --git a/test/clip-twice.rgb24.ref.png b/test/clip-twice.rgb24.ref.png Binary files differindex 3f1c013b..25c44ef7 100644 --- a/test/clip-twice.rgb24.ref.png +++ b/test/clip-twice.rgb24.ref.png diff --git a/test/clip-twice.test-fallback.argb32.ref.png b/test/clip-twice.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..ba621807 --- /dev/null +++ b/test/clip-twice.test-fallback.argb32.ref.png diff --git a/test/clip-twice.test-fallback.rgb24.ref.png b/test/clip-twice.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..9cbdc4d4 --- /dev/null +++ b/test/clip-twice.test-fallback.rgb24.ref.png diff --git a/test/clip-twice.test-paginated.argb32.ref.png b/test/clip-twice.test-paginated.argb32.ref.png Binary files differnew file mode 100644 index 00000000..ffd59aaf --- /dev/null +++ b/test/clip-twice.test-paginated.argb32.ref.png diff --git a/test/clip-twice.test-paginated.rgb24.ref.png b/test/clip-twice.test-paginated.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..e3d0ae49 --- /dev/null +++ b/test/clip-twice.test-paginated.rgb24.ref.png diff --git a/test/clip-twice.xlib.ref.png b/test/clip-twice.xlib.ref.png Binary files differnew file mode 100644 index 00000000..8dc86f30 --- /dev/null +++ b/test/clip-twice.xlib.ref.png diff --git a/test/clip-twice.xlib.rgb24.ref.png b/test/clip-twice.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3f1c013b --- /dev/null +++ b/test/clip-twice.xlib.rgb24.ref.png diff --git a/test/clipped-group.pdf.argb32.ref.png b/test/clipped-group.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..b9975e12 --- /dev/null +++ b/test/clipped-group.pdf.argb32.ref.png diff --git a/test/clipped-group.pdf.rgb24.ref.png b/test/clipped-group.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..b9975e12 --- /dev/null +++ b/test/clipped-group.pdf.rgb24.ref.png diff --git a/test/dash-curve.ref.png b/test/dash-curve.ref.png Binary files differindex 542b2d82..a590fc43 100644 --- a/test/dash-curve.ref.png +++ b/test/dash-curve.ref.png diff --git a/test/degenerate-arc.ref.png b/test/degenerate-arc.ref.png Binary files differindex 5112d7f9..1d131b22 100644 --- a/test/degenerate-arc.ref.png +++ b/test/degenerate-arc.ref.png diff --git a/test/degenerate-arc.test-fallback.argb32.ref.png b/test/degenerate-arc.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..73d41afa --- /dev/null +++ b/test/degenerate-arc.test-fallback.argb32.ref.png diff --git a/test/degenerate-arc.test-fallback.rgb24.ref.png b/test/degenerate-arc.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..73d41afa --- /dev/null +++ b/test/degenerate-arc.test-fallback.rgb24.ref.png diff --git a/test/degenerate-arc.xlib.ref.png b/test/degenerate-arc.xlib.ref.png Binary files differnew file mode 100644 index 00000000..5112d7f9 --- /dev/null +++ b/test/degenerate-arc.xlib.ref.png diff --git a/test/device-offset-fractional.pdf.argb32.ref.png b/test/device-offset-fractional.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..c076932c --- /dev/null +++ b/test/device-offset-fractional.pdf.argb32.ref.png diff --git a/test/device-offset-fractional.pdf.rgb24.ref.png b/test/device-offset-fractional.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..c076932c --- /dev/null +++ b/test/device-offset-fractional.pdf.rgb24.ref.png diff --git a/test/device-offset-positive.c b/test/device-offset-positive.c index 4ea9469d..5afe9730 100644 --- a/test/device-offset-positive.c +++ b/test/device-offset-positive.c @@ -67,6 +67,7 @@ draw (cairo_t *cr, int width, int height) cairo_destroy (cr2); cairo_surface_set_device_offset (surface, + SIZE / 2, + SIZE / 2); cairo_set_source_surface (cr, surface, SIZE / 2, SIZE / 2); + cairo_surface_destroy (surface); cairo_paint (cr); diff --git a/test/fill-alpha-pattern.pdf.argb32.ref.png b/test/fill-alpha-pattern.pdf.argb32.ref.png Binary files differindex d786c86a..d7a7ebe5 100644 --- a/test/fill-alpha-pattern.pdf.argb32.ref.png +++ b/test/fill-alpha-pattern.pdf.argb32.ref.png diff --git a/test/fill-alpha-pattern.pdf.rgb24.ref.png b/test/fill-alpha-pattern.pdf.rgb24.ref.png Binary files differindex 75e580fb..ef9049e2 100644 --- a/test/fill-alpha-pattern.pdf.rgb24.ref.png +++ b/test/fill-alpha-pattern.pdf.rgb24.ref.png diff --git a/test/fill-alpha-pattern.ps3.argb32.ref.png b/test/fill-alpha-pattern.ps3.argb32.ref.png Binary files differnew file mode 100644 index 00000000..b16731af --- /dev/null +++ b/test/fill-alpha-pattern.ps3.argb32.ref.png diff --git a/test/fill-alpha-pattern.ps3.rgb24.ref.png b/test/fill-alpha-pattern.ps3.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d0193545 --- /dev/null +++ b/test/fill-alpha-pattern.ps3.rgb24.ref.png diff --git a/test/fill-alpha-pattern.ref.png b/test/fill-alpha-pattern.ref.png Binary files differindex 0031c04c..9ab39a7d 100644 --- a/test/fill-alpha-pattern.ref.png +++ b/test/fill-alpha-pattern.ref.png diff --git a/test/fill-alpha-pattern.test-fallback.argb32.ref.png b/test/fill-alpha-pattern.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..4dafb835 --- /dev/null +++ b/test/fill-alpha-pattern.test-fallback.argb32.ref.png diff --git a/test/fill-alpha-pattern.test-fallback.rgb24.ref.png b/test/fill-alpha-pattern.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..4dafb835 --- /dev/null +++ b/test/fill-alpha-pattern.test-fallback.rgb24.ref.png diff --git a/test/fill-alpha-pattern.xlib.ref.png b/test/fill-alpha-pattern.xlib.ref.png Binary files differnew file mode 100644 index 00000000..0031c04c --- /dev/null +++ b/test/fill-alpha-pattern.xlib.ref.png diff --git a/test/fill-alpha.ref.png b/test/fill-alpha.ref.png Binary files differindex 61aaac29..b50a456d 100644 --- a/test/fill-alpha.ref.png +++ b/test/fill-alpha.ref.png diff --git a/test/fill-alpha.test-fallback.argb32.ref.png b/test/fill-alpha.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..85df9198 --- /dev/null +++ b/test/fill-alpha.test-fallback.argb32.ref.png diff --git a/test/fill-alpha.test-fallback.rgb24.ref.png b/test/fill-alpha.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..85df9198 --- /dev/null +++ b/test/fill-alpha.test-fallback.rgb24.ref.png diff --git a/test/fill-alpha.xlib.ref.png b/test/fill-alpha.xlib.ref.png Binary files differnew file mode 100644 index 00000000..61aaac29 --- /dev/null +++ b/test/fill-alpha.xlib.ref.png diff --git a/test/fill-degenerate-sort-order.ref.png b/test/fill-degenerate-sort-order.ref.png Binary files differindex 8278d76e..3a95c257 100644 --- a/test/fill-degenerate-sort-order.ref.png +++ b/test/fill-degenerate-sort-order.ref.png diff --git a/test/fill-degenerate-sort-order.rgb24.ref.png b/test/fill-degenerate-sort-order.rgb24.ref.png Binary files differindex 6c76eaf4..377c7087 100644 --- a/test/fill-degenerate-sort-order.rgb24.ref.png +++ b/test/fill-degenerate-sort-order.rgb24.ref.png diff --git a/test/fill-degenerate-sort-order.test-fallback.argb32.ref.png b/test/fill-degenerate-sort-order.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..8cf567dd --- /dev/null +++ b/test/fill-degenerate-sort-order.test-fallback.argb32.ref.png diff --git a/test/fill-degenerate-sort-order.test-fallback.rgb24.ref.png b/test/fill-degenerate-sort-order.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..da5aa50a --- /dev/null +++ b/test/fill-degenerate-sort-order.test-fallback.rgb24.ref.png diff --git a/test/fill-degenerate-sort-order.xlib.ref.png b/test/fill-degenerate-sort-order.xlib.ref.png Binary files differnew file mode 100644 index 00000000..8278d76e --- /dev/null +++ b/test/fill-degenerate-sort-order.xlib.ref.png diff --git a/test/fill-degenerate-sort-order.xlib.rgb24.ref.png b/test/fill-degenerate-sort-order.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..6c76eaf4 --- /dev/null +++ b/test/fill-degenerate-sort-order.xlib.rgb24.ref.png diff --git a/test/fill-missed-stop.pdf.argb32.ref.png b/test/fill-missed-stop.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..7d56e3e8 --- /dev/null +++ b/test/fill-missed-stop.pdf.argb32.ref.png diff --git a/test/fill-rule.ref.png b/test/fill-rule.ref.png Binary files differindex e2e10d4a..6e19b621 100644 --- a/test/fill-rule.ref.png +++ b/test/fill-rule.ref.png diff --git a/test/fill-rule.rgb24.ref.png b/test/fill-rule.rgb24.ref.png Binary files differindex 68d2b9b8..bdfc12f4 100644 --- a/test/fill-rule.rgb24.ref.png +++ b/test/fill-rule.rgb24.ref.png diff --git a/test/fill-rule.test-fallback.argb32.ref.png b/test/fill-rule.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..e2e10d4a --- /dev/null +++ b/test/fill-rule.test-fallback.argb32.ref.png diff --git a/test/fill-rule.test-fallback.rgb24.ref.png b/test/fill-rule.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..49fb39c7 --- /dev/null +++ b/test/fill-rule.test-fallback.rgb24.ref.png diff --git a/test/fill-rule.xlib.ref.png b/test/fill-rule.xlib.ref.png Binary files differnew file mode 100644 index 00000000..e2e10d4a --- /dev/null +++ b/test/fill-rule.xlib.ref.png diff --git a/test/fill-rule.xlib.rgb24.ref.png b/test/fill-rule.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..68d2b9b8 --- /dev/null +++ b/test/fill-rule.xlib.rgb24.ref.png diff --git a/test/filter-nearest-offset.pdf.argb32.ref.png b/test/filter-nearest-offset.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..3475cb6e --- /dev/null +++ b/test/filter-nearest-offset.pdf.argb32.ref.png diff --git a/test/filter-nearest-offset.pdf.rgb24.ref.png b/test/filter-nearest-offset.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3475cb6e --- /dev/null +++ b/test/filter-nearest-offset.pdf.rgb24.ref.png diff --git a/test/filter-nearest-transformed.pdf.argb32.ref.png b/test/filter-nearest-transformed.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..40169593 --- /dev/null +++ b/test/filter-nearest-transformed.pdf.argb32.ref.png diff --git a/test/filter-nearest-transformed.pdf.rgb24.ref.png b/test/filter-nearest-transformed.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..40169593 --- /dev/null +++ b/test/filter-nearest-transformed.pdf.rgb24.ref.png diff --git a/test/finer-grained-fallbacks.ps2.argb32.ref.png b/test/finer-grained-fallbacks.ps2.argb32.ref.png Binary files differnew file mode 100644 index 00000000..92cd9517 --- /dev/null +++ b/test/finer-grained-fallbacks.ps2.argb32.ref.png diff --git a/test/finer-grained-fallbacks.ps2.rgb24.ref.png b/test/finer-grained-fallbacks.ps2.rgb24.ref.png Binary files differindex de482860..688c3e06 100644 --- a/test/finer-grained-fallbacks.ps2.rgb24.ref.png +++ b/test/finer-grained-fallbacks.ps2.rgb24.ref.png diff --git a/test/finer-grained-fallbacks.ps3.argb32.ref.png b/test/finer-grained-fallbacks.ps3.argb32.ref.png Binary files differnew file mode 100644 index 00000000..92cd9517 --- /dev/null +++ b/test/finer-grained-fallbacks.ps3.argb32.ref.png diff --git a/test/finer-grained-fallbacks.ps3.rgb24.ref.png b/test/finer-grained-fallbacks.ps3.rgb24.ref.png Binary files differindex de482860..688c3e06 100644 --- a/test/finer-grained-fallbacks.ps3.rgb24.ref.png +++ b/test/finer-grained-fallbacks.ps3.rgb24.ref.png diff --git a/test/finer-grained-fallbacks.ref.png b/test/finer-grained-fallbacks.ref.png Binary files differindex c7eb113d..5b1e532b 100644 --- a/test/finer-grained-fallbacks.ref.png +++ b/test/finer-grained-fallbacks.ref.png diff --git a/test/finer-grained-fallbacks.rgb24.ref.png b/test/finer-grained-fallbacks.rgb24.ref.png Binary files differindex 3b8e9c38..d3997fe1 100644 --- a/test/finer-grained-fallbacks.rgb24.ref.png +++ b/test/finer-grained-fallbacks.rgb24.ref.png diff --git a/test/finer-grained-fallbacks.test-fallback.argb32.ref.png b/test/finer-grained-fallbacks.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..c7eb113d --- /dev/null +++ b/test/finer-grained-fallbacks.test-fallback.argb32.ref.png diff --git a/test/finer-grained-fallbacks.test-fallback.rgb24.ref.png b/test/finer-grained-fallbacks.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..ff75c6dd --- /dev/null +++ b/test/finer-grained-fallbacks.test-fallback.rgb24.ref.png diff --git a/test/finer-grained-fallbacks.xlib.ref.png b/test/finer-grained-fallbacks.xlib.ref.png Binary files differnew file mode 100644 index 00000000..c7eb113d --- /dev/null +++ b/test/finer-grained-fallbacks.xlib.ref.png diff --git a/test/finer-grained-fallbacks.xlib.rgb24.ref.png b/test/finer-grained-fallbacks.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3b8e9c38 --- /dev/null +++ b/test/finer-grained-fallbacks.xlib.rgb24.ref.png diff --git a/test/font-matrix-translation.svg11.argb32.ref.png b/test/font-matrix-translation.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..441f6e3b --- /dev/null +++ b/test/font-matrix-translation.svg11.argb32.ref.png diff --git a/test/font-matrix-translation.svg11.rgb24.ref.png b/test/font-matrix-translation.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..441f6e3b --- /dev/null +++ b/test/font-matrix-translation.svg11.rgb24.ref.png diff --git a/test/font-matrix-translation.svg12.argb32.ref.png b/test/font-matrix-translation.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..441f6e3b --- /dev/null +++ b/test/font-matrix-translation.svg12.argb32.ref.png diff --git a/test/font-matrix-translation.svg12.rgb24.ref.png b/test/font-matrix-translation.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..441f6e3b --- /dev/null +++ b/test/font-matrix-translation.svg12.rgb24.ref.png diff --git a/test/ft-show-glyphs-table.svg11.argb32.ref.png b/test/ft-show-glyphs-table.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0c6e1c0b --- /dev/null +++ b/test/ft-show-glyphs-table.svg11.argb32.ref.png diff --git a/test/ft-show-glyphs-table.svg11.rgb24.ref.png b/test/ft-show-glyphs-table.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..0c6e1c0b --- /dev/null +++ b/test/ft-show-glyphs-table.svg11.rgb24.ref.png diff --git a/test/ft-show-glyphs-table.svg12.argb32.ref.png b/test/ft-show-glyphs-table.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0c6e1c0b --- /dev/null +++ b/test/ft-show-glyphs-table.svg12.argb32.ref.png diff --git a/test/ft-show-glyphs-table.svg12.rgb24.ref.png b/test/ft-show-glyphs-table.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..0c6e1c0b --- /dev/null +++ b/test/ft-show-glyphs-table.svg12.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type1.pdf.argb32.ref.png b/test/ft-text-vertical-layout-type1.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..242c3be5 --- /dev/null +++ b/test/ft-text-vertical-layout-type1.pdf.argb32.ref.png diff --git a/test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png b/test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..242c3be5 --- /dev/null +++ b/test/ft-text-vertical-layout-type1.pdf.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type1.ref.png b/test/ft-text-vertical-layout-type1.ref.png Binary files differindex 2b74aa60..1accc0b3 100644 --- a/test/ft-text-vertical-layout-type1.ref.png +++ b/test/ft-text-vertical-layout-type1.ref.png diff --git a/test/ft-text-vertical-layout-type1.svg11.argb32.ref.png b/test/ft-text-vertical-layout-type1.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..2de3f5be --- /dev/null +++ b/test/ft-text-vertical-layout-type1.svg11.argb32.ref.png diff --git a/test/ft-text-vertical-layout-type1.svg11.rgb24.ref.png b/test/ft-text-vertical-layout-type1.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..2de3f5be --- /dev/null +++ b/test/ft-text-vertical-layout-type1.svg11.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type1.svg12.argb32.ref.png b/test/ft-text-vertical-layout-type1.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..2de3f5be --- /dev/null +++ b/test/ft-text-vertical-layout-type1.svg12.argb32.ref.png diff --git a/test/ft-text-vertical-layout-type1.svg12.rgb24.ref.png b/test/ft-text-vertical-layout-type1.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..2de3f5be --- /dev/null +++ b/test/ft-text-vertical-layout-type1.svg12.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type1.test-fallback.argb32.ref.png b/test/ft-text-vertical-layout-type1.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..9eba6bb0 --- /dev/null +++ b/test/ft-text-vertical-layout-type1.test-fallback.argb32.ref.png diff --git a/test/ft-text-vertical-layout-type1.test-fallback.rgb24.ref.png b/test/ft-text-vertical-layout-type1.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..9eba6bb0 --- /dev/null +++ b/test/ft-text-vertical-layout-type1.test-fallback.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type1.xlib.ref.png b/test/ft-text-vertical-layout-type1.xlib.ref.png Binary files differnew file mode 100644 index 00000000..2b74aa60 --- /dev/null +++ b/test/ft-text-vertical-layout-type1.xlib.ref.png diff --git a/test/ft-text-vertical-layout-type3.pdf.argb32.ref.png b/test/ft-text-vertical-layout-type3.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..f232b9a5 --- /dev/null +++ b/test/ft-text-vertical-layout-type3.pdf.argb32.ref.png diff --git a/test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png b/test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..f232b9a5 --- /dev/null +++ b/test/ft-text-vertical-layout-type3.pdf.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type3.ref.png b/test/ft-text-vertical-layout-type3.ref.png Binary files differindex 8ec2ebec..6b59c56a 100644 --- a/test/ft-text-vertical-layout-type3.ref.png +++ b/test/ft-text-vertical-layout-type3.ref.png diff --git a/test/ft-text-vertical-layout-type3.svg11.argb32.ref.png b/test/ft-text-vertical-layout-type3.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..cfe92681 --- /dev/null +++ b/test/ft-text-vertical-layout-type3.svg11.argb32.ref.png diff --git a/test/ft-text-vertical-layout-type3.svg11.rgb24.ref.png b/test/ft-text-vertical-layout-type3.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..cfe92681 --- /dev/null +++ b/test/ft-text-vertical-layout-type3.svg11.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type3.svg12.argb32.ref.png b/test/ft-text-vertical-layout-type3.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..cfe92681 --- /dev/null +++ b/test/ft-text-vertical-layout-type3.svg12.argb32.ref.png diff --git a/test/ft-text-vertical-layout-type3.svg12.rgb24.ref.png b/test/ft-text-vertical-layout-type3.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..cfe92681 --- /dev/null +++ b/test/ft-text-vertical-layout-type3.svg12.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type3.test-fallback.argb32.ref.png b/test/ft-text-vertical-layout-type3.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..e57c0831 --- /dev/null +++ b/test/ft-text-vertical-layout-type3.test-fallback.argb32.ref.png diff --git a/test/ft-text-vertical-layout-type3.test-fallback.rgb24.ref.png b/test/ft-text-vertical-layout-type3.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..e57c0831 --- /dev/null +++ b/test/ft-text-vertical-layout-type3.test-fallback.rgb24.ref.png diff --git a/test/ft-text-vertical-layout-type3.xlib.ref.png b/test/ft-text-vertical-layout-type3.xlib.ref.png Binary files differnew file mode 100644 index 00000000..8ec2ebec --- /dev/null +++ b/test/ft-text-vertical-layout-type3.xlib.ref.png diff --git a/test/glitz-surface-source.c b/test/glitz-surface-source.c index 2dfa7355..89094e48 100644 --- a/test/glitz-surface-source.c +++ b/test/glitz-surface-source.c @@ -25,8 +25,6 @@ #include "cairo-test.h" #include <cairo-glitz.h> -#include <cairo-xlib.h> -#include <cairo-xlib-xrender.h> #define NAME "glitz" #include "surface-source.c" @@ -34,6 +32,8 @@ static cairo_user_data_key_t closure_key; #if CAIRO_CAN_TEST_GLITZ_GLX_SURFACE +#include <cairo-xlib.h> +#include <cairo-xlib-xrender.h> #include <glitz-glx.h> struct closure { @@ -198,4 +198,96 @@ create_source_surface (int size) return surface; } + +#elif CAIRO_CAN_TEST_GLITZ_AGL_SURFACE +#include <glitz-agl.h> + +static void +cleanup (void *data) +{ + glitz_agl_fini (); +} + +static glitz_surface_t * +_glitz_agl_create_surface (glitz_format_name_t formatname, + int width, + int height) +{ + glitz_drawable_format_t * dformat = NULL; + glitz_drawable_t * drawable = NULL; + glitz_format_t * format; + glitz_format_t templ; + glitz_surface_t * sr; + int i; + int alpha_size; + + glitz_agl_init (); + + /* Find a reasonably lame window format and use it to create a pbuffer. */ + i = 0; + alpha_size = (formatname == GLITZ_STANDARD_ARGB32) ? 8 : 0; + while ((dformat = glitz_agl_find_window_format (0, 0, i)) != NULL + && !(dformat->doublebuffer == 0 + && dformat->stencil_size == 0 + && dformat->depth_size == 0 + && dformat->color.fourcc == GLITZ_FOURCC_RGB + && dformat->color.alpha_size == alpha_size)) + i++; + + if (!dformat) + goto FAIL; + + /* Try for a pbuffer first */ + drawable = glitz_agl_create_pbuffer_drawable (dformat, width, height); + if (!drawable) + goto FAIL; + + templ.color = dformat->color; + format = glitz_find_format (drawable, + GLITZ_FORMAT_FOURCC_MASK | + GLITZ_FORMAT_RED_SIZE_MASK | + GLITZ_FORMAT_GREEN_SIZE_MASK | + GLITZ_FORMAT_BLUE_SIZE_MASK | + GLITZ_FORMAT_ALPHA_SIZE_MASK, + &templ, + 0); + if (!format) { + fprintf (stderr, "Error: couldn't find surface format\n"); + return NULL; + } + + sr = glitz_surface_create (drawable, format, width, height, 0, NULL); + if (!sr) + goto DESTROY_DRAWABLE; + + glitz_surface_attach (sr, drawable, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR); + glitz_drawable_destroy (drawable); + + return sr; + DESTROY_DRAWABLE: + glitz_drawable_destroy (drawable); + FAIL: + return NULL; +} + +static cairo_surface_t * +create_source_surface (int size) +{ + glitz_surface_t *glitz_surface; + cairo_surface_t *surface; + + glitz_surface = _glitz_agl_create_surface (GLITZ_STANDARD_ARGB32, + size, size); + + surface = cairo_glitz_surface_create (glitz_surface); + cairo_surface_set_user_data (surface, &closure_key, NULL, cleanup); + return surface; +} #endif + +CAIRO_TEST (glitz_surface_source, + "Test using a Glitz surface as the source", + "source", /* keywords */ + NULL, /* requirements */ + SIZE, SIZE, + preamble, draw) diff --git a/test/glitz-surface-source.ps2.ref.png b/test/glitz-surface-source.ps2.ref.png Binary files differnew file mode 100644 index 00000000..10231581 --- /dev/null +++ b/test/glitz-surface-source.ps2.ref.png diff --git a/test/glitz-surface-source.ps3.ref.png b/test/glitz-surface-source.ps3.ref.png Binary files differnew file mode 100644 index 00000000..10231581 --- /dev/null +++ b/test/glitz-surface-source.ps3.ref.png diff --git a/test/huge-pattern.pdf.argb32.ref.png b/test/huge-pattern.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..005d4a65 --- /dev/null +++ b/test/huge-pattern.pdf.argb32.ref.png diff --git a/test/linear-gradient.pdf.argb32.ref.png b/test/linear-gradient.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..f820c374 --- /dev/null +++ b/test/linear-gradient.pdf.argb32.ref.png diff --git a/test/linear-gradient.pdf.rgb24.ref.png b/test/linear-gradient.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..f820c374 --- /dev/null +++ b/test/linear-gradient.pdf.rgb24.ref.png diff --git a/test/linear-gradient.ref.png b/test/linear-gradient.ref.png Binary files differindex cb8f9089..ee238e6a 100644 --- a/test/linear-gradient.ref.png +++ b/test/linear-gradient.ref.png diff --git a/test/linear-gradient.svg11.argb32.ref.png b/test/linear-gradient.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..ea0e7238 --- /dev/null +++ b/test/linear-gradient.svg11.argb32.ref.png diff --git a/test/linear-gradient.svg11.rgb24.ref.png b/test/linear-gradient.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..ea0e7238 --- /dev/null +++ b/test/linear-gradient.svg11.rgb24.ref.png diff --git a/test/linear-gradient.svg12.argb32.ref.png b/test/linear-gradient.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..ea0e7238 --- /dev/null +++ b/test/linear-gradient.svg12.argb32.ref.png diff --git a/test/linear-gradient.svg12.rgb24.ref.png b/test/linear-gradient.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..ea0e7238 --- /dev/null +++ b/test/linear-gradient.svg12.rgb24.ref.png diff --git a/test/linear-gradient.test-fallback.argb32.ref.png b/test/linear-gradient.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..8202880e --- /dev/null +++ b/test/linear-gradient.test-fallback.argb32.ref.png diff --git a/test/linear-gradient.test-fallback.rgb24.ref.png b/test/linear-gradient.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..8202880e --- /dev/null +++ b/test/linear-gradient.test-fallback.rgb24.ref.png diff --git a/test/linear-gradient.xlib.ref.png b/test/linear-gradient.xlib.ref.png Binary files differnew file mode 100644 index 00000000..cb8f9089 --- /dev/null +++ b/test/linear-gradient.xlib.ref.png diff --git a/test/mask-alpha.ref.png b/test/mask-alpha.ref.png Binary files differindex 715a959e..d100da46 100644 --- a/test/mask-alpha.ref.png +++ b/test/mask-alpha.ref.png diff --git a/test/mask-alpha.svg11.argb32.ref.png b/test/mask-alpha.svg11.argb32.ref.png Binary files differindex 3e56aa34..fa9e82d1 100644 --- a/test/mask-alpha.svg11.argb32.ref.png +++ b/test/mask-alpha.svg11.argb32.ref.png diff --git a/test/mask-alpha.svg11.rgb24.ref.png b/test/mask-alpha.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..167eab48 --- /dev/null +++ b/test/mask-alpha.svg11.rgb24.ref.png diff --git a/test/mask-alpha.svg12.argb32.ref.png b/test/mask-alpha.svg12.argb32.ref.png Binary files differindex 3e56aa34..fa9e82d1 100644 --- a/test/mask-alpha.svg12.argb32.ref.png +++ b/test/mask-alpha.svg12.argb32.ref.png diff --git a/test/mask-alpha.svg12.rgb24.ref.png b/test/mask-alpha.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..167eab48 --- /dev/null +++ b/test/mask-alpha.svg12.rgb24.ref.png diff --git a/test/mask-alpha.test-fallback.argb32.ref.png b/test/mask-alpha.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..a0b9017e --- /dev/null +++ b/test/mask-alpha.test-fallback.argb32.ref.png diff --git a/test/mask-alpha.xlib.ref.png b/test/mask-alpha.xlib.ref.png Binary files differnew file mode 100644 index 00000000..715a959e --- /dev/null +++ b/test/mask-alpha.xlib.ref.png diff --git a/test/mask-alpha.xlib.rgb24.ref.png b/test/mask-alpha.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..aa2010f3 --- /dev/null +++ b/test/mask-alpha.xlib.rgb24.ref.png diff --git a/test/mask.pdf.argb32.ref.png b/test/mask.pdf.argb32.ref.png Binary files differindex 4570bff1..8bd8f140 100644 --- a/test/mask.pdf.argb32.ref.png +++ b/test/mask.pdf.argb32.ref.png diff --git a/test/mask.pdf.rgb24.ref.png b/test/mask.pdf.rgb24.ref.png Binary files differindex 1231965d..a3d3845c 100644 --- a/test/mask.pdf.rgb24.ref.png +++ b/test/mask.pdf.rgb24.ref.png diff --git a/test/mask.ref.png b/test/mask.ref.png Binary files differindex 549c130c..2c2fa117 100644 --- a/test/mask.ref.png +++ b/test/mask.ref.png diff --git a/test/mask.rgb24.ref.png b/test/mask.rgb24.ref.png Binary files differindex 70323672..34400504 100644 --- a/test/mask.rgb24.ref.png +++ b/test/mask.rgb24.ref.png diff --git a/test/mask.svg11.argb32.ref.png b/test/mask.svg11.argb32.ref.png Binary files differindex c5828591..3ce4d53f 100644 --- a/test/mask.svg11.argb32.ref.png +++ b/test/mask.svg11.argb32.ref.png diff --git a/test/mask.svg11.rgb24.ref.png b/test/mask.svg11.rgb24.ref.png Binary files differindex 79957237..94e38009 100644 --- a/test/mask.svg11.rgb24.ref.png +++ b/test/mask.svg11.rgb24.ref.png diff --git a/test/mask.svg12.argb32.ref.png b/test/mask.svg12.argb32.ref.png Binary files differindex c5828591..3ce4d53f 100644 --- a/test/mask.svg12.argb32.ref.png +++ b/test/mask.svg12.argb32.ref.png diff --git a/test/mask.svg12.rgb24.ref.png b/test/mask.svg12.rgb24.ref.png Binary files differindex 79957237..94e38009 100644 --- a/test/mask.svg12.rgb24.ref.png +++ b/test/mask.svg12.rgb24.ref.png diff --git a/test/mask.test-fallback.argb32.ref.png b/test/mask.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..bba0f9f3 --- /dev/null +++ b/test/mask.test-fallback.argb32.ref.png diff --git a/test/mask.test-fallback.rgb24.ref.png b/test/mask.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..49a5b364 --- /dev/null +++ b/test/mask.test-fallback.rgb24.ref.png diff --git a/test/mask.xlib-fallback.rgb24.ref.png b/test/mask.xlib-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..34400504 --- /dev/null +++ b/test/mask.xlib-fallback.rgb24.ref.png diff --git a/test/mask.xlib.ref.png b/test/mask.xlib.ref.png Binary files differnew file mode 100644 index 00000000..549c130c --- /dev/null +++ b/test/mask.xlib.ref.png diff --git a/test/mask.xlib.rgb24.ref.png b/test/mask.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..70323672 --- /dev/null +++ b/test/mask.xlib.rgb24.ref.png diff --git a/test/meta-surface-pattern.pdf.argb32.ref.png b/test/meta-surface-pattern.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..2ee9b7da --- /dev/null +++ b/test/meta-surface-pattern.pdf.argb32.ref.png diff --git a/test/meta-surface-pattern.pdf.rgb24.ref.png b/test/meta-surface-pattern.pdf.rgb24.ref.png Binary files differindex 680f0f50..6555a265 100644 --- a/test/meta-surface-pattern.pdf.rgb24.ref.png +++ b/test/meta-surface-pattern.pdf.rgb24.ref.png diff --git a/test/meta-surface-pattern.svg11.argb32.ref.png b/test/meta-surface-pattern.svg11.argb32.ref.png Binary files differindex 6250f26c..99695748 100644 --- a/test/meta-surface-pattern.svg11.argb32.ref.png +++ b/test/meta-surface-pattern.svg11.argb32.ref.png diff --git a/test/meta-surface-pattern.svg11.rgb24.ref.png b/test/meta-surface-pattern.svg11.rgb24.ref.png Binary files differindex feda67da..dea9b9b5 100644 --- a/test/meta-surface-pattern.svg11.rgb24.ref.png +++ b/test/meta-surface-pattern.svg11.rgb24.ref.png diff --git a/test/meta-surface-pattern.svg12.argb32.ref.png b/test/meta-surface-pattern.svg12.argb32.ref.png Binary files differindex 6250f26c..99695748 100644 --- a/test/meta-surface-pattern.svg12.argb32.ref.png +++ b/test/meta-surface-pattern.svg12.argb32.ref.png diff --git a/test/meta-surface-pattern.svg12.rgb24.ref.png b/test/meta-surface-pattern.svg12.rgb24.ref.png Binary files differindex feda67da..dea9b9b5 100644 --- a/test/meta-surface-pattern.svg12.rgb24.ref.png +++ b/test/meta-surface-pattern.svg12.rgb24.ref.png diff --git a/test/operator-clear.pdf.argb32.ref.png b/test/operator-clear.pdf.argb32.ref.png Binary files differindex 06fc51e3..258c61c9 100644 --- a/test/operator-clear.pdf.argb32.ref.png +++ b/test/operator-clear.pdf.argb32.ref.png diff --git a/test/operator-clear.ps2.argb32.ref.png b/test/operator-clear.ps2.argb32.ref.png Binary files differnew file mode 100644 index 00000000..92b41111 --- /dev/null +++ b/test/operator-clear.ps2.argb32.ref.png diff --git a/test/operator-clear.ps3.argb32.ref.png b/test/operator-clear.ps3.argb32.ref.png Binary files differnew file mode 100644 index 00000000..92b41111 --- /dev/null +++ b/test/operator-clear.ps3.argb32.ref.png diff --git a/test/operator-source.pdf.argb32.ref.png b/test/operator-source.pdf.argb32.ref.png Binary files differindex f110ff2a..f42d5af4 100644 --- a/test/operator-source.pdf.argb32.ref.png +++ b/test/operator-source.pdf.argb32.ref.png diff --git a/test/operator-source.pdf.rgb24.ref.png b/test/operator-source.pdf.rgb24.ref.png Binary files differindex c6b71705..8269bc10 100644 --- a/test/operator-source.pdf.rgb24.ref.png +++ b/test/operator-source.pdf.rgb24.ref.png diff --git a/test/operator-source.ref.png b/test/operator-source.ref.png Binary files differindex 8e2f5e61..006bf950 100644 --- a/test/operator-source.ref.png +++ b/test/operator-source.ref.png diff --git a/test/operator-source.rgb24.ref.png b/test/operator-source.rgb24.ref.png Binary files differindex a762d60a..013d8a42 100644 --- a/test/operator-source.rgb24.ref.png +++ b/test/operator-source.rgb24.ref.png diff --git a/test/operator-source.test-fallback.argb32.ref.png b/test/operator-source.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..8aac39d1 --- /dev/null +++ b/test/operator-source.test-fallback.argb32.ref.png diff --git a/test/operator-source.test-fallback.rgb24.ref.png b/test/operator-source.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..ad37a60b --- /dev/null +++ b/test/operator-source.test-fallback.rgb24.ref.png diff --git a/test/operator-source.xlib-fallback.rgb24.ref.png b/test/operator-source.xlib-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..fe0d3c61 --- /dev/null +++ b/test/operator-source.xlib-fallback.rgb24.ref.png diff --git a/test/operator-source.xlib.ref.png b/test/operator-source.xlib.ref.png Binary files differnew file mode 100644 index 00000000..8e2f5e61 --- /dev/null +++ b/test/operator-source.xlib.ref.png diff --git a/test/operator-source.xlib.rgb24.ref.png b/test/operator-source.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..a762d60a --- /dev/null +++ b/test/operator-source.xlib.rgb24.ref.png diff --git a/test/over-above-source.ps2.argb32.ref.png b/test/over-above-source.ps2.argb32.ref.png Binary files differindex 886faad4..7c90d086 100644 --- a/test/over-above-source.ps2.argb32.ref.png +++ b/test/over-above-source.ps2.argb32.ref.png diff --git a/test/over-above-source.ps3.argb32.ref.png b/test/over-above-source.ps3.argb32.ref.png Binary files differindex 886faad4..7c90d086 100644 --- a/test/over-above-source.ps3.argb32.ref.png +++ b/test/over-above-source.ps3.argb32.ref.png diff --git a/test/over-above-source.ref.png b/test/over-above-source.ref.png Binary files differindex f3a49f61..c45fcbde 100644 --- a/test/over-above-source.ref.png +++ b/test/over-above-source.ref.png diff --git a/test/over-above-source.rgb24.ref.png b/test/over-above-source.rgb24.ref.png Binary files differindex 68c7d982..84fc880c 100644 --- a/test/over-above-source.rgb24.ref.png +++ b/test/over-above-source.rgb24.ref.png diff --git a/test/over-above-source.test-fallback.argb32.ref.png b/test/over-above-source.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..8a0183a6 --- /dev/null +++ b/test/over-above-source.test-fallback.argb32.ref.png diff --git a/test/over-above-source.test-fallback.rgb24.ref.png b/test/over-above-source.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..85c19971 --- /dev/null +++ b/test/over-above-source.test-fallback.rgb24.ref.png diff --git a/test/over-above-source.xlib.ref.png b/test/over-above-source.xlib.ref.png Binary files differnew file mode 100644 index 00000000..f3a49f61 --- /dev/null +++ b/test/over-above-source.xlib.ref.png diff --git a/test/over-above-source.xlib.rgb24.ref.png b/test/over-above-source.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..68c7d982 --- /dev/null +++ b/test/over-above-source.xlib.rgb24.ref.png diff --git a/test/over-around-source.pdf.argb32.ref.png b/test/over-around-source.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..02af76a9 --- /dev/null +++ b/test/over-around-source.pdf.argb32.ref.png diff --git a/test/over-around-source.ps2.argb32.ref.png b/test/over-around-source.ps2.argb32.ref.png Binary files differindex ea6de696..647420ad 100644 --- a/test/over-around-source.ps2.argb32.ref.png +++ b/test/over-around-source.ps2.argb32.ref.png diff --git a/test/over-around-source.ps3.argb32.ref.png b/test/over-around-source.ps3.argb32.ref.png Binary files differindex ea6de696..647420ad 100644 --- a/test/over-around-source.ps3.argb32.ref.png +++ b/test/over-around-source.ps3.argb32.ref.png diff --git a/test/over-around-source.ref.png b/test/over-around-source.ref.png Binary files differindex ccae9514..abaeb4e4 100644 --- a/test/over-around-source.ref.png +++ b/test/over-around-source.ref.png diff --git a/test/over-around-source.test-fallback.argb32.ref.png b/test/over-around-source.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..fca75056 --- /dev/null +++ b/test/over-around-source.test-fallback.argb32.ref.png diff --git a/test/over-around-source.xlib.ref.png b/test/over-around-source.xlib.ref.png Binary files differnew file mode 100644 index 00000000..ccae9514 --- /dev/null +++ b/test/over-around-source.xlib.ref.png diff --git a/test/over-around-source.xlib.rgb24.ref.png b/test/over-around-source.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..943a28e3 --- /dev/null +++ b/test/over-around-source.xlib.rgb24.ref.png diff --git a/test/over-below-source.pdf.argb32.ref.png b/test/over-below-source.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..b9c4fe28 --- /dev/null +++ b/test/over-below-source.pdf.argb32.ref.png diff --git a/test/over-between-source.ps2.argb32.ref.png b/test/over-between-source.ps2.argb32.ref.png Binary files differindex 43e9424b..dd95940a 100644 --- a/test/over-between-source.ps2.argb32.ref.png +++ b/test/over-between-source.ps2.argb32.ref.png diff --git a/test/over-between-source.ps3.argb32.ref.png b/test/over-between-source.ps3.argb32.ref.png Binary files differindex 43e9424b..dd95940a 100644 --- a/test/over-between-source.ps3.argb32.ref.png +++ b/test/over-between-source.ps3.argb32.ref.png diff --git a/test/over-between-source.ref.png b/test/over-between-source.ref.png Binary files differindex 79ea75e9..0c3986fc 100644 --- a/test/over-between-source.ref.png +++ b/test/over-between-source.ref.png diff --git a/test/over-between-source.test-fallback.argb32.ref.png b/test/over-between-source.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..a8fe66a3 --- /dev/null +++ b/test/over-between-source.test-fallback.argb32.ref.png diff --git a/test/over-between-source.xlib.ref.png b/test/over-between-source.xlib.ref.png Binary files differnew file mode 100644 index 00000000..79ea75e9 --- /dev/null +++ b/test/over-between-source.xlib.ref.png diff --git a/test/over-between-source.xlib.rgb24.ref.png b/test/over-between-source.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..602f2d26 --- /dev/null +++ b/test/over-between-source.xlib.rgb24.ref.png diff --git a/test/push-group.pdf.argb32.ref.png b/test/push-group.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..9cb59c94 --- /dev/null +++ b/test/push-group.pdf.argb32.ref.png diff --git a/test/push-group.pdf.rgb24.ref.png b/test/push-group.pdf.rgb24.ref.png Binary files differindex 7e84ec83..34d7f74e 100644 --- a/test/push-group.pdf.rgb24.ref.png +++ b/test/push-group.pdf.rgb24.ref.png diff --git a/test/push-group.ref.png b/test/push-group.ref.png Binary files differindex 84bc184d..e4ae291f 100644 --- a/test/push-group.ref.png +++ b/test/push-group.ref.png diff --git a/test/push-group.rgb24.ref.png b/test/push-group.rgb24.ref.png Binary files differindex cababd95..3a951827 100644 --- a/test/push-group.rgb24.ref.png +++ b/test/push-group.rgb24.ref.png diff --git a/test/push-group.svg11.argb32.ref.png b/test/push-group.svg11.argb32.ref.png Binary files differindex 34f06bf7..d6958798 100644 --- a/test/push-group.svg11.argb32.ref.png +++ b/test/push-group.svg11.argb32.ref.png diff --git a/test/push-group.svg12.argb32.ref.png b/test/push-group.svg12.argb32.ref.png Binary files differindex 34f06bf7..d6958798 100644 --- a/test/push-group.svg12.argb32.ref.png +++ b/test/push-group.svg12.argb32.ref.png diff --git a/test/push-group.test-fallback.argb32.ref.png b/test/push-group.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..7c5905a6 --- /dev/null +++ b/test/push-group.test-fallback.argb32.ref.png diff --git a/test/push-group.test-fallback.rgb24.ref.png b/test/push-group.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..4586d5c5 --- /dev/null +++ b/test/push-group.test-fallback.rgb24.ref.png diff --git a/test/push-group.xlib-fallback.rgb24.ref.png b/test/push-group.xlib-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3a951827 --- /dev/null +++ b/test/push-group.xlib-fallback.rgb24.ref.png diff --git a/test/push-group.xlib.ref.png b/test/push-group.xlib.ref.png Binary files differnew file mode 100644 index 00000000..84bc184d --- /dev/null +++ b/test/push-group.xlib.ref.png diff --git a/test/push-group.xlib.rgb24.ref.png b/test/push-group.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..cababd95 --- /dev/null +++ b/test/push-group.xlib.rgb24.ref.png diff --git a/test/quartz-surface-source.c b/test/quartz-surface-source.c new file mode 100644 index 00000000..b0c86d0f --- /dev/null +++ b/test/quartz-surface-source.c @@ -0,0 +1,42 @@ +/* + * Copyright © 2008 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 <chris@chris-wilson.co.uk> + */ + +#include "cairo-test.h" +#include "cairo-quartz.h" + +#include "surface-source.c" + +static cairo_surface_t * +create_source_surface (int size) +{ + return cairo_quartz_surface_create (CAIRO_FORMAT_ARGB32, size, size); +} + +CAIRO_TEST (quartz_surface_source, + "Test using a Quartz surface as the source", + "source", /* keywords */ + NULL, /* requirements */ + SIZE, SIZE, + preamble, draw) diff --git a/test/quartz-surface-source.ps2.ref.png b/test/quartz-surface-source.ps2.ref.png Binary files differnew file mode 100644 index 00000000..10231581 --- /dev/null +++ b/test/quartz-surface-source.ps2.ref.png diff --git a/test/quartz-surface-source.ps3.ref.png b/test/quartz-surface-source.ps3.ref.png Binary files differnew file mode 100644 index 00000000..10231581 --- /dev/null +++ b/test/quartz-surface-source.ps3.ref.png diff --git a/test/quartz-surface-source.ref.png b/test/quartz-surface-source.ref.png Binary files differnew file mode 100644 index 00000000..9fbbedd5 --- /dev/null +++ b/test/quartz-surface-source.ref.png diff --git a/test/radial-gradient.pdf.argb32.ref.png b/test/radial-gradient.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..6cee5d12 --- /dev/null +++ b/test/radial-gradient.pdf.argb32.ref.png diff --git a/test/radial-gradient.pdf.rgb24.ref.png b/test/radial-gradient.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..6cee5d12 --- /dev/null +++ b/test/radial-gradient.pdf.rgb24.ref.png diff --git a/test/random-intersections.ref.png b/test/random-intersections.ref.png Binary files differindex 3188edef..ace75a24 100644 --- a/test/random-intersections.ref.png +++ b/test/random-intersections.ref.png diff --git a/test/random-intersections.test-fallback.argb32.ref.png b/test/random-intersections.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..a35364d8 --- /dev/null +++ b/test/random-intersections.test-fallback.argb32.ref.png diff --git a/test/random-intersections.test-fallback.rgb24.ref.png b/test/random-intersections.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..a35364d8 --- /dev/null +++ b/test/random-intersections.test-fallback.rgb24.ref.png diff --git a/test/random-intersections.xlib.ref.png b/test/random-intersections.xlib.ref.png Binary files differnew file mode 100644 index 00000000..3188edef --- /dev/null +++ b/test/random-intersections.xlib.ref.png diff --git a/test/rotate-image-surface-paint.pdf.argb32.ref.png b/test/rotate-image-surface-paint.pdf.argb32.ref.png Binary files differindex c12ae8fd..93fab525 100644 --- a/test/rotate-image-surface-paint.pdf.argb32.ref.png +++ b/test/rotate-image-surface-paint.pdf.argb32.ref.png diff --git a/test/rotate-image-surface-paint.pdf.rgb24.ref.png b/test/rotate-image-surface-paint.pdf.rgb24.ref.png Binary files differindex 5cd7bf61..93fab525 100644 --- a/test/rotate-image-surface-paint.pdf.rgb24.ref.png +++ b/test/rotate-image-surface-paint.pdf.rgb24.ref.png diff --git a/test/smask-fill.pdf.argb32.ref.png b/test/smask-fill.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..51d34d43 --- /dev/null +++ b/test/smask-fill.pdf.argb32.ref.png diff --git a/test/smask-fill.pdf.rgb24.ref.png b/test/smask-fill.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..51d34d43 --- /dev/null +++ b/test/smask-fill.pdf.rgb24.ref.png diff --git a/test/smask-fill.ref.png b/test/smask-fill.ref.png Binary files differindex c778a791..28ab7338 100644 --- a/test/smask-fill.ref.png +++ b/test/smask-fill.ref.png diff --git a/test/smask-fill.svg11.argb32.ref.png b/test/smask-fill.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..57ae76e6 --- /dev/null +++ b/test/smask-fill.svg11.argb32.ref.png diff --git a/test/smask-fill.svg11.rgb24.ref.png b/test/smask-fill.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..57ae76e6 --- /dev/null +++ b/test/smask-fill.svg11.rgb24.ref.png diff --git a/test/smask-fill.svg12.argb32.ref.png b/test/smask-fill.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..57ae76e6 --- /dev/null +++ b/test/smask-fill.svg12.argb32.ref.png diff --git a/test/smask-fill.svg12.rgb24.ref.png b/test/smask-fill.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..57ae76e6 --- /dev/null +++ b/test/smask-fill.svg12.rgb24.ref.png diff --git a/test/smask-fill.test-fallback.argb32.ref.png b/test/smask-fill.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..3d375bba --- /dev/null +++ b/test/smask-fill.test-fallback.argb32.ref.png diff --git a/test/smask-fill.test-fallback.rgb24.ref.png b/test/smask-fill.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3d375bba --- /dev/null +++ b/test/smask-fill.test-fallback.rgb24.ref.png diff --git a/test/smask-fill.xlib-fallback.ref.png b/test/smask-fill.xlib-fallback.ref.png Binary files differnew file mode 100644 index 00000000..28ab7338 --- /dev/null +++ b/test/smask-fill.xlib-fallback.ref.png diff --git a/test/smask-fill.xlib.ref.png b/test/smask-fill.xlib.ref.png Binary files differnew file mode 100644 index 00000000..c778a791 --- /dev/null +++ b/test/smask-fill.xlib.ref.png diff --git a/test/smask-image-mask.pdf.argb32.ref.png b/test/smask-image-mask.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..19a20f48 --- /dev/null +++ b/test/smask-image-mask.pdf.argb32.ref.png diff --git a/test/smask-image-mask.pdf.rgb24.ref.png b/test/smask-image-mask.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..19a20f48 --- /dev/null +++ b/test/smask-image-mask.pdf.rgb24.ref.png diff --git a/test/smask-mask.pdf.argb32.ref.png b/test/smask-mask.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0dc2135d --- /dev/null +++ b/test/smask-mask.pdf.argb32.ref.png diff --git a/test/smask-mask.pdf.rgb24.ref.png b/test/smask-mask.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..0dc2135d --- /dev/null +++ b/test/smask-mask.pdf.rgb24.ref.png diff --git a/test/smask-paint.pdf.argb32.ref.png b/test/smask-paint.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..c6b1731f --- /dev/null +++ b/test/smask-paint.pdf.argb32.ref.png diff --git a/test/smask-paint.pdf.rgb24.ref.png b/test/smask-paint.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..c6b1731f --- /dev/null +++ b/test/smask-paint.pdf.rgb24.ref.png diff --git a/test/smask-stroke.pdf.argb32.ref.png b/test/smask-stroke.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..41321f23 --- /dev/null +++ b/test/smask-stroke.pdf.argb32.ref.png diff --git a/test/smask-stroke.pdf.rgb24.ref.png b/test/smask-stroke.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..41321f23 --- /dev/null +++ b/test/smask-stroke.pdf.rgb24.ref.png diff --git a/test/smask-text.svg11.argb32.ref.png b/test/smask-text.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..5034526a --- /dev/null +++ b/test/smask-text.svg11.argb32.ref.png diff --git a/test/smask-text.svg11.rgb24.ref.png b/test/smask-text.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..5034526a --- /dev/null +++ b/test/smask-text.svg11.rgb24.ref.png diff --git a/test/smask-text.svg12.argb32.ref.png b/test/smask-text.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..5034526a --- /dev/null +++ b/test/smask-text.svg12.argb32.ref.png diff --git a/test/smask-text.svg12.rgb24.ref.png b/test/smask-text.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..5034526a --- /dev/null +++ b/test/smask-text.svg12.rgb24.ref.png diff --git a/test/smask.pdf.argb32.ref.png b/test/smask.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..c6b1731f --- /dev/null +++ b/test/smask.pdf.argb32.ref.png diff --git a/test/smask.pdf.rgb24.ref.png b/test/smask.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..c6b1731f --- /dev/null +++ b/test/smask.pdf.rgb24.ref.png diff --git a/test/surface-pattern-scale-down.pdf.argb32.ref.png b/test/surface-pattern-scale-down.pdf.argb32.ref.png Binary files differindex c29d804c..dc4b3a31 100644 --- a/test/surface-pattern-scale-down.pdf.argb32.ref.png +++ b/test/surface-pattern-scale-down.pdf.argb32.ref.png diff --git a/test/surface-pattern-scale-down.pdf.rgb24.ref.png b/test/surface-pattern-scale-down.pdf.rgb24.ref.png Binary files differindex c29d804c..dc4b3a31 100644 --- a/test/surface-pattern-scale-down.pdf.rgb24.ref.png +++ b/test/surface-pattern-scale-down.pdf.rgb24.ref.png diff --git a/test/surface-pattern-scale-up.pdf.argb32.ref.png b/test/surface-pattern-scale-up.pdf.argb32.ref.png Binary files differindex 6f3a53c5..c0a2896a 100644 --- a/test/surface-pattern-scale-up.pdf.argb32.ref.png +++ b/test/surface-pattern-scale-up.pdf.argb32.ref.png diff --git a/test/surface-pattern-scale-up.pdf.rgb24.ref.png b/test/surface-pattern-scale-up.pdf.rgb24.ref.png Binary files differindex 6f3a53c5..c0a2896a 100644 --- a/test/surface-pattern-scale-up.pdf.rgb24.ref.png +++ b/test/surface-pattern-scale-up.pdf.rgb24.ref.png diff --git a/test/surface-pattern.pdf.argb32.ref.png b/test/surface-pattern.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..70a44767 --- /dev/null +++ b/test/surface-pattern.pdf.argb32.ref.png diff --git a/test/surface-pattern.pdf.rgb24.ref.png b/test/surface-pattern.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..70a44767 --- /dev/null +++ b/test/surface-pattern.pdf.rgb24.ref.png diff --git a/test/text-pattern.pdf.argb32.ref.png b/test/text-pattern.pdf.argb32.ref.png Binary files differindex 2a70deb0..dfaed39f 100644 --- a/test/text-pattern.pdf.argb32.ref.png +++ b/test/text-pattern.pdf.argb32.ref.png diff --git a/test/text-pattern.svg11.argb32.ref.png b/test/text-pattern.svg11.argb32.ref.png Binary files differindex 97d7534c..47ee89c2 100644 --- a/test/text-pattern.svg11.argb32.ref.png +++ b/test/text-pattern.svg11.argb32.ref.png diff --git a/test/text-pattern.svg12.argb32.ref.png b/test/text-pattern.svg12.argb32.ref.png Binary files differindex 97d7534c..47ee89c2 100644 --- a/test/text-pattern.svg12.argb32.ref.png +++ b/test/text-pattern.svg12.argb32.ref.png diff --git a/test/text-rotate.svg11.argb32.ref.png b/test/text-rotate.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..4864046f --- /dev/null +++ b/test/text-rotate.svg11.argb32.ref.png diff --git a/test/text-rotate.svg11.rgb24.ref.png b/test/text-rotate.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..4864046f --- /dev/null +++ b/test/text-rotate.svg11.rgb24.ref.png diff --git a/test/text-rotate.svg12.argb32.ref.png b/test/text-rotate.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..4864046f --- /dev/null +++ b/test/text-rotate.svg12.argb32.ref.png diff --git a/test/text-rotate.svg12.rgb24.ref.png b/test/text-rotate.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..4864046f --- /dev/null +++ b/test/text-rotate.svg12.rgb24.ref.png diff --git a/test/text-transform.svg11.argb32.ref.png b/test/text-transform.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0c4e57cc --- /dev/null +++ b/test/text-transform.svg11.argb32.ref.png diff --git a/test/text-transform.svg11.rgb24.ref.png b/test/text-transform.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..0c4e57cc --- /dev/null +++ b/test/text-transform.svg11.rgb24.ref.png diff --git a/test/text-transform.svg12.argb32.ref.png b/test/text-transform.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0c4e57cc --- /dev/null +++ b/test/text-transform.svg12.argb32.ref.png diff --git a/test/text-transform.svg12.rgb24.ref.png b/test/text-transform.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..0c4e57cc --- /dev/null +++ b/test/text-transform.svg12.rgb24.ref.png diff --git a/test/trap-clip.pdf.argb32.ref.png b/test/trap-clip.pdf.argb32.ref.png Binary files differindex c3ee9971..15010164 100644 --- a/test/trap-clip.pdf.argb32.ref.png +++ b/test/trap-clip.pdf.argb32.ref.png diff --git a/test/trap-clip.pdf.rgb24.ref.png b/test/trap-clip.pdf.rgb24.ref.png Binary files differindex f787011c..06163675 100644 --- a/test/trap-clip.pdf.rgb24.ref.png +++ b/test/trap-clip.pdf.rgb24.ref.png diff --git a/test/trap-clip.ps2.argb32.ref.png b/test/trap-clip.ps2.argb32.ref.png Binary files differindex 37121cde..957b9382 100644 --- a/test/trap-clip.ps2.argb32.ref.png +++ b/test/trap-clip.ps2.argb32.ref.png diff --git a/test/trap-clip.ref.png b/test/trap-clip.ref.png Binary files differindex 2cbbdb76..e8c26d32 100644 --- a/test/trap-clip.ref.png +++ b/test/trap-clip.ref.png diff --git a/test/trap-clip.rgb24.ref.png b/test/trap-clip.rgb24.ref.png Binary files differindex 15068aa5..e61992ff 100644 --- a/test/trap-clip.rgb24.ref.png +++ b/test/trap-clip.rgb24.ref.png diff --git a/test/trap-clip.test-fallback.argb32.ref.png b/test/trap-clip.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..319d8356 --- /dev/null +++ b/test/trap-clip.test-fallback.argb32.ref.png diff --git a/test/trap-clip.test-fallback.rgb24.ref.png b/test/trap-clip.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..7ac5789b --- /dev/null +++ b/test/trap-clip.test-fallback.rgb24.ref.png diff --git a/test/trap-clip.test-paginated.argb32.ref.png b/test/trap-clip.test-paginated.argb32.ref.png Binary files differnew file mode 100644 index 00000000..dee57e7b --- /dev/null +++ b/test/trap-clip.test-paginated.argb32.ref.png diff --git a/test/trap-clip.xlib.ref.png b/test/trap-clip.xlib.ref.png Binary files differnew file mode 100644 index 00000000..2cbbdb76 --- /dev/null +++ b/test/trap-clip.xlib.ref.png diff --git a/test/trap-clip.xlib.rgb24.ref.png b/test/trap-clip.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..15068aa5 --- /dev/null +++ b/test/trap-clip.xlib.rgb24.ref.png diff --git a/test/twin.svg11.argb32.ref.png b/test/twin.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0818c67c --- /dev/null +++ b/test/twin.svg11.argb32.ref.png diff --git a/test/twin.svg11.rgb24.ref.png b/test/twin.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..0818c67c --- /dev/null +++ b/test/twin.svg11.rgb24.ref.png diff --git a/test/twin.svg12.argb32.ref.png b/test/twin.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0818c67c --- /dev/null +++ b/test/twin.svg12.argb32.ref.png diff --git a/test/twin.svg12.rgb24.ref.png b/test/twin.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..0818c67c --- /dev/null +++ b/test/twin.svg12.rgb24.ref.png diff --git a/test/unbounded-operator.pdf.argb32.ref.png b/test/unbounded-operator.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..4aa476de --- /dev/null +++ b/test/unbounded-operator.pdf.argb32.ref.png diff --git a/test/unbounded-operator.ps2.argb32.ref.png b/test/unbounded-operator.ps2.argb32.ref.png Binary files differnew file mode 100644 index 00000000..4aa476de --- /dev/null +++ b/test/unbounded-operator.ps2.argb32.ref.png diff --git a/test/unbounded-operator.ps3.argb32.ref.png b/test/unbounded-operator.ps3.argb32.ref.png Binary files differnew file mode 100644 index 00000000..4aa476de --- /dev/null +++ b/test/unbounded-operator.ps3.argb32.ref.png diff --git a/test/unbounded-operator.rgb24.ref.png b/test/unbounded-operator.rgb24.ref.png Binary files differindex b2f1a84d..ad3225d0 100644 --- a/test/unbounded-operator.rgb24.ref.png +++ b/test/unbounded-operator.rgb24.ref.png diff --git a/test/unbounded-operator.test-fallback.rgb24.ref.png b/test/unbounded-operator.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..07c7ecff --- /dev/null +++ b/test/unbounded-operator.test-fallback.rgb24.ref.png diff --git a/test/unbounded-operator.xlib.rgb24.ref.png b/test/unbounded-operator.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..b2f1a84d --- /dev/null +++ b/test/unbounded-operator.xlib.rgb24.ref.png diff --git a/test/user-font-proxy.pdf.argb32.ref.png b/test/user-font-proxy.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..cffa9edb --- /dev/null +++ b/test/user-font-proxy.pdf.argb32.ref.png diff --git a/test/user-font-proxy.pdf.rgb24.ref.png b/test/user-font-proxy.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..cffa9edb --- /dev/null +++ b/test/user-font-proxy.pdf.rgb24.ref.png diff --git a/test/user-font-proxy.ref.png b/test/user-font-proxy.ref.png Binary files differindex ebd97198..cffa9edb 100644 --- a/test/user-font-proxy.ref.png +++ b/test/user-font-proxy.ref.png diff --git a/test/user-font-proxy.svg11.argb32.ref.png b/test/user-font-proxy.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..d2a7812b --- /dev/null +++ b/test/user-font-proxy.svg11.argb32.ref.png diff --git a/test/user-font-proxy.svg11.rgb24.ref.png b/test/user-font-proxy.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d2a7812b --- /dev/null +++ b/test/user-font-proxy.svg11.rgb24.ref.png diff --git a/test/user-font-proxy.svg12.argb32.ref.png b/test/user-font-proxy.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..d2a7812b --- /dev/null +++ b/test/user-font-proxy.svg12.argb32.ref.png diff --git a/test/user-font-proxy.svg12.rgb24.ref.png b/test/user-font-proxy.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d2a7812b --- /dev/null +++ b/test/user-font-proxy.svg12.rgb24.ref.png diff --git a/test/user-font-proxy.test-fallback.argb32.ref.png b/test/user-font-proxy.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..9cccf312 --- /dev/null +++ b/test/user-font-proxy.test-fallback.argb32.ref.png diff --git a/test/user-font-proxy.test-fallback.rgb24.ref.png b/test/user-font-proxy.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..9cccf312 --- /dev/null +++ b/test/user-font-proxy.test-fallback.rgb24.ref.png diff --git a/test/user-font-proxy.xlib.ref.png b/test/user-font-proxy.xlib.ref.png Binary files differnew file mode 100644 index 00000000..ebd97198 --- /dev/null +++ b/test/user-font-proxy.xlib.ref.png diff --git a/test/user-font.ref.png b/test/user-font.ref.png Binary files differindex abc31171..753fc7bc 100644 --- a/test/user-font.ref.png +++ b/test/user-font.ref.png diff --git a/test/user-font.svg11.argb32.ref.png b/test/user-font.svg11.argb32.ref.png Binary files differnew file mode 100644 index 00000000..3dc77ae4 --- /dev/null +++ b/test/user-font.svg11.argb32.ref.png diff --git a/test/user-font.svg11.rgb24.ref.png b/test/user-font.svg11.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3dc77ae4 --- /dev/null +++ b/test/user-font.svg11.rgb24.ref.png diff --git a/test/user-font.svg12.argb32.ref.png b/test/user-font.svg12.argb32.ref.png Binary files differnew file mode 100644 index 00000000..3dc77ae4 --- /dev/null +++ b/test/user-font.svg12.argb32.ref.png diff --git a/test/user-font.svg12.rgb24.ref.png b/test/user-font.svg12.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3dc77ae4 --- /dev/null +++ b/test/user-font.svg12.rgb24.ref.png diff --git a/test/user-font.test-fallback.argb32.ref.png b/test/user-font.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..3080c694 --- /dev/null +++ b/test/user-font.test-fallback.argb32.ref.png diff --git a/test/user-font.test-fallback.rgb24.ref.png b/test/user-font.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3080c694 --- /dev/null +++ b/test/user-font.test-fallback.rgb24.ref.png diff --git a/test/user-font.xlib.ref.png b/test/user-font.xlib.ref.png Binary files differnew file mode 100644 index 00000000..abc31171 --- /dev/null +++ b/test/user-font.xlib.ref.png diff --git a/util/cairo-script/Makefile.am b/util/cairo-script/Makefile.am index 4d228128..b6ab355e 100644 --- a/util/cairo-script/Makefile.am +++ b/util/cairo-script/Makefile.am @@ -17,10 +17,10 @@ libcairo_script_interpreter_la_SOURCES = \ $(NULL) libcairo_script_interpreter_la_CFLAGS = $(CAIRO_CFLAGS) libcairo_script_interpreter_la_LDFLAGS = -version-info $(CAIRO_LIBTOOL_VERSION_INFO) -no-undefined $(export_symbols) -libcairo_script_interpreter_la_LIBADD = -lz $(CAIRO_LIBS) -L$(top_builddir)/src -lcairo +libcairo_script_interpreter_la_LIBADD = $(top_builddir)/src/libcairo.la $(CAIRO_LIBS) csi_replay_SOURCES = csi-replay.c -csi_replay_LDADD = libcairo-script-interpreter.la $(top_builddir)/src/libcairo.la +csi_replay_LDADD = libcairo-script-interpreter.la $(top_builddir)/src/libcairo.la $(CAIRO_LIBS) EXTRA_DIST = \ COPYING diff --git a/util/cairo-script/cairo-script-file.c b/util/cairo-script/cairo-script-file.c index c21ef630..fcdccf14 100644 --- a/util/cairo-script/cairo-script-file.c +++ b/util/cairo-script/cairo-script-file.c @@ -36,7 +36,6 @@ #include <stdio.h> #include <string.h> -#include <zlib.h> #define CHUNK_SIZE 32768 @@ -372,6 +371,9 @@ csi_file_new_ascii85_decode (csi_t *ctx, return _csi_file_new_filter (ctx, obj, src, &funcs, data); } +#if HAVE_ZLIB +#include <zlib.h> + typedef struct _deflate_decode_data { z_stream zlib_stream; @@ -503,6 +505,7 @@ csi_file_new_deflate_decode (csi_t *ctx, return _csi_file_new_filter (ctx, obj, src, &funcs, data); } +#endif #if 0 static int diff --git a/util/cairo-script/cairo-script-operators.c b/util/cairo-script/cairo-script-operators.c index a70b55d5..13d6f766 100644 --- a/util/cairo-script/cairo-script-operators.c +++ b/util/cairo-script/cairo-script-operators.c @@ -1317,7 +1317,9 @@ _filter (csi_t *ctx) csi_object_t *); } filters[] = { { "ascii85", csi_file_new_ascii85_decode }, +#if HAVE_ZLIB { "deflate", csi_file_new_deflate_decode }, +#endif #if 0 { "lzw", csi_file_new_lzw_decode }, #endif diff --git a/util/cairo-script/csi-replay.c b/util/cairo-script/csi-replay.c index 5ca035f2..e5a847e4 100644 --- a/util/cairo-script/csi-replay.c +++ b/util/cairo-script/csi-replay.c @@ -68,6 +68,14 @@ _surface_create (void *closure, return surface; } +#else +/* fallback: just use an image surface */ +static cairo_surface_t * +_surface_create (void *closure, + double width, double height) +{ + return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height); +} #endif int |