mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Backed out changeset 3d7b55f16ec5
This commit is contained in:
parent
b051e5a8e1
commit
c9f45bc3f1
@ -874,7 +874,6 @@ _return_success (void)
|
||||
typedef cairo_int_status_t
|
||||
(*_set_clip_region_func) (void *surface,
|
||||
cairo_region_t *region);
|
||||
|
||||
typedef cairo_int_status_t
|
||||
(*_paint_func) (void *surface,
|
||||
cairo_operator_t op,
|
||||
|
@ -352,6 +352,14 @@ _cairo_array_size (cairo_array_t *array)
|
||||
return array->size;
|
||||
}
|
||||
|
||||
/* #cairo_user_data_array_t */
|
||||
|
||||
typedef struct {
|
||||
const cairo_user_data_key_t *key;
|
||||
void *user_data;
|
||||
cairo_destroy_func_t destroy;
|
||||
} cairo_user_data_slot_t;
|
||||
|
||||
/**
|
||||
* _cairo_user_data_array_init:
|
||||
* @array: a #cairo_user_data_array_t
|
||||
|
@ -55,19 +55,6 @@ typedef int cairo_atomic_int_t;
|
||||
# define _cairo_atomic_int_dec_and_test(x) (__sync_fetch_and_add(x, -1) == 1)
|
||||
# define _cairo_atomic_int_cmpxchg(x, oldv, newv) __sync_val_compare_and_swap (x, oldv, newv)
|
||||
|
||||
#if SIZEOF_VOID_P==SIZEOF_INT
|
||||
typedef int cairo_atomic_intptr_t;
|
||||
#elif SIZEOF_VOID_P==SIZEOF_LONG
|
||||
typedef long cairo_atomic_intptr_t;
|
||||
#elif SIZEOF_VOID_P==SIZEOF_LONG_LONG
|
||||
typedef long long cairo_atomic_intptr_t;
|
||||
#else
|
||||
#error No matching integer pointer type
|
||||
#endif
|
||||
|
||||
# define _cairo_atomic_ptr_cmpxchg(x, oldv, newv) \
|
||||
(void*)__sync_val_compare_and_swap ((cairo_atomic_intptr_t*)x, (cairo_atomic_intptr_t)oldv, (cairo_atomic_intptr_t)newv)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -84,9 +71,6 @@ _cairo_atomic_int_dec_and_test (int *x);
|
||||
cairo_private int
|
||||
_cairo_atomic_int_cmpxchg (int *x, int oldv, int newv);
|
||||
|
||||
cairo_private void *
|
||||
_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -107,9 +91,6 @@ _cairo_atomic_int_set (int *x, int value);
|
||||
|
||||
#endif
|
||||
|
||||
#define _cairo_atomic_uint_get(x) _cairo_atomic_int_get(x)
|
||||
#define _cairo_atomic_uint_cmpxchg(x, oldv, newv) \
|
||||
_cairo_atomic_int_cmpxchg((int *)x, oldv, newv)
|
||||
|
||||
#define _cairo_status_set_error(status, err) do { \
|
||||
/* hide compiler warnings about cairo_status_t != int (gcc treats its as \
|
||||
|
@ -36,11 +36,7 @@
|
||||
#include "cairo-atomic-private.h"
|
||||
#include "cairo-mutex-private.h"
|
||||
|
||||
#ifdef HAS_ATOMIC_OPS
|
||||
COMPILE_TIME_ASSERT(sizeof(void*) == sizeof(int) ||
|
||||
sizeof(void*) == sizeof(long) ||
|
||||
sizeof(void*) == sizeof(long long));
|
||||
#else
|
||||
#ifndef HAS_ATOMIC_OPS
|
||||
void
|
||||
_cairo_atomic_int_inc (int *x)
|
||||
{
|
||||
@ -75,19 +71,6 @@ _cairo_atomic_int_cmpxchg (int *x, int oldv, int newv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *
|
||||
_cairo_atomic_ptr_cmpxchg (void **x, void *oldv, void *newv)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_atomic_mutex);
|
||||
ret = *x;
|
||||
if (ret == oldv)
|
||||
*x = newv;
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_atomic_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ATOMIC_OP_NEEDS_MEMORY_BARRIER
|
||||
|
@ -88,20 +88,6 @@ typedef struct _cairo_cache_entry {
|
||||
unsigned long size;
|
||||
} cairo_cache_entry_t;
|
||||
|
||||
typedef cairo_bool_t (*cairo_cache_predicate_func_t) (const void *entry);
|
||||
|
||||
struct _cairo_cache {
|
||||
cairo_hash_table_t *hash_table;
|
||||
|
||||
cairo_cache_predicate_func_t predicate;
|
||||
cairo_destroy_func_t entry_destroy;
|
||||
|
||||
unsigned long max_size;
|
||||
unsigned long size;
|
||||
|
||||
int freeze_count;
|
||||
};
|
||||
|
||||
typedef cairo_bool_t
|
||||
(*cairo_cache_keys_equal_func_t) (const void *key_a, const void *key_b);
|
||||
|
||||
@ -109,15 +95,14 @@ typedef void
|
||||
(*cairo_cache_callback_func_t) (void *entry,
|
||||
void *closure);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_cache_init (cairo_cache_t *cache,
|
||||
cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_cache_predicate_func_t predicate,
|
||||
cairo_destroy_func_t entry_destroy,
|
||||
unsigned long max_size);
|
||||
cairo_private cairo_cache_t *
|
||||
_cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_cache_predicate_func_t predicate,
|
||||
cairo_destroy_func_t entry_destroy,
|
||||
unsigned long max_size);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_fini (cairo_cache_t *cache);
|
||||
_cairo_cache_destroy (cairo_cache_t *cache);
|
||||
|
||||
cairo_private void
|
||||
_cairo_cache_freeze (cairo_cache_t *cache);
|
||||
|
@ -48,10 +48,48 @@ _cairo_cache_entry_is_non_zero (const void *entry)
|
||||
return ((const cairo_cache_entry_t *) entry)->size;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_cache_init (cairo_cache_t *cache,
|
||||
cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_cache_predicate_func_t predicate,
|
||||
cairo_destroy_func_t entry_destroy,
|
||||
unsigned long max_size)
|
||||
{
|
||||
cache->hash_table = _cairo_hash_table_create (keys_equal);
|
||||
if (unlikely (cache->hash_table == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (predicate == NULL)
|
||||
predicate = _cairo_cache_entry_is_non_zero;
|
||||
cache->predicate = predicate;
|
||||
cache->entry_destroy = entry_destroy;
|
||||
|
||||
cache->max_size = max_size;
|
||||
cache->size = 0;
|
||||
|
||||
cache->freeze_count = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_cache_pluck (void *entry, void *closure)
|
||||
{
|
||||
_cairo_cache_remove (closure, entry);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_cache_fini (cairo_cache_t *cache)
|
||||
{
|
||||
_cairo_hash_table_foreach (cache->hash_table,
|
||||
_cairo_cache_pluck,
|
||||
cache);
|
||||
assert (cache->size == 0);
|
||||
_cairo_hash_table_destroy (cache->hash_table);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_init:
|
||||
* @cache: the #cairo_cache_t to initialise
|
||||
* _cairo_cache_create:
|
||||
* @keys_equal: a function to return %TRUE if two keys are equal
|
||||
* @entry_destroy: destroy notifier for cache entries
|
||||
* @max_size: the maximum size for this cache
|
||||
@ -84,53 +122,49 @@ _cairo_cache_entry_is_non_zero (const void *entry)
|
||||
* used to establish a window during which no automatic removal of
|
||||
* entries will occur.
|
||||
**/
|
||||
cairo_status_t
|
||||
_cairo_cache_init (cairo_cache_t *cache,
|
||||
cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_cache_predicate_func_t predicate,
|
||||
cairo_destroy_func_t entry_destroy,
|
||||
unsigned long max_size)
|
||||
cairo_cache_t *
|
||||
_cairo_cache_create (cairo_cache_keys_equal_func_t keys_equal,
|
||||
cairo_cache_predicate_func_t predicate,
|
||||
cairo_destroy_func_t entry_destroy,
|
||||
unsigned long max_size)
|
||||
{
|
||||
cache->hash_table = _cairo_hash_table_create (keys_equal);
|
||||
if (unlikely (cache->hash_table == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
cairo_status_t status;
|
||||
cairo_cache_t *cache;
|
||||
|
||||
if (predicate == NULL)
|
||||
predicate = _cairo_cache_entry_is_non_zero;
|
||||
cache->predicate = predicate;
|
||||
cache->entry_destroy = entry_destroy;
|
||||
cache = malloc (sizeof (cairo_cache_t));
|
||||
if (unlikely (cache == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cache->max_size = max_size;
|
||||
cache->size = 0;
|
||||
status = _cairo_cache_init (cache,
|
||||
keys_equal,
|
||||
predicate,
|
||||
entry_destroy,
|
||||
max_size);
|
||||
if (unlikely (status)) {
|
||||
free (cache);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cache->freeze_count = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_cache_pluck (void *entry, void *closure)
|
||||
{
|
||||
_cairo_cache_remove (closure, entry);
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_cache_fini:
|
||||
* _cairo_cache_destroy:
|
||||
* @cache: a cache to destroy
|
||||
*
|
||||
* Immediately destroys the given cache, freeing all resources
|
||||
* associated with it. As part of this process, the entry_destroy()
|
||||
* function, (as passed to _cairo_cache_init()), will be called for
|
||||
* function, (as passed to _cairo_cache_create()), will be called for
|
||||
* each entry in the cache.
|
||||
**/
|
||||
void
|
||||
_cairo_cache_fini (cairo_cache_t *cache)
|
||||
_cairo_cache_destroy (cairo_cache_t *cache)
|
||||
{
|
||||
_cairo_hash_table_foreach (cache->hash_table,
|
||||
_cairo_cache_pluck,
|
||||
cache);
|
||||
assert (cache->size == 0);
|
||||
_cairo_hash_table_destroy (cache->hash_table);
|
||||
_cairo_cache_fini (cache);
|
||||
|
||||
free (cache);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,7 +222,7 @@ _cairo_cache_thaw (cairo_cache_t *cache)
|
||||
*
|
||||
* Performs a lookup in @cache looking for an entry which has a key
|
||||
* that matches @key, (as determined by the keys_equal() function
|
||||
* passed to _cairo_cache_init()).
|
||||
* passed to _cairo_cache_create()).
|
||||
*
|
||||
* Return value: %TRUE if there is an entry in the cache that matches
|
||||
* @key, (which will now be in *entry_return). %FALSE otherwise, (in
|
||||
|
@ -336,12 +336,17 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
|
||||
|
||||
if (clip->region) {
|
||||
status = cairo_region_intersect (clip->region, region);
|
||||
cairo_region_destroy (region);
|
||||
} else {
|
||||
clip->region = region;
|
||||
clip->region = cairo_region_copy (region);
|
||||
|
||||
assert (clip->region != NULL);
|
||||
|
||||
if ((status = cairo_region_status (clip->region)))
|
||||
clip->region = NULL;
|
||||
}
|
||||
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
cairo_region_destroy (region);
|
||||
|
||||
if (!clip->region || cairo_region_is_empty (clip->region))
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
@ -627,10 +632,9 @@ _cairo_clip_clip (cairo_clip_t *clip,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_rectangle_int_t limits, extents;
|
||||
cairo_rectangle_int_t rectangle;
|
||||
cairo_traps_t traps;
|
||||
cairo_box_t ignored_box;
|
||||
cairo_bool_t have_limits;
|
||||
|
||||
if (clip->all_clipped)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -664,43 +668,13 @@ _cairo_clip_clip (cairo_clip_t *clip,
|
||||
|
||||
_cairo_traps_init (&traps);
|
||||
|
||||
/* Limit the traps to the target surface and current clip
|
||||
/* Limit the traps to the target surface
|
||||
* - so we don't add more traps than needed. */
|
||||
have_limits = FALSE;
|
||||
if (clip->region != NULL) {
|
||||
cairo_region_get_extents (clip->region, &limits);
|
||||
have_limits = TRUE;
|
||||
}
|
||||
|
||||
if (clip->surface != NULL) {
|
||||
if (have_limits) {
|
||||
if (! _cairo_rectangle_intersect (&limits, &clip->surface_rect)) {
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
limits = clip->surface_rect;
|
||||
have_limits = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_surface_get_extents (target, &extents);
|
||||
status = _cairo_surface_get_extents (target, &rectangle);
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
if (have_limits) {
|
||||
if (! _cairo_rectangle_intersect (&limits, &extents)) {
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
limits = extents;
|
||||
have_limits = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_limits) {
|
||||
cairo_box_t box;
|
||||
|
||||
_cairo_box_from_rectangle (&box, &limits);
|
||||
_cairo_box_from_rectangle (&box, &rectangle);
|
||||
_cairo_traps_limit (&traps, &box);
|
||||
}
|
||||
|
||||
|
@ -79,6 +79,8 @@ cairo_debug_reset_static_data (void)
|
||||
}
|
||||
|
||||
#if HAVE_VALGRIND
|
||||
#include <memcheck.h>
|
||||
|
||||
void
|
||||
_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
|
||||
{
|
||||
@ -105,7 +107,7 @@ _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
|
||||
width = image->width*4;
|
||||
break;
|
||||
default:
|
||||
/* XXX compute width from pixman bpp */
|
||||
ASSERT_NOT_REACHED;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -117,45 +119,3 @@ _cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
_cairo_image_surface_write_to_ppm (cairo_image_surface_t *isurf, const char *fn)
|
||||
{
|
||||
char *fmt;
|
||||
if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24)
|
||||
fmt = "P6";
|
||||
else if (isurf->format == CAIRO_FORMAT_A8)
|
||||
fmt = "P5";
|
||||
else
|
||||
return;
|
||||
|
||||
FILE *fp = fopen(fn, "wb");
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
fprintf (fp, "%s %d %d 255\n", fmt,isurf->width, isurf->height);
|
||||
for (int j = 0; j < isurf->height; j++) {
|
||||
unsigned char *row = isurf->data + isurf->stride * j;
|
||||
for (int i = 0; i < isurf->width; i++) {
|
||||
if (isurf->format == CAIRO_FORMAT_ARGB32 || isurf->format == CAIRO_FORMAT_RGB24) {
|
||||
unsigned char r = *row++;
|
||||
unsigned char g = *row++;
|
||||
unsigned char b = *row++;
|
||||
*row++;
|
||||
putc(r, fp);
|
||||
putc(g, fp);
|
||||
putc(b, fp);
|
||||
} else {
|
||||
unsigned char a = *row++;
|
||||
putc(a, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
|
||||
fprintf (stderr, "Wrote %s\n", fn);
|
||||
}
|
||||
#endif
|
||||
|
@ -766,7 +766,6 @@ _directfb_prepare_composite (cairo_directfb_surface_t *dst,
|
||||
status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
*src_x, *src_y, width, height,
|
||||
CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
|
||||
(cairo_surface_t **) &src,
|
||||
&src_attr);
|
||||
if (status)
|
||||
|
@ -283,11 +283,11 @@ face_props_parse (twin_face_properties_t *props,
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
twin_font_face_create_properties (cairo_font_face_t *twin_face,
|
||||
twin_face_properties_t **props_out)
|
||||
twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face,
|
||||
cairo_toy_font_face_t *toy_face)
|
||||
{
|
||||
twin_face_properties_t *props;
|
||||
cairo_status_t status;
|
||||
twin_face_properties_t *props;
|
||||
|
||||
props = malloc (sizeof (twin_face_properties_t));
|
||||
if (unlikely (props == NULL))
|
||||
@ -297,37 +297,22 @@ twin_font_face_create_properties (cairo_font_face_t *twin_face,
|
||||
props->monospace = FALSE;
|
||||
props->smallcaps = FALSE;
|
||||
|
||||
status = cairo_font_face_set_user_data (twin_face,
|
||||
&twin_properties_key,
|
||||
props, free);
|
||||
if (unlikely (status)) {
|
||||
free (props);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (props_out)
|
||||
*props_out = props;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
twin_font_face_set_properties_from_toy (cairo_font_face_t *twin_face,
|
||||
cairo_toy_font_face_t *toy_face)
|
||||
{
|
||||
cairo_status_t status;
|
||||
twin_face_properties_t *props;
|
||||
|
||||
status = twin_font_face_create_properties (twin_face, &props);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
props->slant = toy_face->slant;
|
||||
props->weight = toy_face->weight == CAIRO_FONT_WEIGHT_NORMAL ?
|
||||
TWIN_WEIGHT_NORMAL : TWIN_WEIGHT_BOLD;
|
||||
face_props_parse (props, toy_face->family);
|
||||
|
||||
status = cairo_font_face_set_user_data (twin_face,
|
||||
&twin_properties_key,
|
||||
props, free);
|
||||
if (unlikely (status))
|
||||
goto FREE_PROPS;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
FREE_PROPS:
|
||||
free (props);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@ -709,35 +694,6 @@ twin_scaled_font_unicode_to_glyph (cairo_scaled_font_t *scaled_font,
|
||||
* Face constructor
|
||||
*/
|
||||
|
||||
static cairo_font_face_t *
|
||||
_cairo_font_face_twin_create_internal (void)
|
||||
{
|
||||
cairo_font_face_t *twin_font_face;
|
||||
|
||||
twin_font_face = cairo_user_font_face_create ();
|
||||
cairo_user_font_face_set_init_func (twin_font_face, twin_scaled_font_init);
|
||||
cairo_user_font_face_set_render_glyph_func (twin_font_face, twin_scaled_font_render_glyph);
|
||||
cairo_user_font_face_set_unicode_to_glyph_func (twin_font_face, twin_scaled_font_unicode_to_glyph);
|
||||
|
||||
return twin_font_face;
|
||||
}
|
||||
|
||||
cairo_font_face_t *
|
||||
_cairo_font_face_twin_create_fallback (void)
|
||||
{
|
||||
cairo_font_face_t *twin_font_face;
|
||||
cairo_status_t status;
|
||||
|
||||
twin_font_face = _cairo_font_face_twin_create_internal ();
|
||||
status = twin_font_face_create_properties (twin_font_face, NULL);
|
||||
if (status) {
|
||||
cairo_font_face_destroy (twin_font_face);
|
||||
return (cairo_font_face_t *) &_cairo_font_face_nil;
|
||||
}
|
||||
|
||||
return twin_font_face;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face,
|
||||
cairo_font_face_t **font_face)
|
||||
@ -745,7 +701,10 @@ _cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face,
|
||||
cairo_status_t status;
|
||||
cairo_font_face_t *twin_font_face;
|
||||
|
||||
twin_font_face = _cairo_font_face_twin_create_internal ();
|
||||
twin_font_face = cairo_user_font_face_create ();
|
||||
cairo_user_font_face_set_init_func (twin_font_face, twin_scaled_font_init);
|
||||
cairo_user_font_face_set_render_glyph_func (twin_font_face, twin_scaled_font_render_glyph);
|
||||
cairo_user_font_face_set_unicode_to_glyph_func (twin_font_face, twin_scaled_font_unicode_to_glyph);
|
||||
status = twin_font_face_set_properties_from_toy (twin_font_face, toy_face);
|
||||
if (status) {
|
||||
cairo_font_face_destroy (twin_font_face);
|
||||
|
@ -132,7 +132,7 @@ cairo_font_options_copy (const cairo_font_options_t *original)
|
||||
* cairo_font_options_destroy:
|
||||
* @options: a #cairo_font_options_t
|
||||
*
|
||||
* Destroys a #cairo_font_options_t object created with
|
||||
* Destroys a #cairo_font_options_t object created with with
|
||||
* cairo_font_options_create() or cairo_font_options_copy().
|
||||
**/
|
||||
void
|
||||
|
@ -27,7 +27,7 @@
|
||||
void
|
||||
_cairo_freelist_init (cairo_freelist_t *freelist, unsigned nodesize)
|
||||
{
|
||||
memset (freelist, 0, sizeof (cairo_freelist_t));
|
||||
memset (freelist, 0, sizeof(cairo_freelist_t));
|
||||
freelist->nodesize = nodesize;
|
||||
}
|
||||
|
||||
@ -36,11 +36,7 @@ _cairo_freelist_fini (cairo_freelist_t *freelist)
|
||||
{
|
||||
cairo_freelist_node_t *node = freelist->first_free_node;
|
||||
while (node) {
|
||||
cairo_freelist_node_t *next;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
|
||||
next = node->next;
|
||||
|
||||
cairo_freelist_node_t *next = node->next;
|
||||
free (node);
|
||||
node = next;
|
||||
}
|
||||
@ -50,16 +46,10 @@ void *
|
||||
_cairo_freelist_alloc (cairo_freelist_t *freelist)
|
||||
{
|
||||
if (freelist->first_free_node) {
|
||||
cairo_freelist_node_t *node;
|
||||
|
||||
node = freelist->first_free_node;
|
||||
VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
|
||||
cairo_freelist_node_t *node = freelist->first_free_node;
|
||||
freelist->first_free_node = node->next;
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freelist->nodesize));
|
||||
|
||||
return node;
|
||||
return (void*)node;
|
||||
}
|
||||
|
||||
return malloc (freelist->nodesize);
|
||||
}
|
||||
|
||||
@ -79,6 +69,5 @@ _cairo_freelist_free (cairo_freelist_t *freelist, void *voidnode)
|
||||
if (node) {
|
||||
node->next = freelist->first_free_node;
|
||||
freelist->first_free_node = node;
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (node, freelist->nodesize));
|
||||
}
|
||||
}
|
||||
|
@ -143,8 +143,6 @@ struct _cairo_ft_font_face {
|
||||
|
||||
#if CAIRO_HAS_FC_FONT
|
||||
FcPattern *pattern; /* if pattern is set, the above fields will be NULL */
|
||||
cairo_font_face_t *resolved_font_face;
|
||||
FcConfig *resolved_config;
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -155,11 +153,13 @@ static cairo_status_t
|
||||
_cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
FcPattern *pattern);
|
||||
|
||||
static cairo_font_face_t *
|
||||
static cairo_status_t
|
||||
_cairo_ft_resolve_pattern (FcPattern *pattern,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options);
|
||||
const cairo_font_options_t *options,
|
||||
cairo_ft_unscaled_font_t **unscaled,
|
||||
cairo_ft_options_t *ft_options);
|
||||
|
||||
#endif
|
||||
|
||||
@ -239,9 +239,7 @@ _cairo_ft_unscaled_font_map_pluck_entry (void *entry, void *closure)
|
||||
_cairo_hash_table_remove (font_map->hash_table,
|
||||
&unscaled->base.hash_entry);
|
||||
|
||||
if (! unscaled->from_face)
|
||||
_font_map_release_face_lock_held (font_map, unscaled);
|
||||
|
||||
_font_map_release_face_lock_held (font_map, unscaled);
|
||||
_cairo_ft_unscaled_font_fini (unscaled);
|
||||
free (unscaled);
|
||||
}
|
||||
@ -1539,40 +1537,38 @@ _cairo_ft_options_merge (cairo_ft_options_t *options,
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_ft_font_face_scaled_font_create (void *abstract_font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **font_out)
|
||||
_cairo_ft_scaled_font_create (cairo_ft_unscaled_font_t *unscaled,
|
||||
cairo_font_face_t *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_ft_options_t ft_options,
|
||||
cairo_scaled_font_t **font_out)
|
||||
{
|
||||
cairo_ft_font_face_t *font_face = abstract_font_face;
|
||||
cairo_ft_scaled_font_t *scaled_font;
|
||||
FT_Face face;
|
||||
FT_Size_Metrics *metrics;
|
||||
cairo_font_extents_t fs_metrics;
|
||||
cairo_status_t status;
|
||||
cairo_ft_unscaled_font_t *unscaled;
|
||||
|
||||
assert (font_face->unscaled);
|
||||
|
||||
face = _cairo_ft_unscaled_font_lock_face (font_face->unscaled);
|
||||
face = _cairo_ft_unscaled_font_lock_face (unscaled);
|
||||
if (unlikely (face == NULL)) /* backend error */
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
scaled_font = malloc (sizeof (cairo_ft_scaled_font_t));
|
||||
scaled_font = malloc (sizeof(cairo_ft_scaled_font_t));
|
||||
if (unlikely (scaled_font == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
scaled_font->unscaled = unscaled = font_face->unscaled;
|
||||
_cairo_unscaled_font_reference (&unscaled->base);
|
||||
scaled_font->unscaled = unscaled;
|
||||
|
||||
_cairo_font_options_init_copy (&scaled_font->ft_options.base, options);
|
||||
_cairo_ft_options_merge (&scaled_font->ft_options, &font_face->ft_options);
|
||||
_cairo_ft_options_merge (&scaled_font->ft_options, &ft_options);
|
||||
|
||||
status = _cairo_scaled_font_init (&scaled_font->base,
|
||||
&font_face->base,
|
||||
font_face,
|
||||
font_matrix, ctm, options,
|
||||
&_cairo_ft_scaled_font_backend);
|
||||
if (unlikely (status))
|
||||
@ -1652,7 +1648,7 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_font_face,
|
||||
_cairo_unscaled_font_destroy (&unscaled->base);
|
||||
free (scaled_font);
|
||||
FAIL:
|
||||
_cairo_ft_unscaled_font_unlock_face (font_face->unscaled);
|
||||
_cairo_ft_unscaled_font_unlock_face (unscaled);
|
||||
*font_out = _cairo_scaled_font_create_in_error (status);
|
||||
return CAIRO_STATUS_SUCCESS; /* non-backend error */
|
||||
}
|
||||
@ -1934,7 +1930,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
FT_Pos x1, x2;
|
||||
FT_Pos y1, y2;
|
||||
FT_Pos advance;
|
||||
|
||||
|
||||
if (!vertical_layout) {
|
||||
x1 = (metrics->horiBearingX) & -64;
|
||||
x2 = (metrics->horiBearingX + metrics->width + 63) & -64;
|
||||
@ -1989,7 +1985,7 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
if (hint_metrics || glyph->format != FT_GLYPH_FORMAT_OUTLINE)
|
||||
fs_metrics.y_advance = DOUBLE_FROM_26_6 (metrics->vertAdvance) * y_factor;
|
||||
else
|
||||
fs_metrics.y_advance = DOUBLE_FROM_16_16 (glyph->linearVertAdvance) * y_factor;
|
||||
fs_metrics.y_advance = DOUBLE_FROM_26_6 (glyph->linearVertAdvance) * y_factor;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2297,20 +2293,21 @@ _cairo_ft_font_face_destroy (void *abstract_face)
|
||||
}
|
||||
|
||||
#if CAIRO_HAS_FC_FONT
|
||||
if (font_face->pattern) {
|
||||
if (font_face->pattern)
|
||||
FcPatternDestroy (font_face->pattern);
|
||||
cairo_font_face_destroy (font_face->resolved_font_face);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static cairo_font_face_t *
|
||||
_cairo_ft_font_face_get_implementation (void *abstract_face,
|
||||
static cairo_status_t
|
||||
_cairo_ft_font_face_scaled_font_create (void *abstract_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options)
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **scaled_font)
|
||||
{
|
||||
cairo_ft_font_face_t *font_face = abstract_face;
|
||||
cairo_ft_unscaled_font_t *unscaled = NULL;
|
||||
cairo_ft_options_t ft_options;
|
||||
|
||||
/* The handling of font options is different depending on how the
|
||||
* font face was created. When the user creates a font face with
|
||||
@ -2327,35 +2324,34 @@ _cairo_ft_font_face_get_implementation (void *abstract_face,
|
||||
* unscaled font. Otherwise, use the ones stored in font_face.
|
||||
*/
|
||||
if (font_face->pattern) {
|
||||
cairo_font_face_t *resolved;
|
||||
cairo_status_t status;
|
||||
|
||||
/* Cache the resolved font whilst the FcConfig remains consistent. */
|
||||
resolved = font_face->resolved_font_face;
|
||||
if (resolved != NULL) {
|
||||
if (! FcInitBringUptoDate ()) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_font_face_t *) &_cairo_font_face_nil;
|
||||
}
|
||||
|
||||
if (font_face->resolved_config == FcConfigGetCurrent ())
|
||||
return cairo_font_face_reference (resolved);
|
||||
|
||||
cairo_font_face_destroy (resolved);
|
||||
status = _cairo_ft_resolve_pattern (font_face->pattern,
|
||||
font_matrix,
|
||||
ctm,
|
||||
options,
|
||||
&unscaled,
|
||||
&ft_options);
|
||||
if (unlikely (status)) {
|
||||
/* XXX It is possible for a failure to generate the unscaled font
|
||||
* here could indicate that the font_face itself is broken - for
|
||||
* which we should propagate the error.
|
||||
*/
|
||||
*scaled_font = _cairo_scaled_font_create_in_error (status);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
resolved = _cairo_ft_resolve_pattern (font_face->pattern,
|
||||
font_matrix,
|
||||
ctm,
|
||||
options);
|
||||
|
||||
font_face->resolved_font_face = cairo_font_face_reference (resolved);
|
||||
font_face->resolved_config = FcConfigGetCurrent ();
|
||||
|
||||
return resolved;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
unscaled = font_face->unscaled;
|
||||
ft_options = font_face->ft_options;
|
||||
}
|
||||
|
||||
return abstract_face;
|
||||
return _cairo_ft_scaled_font_create (unscaled,
|
||||
&font_face->base,
|
||||
font_matrix, ctm,
|
||||
options, ft_options,
|
||||
scaled_font);
|
||||
}
|
||||
|
||||
const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
|
||||
@ -2366,8 +2362,7 @@ const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
|
||||
NULL,
|
||||
#endif
|
||||
_cairo_ft_font_face_destroy,
|
||||
_cairo_ft_font_face_scaled_font_create,
|
||||
_cairo_ft_font_face_get_implementation
|
||||
_cairo_ft_font_face_scaled_font_create
|
||||
};
|
||||
|
||||
#if CAIRO_HAS_FC_FONT
|
||||
@ -2390,9 +2385,6 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
font_face->resolved_font_face = NULL;
|
||||
font_face->resolved_config = NULL;
|
||||
|
||||
_cairo_font_face_init (&font_face->base, &_cairo_ft_font_face_backend);
|
||||
|
||||
*out = &font_face->base;
|
||||
@ -2585,11 +2577,13 @@ cairo_ft_font_options_substitute (const cairo_font_options_t *options,
|
||||
_cairo_ft_font_options_substitute (options, pattern);
|
||||
}
|
||||
|
||||
static cairo_font_face_t *
|
||||
static cairo_status_t
|
||||
_cairo_ft_resolve_pattern (FcPattern *pattern,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *font_options)
|
||||
const cairo_font_options_t *font_options,
|
||||
cairo_ft_unscaled_font_t **unscaled,
|
||||
cairo_ft_options_t *ft_options)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
@ -2597,9 +2591,6 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
|
||||
FcPattern *resolved;
|
||||
cairo_ft_font_transform_t sf;
|
||||
FcResult result;
|
||||
cairo_ft_unscaled_font_t *unscaled;
|
||||
cairo_ft_options_t ft_options;
|
||||
cairo_font_face_t *font_face;
|
||||
|
||||
scale = *ctm;
|
||||
scale.x0 = scale.y0 = 0;
|
||||
@ -2608,52 +2599,40 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
|
||||
&scale);
|
||||
|
||||
status = _compute_transform (&sf, &scale);
|
||||
if (unlikely (status))
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
pattern = FcPatternDuplicate (pattern);
|
||||
if (pattern == NULL)
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (! FcPatternAddDouble (pattern, FC_PIXEL_SIZE, sf.y_scale)) {
|
||||
font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
if (! FcConfigSubstitute (NULL, pattern, FcMatchPattern)) {
|
||||
font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
status = _cairo_ft_font_options_substitute (font_options, pattern);
|
||||
if (status) {
|
||||
font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
if (status)
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
FcDefaultSubstitute (pattern);
|
||||
|
||||
resolved = FcFontMatch (NULL, pattern, &result);
|
||||
if (!resolved) {
|
||||
/* We failed to find any font. Substitute twin so that the user can
|
||||
* see something (and hopefully recognise that the font is missing)
|
||||
* and not just receive a NO_MEMORY error during rendering.
|
||||
*/
|
||||
font_face = _cairo_font_face_twin_create_fallback ();
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
status = _cairo_ft_unscaled_font_create_for_pattern (resolved, &unscaled);
|
||||
if (unlikely (status)) {
|
||||
font_face = (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
status = _cairo_ft_unscaled_font_create_for_pattern (resolved, unscaled);
|
||||
if (unlikely (status))
|
||||
goto FREE_RESOLVED;
|
||||
}
|
||||
|
||||
assert (unscaled != NULL);
|
||||
|
||||
_get_pattern_ft_options (resolved, &ft_options);
|
||||
font_face = _cairo_ft_font_face_create (unscaled, &ft_options);
|
||||
_cairo_unscaled_font_destroy (&unscaled->base);
|
||||
_get_pattern_ft_options (resolved, ft_options);
|
||||
|
||||
FREE_RESOLVED:
|
||||
FcPatternDestroy (resolved);
|
||||
@ -2661,7 +2640,7 @@ FREE_RESOLVED:
|
||||
FREE_PATTERN:
|
||||
FcPatternDestroy (pattern);
|
||||
|
||||
return font_face;
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,20 +300,6 @@ _cairo_glitz_surface_acquire_source_image (void *abstract_surface,
|
||||
return _cairo_glitz_surface_get_image (surface, NULL, image_out, NULL);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_glitz_surface_snapshot (void *abstract_surface)
|
||||
{
|
||||
cairo_glitz_surface_t *surface = abstract_surface;
|
||||
cairo_status_t status;
|
||||
cairo_image_surface_t *image;
|
||||
|
||||
status = _cairo_glitz_surface_get_image (surface, NULL, &image, NULL);
|
||||
if (unlikely (status))
|
||||
return _cairo_surface_create_in_error (status);
|
||||
|
||||
return &image->base;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_glitz_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
@ -733,7 +719,6 @@ _cairo_glitz_pattern_acquire_surface (const cairo_pattern_t *pattern,
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
x, y, width, height,
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &src,
|
||||
&attr->base);
|
||||
if (status)
|
||||
@ -2331,7 +2316,7 @@ static const cairo_surface_backend_t cairo_glitz_surface_backend = {
|
||||
NULL, /* fill */
|
||||
NULL, /* show_glyphs */
|
||||
|
||||
_cairo_glitz_surface_snapshot,
|
||||
NULL, /* snapshot */
|
||||
_cairo_glitz_surface_is_similar,
|
||||
|
||||
_cairo_glitz_surface_reset
|
||||
|
@ -50,7 +50,6 @@ struct _cairo_gstate {
|
||||
|
||||
cairo_font_face_t *font_face;
|
||||
cairo_scaled_font_t *scaled_font; /* Specific to the current CTM */
|
||||
cairo_scaled_font_t *previous_scaled_font; /* holdover */
|
||||
cairo_matrix_t font_matrix;
|
||||
cairo_font_options_t font_options;
|
||||
|
||||
|
@ -77,8 +77,6 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (gstate, sizeof (cairo_gstate_t)));
|
||||
|
||||
gstate->next = NULL;
|
||||
|
||||
gstate->op = CAIRO_GSTATE_OPERATOR_DEFAULT;
|
||||
@ -92,7 +90,6 @@ _cairo_gstate_init (cairo_gstate_t *gstate,
|
||||
|
||||
gstate->font_face = NULL;
|
||||
gstate->scaled_font = NULL;
|
||||
gstate->previous_scaled_font = NULL;
|
||||
|
||||
cairo_matrix_init_scale (&gstate->font_matrix,
|
||||
CAIRO_GSTATE_DEFAULT_FONT_SIZE,
|
||||
@ -142,8 +139,6 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (gstate, sizeof (cairo_gstate_t)));
|
||||
|
||||
gstate->op = other->op;
|
||||
|
||||
gstate->tolerance = other->tolerance;
|
||||
@ -158,7 +153,6 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
||||
|
||||
gstate->font_face = cairo_font_face_reference (other->font_face);
|
||||
gstate->scaled_font = cairo_scaled_font_reference (other->scaled_font);
|
||||
gstate->previous_scaled_font = cairo_scaled_font_reference (other->previous_scaled_font);
|
||||
|
||||
gstate->font_matrix = other->font_matrix;
|
||||
|
||||
@ -169,7 +163,6 @@ _cairo_gstate_init_copy (cairo_gstate_t *gstate, cairo_gstate_t *other)
|
||||
_cairo_stroke_style_fini (&gstate->stroke_style);
|
||||
cairo_font_face_destroy (gstate->font_face);
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
cairo_scaled_font_destroy (gstate->previous_scaled_font);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -197,9 +190,6 @@ _cairo_gstate_fini (cairo_gstate_t *gstate)
|
||||
cairo_font_face_destroy (gstate->font_face);
|
||||
gstate->font_face = NULL;
|
||||
|
||||
cairo_scaled_font_destroy (gstate->previous_scaled_font);
|
||||
gstate->previous_scaled_font = NULL;
|
||||
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
gstate->scaled_font = NULL;
|
||||
|
||||
@ -216,8 +206,6 @@ _cairo_gstate_fini (cairo_gstate_t *gstate)
|
||||
|
||||
cairo_pattern_destroy (gstate->source);
|
||||
gstate->source = NULL;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (gstate, sizeof (cairo_gstate_t)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -276,7 +264,6 @@ _cairo_gstate_restore (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
|
||||
*gstate = top->next;
|
||||
|
||||
_cairo_gstate_fini (top);
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (&top->next, sizeof (cairo_gstate_t *)));
|
||||
top->next = *freelist;
|
||||
*freelist = top;
|
||||
|
||||
@ -827,13 +814,14 @@ _cairo_gstate_path_extents (cairo_gstate_t *gstate,
|
||||
*y2 = py2;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
_cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_pattern_t **pattern,
|
||||
cairo_pattern_t *original,
|
||||
cairo_matrix_t *ctm_inverse)
|
||||
{
|
||||
_cairo_pattern_init_static_copy (pattern, original);
|
||||
cairo_status_t status;
|
||||
cairo_bool_t have_copy = FALSE;
|
||||
|
||||
/* apply device_transform first so that it is transformed by ctm_inverse */
|
||||
if (original->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
@ -843,38 +831,60 @@ _cairo_gstate_copy_transformed_pattern (cairo_gstate_t *gstate,
|
||||
surface_pattern = (cairo_surface_pattern_t *) original;
|
||||
surface = surface_pattern->surface;
|
||||
|
||||
if (_cairo_surface_has_device_transform (surface))
|
||||
_cairo_pattern_transform (pattern, &surface->device_transform);
|
||||
if (_cairo_surface_has_device_transform (surface)) {
|
||||
status = _cairo_pattern_init_copy (*pattern, original);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
have_copy = TRUE;
|
||||
|
||||
_cairo_pattern_transform (*pattern, &surface->device_transform);
|
||||
}
|
||||
}
|
||||
|
||||
if (! _cairo_matrix_is_identity (ctm_inverse))
|
||||
_cairo_pattern_transform (pattern, ctm_inverse);
|
||||
if (! _cairo_matrix_is_identity (ctm_inverse)) {
|
||||
if (! have_copy) {
|
||||
status = _cairo_pattern_init_copy (*pattern, original);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
have_copy = TRUE;
|
||||
}
|
||||
|
||||
_cairo_pattern_transform (*pattern, ctm_inverse);
|
||||
}
|
||||
|
||||
if (! have_copy)
|
||||
*pattern = original;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
_cairo_gstate_copy_transformed_source (cairo_gstate_t *gstate,
|
||||
cairo_pattern_t *pattern)
|
||||
cairo_pattern_t **pattern)
|
||||
{
|
||||
_cairo_gstate_copy_transformed_pattern (gstate, pattern,
|
||||
gstate->source,
|
||||
&gstate->source_ctm_inverse);
|
||||
return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
|
||||
gstate->source,
|
||||
&gstate->source_ctm_inverse);
|
||||
}
|
||||
|
||||
static void
|
||||
static cairo_status_t
|
||||
_cairo_gstate_copy_transformed_mask (cairo_gstate_t *gstate,
|
||||
cairo_pattern_t *pattern,
|
||||
cairo_pattern_t **pattern,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
_cairo_gstate_copy_transformed_pattern (gstate, pattern,
|
||||
mask,
|
||||
&gstate->ctm_inverse);
|
||||
return _cairo_gstate_copy_transformed_pattern (gstate, pattern,
|
||||
mask,
|
||||
&gstate->ctm_inverse);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_paint (cairo_gstate_t *gstate)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_pattern_union_t pattern_stack;
|
||||
|
||||
if (gstate->source->status)
|
||||
return gstate->source->status;
|
||||
@ -883,12 +893,19 @@ _cairo_gstate_paint (cairo_gstate_t *gstate)
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_gstate_copy_transformed_source (gstate, &pattern.base);
|
||||
pattern = &pattern_stack.base;
|
||||
status = _cairo_gstate_copy_transformed_source (gstate, &pattern);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
return _cairo_surface_paint (gstate->target,
|
||||
gstate->op,
|
||||
&pattern.base,
|
||||
NULL);
|
||||
status = _cairo_surface_paint (gstate->target,
|
||||
gstate->op,
|
||||
pattern, NULL);
|
||||
|
||||
if (pattern == &pattern_stack.base)
|
||||
_cairo_pattern_fini (pattern);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -896,7 +913,8 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
|
||||
cairo_pattern_t *mask)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t source_pattern, mask_pattern;
|
||||
cairo_pattern_union_t source_pattern_stack, mask_pattern_stack;
|
||||
cairo_pattern_t *source_pattern, *mask_pattern;
|
||||
|
||||
if (mask->status)
|
||||
return mask->status;
|
||||
@ -908,21 +926,36 @@ _cairo_gstate_mask (cairo_gstate_t *gstate,
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
||||
_cairo_gstate_copy_transformed_mask (gstate, &mask_pattern.base, mask);
|
||||
source_pattern = &source_pattern_stack.base;
|
||||
status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
return _cairo_surface_mask (gstate->target,
|
||||
gstate->op,
|
||||
&source_pattern.base,
|
||||
&mask_pattern.base,
|
||||
NULL);
|
||||
mask_pattern = &mask_pattern_stack.base;
|
||||
status = _cairo_gstate_copy_transformed_mask (gstate, &mask_pattern, mask);
|
||||
if (unlikely (status))
|
||||
goto CLEANUP_SOURCE;
|
||||
|
||||
status = _cairo_surface_mask (gstate->target,
|
||||
gstate->op,
|
||||
source_pattern,
|
||||
mask_pattern, NULL);
|
||||
|
||||
if (mask_pattern == &mask_pattern_stack.base)
|
||||
_cairo_pattern_fini (&mask_pattern_stack.base);
|
||||
CLEANUP_SOURCE:
|
||||
if (source_pattern == &source_pattern_stack.base)
|
||||
_cairo_pattern_fini (&source_pattern_stack.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t source_pattern;
|
||||
cairo_pattern_union_t source_pattern_stack;
|
||||
cairo_pattern_t *source_pattern;
|
||||
|
||||
if (gstate->source->status)
|
||||
return gstate->source->status;
|
||||
@ -934,18 +967,26 @@ _cairo_gstate_stroke (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
||||
source_pattern = &source_pattern_stack.base;
|
||||
status = _cairo_gstate_copy_transformed_source (gstate,
|
||||
&source_pattern);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
return _cairo_surface_stroke (gstate->target,
|
||||
gstate->op,
|
||||
&source_pattern.base,
|
||||
path,
|
||||
&gstate->stroke_style,
|
||||
&gstate->ctm,
|
||||
&gstate->ctm_inverse,
|
||||
gstate->tolerance,
|
||||
gstate->antialias,
|
||||
NULL);
|
||||
status = _cairo_surface_stroke (gstate->target,
|
||||
gstate->op,
|
||||
source_pattern,
|
||||
path,
|
||||
&gstate->stroke_style,
|
||||
&gstate->ctm,
|
||||
&gstate->ctm_inverse,
|
||||
gstate->tolerance,
|
||||
gstate->antialias, NULL);
|
||||
|
||||
if (source_pattern == &source_pattern_stack.base)
|
||||
_cairo_pattern_fini (&source_pattern_stack.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1010,7 +1051,8 @@ cairo_status_t
|
||||
_cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_pattern_union_t pattern_stack;
|
||||
cairo_pattern_t *pattern;
|
||||
|
||||
if (gstate->source->status)
|
||||
return gstate->source->status;
|
||||
@ -1019,16 +1061,24 @@ _cairo_gstate_fill (cairo_gstate_t *gstate, cairo_path_fixed_t *path)
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_gstate_copy_transformed_source (gstate, &pattern.base);
|
||||
pattern = &pattern_stack.base;
|
||||
status = _cairo_gstate_copy_transformed_source (gstate, &pattern);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
return _cairo_surface_fill (gstate->target,
|
||||
gstate->op,
|
||||
&pattern.base,
|
||||
path,
|
||||
gstate->fill_rule,
|
||||
gstate->tolerance,
|
||||
gstate->antialias,
|
||||
NULL);
|
||||
status = _cairo_surface_fill (gstate->target,
|
||||
gstate->op,
|
||||
pattern,
|
||||
path,
|
||||
gstate->fill_rule,
|
||||
gstate->tolerance,
|
||||
gstate->antialias,
|
||||
NULL);
|
||||
|
||||
if (pattern == &pattern_stack.base)
|
||||
_cairo_pattern_fini (&pattern_stack.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1243,14 +1293,10 @@ _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
|
||||
static void
|
||||
_cairo_gstate_unset_scaled_font (cairo_gstate_t *gstate)
|
||||
{
|
||||
if (gstate->scaled_font == NULL)
|
||||
return;
|
||||
|
||||
if (gstate->previous_scaled_font != NULL)
|
||||
cairo_scaled_font_destroy (gstate->previous_scaled_font);
|
||||
|
||||
gstate->previous_scaled_font = gstate->scaled_font;
|
||||
gstate->scaled_font = NULL;
|
||||
if (gstate->scaled_font) {
|
||||
cairo_scaled_font_destroy (gstate->scaled_font);
|
||||
gstate->scaled_font = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1574,7 +1620,8 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||
int num_clusters,
|
||||
cairo_text_cluster_flags_t cluster_flags)
|
||||
{
|
||||
cairo_pattern_union_t source_pattern;
|
||||
cairo_pattern_union_t source_pattern_stack;
|
||||
cairo_pattern_t *source_pattern;
|
||||
cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
|
||||
cairo_glyph_t *transformed_glyphs;
|
||||
cairo_text_cluster_t stack_transformed_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)];
|
||||
@ -1627,7 +1674,10 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||
if (status || num_glyphs == 0)
|
||||
goto CLEANUP_GLYPHS;
|
||||
|
||||
_cairo_gstate_copy_transformed_source (gstate, &source_pattern.base);
|
||||
source_pattern = &source_pattern_stack.base;
|
||||
status = _cairo_gstate_copy_transformed_source (gstate, &source_pattern);
|
||||
if (unlikely (status))
|
||||
goto CLEANUP_GLYPHS;
|
||||
|
||||
/* For really huge font sizes, we can just do path;fill instead of
|
||||
* show_glyphs, as show_glyphs would put excess pressure on the cache,
|
||||
@ -1648,7 +1698,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||
_cairo_surface_get_text_path_fill_threshold (gstate->target)) {
|
||||
status = _cairo_surface_show_text_glyphs (gstate->target,
|
||||
gstate->op,
|
||||
&source_pattern.base,
|
||||
source_pattern,
|
||||
utf8, utf8_len,
|
||||
transformed_glyphs, num_glyphs,
|
||||
transformed_clusters, num_clusters,
|
||||
@ -1666,7 +1716,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_surface_fill (gstate->target,
|
||||
gstate->op,
|
||||
&source_pattern.base,
|
||||
source_pattern,
|
||||
&path,
|
||||
CAIRO_FILL_RULE_WINDING,
|
||||
gstate->tolerance,
|
||||
@ -1675,6 +1725,9 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
|
||||
_cairo_path_fixed_fini (&path);
|
||||
}
|
||||
|
||||
if (source_pattern == &source_pattern_stack.base)
|
||||
_cairo_pattern_fini (&source_pattern_stack.base);
|
||||
|
||||
CLEANUP_GLYPHS:
|
||||
if (transformed_glyphs != stack_transformed_glyphs)
|
||||
cairo_glyph_free (transformed_glyphs);
|
||||
|
@ -449,7 +449,7 @@ slim_hidden_def (cairo_format_stride_for_width);
|
||||
* Creates an image surface for the provided pixel data. The output
|
||||
* buffer must be kept around until the #cairo_surface_t is destroyed
|
||||
* or cairo_surface_finish() is called on the surface. The initial
|
||||
* contents of @data will be used as the initial image contents; you
|
||||
* contents of @buffer will be used as the initial image contents; you
|
||||
* must explicitly clear the buffer, using, for example,
|
||||
* cairo_rectangle() and cairo_fill() if you want it cleared.
|
||||
*
|
||||
@ -967,7 +967,6 @@ _cairo_image_surface_composite (cairo_operator_t op,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &src,
|
||||
(cairo_surface_t **) &mask,
|
||||
&src_attr, &mask_attr);
|
||||
@ -1084,40 +1083,12 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
|
||||
return status;
|
||||
}
|
||||
|
||||
static pixman_format_code_t
|
||||
_pixman_mask_format_from_antialias (cairo_antialias_t antialias)
|
||||
static cairo_format_t
|
||||
_cairo_mask_format_from_antialias (cairo_antialias_t antialias)
|
||||
{
|
||||
if (antialias == CAIRO_ANTIALIAS_NONE)
|
||||
return PIXMAN_a1;
|
||||
return PIXMAN_a8;
|
||||
}
|
||||
|
||||
static void
|
||||
_pixman_add_trapezoids (pixman_image_t *image,
|
||||
int dst_x, int dst_y,
|
||||
const cairo_trapezoid_t *traps,
|
||||
int num_traps)
|
||||
{
|
||||
while (num_traps--) {
|
||||
pixman_trapezoid_t trap;
|
||||
|
||||
trap.top = _cairo_fixed_to_16_16 (traps->top);
|
||||
trap.bottom = _cairo_fixed_to_16_16 (traps->bottom);
|
||||
|
||||
trap.left.p1.x = _cairo_fixed_to_16_16 (traps->left.p1.x);
|
||||
trap.left.p1.y = _cairo_fixed_to_16_16 (traps->left.p1.y);
|
||||
trap.left.p2.x = _cairo_fixed_to_16_16 (traps->left.p2.x);
|
||||
trap.left.p2.y = _cairo_fixed_to_16_16 (traps->left.p2.y);
|
||||
|
||||
trap.right.p1.x = _cairo_fixed_to_16_16 (traps->right.p1.x);
|
||||
trap.right.p1.y = _cairo_fixed_to_16_16 (traps->right.p1.y);
|
||||
trap.right.p2.x = _cairo_fixed_to_16_16 (traps->right.p2.x);
|
||||
trap.right.p2.y = _cairo_fixed_to_16_16 (traps->right.p2.y);
|
||||
|
||||
pixman_rasterize_trapezoid (image, &trap, -dst_x, -dst_y);
|
||||
|
||||
traps++;
|
||||
}
|
||||
return CAIRO_FORMAT_A1;
|
||||
return CAIRO_FORMAT_A8;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
@ -1138,7 +1109,10 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
cairo_image_surface_t *dst = abstract_dst;
|
||||
cairo_image_surface_t *src;
|
||||
cairo_int_status_t status;
|
||||
pixman_image_t *mask;
|
||||
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 i;
|
||||
|
||||
if (height == 0 || width == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -1146,6 +1120,26 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
/* Convert traps to pixman traps */
|
||||
if (num_traps > ARRAY_LENGTH (stack_traps)) {
|
||||
pixman_traps = _cairo_malloc_ab (num_traps, sizeof (pixman_trapezoid_t));
|
||||
if (unlikely (pixman_traps == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_traps; i++) {
|
||||
pixman_traps[i].top = _cairo_fixed_to_16_16 (traps[i].top);
|
||||
pixman_traps[i].bottom = _cairo_fixed_to_16_16 (traps[i].bottom);
|
||||
pixman_traps[i].left.p1.x = _cairo_fixed_to_16_16 (traps[i].left.p1.x);
|
||||
pixman_traps[i].left.p1.y = _cairo_fixed_to_16_16 (traps[i].left.p1.y);
|
||||
pixman_traps[i].left.p2.x = _cairo_fixed_to_16_16 (traps[i].left.p2.x);
|
||||
pixman_traps[i].left.p2.y = _cairo_fixed_to_16_16 (traps[i].left.p2.y);
|
||||
pixman_traps[i].right.p1.x = _cairo_fixed_to_16_16 (traps[i].right.p1.x);
|
||||
pixman_traps[i].right.p1.y = _cairo_fixed_to_16_16 (traps[i].right.p1.y);
|
||||
pixman_traps[i].right.p2.x = _cairo_fixed_to_16_16 (traps[i].right.p2.x);
|
||||
pixman_traps[i].right.p2.y = _cairo_fixed_to_16_16 (traps[i].right.p2.y);
|
||||
}
|
||||
|
||||
/* Special case adding trapezoids onto a mask surface; we want to avoid
|
||||
* creating an intermediate temporary mask unnecessarily.
|
||||
*
|
||||
@ -1165,18 +1159,19 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
! dst->has_clip &&
|
||||
antialias != CAIRO_ANTIALIAS_NONE)
|
||||
{
|
||||
_pixman_add_trapezoids (dst->pixman_image, 0, 0, traps, num_traps);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
pixman_add_trapezoids (dst->pixman_image, 0, 0,
|
||||
num_traps, pixman_traps);
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
src_x, src_y, width, height,
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
goto finish;
|
||||
|
||||
status = _cairo_image_surface_set_attributes (src, &attributes,
|
||||
dst_x + width / 2.,
|
||||
@ -1184,18 +1179,20 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
if (unlikely (status))
|
||||
goto CLEANUP_SOURCE;
|
||||
|
||||
mask = pixman_image_create_bits (_pixman_mask_format_from_antialias (antialias),
|
||||
width, height, NULL, 0);
|
||||
if (unlikely (mask == 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);
|
||||
status = mask->base.status;
|
||||
if (unlikely (status))
|
||||
goto CLEANUP_SOURCE;
|
||||
}
|
||||
|
||||
_pixman_add_trapezoids (mask, dst_x, dst_y, traps, num_traps);
|
||||
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,
|
||||
@ -1203,8 +1200,6 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
pixman_image_unref (mask);
|
||||
|
||||
if (! _cairo_operator_bounded_by_mask (op))
|
||||
status = _cairo_surface_composite_shape_fixup_unbounded (&dst->base,
|
||||
&attributes,
|
||||
@ -1213,10 +1208,15 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
||||
src_x, src_y,
|
||||
0, 0,
|
||||
dst_x, dst_y, width, height);
|
||||
cairo_surface_destroy (&mask->base);
|
||||
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_release_surface (pattern, &src->base, &attributes);
|
||||
|
||||
finish:
|
||||
if (pixman_traps != stack_traps)
|
||||
free (pixman_traps);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -1237,9 +1237,9 @@ typedef struct _cairo_image_surface_span_renderer {
|
||||
|
||||
void
|
||||
_cairo_image_surface_span_render_row (
|
||||
int y,
|
||||
const cairo_half_open_span_t *spans,
|
||||
unsigned num_spans,
|
||||
int y,
|
||||
const cairo_half_open_span_t *spans,
|
||||
unsigned num_spans,
|
||||
cairo_image_surface_t *mask,
|
||||
const cairo_composite_rectangles_t *rects)
|
||||
{
|
||||
@ -1414,7 +1414,6 @@ _cairo_image_surface_create_span_renderer (cairo_operator_t op,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
rects->src.x, rects->src.y,
|
||||
width, height,
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &renderer->src,
|
||||
&renderer->src_attributes);
|
||||
if (status)
|
||||
|
@ -1,189 +0,0 @@
|
||||
/* cairo - a vector graphics library with display and print output
|
||||
*
|
||||
* Copyright © 2009 Chris Wilson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it either under the terms of the GNU Lesser General Public
|
||||
* License version 2.1 as published by the Free Software Foundation
|
||||
* (the "LGPL") or, at your option, under the terms of the Mozilla
|
||||
* Public License Version 1.1 (the "MPL"). If you do not alter this
|
||||
* notice, a recipient may use your version of this file under either
|
||||
* the MPL or the LGPL.
|
||||
*
|
||||
* You should have received a copy of the LGPL along with this library
|
||||
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* You should have received a copy of the MPL along with this library
|
||||
* in the file COPYING-MPL-1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
|
||||
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
|
||||
* the specific language governing rights and limitations.
|
||||
*
|
||||
* The Original Code is the cairo graphics library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Chris Wilson.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Wilson <chris@chris-wilson.co.uk>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CAIRO_LIST_PRIVATE_H
|
||||
#define CAIRO_LIST_PRIVATE_H
|
||||
|
||||
#include "cairo-compiler-private.h"
|
||||
|
||||
/* Basic circular, doubly linked list implementation */
|
||||
|
||||
typedef struct _cairo_list {
|
||||
struct _cairo_list *next, *prev;
|
||||
} cairo_list_t;
|
||||
|
||||
#define cairo_list_entry(ptr, type, member) \
|
||||
cairo_container_of(ptr, type, member)
|
||||
|
||||
#define cairo_list_first_entry(ptr, type, member) \
|
||||
cairo_list_entry((ptr)->next, type, member)
|
||||
|
||||
#define cairo_list_last_entry(ptr, type, member) \
|
||||
cairo_list_entry((ptr)->prev, type, member)
|
||||
|
||||
#define cairo_list_foreach(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
#define cairo_list_foreach_entry(pos, type, head, member) \
|
||||
for (pos = cairo_list_entry((head)->next, type, member);\
|
||||
&pos->member != (head); \
|
||||
pos = cairo_list_entry(pos->member.next, type, member))
|
||||
|
||||
#define cairo_list_foreach_entry_safe(pos, n, type, head, member) \
|
||||
for (pos = cairo_list_entry ((head)->next, type, member),\
|
||||
n = cairo_list_entry (pos->member.next, type, member);\
|
||||
&pos->member != (head); \
|
||||
pos = n, n = cairo_list_entry (n->member.next, type, member))
|
||||
|
||||
#define cairo_list_foreach_entry_reverse(pos, type, head, member) \
|
||||
for (pos = cairo_list_entry((head)->prev, type, member);\
|
||||
&pos->member != (head); \
|
||||
pos = cairo_list_entry(pos->member.prev, type, member))
|
||||
|
||||
#ifdef CAIRO_LIST_DEBUG
|
||||
static inline void
|
||||
cairo_list_validate (const cairo_list_t *head)
|
||||
{
|
||||
cairo_list_t *link;
|
||||
|
||||
cairo_list_foreach (link, head) {
|
||||
assert (link->next->prev == link);
|
||||
assert (link->prev->next == link);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define cairo_list_validate(head)
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
cairo_list_init (cairo_list_t *entry)
|
||||
{
|
||||
entry->next = entry;
|
||||
entry->prev = entry;
|
||||
}
|
||||
|
||||
static inline void
|
||||
__cairo_list_add (cairo_list_t *entry,
|
||||
cairo_list_t *prev,
|
||||
cairo_list_t *next)
|
||||
{
|
||||
next->prev = entry;
|
||||
entry->next = next;
|
||||
entry->prev = prev;
|
||||
prev->next = entry;
|
||||
}
|
||||
|
||||
static inline void
|
||||
cairo_list_add (cairo_list_t *entry, cairo_list_t *head)
|
||||
{
|
||||
cairo_list_validate (head);
|
||||
__cairo_list_add (entry, head, head->next);
|
||||
cairo_list_validate (head);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cairo_list_add_tail (cairo_list_t *entry, cairo_list_t *head)
|
||||
{
|
||||
cairo_list_validate (head);
|
||||
__cairo_list_add (entry, head->prev, head);
|
||||
cairo_list_validate (head);
|
||||
}
|
||||
|
||||
static inline void
|
||||
__cairo_list_del (cairo_list_t *prev, cairo_list_t *next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
static inline void
|
||||
cairo_list_del (cairo_list_t *entry)
|
||||
{
|
||||
__cairo_list_del (entry->prev, entry->next);
|
||||
cairo_list_init (entry);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cairo_list_move (cairo_list_t *entry, cairo_list_t *head)
|
||||
{
|
||||
cairo_list_validate (head);
|
||||
__cairo_list_del (entry->prev, entry->next);
|
||||
__cairo_list_add (entry, head, head->next);
|
||||
cairo_list_validate (head);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cairo_list_move_tail (cairo_list_t *entry, cairo_list_t *head)
|
||||
{
|
||||
cairo_list_validate (head);
|
||||
__cairo_list_del (entry->prev, entry->next);
|
||||
__cairo_list_add (entry, head->prev, head);
|
||||
cairo_list_validate (head);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cairo_list_swap (cairo_list_t *entry, cairo_list_t *other)
|
||||
{
|
||||
cairo_list_validate (head);
|
||||
__cairo_list_add (entry, other->prev, other->next);
|
||||
cairo_list_init (other);
|
||||
cairo_list_validate (head);
|
||||
}
|
||||
|
||||
static inline cairo_bool_t
|
||||
cairo_list_is_first (const cairo_list_t *entry,
|
||||
const cairo_list_t *head)
|
||||
{
|
||||
cairo_list_validate (head);
|
||||
return entry->prev == head;
|
||||
}
|
||||
|
||||
static inline cairo_bool_t
|
||||
cairo_list_is_last (const cairo_list_t *entry,
|
||||
const cairo_list_t *head)
|
||||
{
|
||||
cairo_list_validate (head);
|
||||
return entry->next == head;
|
||||
}
|
||||
|
||||
static inline cairo_bool_t
|
||||
cairo_list_is_empty (const cairo_list_t *head)
|
||||
{
|
||||
cairo_list_validate (head);
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
#endif /* CAIRO_LIST_PRIVATE_H */
|
@ -150,9 +150,8 @@ typedef struct _cairo_meta_surface {
|
||||
/* A meta-surface is logically unbounded, but when used as a
|
||||
* source we need to render it to an image, so we need a size at
|
||||
* which to create that image. */
|
||||
double width_pixels;
|
||||
double height_pixels;
|
||||
cairo_rectangle_int_t extents;
|
||||
int width_pixels;
|
||||
int height_pixels;
|
||||
|
||||
cairo_array_t commands;
|
||||
cairo_surface_t *commands_owner;
|
||||
@ -161,13 +160,18 @@ typedef struct _cairo_meta_surface {
|
||||
int replay_start_idx;
|
||||
} cairo_meta_surface_t;
|
||||
|
||||
slim_hidden_proto (cairo_meta_surface_create);
|
||||
slim_hidden_proto (cairo_meta_surface_replay);
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_meta_surface_create (cairo_content_t content,
|
||||
int width_pixels,
|
||||
int height_pixels);
|
||||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_meta_surface_get_path (cairo_surface_t *surface,
|
||||
cairo_path_fixed_t *path);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_meta_surface_replay_analyze_meta_pattern (cairo_surface_t *surface,
|
||||
|
@ -42,9 +42,7 @@
|
||||
* level of paint, mask, stroke, fill, and show_text_glyphs). The meta
|
||||
* surface can then be "replayed" against any target surface with:
|
||||
*
|
||||
* <informalexample><programlisting>
|
||||
* cairo_meta_surface_replay (meta, target);
|
||||
* </programlisting></informalexample>
|
||||
* _cairo_meta_surface_replay (meta, target);
|
||||
*
|
||||
* after which the results in target will be identical to the results
|
||||
* that would have been obtained if the original operations applied to
|
||||
@ -59,7 +57,6 @@
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
#include "cairo-clip-private.h"
|
||||
|
||||
@ -76,38 +73,13 @@ static const cairo_surface_backend_t cairo_meta_surface_backend;
|
||||
*
|
||||
* XXX: The naming of "pixels" in the size here is a misnomer. It's
|
||||
* actually a size in whatever device-space units are desired (again,
|
||||
* according to the intended replay target).
|
||||
* according to the intended replay target). This should likely also
|
||||
* be changed to use doubles not ints.
|
||||
*/
|
||||
|
||||
/**
|
||||
* cairo_meta_surface_create:
|
||||
* @content: the content of the meta surface
|
||||
* @width_pixels: width of the surface, in pixels
|
||||
* @height_pixels: height of the surface, in pixels
|
||||
*
|
||||
* Creates a meta-surface which can be used to record all drawing operations
|
||||
* at the highest level (that is, the level of paint, mask, stroke, fill
|
||||
* and show_text_glyphs). The meta surface can then be "replayed" against
|
||||
* any target surface with:
|
||||
*
|
||||
* <informalexample><programlisting>
|
||||
* cairo_meta_surface_replay (meta, target);
|
||||
* </programlisting></informalexample>
|
||||
*
|
||||
* after which the results in target will be identical to the results
|
||||
* that would have been obtained if the original operations applied to
|
||||
* the meta surface had instead been applied to the target surface.
|
||||
*
|
||||
* The recording phase of the meta surface is careful to snapshot all
|
||||
* necessary objects (paths, patterns, etc.), in order to achieve
|
||||
* accurate replay.
|
||||
*
|
||||
* Since 1.10
|
||||
**/
|
||||
cairo_surface_t *
|
||||
cairo_meta_surface_create (cairo_content_t content,
|
||||
double width_pixels,
|
||||
double height_pixels)
|
||||
_cairo_meta_surface_create (cairo_content_t content,
|
||||
int width_pixels,
|
||||
int height_pixels)
|
||||
{
|
||||
cairo_meta_surface_t *meta;
|
||||
|
||||
@ -122,29 +94,6 @@ cairo_meta_surface_create (cairo_content_t content,
|
||||
meta->width_pixels = width_pixels;
|
||||
meta->height_pixels = height_pixels;
|
||||
|
||||
/* unbounded -> 'infinite' extents */
|
||||
if (width_pixels < 0) {
|
||||
meta->extents.x = CAIRO_RECT_INT_MIN;
|
||||
meta->extents.width = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
||||
} else {
|
||||
meta->extents.x = 0;
|
||||
if (ceil (width_pixels) > CAIRO_RECT_INT_MAX)
|
||||
meta->extents.width = CAIRO_RECT_INT_MAX;
|
||||
else
|
||||
meta->extents.width = ceil (width_pixels);
|
||||
}
|
||||
|
||||
if (height_pixels < 0) {
|
||||
meta->extents.y = CAIRO_RECT_INT_MIN;
|
||||
meta->extents.height = CAIRO_RECT_INT_MAX - CAIRO_RECT_INT_MIN;
|
||||
} else {
|
||||
meta->extents.y = 0;
|
||||
if (ceil (height_pixels) > CAIRO_RECT_INT_MAX)
|
||||
meta->extents.height = CAIRO_RECT_INT_MAX;
|
||||
else
|
||||
meta->extents.height = ceil (height_pixels);
|
||||
}
|
||||
|
||||
_cairo_array_init (&meta->commands, sizeof (cairo_command_t *));
|
||||
meta->commands_owner = NULL;
|
||||
|
||||
@ -153,7 +102,6 @@ cairo_meta_surface_create (cairo_content_t content,
|
||||
|
||||
return &meta->base;
|
||||
}
|
||||
slim_hidden_def (cairo_meta_surface_create);
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_meta_surface_create_similar (void *abstract_surface,
|
||||
@ -161,7 +109,7 @@ _cairo_meta_surface_create_similar (void *abstract_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return cairo_meta_surface_create (content, width, height);
|
||||
return _cairo_meta_surface_create (content, width, height);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -186,31 +134,31 @@ _cairo_meta_surface_finish (void *abstract_surface)
|
||||
/* 5 basic drawing operations */
|
||||
|
||||
case CAIRO_COMMAND_PAINT:
|
||||
_cairo_pattern_fini_snapshot (&command->paint.source.base);
|
||||
_cairo_pattern_fini (&command->paint.source.base);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_MASK:
|
||||
_cairo_pattern_fini_snapshot (&command->mask.source.base);
|
||||
_cairo_pattern_fini_snapshot (&command->mask.mask.base);
|
||||
_cairo_pattern_fini (&command->mask.source.base);
|
||||
_cairo_pattern_fini (&command->mask.mask.base);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_STROKE:
|
||||
_cairo_pattern_fini_snapshot (&command->stroke.source.base);
|
||||
_cairo_pattern_fini (&command->stroke.source.base);
|
||||
_cairo_path_fixed_fini (&command->stroke.path);
|
||||
_cairo_stroke_style_fini (&command->stroke.style);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_FILL:
|
||||
_cairo_pattern_fini_snapshot (&command->fill.source.base);
|
||||
_cairo_pattern_fini (&command->fill.source.base);
|
||||
_cairo_path_fixed_fini (&command->fill.path);
|
||||
free (command);
|
||||
break;
|
||||
|
||||
case CAIRO_COMMAND_SHOW_TEXT_GLYPHS:
|
||||
_cairo_pattern_fini_snapshot (&command->show_text_glyphs.source.base);
|
||||
_cairo_pattern_fini (&command->show_text_glyphs.source.base);
|
||||
free (command->show_text_glyphs.utf8);
|
||||
free (command->show_text_glyphs.glyphs);
|
||||
free (command->show_text_glyphs.clusters);
|
||||
@ -244,26 +192,11 @@ _cairo_meta_surface_acquire_source_image (void *abstract_surface,
|
||||
cairo_meta_surface_t *surface = abstract_surface;
|
||||
cairo_surface_t *image;
|
||||
|
||||
image = _cairo_surface_has_snapshot (&surface->base,
|
||||
&_cairo_image_surface_backend,
|
||||
surface->content);
|
||||
if (image != NULL) {
|
||||
*image_out = (cairo_image_surface_t *) cairo_surface_reference (image);
|
||||
*image_extra = NULL;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
image = _cairo_image_surface_create_with_content (surface->content,
|
||||
ceil (surface->width_pixels),
|
||||
ceil (surface->height_pixels));
|
||||
surface->width_pixels,
|
||||
surface->height_pixels);
|
||||
|
||||
status = cairo_meta_surface_replay (&surface->base, image);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (image);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_surface_attach_snapshot (&surface->base, image, NULL);
|
||||
status = _cairo_meta_surface_replay (&surface->base, image);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (image);
|
||||
return status;
|
||||
@ -271,7 +204,8 @@ _cairo_meta_surface_acquire_source_image (void *abstract_surface,
|
||||
|
||||
*image_out = (cairo_image_surface_t *) image;
|
||||
*image_extra = NULL;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -282,16 +216,6 @@ _cairo_meta_surface_release_source_image (void *abstract_surface,
|
||||
cairo_surface_destroy (&image->base);
|
||||
}
|
||||
|
||||
static void
|
||||
_draw_command_init (cairo_command_header_t *command,
|
||||
cairo_command_type_t type,
|
||||
cairo_meta_surface_t *meta)
|
||||
{
|
||||
command->type = type;
|
||||
command->region = CAIRO_META_REGION_ALL;
|
||||
command->extents = meta->extents;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_paint (void *abstract_surface,
|
||||
cairo_operator_t op,
|
||||
@ -306,7 +230,12 @@ _cairo_meta_surface_paint (void *abstract_surface,
|
||||
if (unlikely (command == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_draw_command_init (&command->header, CAIRO_COMMAND_PAINT, meta);
|
||||
command->header.type = CAIRO_COMMAND_PAINT;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
command->header.extents.x = 0;
|
||||
command->header.extents.y = 0;
|
||||
command->header.extents.width = meta->width_pixels;
|
||||
command->header.extents.height = meta->height_pixels;
|
||||
command->op = op;
|
||||
|
||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||
@ -326,7 +255,7 @@ _cairo_meta_surface_paint (void *abstract_surface,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini_snapshot (&command->source.base);
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
@ -347,7 +276,12 @@ _cairo_meta_surface_mask (void *abstract_surface,
|
||||
if (unlikely (command == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_draw_command_init (&command->header, CAIRO_COMMAND_MASK, meta);
|
||||
command->header.type = CAIRO_COMMAND_MASK;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
command->header.extents.x = 0;
|
||||
command->header.extents.y = 0;
|
||||
command->header.extents.width = meta->width_pixels;
|
||||
command->header.extents.height = meta->height_pixels;
|
||||
command->op = op;
|
||||
|
||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||
@ -365,9 +299,9 @@ _cairo_meta_surface_mask (void *abstract_surface,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
CLEANUP_MASK:
|
||||
_cairo_pattern_fini_snapshot (&command->mask.base);
|
||||
_cairo_pattern_fini (&command->mask.base);
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini_snapshot (&command->source.base);
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
@ -393,7 +327,12 @@ _cairo_meta_surface_stroke (void *abstract_surface,
|
||||
if (unlikely (command == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_draw_command_init (&command->header, CAIRO_COMMAND_STROKE, meta);
|
||||
command->header.type = CAIRO_COMMAND_STROKE;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
command->header.extents.x = 0;
|
||||
command->header.extents.y = 0;
|
||||
command->header.extents.width = meta->width_pixels;
|
||||
command->header.extents.height = meta->height_pixels;
|
||||
command->op = op;
|
||||
|
||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||
@ -424,7 +363,7 @@ _cairo_meta_surface_stroke (void *abstract_surface,
|
||||
CLEANUP_PATH:
|
||||
_cairo_path_fixed_fini (&command->path);
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini_snapshot (&command->source.base);
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
@ -448,7 +387,12 @@ _cairo_meta_surface_fill (void *abstract_surface,
|
||||
if (unlikely (command == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_draw_command_init (&command->header, CAIRO_COMMAND_FILL, meta);
|
||||
command->header.type = CAIRO_COMMAND_FILL;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
command->header.extents.x = 0;
|
||||
command->header.extents.y = 0;
|
||||
command->header.extents.width = meta->width_pixels;
|
||||
command->header.extents.height = meta->height_pixels;
|
||||
command->op = op;
|
||||
|
||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||
@ -472,7 +416,7 @@ _cairo_meta_surface_fill (void *abstract_surface,
|
||||
CLEANUP_PATH:
|
||||
_cairo_path_fixed_fini (&command->path);
|
||||
CLEANUP_SOURCE:
|
||||
_cairo_pattern_fini_snapshot (&command->source.base);
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
@ -506,7 +450,12 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
|
||||
if (unlikely (command == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_draw_command_init (&command->header, CAIRO_COMMAND_SHOW_TEXT_GLYPHS, meta);
|
||||
command->header.type = CAIRO_COMMAND_SHOW_TEXT_GLYPHS;
|
||||
command->header.region = CAIRO_META_REGION_ALL;
|
||||
command->header.extents.x = 0;
|
||||
command->header.extents.y = 0;
|
||||
command->header.extents.width = meta->width_pixels;
|
||||
command->header.extents.height = meta->height_pixels;
|
||||
command->op = op;
|
||||
|
||||
status = _cairo_pattern_init_snapshot (&command->source.base, source);
|
||||
@ -562,7 +511,7 @@ _cairo_meta_surface_show_text_glyphs (void *abstract_surface,
|
||||
free (command->glyphs);
|
||||
free (command->clusters);
|
||||
|
||||
_cairo_pattern_fini_snapshot (&command->source.base);
|
||||
_cairo_pattern_fini (&command->source.base);
|
||||
CLEANUP_COMMAND:
|
||||
free (command);
|
||||
return status;
|
||||
@ -593,10 +542,10 @@ _cairo_meta_surface_snapshot (void *abstract_other)
|
||||
|
||||
_cairo_surface_init (&meta->base, &cairo_meta_surface_backend,
|
||||
other->base.content);
|
||||
meta->base.is_snapshot = TRUE;
|
||||
|
||||
meta->width_pixels = other->width_pixels;
|
||||
meta->height_pixels = other->height_pixels;
|
||||
meta->extents = other->extents;
|
||||
meta->replay_start_idx = other->replay_start_idx;
|
||||
meta->content = other->content;
|
||||
|
||||
@ -653,7 +602,7 @@ _cairo_meta_surface_intersect_clip_path (void *dst,
|
||||
|
||||
/* Currently, we're using as the "size" of a meta surface the largest
|
||||
* surface size against which the meta-surface is expected to be
|
||||
* replayed, (as passed in to cairo_meta_surface_create()).
|
||||
* replayed, (as passed in to _cairo_meta_surface_create).
|
||||
*/
|
||||
static cairo_int_status_t
|
||||
_cairo_meta_surface_get_extents (void *abstract_surface,
|
||||
@ -661,13 +610,13 @@ _cairo_meta_surface_get_extents (void *abstract_surface,
|
||||
{
|
||||
cairo_meta_surface_t *surface = abstract_surface;
|
||||
|
||||
if (surface->width_pixels < 0 || surface->height_pixels < 0)
|
||||
if (surface->width_pixels == -1 && surface->height_pixels == -1)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
rectangle->x = 0;
|
||||
rectangle->y = 0;
|
||||
rectangle->width = ceil (surface->width_pixels);
|
||||
rectangle->height = ceil (surface->height_pixels);
|
||||
rectangle->width = surface->width_pixels;
|
||||
rectangle->height = surface->height_pixels;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -687,7 +636,7 @@ _cairo_surface_is_meta (const cairo_surface_t *surface)
|
||||
}
|
||||
|
||||
static const cairo_surface_backend_t cairo_meta_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_META,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_META,
|
||||
_cairo_meta_surface_create_similar,
|
||||
_cairo_meta_surface_finish,
|
||||
_cairo_meta_surface_acquire_source_image,
|
||||
@ -1052,30 +1001,15 @@ _cairo_meta_surface_replay_internal (cairo_surface_t *surface,
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_meta_surface_replay:
|
||||
* @surface: the #cairo_meta_surface_t
|
||||
* @target: a target #cairo_surface_t onto which to replay the operations
|
||||
* @width_pixels: width of the surface, in pixels
|
||||
* @height_pixels: height of the surface, in pixels
|
||||
*
|
||||
* A meta surface can be "replayed" against any target surface,
|
||||
* after which the results in target will be identical to the results
|
||||
* that would have been obtained if the original operations applied to
|
||||
* the meta surface had instead been applied to the target surface.
|
||||
*
|
||||
* Since 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target)
|
||||
_cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
return _cairo_meta_surface_replay_internal (surface,
|
||||
target,
|
||||
CAIRO_META_REPLAY,
|
||||
CAIRO_META_REGION_ALL);
|
||||
}
|
||||
slim_hidden_def (cairo_meta_surface_replay);
|
||||
|
||||
/* Replay meta to surface. When the return status of each operation is
|
||||
* one of %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED, or
|
||||
@ -1103,59 +1037,3 @@ _cairo_meta_surface_replay_region (cairo_surface_t *surface,
|
||||
CAIRO_META_REPLAY,
|
||||
region);
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_meta_surface_ink_extents:
|
||||
* @surface: a #cairo_meta_surface_t
|
||||
* @x0: the x-coordinate of the top-left of the ink bounding box
|
||||
* @y0: the y-coordinate of the top-left of the ink bounding box
|
||||
* @width: the width of the ink bounding box
|
||||
* @height: the height of the ink bounding box
|
||||
*
|
||||
* Measures the extents of the operations stored within the meta-surface.
|
||||
* This is useful to compute the required size of an image surface (or
|
||||
* equivalent) into which to replay the full sequence of drawing operaitions.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
cairo_meta_surface_ink_extents (cairo_surface_t *surface,
|
||||
double *x0,
|
||||
double *y0,
|
||||
double *width,
|
||||
double *height)
|
||||
{
|
||||
cairo_surface_t *null_surface;
|
||||
cairo_surface_t *analysis_surface;
|
||||
cairo_status_t status;
|
||||
cairo_box_t bbox;
|
||||
|
||||
memset (&bbox, 0, sizeof (bbox));
|
||||
|
||||
if (! _cairo_surface_is_meta (surface)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
null_surface = _cairo_null_surface_create (CAIRO_CONTENT_COLOR_ALPHA);
|
||||
analysis_surface = _cairo_analysis_surface_create (null_surface, -1, -1);
|
||||
cairo_surface_destroy (null_surface);
|
||||
|
||||
status = analysis_surface->status;
|
||||
if (unlikely (status))
|
||||
goto DONE;
|
||||
|
||||
status = cairo_meta_surface_replay (surface, analysis_surface);
|
||||
_cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
|
||||
cairo_surface_destroy (analysis_surface);
|
||||
|
||||
DONE:
|
||||
if (x0)
|
||||
*x0 = _cairo_fixed_to_double (bbox.p1.x);
|
||||
if (y0)
|
||||
*y0 = _cairo_fixed_to_double (bbox.p1.y);
|
||||
if (width)
|
||||
*width = _cairo_fixed_to_double (bbox.p2.x - bbox.p1.x);
|
||||
if (height)
|
||||
*height = _cairo_fixed_to_double (bbox.p2.y - bbox.p1.y);
|
||||
}
|
||||
|
@ -58,13 +58,13 @@ cairo_status_to_string (cairo_status_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case CAIRO_STATUS_SUCCESS:
|
||||
return "no error has occurred";
|
||||
return "success";
|
||||
case CAIRO_STATUS_NO_MEMORY:
|
||||
return "out of memory";
|
||||
case CAIRO_STATUS_INVALID_RESTORE:
|
||||
return "cairo_restore() without matching cairo_save()";
|
||||
return "cairo_restore without matching cairo_save";
|
||||
case CAIRO_STATUS_INVALID_POP_GROUP:
|
||||
return "no saved group to pop, i.e. cairo_pop_group() without matching cairo_push_group()";
|
||||
return "cairo_pop_group without matching cairo_push_group";
|
||||
case CAIRO_STATUS_NO_CURRENT_POINT:
|
||||
return "no current point defined";
|
||||
case CAIRO_STATUS_INVALID_MATRIX:
|
||||
@ -118,11 +118,11 @@ cairo_status_to_string (cairo_status_t status)
|
||||
case CAIRO_STATUS_INVALID_CLUSTERS:
|
||||
return "input clusters do not represent the accompanying text and glyph arrays";
|
||||
case CAIRO_STATUS_INVALID_SLANT:
|
||||
return "invalid value for an input cairo_font_slant_t";
|
||||
return "invalid value for an input #cairo_font_slant_t";
|
||||
case CAIRO_STATUS_INVALID_WEIGHT:
|
||||
return "invalid value for an input cairo_font_weight_t";
|
||||
return "invalid value for an input #cairo_font_weight_t";
|
||||
case CAIRO_STATUS_INVALID_SIZE:
|
||||
return "invalid value (typically too big) for the size of the input (surface, pattern, etc.)";
|
||||
return "invalid value for the size of the input (surface, pattern, etc.)";
|
||||
case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
|
||||
return "user-font method not implemented";
|
||||
default:
|
||||
|
@ -36,6 +36,7 @@
|
||||
#define CAIRO_MUTEX_DECLARE(mutex)
|
||||
#endif
|
||||
|
||||
CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_pattern_cache_lock)
|
||||
CAIRO_MUTEX_DECLARE (_cairo_pattern_solid_surface_cache_lock)
|
||||
|
||||
CAIRO_MUTEX_DECLARE (_cairo_toy_font_face_mutex)
|
||||
|
@ -97,7 +97,7 @@ _cairo_paginated_surface_create (cairo_surface_t *target,
|
||||
|
||||
surface->backend = backend;
|
||||
|
||||
surface->meta = cairo_meta_surface_create (content, width, height);
|
||||
surface->meta = _cairo_meta_surface_create (content, width, height);
|
||||
status = cairo_surface_status (surface->meta);
|
||||
if (unlikely (status))
|
||||
goto FAIL_CLEANUP_SURFACE;
|
||||
@ -148,8 +148,8 @@ _cairo_paginated_surface_set_size (cairo_surface_t *surface,
|
||||
paginated_surface->height = height;
|
||||
|
||||
cairo_surface_destroy (paginated_surface->meta);
|
||||
paginated_surface->meta = cairo_meta_surface_create (paginated_surface->content,
|
||||
width, height);
|
||||
paginated_surface->meta = _cairo_meta_surface_create (paginated_surface->content,
|
||||
width, height);
|
||||
status = cairo_surface_status (paginated_surface->meta);
|
||||
if (unlikely (status))
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
@ -222,7 +222,7 @@ _cairo_paginated_surface_acquire_source_image (void *abstract_surface,
|
||||
extents.width,
|
||||
extents.height);
|
||||
|
||||
status = cairo_meta_surface_replay (surface->meta, image);
|
||||
status = _cairo_meta_surface_replay (surface->meta, image);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (image);
|
||||
return status;
|
||||
@ -266,7 +266,7 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
|
||||
* so we have to do the scaling manually. */
|
||||
cairo_surface_set_device_offset (image, -x*x_scale, -y*y_scale);
|
||||
|
||||
status = cairo_meta_surface_replay (surface->meta, image);
|
||||
status = _cairo_meta_surface_replay (surface->meta, image);
|
||||
if (unlikely (status))
|
||||
goto CLEANUP_IMAGE;
|
||||
|
||||
@ -481,9 +481,9 @@ _cairo_paginated_surface_show_page (void *abstract_surface)
|
||||
|
||||
cairo_surface_destroy (surface->meta);
|
||||
|
||||
surface->meta = cairo_meta_surface_create (surface->content,
|
||||
surface->width,
|
||||
surface->height);
|
||||
surface->meta = _cairo_meta_surface_create (surface->content,
|
||||
surface->width,
|
||||
surface->height);
|
||||
status = cairo_surface_status (surface->meta);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
@ -38,12 +38,6 @@
|
||||
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-list-private.h"
|
||||
|
||||
#define WATCH_PATH 0
|
||||
#if WATCH_PATH
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
enum cairo_path_op {
|
||||
CAIRO_PATH_OP_MOVE_TO = 0,
|
||||
@ -51,16 +45,15 @@ enum cairo_path_op {
|
||||
CAIRO_PATH_OP_CURVE_TO = 2,
|
||||
CAIRO_PATH_OP_CLOSE_PATH = 3
|
||||
};
|
||||
|
||||
/* we want to make sure a single byte is used for the enum */
|
||||
/* we want to make sure a single byte is used for thie enum */
|
||||
typedef char cairo_path_op_t;
|
||||
|
||||
/* make _cairo_path_fixed fit into ~512 bytes -- about 50 items */
|
||||
#define CAIRO_PATH_BUF_SIZE ((512 - sizeof (cairo_path_buf_t)) \
|
||||
/* make _cairo_path_fixed fit a 512 bytes. about 50 items */
|
||||
#define CAIRO_PATH_BUF_SIZE ((512 - 4 * sizeof (void*) - sizeof (cairo_path_buf_t)) \
|
||||
/ (2 * sizeof (cairo_point_t) + sizeof (cairo_path_op_t)))
|
||||
|
||||
typedef struct _cairo_path_buf {
|
||||
cairo_list_t link;
|
||||
struct _cairo_path_buf *next, *prev;
|
||||
unsigned int buf_size;
|
||||
unsigned int num_ops;
|
||||
unsigned int num_points;
|
||||
@ -68,7 +61,6 @@ typedef struct _cairo_path_buf {
|
||||
cairo_path_op_t *op;
|
||||
cairo_point_t *points;
|
||||
} cairo_path_buf_t;
|
||||
|
||||
typedef struct _cairo_path_buf_fixed {
|
||||
cairo_path_buf_t base;
|
||||
|
||||
@ -81,10 +73,9 @@ struct _cairo_path_fixed {
|
||||
cairo_point_t current_point;
|
||||
unsigned int has_current_point : 1;
|
||||
unsigned int has_curve_to : 1;
|
||||
unsigned int is_box : 1;
|
||||
unsigned int is_region : 1;
|
||||
|
||||
cairo_path_buf_fixed_t buf;
|
||||
cairo_path_buf_t *buf_tail;
|
||||
cairo_path_buf_fixed_t buf_head;
|
||||
};
|
||||
|
||||
cairo_private unsigned long
|
||||
@ -114,14 +105,4 @@ _cairo_path_fixed_iter_is_fill_box (cairo_path_fixed_iter_t *_iter,
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_path_fixed_iter_at_end (const cairo_path_fixed_iter_t *iter);
|
||||
|
||||
static inline cairo_bool_t
|
||||
_cairo_path_fixed_is_region (cairo_path_fixed_t *path)
|
||||
{
|
||||
#if WATCH_PATH
|
||||
fprintf (stderr, "_cairo_path_fixed_is_region () = %s\n",
|
||||
path->is_region ? "true" : "false");
|
||||
#endif
|
||||
return path->is_region;
|
||||
}
|
||||
|
||||
#endif /* CAIRO_PATH_FIXED_PRIVATE_H */
|
||||
|
@ -40,11 +40,12 @@
|
||||
|
||||
#include "cairo-path-fixed-private.h"
|
||||
|
||||
/* private functions */
|
||||
static cairo_status_t
|
||||
_cairo_path_fixed_add (cairo_path_fixed_t *path,
|
||||
cairo_path_op_t op,
|
||||
const cairo_point_t *points,
|
||||
int num_points);
|
||||
_cairo_path_fixed_add (cairo_path_fixed_t *path,
|
||||
cairo_path_op_t op,
|
||||
cairo_point_t *points,
|
||||
int num_points);
|
||||
|
||||
static void
|
||||
_cairo_path_fixed_add_buf (cairo_path_fixed_t *path,
|
||||
@ -61,43 +62,28 @@ _cairo_path_buf_add_op (cairo_path_buf_t *buf,
|
||||
cairo_path_op_t op);
|
||||
|
||||
static void
|
||||
_cairo_path_buf_add_points (cairo_path_buf_t *buf,
|
||||
const cairo_point_t *points,
|
||||
int num_points);
|
||||
|
||||
#define cairo_path_head(path__) (&(path__)->buf.base)
|
||||
#define cairo_path_tail(path__) cairo_path_buf_prev (cairo_path_head (path__))
|
||||
|
||||
#define cairo_path_buf_next(pos__) \
|
||||
cairo_list_entry ((pos__)->link.next, cairo_path_buf_t, link)
|
||||
#define cairo_path_buf_prev(pos__) \
|
||||
cairo_list_entry ((pos__)->link.prev, cairo_path_buf_t, link)
|
||||
|
||||
#define cairo_path_foreach_buf_start(pos__, path__) \
|
||||
pos__ = cairo_path_head (path__); do
|
||||
#define cairo_path_foreach_buf_end(pos__, path__) \
|
||||
while ((pos__ = cairo_path_buf_next (pos__)) != cairo_path_head (path__))
|
||||
_cairo_path_buf_add_points (cairo_path_buf_t *buf,
|
||||
cairo_point_t *points,
|
||||
int num_points);
|
||||
|
||||
void
|
||||
_cairo_path_fixed_init (cairo_path_fixed_t *path)
|
||||
{
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (path, sizeof (cairo_path_fixed_t)));
|
||||
path->buf_head.base.next = NULL;
|
||||
path->buf_head.base.prev = NULL;
|
||||
path->buf_tail = &path->buf_head.base;
|
||||
|
||||
cairo_list_init (&path->buf.base.link);
|
||||
|
||||
path->buf.base.num_ops = 0;
|
||||
path->buf.base.num_points = 0;
|
||||
path->buf.base.buf_size = CAIRO_PATH_BUF_SIZE;
|
||||
path->buf.base.op = path->buf.op;
|
||||
path->buf.base.points = path->buf.points;
|
||||
path->buf_head.base.num_ops = 0;
|
||||
path->buf_head.base.num_points = 0;
|
||||
path->buf_head.base.buf_size = CAIRO_PATH_BUF_SIZE;
|
||||
path->buf_head.base.op = path->buf_head.op;
|
||||
path->buf_head.base.points = path->buf_head.points;
|
||||
|
||||
path->current_point.x = 0;
|
||||
path->current_point.y = 0;
|
||||
path->last_move_point = path->current_point;
|
||||
path->has_current_point = FALSE;
|
||||
path->has_curve_to = FALSE;
|
||||
path->is_region = TRUE;
|
||||
path->is_box = TRUE;
|
||||
path->last_move_point = path->current_point;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -111,23 +97,21 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
||||
|
||||
path->current_point = other->current_point;
|
||||
path->has_current_point = other->has_current_point;
|
||||
path->last_move_point = other->last_move_point;
|
||||
path->has_curve_to = other->has_curve_to;
|
||||
path->is_box = other->is_box;
|
||||
path->is_region = other->is_region;
|
||||
path->last_move_point = other->last_move_point;
|
||||
|
||||
path->buf.base.num_ops = other->buf.base.num_ops;
|
||||
path->buf.base.num_points = other->buf.base.num_points;
|
||||
path->buf.base.buf_size = other->buf.base.buf_size;
|
||||
memcpy (path->buf.op, other->buf.base.op,
|
||||
other->buf.base.num_ops * sizeof (other->buf.op[0]));
|
||||
memcpy (path->buf.points, other->buf.points,
|
||||
other->buf.base.num_points * sizeof (other->buf.points[0]));
|
||||
path->buf_head.base.num_ops = other->buf_head.base.num_ops;
|
||||
path->buf_head.base.num_points = other->buf_head.base.num_points;
|
||||
path->buf_head.base.buf_size = other->buf_head.base.buf_size;
|
||||
memcpy (path->buf_head.op, other->buf_head.base.op,
|
||||
other->buf_head.base.num_ops * sizeof (other->buf_head.op[0]));
|
||||
memcpy (path->buf_head.points, other->buf_head.points,
|
||||
other->buf_head.base.num_points * sizeof (other->buf_head.points[0]));
|
||||
|
||||
num_points = num_ops = 0;
|
||||
for (other_buf = cairo_path_buf_next (cairo_path_head (other));
|
||||
other_buf != cairo_path_head (other);
|
||||
other_buf = cairo_path_buf_next (other_buf))
|
||||
for (other_buf = other->buf_head.base.next;
|
||||
other_buf != NULL;
|
||||
other_buf = other_buf->next)
|
||||
{
|
||||
num_ops += other_buf->num_ops;
|
||||
num_points += other_buf->num_points;
|
||||
@ -141,9 +125,9 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (other_buf = cairo_path_buf_next (cairo_path_head (other));
|
||||
other_buf != cairo_path_head (other);
|
||||
other_buf = cairo_path_buf_next (other_buf))
|
||||
for (other_buf = other->buf_head.base.next;
|
||||
other_buf != NULL;
|
||||
other_buf = other_buf->next)
|
||||
{
|
||||
memcpy (buf->op + buf->num_ops, other_buf->op,
|
||||
other_buf->num_ops * sizeof (buf->op[0]));
|
||||
@ -163,20 +147,31 @@ _cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
|
||||
unsigned long
|
||||
_cairo_path_fixed_hash (const cairo_path_fixed_t *path)
|
||||
{
|
||||
unsigned long hash = _CAIRO_HASH_INIT_VALUE;
|
||||
unsigned long hash = 0;
|
||||
const cairo_path_buf_t *buf;
|
||||
int num_points, num_ops;
|
||||
|
||||
num_ops = num_points = 0;
|
||||
cairo_path_foreach_buf_start (buf, path) {
|
||||
hash = _cairo_hash_bytes (hash,
|
||||
&path->current_point,
|
||||
sizeof (path->current_point));
|
||||
hash = _cairo_hash_bytes (hash,
|
||||
&path->last_move_point,
|
||||
sizeof (path->last_move_point));
|
||||
|
||||
num_ops = path->buf_head.base.num_ops;
|
||||
num_points = path->buf_head.base.num_points;
|
||||
for (buf = path->buf_head.base.next;
|
||||
buf != NULL;
|
||||
buf = buf->next)
|
||||
{
|
||||
hash = _cairo_hash_bytes (hash, buf->op,
|
||||
buf->num_ops * sizeof (buf->op[0]));
|
||||
buf->num_ops * sizeof (buf->op[0]));
|
||||
hash = _cairo_hash_bytes (hash, buf->points,
|
||||
buf->num_points * sizeof (buf->points[0]));
|
||||
buf->num_points * sizeof (buf->points[0]));
|
||||
|
||||
num_ops += buf->num_ops;
|
||||
num_points += buf->num_points;
|
||||
} cairo_path_foreach_buf_end (buf, path);
|
||||
}
|
||||
|
||||
hash = _cairo_hash_bytes (hash, &num_ops, sizeof (num_ops));
|
||||
hash = _cairo_hash_bytes (hash, &num_points, sizeof (num_points));
|
||||
@ -190,11 +185,15 @@ _cairo_path_fixed_size (const cairo_path_fixed_t *path)
|
||||
const cairo_path_buf_t *buf;
|
||||
int num_points, num_ops;
|
||||
|
||||
num_ops = num_points = 0;
|
||||
cairo_path_foreach_buf_start (buf, path) {
|
||||
num_ops = path->buf_head.base.num_ops;
|
||||
num_points = path->buf_head.base.num_points;
|
||||
for (buf = path->buf_head.base.next;
|
||||
buf != NULL;
|
||||
buf = buf->next)
|
||||
{
|
||||
num_ops += buf->num_ops;
|
||||
num_points += buf->num_points;
|
||||
} cairo_path_foreach_buf_end (buf, path);
|
||||
}
|
||||
|
||||
return num_ops * sizeof (buf->op[0]) +
|
||||
num_points * sizeof (buf->points[0]);
|
||||
@ -213,29 +212,31 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
|
||||
if (a == b)
|
||||
return TRUE;
|
||||
|
||||
/* use the flags to quickly differentiate based on contents */
|
||||
if (a->has_curve_to != b->has_curve_to ||
|
||||
a->is_region != b->is_region ||
|
||||
a->is_box != b->is_box)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
num_ops_a = num_points_a = 0;
|
||||
if (a != NULL) {
|
||||
cairo_path_foreach_buf_start (buf_a, a) {
|
||||
num_ops_a = a->buf_head.base.num_ops;
|
||||
num_points_a = a->buf_head.base.num_points;
|
||||
for (buf_a = a->buf_head.base.next;
|
||||
buf_a != NULL;
|
||||
buf_a = buf_a->next)
|
||||
{
|
||||
num_ops_a += buf_a->num_ops;
|
||||
num_points_a += buf_a->num_points;
|
||||
} cairo_path_foreach_buf_end (buf_a, a);
|
||||
}
|
||||
}
|
||||
} else
|
||||
num_ops_a = num_points_a = 0;
|
||||
|
||||
num_ops_b = num_points_b = 0;
|
||||
if (b != NULL) {
|
||||
cairo_path_foreach_buf_start (buf_b, b) {
|
||||
num_ops_b = b->buf_head.base.num_ops;
|
||||
num_points_b = b->buf_head.base.num_points;
|
||||
for (buf_b = b->buf_head.base.next;
|
||||
buf_b != NULL;
|
||||
buf_b = buf_b->next)
|
||||
{
|
||||
num_ops_b += buf_b->num_ops;
|
||||
num_points_b += buf_b->num_points;
|
||||
} cairo_path_foreach_buf_end (buf_b, b);
|
||||
}
|
||||
}
|
||||
} else
|
||||
num_ops_b = num_points_b = 0;
|
||||
|
||||
if (num_ops_a == 0 && num_ops_b == 0)
|
||||
return TRUE;
|
||||
@ -245,13 +246,13 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
|
||||
|
||||
assert (a != NULL && b != NULL);
|
||||
|
||||
buf_a = cairo_path_head (a);
|
||||
buf_a = &a->buf_head.base;
|
||||
num_points_a = buf_a->num_points;
|
||||
num_ops_a = buf_a->num_ops;
|
||||
ops_a = buf_a->op;
|
||||
points_a = buf_a->points;
|
||||
|
||||
buf_b = cairo_path_head (b);
|
||||
buf_b = &b->buf_head.base;
|
||||
num_points_b = buf_b->num_points;
|
||||
num_ops_b = buf_b->num_ops;
|
||||
ops_b = buf_b->op;
|
||||
@ -274,8 +275,8 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
|
||||
if (num_ops_a || num_points_a)
|
||||
return FALSE;
|
||||
|
||||
buf_a = cairo_path_buf_next (buf_a);
|
||||
if (buf_a == cairo_path_head (a))
|
||||
buf_a = buf_a->next;
|
||||
if (buf_a == NULL)
|
||||
break;
|
||||
|
||||
num_points_a = buf_a->num_points;
|
||||
@ -292,8 +293,8 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
|
||||
if (num_ops_b || num_points_b)
|
||||
return FALSE;
|
||||
|
||||
buf_b = cairo_path_buf_next (buf_b);
|
||||
if (buf_b == cairo_path_head (b))
|
||||
buf_b = buf_b->next;
|
||||
if (buf_b == NULL)
|
||||
break;
|
||||
|
||||
num_points_b = buf_b->num_points;
|
||||
@ -306,6 +307,7 @@ _cairo_path_fixed_equal (const cairo_path_fixed_t *a,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
cairo_path_fixed_t *
|
||||
_cairo_path_fixed_create (void)
|
||||
{
|
||||
@ -326,14 +328,20 @@ _cairo_path_fixed_fini (cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
|
||||
buf = cairo_path_buf_next (cairo_path_head (path));
|
||||
while (buf != cairo_path_head (path)) {
|
||||
buf = path->buf_head.base.next;
|
||||
while (buf) {
|
||||
cairo_path_buf_t *this = buf;
|
||||
buf = cairo_path_buf_next (buf);
|
||||
buf = buf->next;
|
||||
_cairo_path_buf_destroy (this);
|
||||
}
|
||||
path->buf_head.base.next = NULL;
|
||||
path->buf_head.base.prev = NULL;
|
||||
path->buf_tail = &path->buf_head.base;
|
||||
path->buf_head.base.num_ops = 0;
|
||||
path->buf_head.base.num_points = 0;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (path, sizeof (cairo_path_fixed_t)));
|
||||
path->has_current_point = FALSE;
|
||||
path->has_curve_to = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
@ -343,18 +351,6 @@ _cairo_path_fixed_destroy (cairo_path_fixed_t *path)
|
||||
free (path);
|
||||
}
|
||||
|
||||
static cairo_path_op_t
|
||||
_cairo_path_last_op (cairo_path_fixed_t *path)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
|
||||
buf = cairo_path_tail (path);
|
||||
if (buf->num_ops == 0)
|
||||
return -1;
|
||||
|
||||
return buf->op[buf->num_ops - 1];
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t x,
|
||||
@ -368,31 +364,21 @@ _cairo_path_fixed_move_to (cairo_path_fixed_t *path,
|
||||
|
||||
/* If the previous op was also a MOVE_TO, then just change its
|
||||
* point rather than adding a new op. */
|
||||
if (_cairo_path_last_op (path) == CAIRO_PATH_OP_MOVE_TO) {
|
||||
cairo_path_buf_t *buf;
|
||||
|
||||
buf = cairo_path_tail (path);
|
||||
buf->points[buf->num_points - 1] = point;
|
||||
if (path->buf_tail && path->buf_tail->num_ops &&
|
||||
path->buf_tail->op[path->buf_tail->num_ops - 1] == CAIRO_PATH_OP_MOVE_TO)
|
||||
{
|
||||
cairo_point_t *last_move_to_point;
|
||||
last_move_to_point = &path->buf_tail->points[path->buf_tail->num_points - 1];
|
||||
*last_move_to_point = point;
|
||||
} else {
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO, &point, 1);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (path->has_current_point && path->is_box) {
|
||||
/* a move-to is first an implicit close */
|
||||
path->is_box = path->current_point.x == path->last_move_point.x ||
|
||||
path->current_point.y == path->last_move_point.y;
|
||||
path->is_region &= path->is_box;
|
||||
}
|
||||
if (path->is_region) {
|
||||
path->is_region = _cairo_fixed_is_integer (x) &&
|
||||
_cairo_fixed_is_integer (y);
|
||||
}
|
||||
}
|
||||
|
||||
path->current_point = point;
|
||||
path->last_move_point = point;
|
||||
path->has_current_point = TRUE;
|
||||
path->last_move_point = path->current_point;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -408,13 +394,15 @@ _cairo_path_fixed_rel_move_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx,
|
||||
cairo_fixed_t dy)
|
||||
{
|
||||
if (unlikely (! path->has_current_point))
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
return _cairo_path_fixed_move_to (path,
|
||||
path->current_point.x + dx,
|
||||
path->current_point.y + dy);
|
||||
x = path->current_point.x + dx;
|
||||
y = path->current_point.y + dy;
|
||||
|
||||
return _cairo_path_fixed_move_to (path, x, y);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -430,28 +418,21 @@ _cairo_path_fixed_line_to (cairo_path_fixed_t *path,
|
||||
|
||||
/* When there is not yet a current point, the line_to operation
|
||||
* becomes a move_to instead. Note: We have to do this by
|
||||
* explicitly calling into _cairo_path_fixed_move_to to ensure
|
||||
* explicitly calling into _cairo_path_fixed_line_to to ensure
|
||||
* that the last_move_point state is updated properly.
|
||||
*/
|
||||
if (! path->has_current_point) {
|
||||
if (! path->has_current_point)
|
||||
status = _cairo_path_fixed_move_to (path, point.x, point.y);
|
||||
} else {
|
||||
else
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_LINE_TO, &point, 1);
|
||||
if (path->is_box) {
|
||||
path->is_box = path->current_point.x == x ||
|
||||
path->current_point.y == y;
|
||||
path->is_region &= path->is_box;
|
||||
}
|
||||
if (path->is_region) {
|
||||
path->is_region = _cairo_fixed_is_integer (x) &&
|
||||
_cairo_fixed_is_integer (y);
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
path->current_point = point;
|
||||
path->has_current_point = TRUE;
|
||||
|
||||
return status;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -459,12 +440,15 @@ _cairo_path_fixed_rel_line_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx,
|
||||
cairo_fixed_t dy)
|
||||
{
|
||||
if (unlikely (! path->has_current_point))
|
||||
cairo_fixed_t x, y;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
return _cairo_path_fixed_line_to (path,
|
||||
path->current_point.x + dx,
|
||||
path->current_point.y + dy);
|
||||
x = path->current_point.x + dx;
|
||||
y = path->current_point.y + dy;
|
||||
|
||||
return _cairo_path_fixed_line_to (path, x, y);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -476,19 +460,17 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
|
||||
cairo_status_t status;
|
||||
cairo_point_t point[3];
|
||||
|
||||
/* make sure subpaths are started properly */
|
||||
point[0].x = x0; point[0].y = y0;
|
||||
point[1].x = x1; point[1].y = y1;
|
||||
point[2].x = x2; point[2].y = y2;
|
||||
|
||||
if (! path->has_current_point) {
|
||||
status = _cairo_path_fixed_move_to (path, x0, y0);
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_MOVE_TO,
|
||||
&point[0], 1);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
||||
if (x2 == path->current_point.x && y2 == path->current_point.y)
|
||||
return _cairo_path_fixed_line_to (path, x2, y2);
|
||||
|
||||
point[0].x = x0; point[0].y = y0;
|
||||
point[1].x = x1; point[1].y = y1;
|
||||
point[2].x = x2; point[2].y = y2;
|
||||
status = _cairo_path_fixed_add (path, CAIRO_PATH_OP_CURVE_TO, point, 3);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
@ -496,8 +478,6 @@ _cairo_path_fixed_curve_to (cairo_path_fixed_t *path,
|
||||
path->current_point = point[2];
|
||||
path->has_current_point = TRUE;
|
||||
path->has_curve_to = TRUE;
|
||||
path->is_box = FALSE;
|
||||
path->is_region = FALSE;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -508,24 +488,26 @@ _cairo_path_fixed_rel_curve_to (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t dx1, cairo_fixed_t dy1,
|
||||
cairo_fixed_t dx2, cairo_fixed_t dy2)
|
||||
{
|
||||
if (unlikely (! path->has_current_point))
|
||||
cairo_fixed_t x0, y0;
|
||||
cairo_fixed_t x1, y1;
|
||||
cairo_fixed_t x2, y2;
|
||||
|
||||
if (! path->has_current_point)
|
||||
return _cairo_error (CAIRO_STATUS_NO_CURRENT_POINT);
|
||||
|
||||
if (dx2 == 0 && dy2 == 0) {
|
||||
return _cairo_path_fixed_line_to (path,
|
||||
path->current_point.x,
|
||||
path->current_point.y);
|
||||
}
|
||||
x0 = path->current_point.x + dx0;
|
||||
y0 = path->current_point.y + dy0;
|
||||
|
||||
x1 = path->current_point.x + dx1;
|
||||
y1 = path->current_point.y + dy1;
|
||||
|
||||
x2 = path->current_point.x + dx2;
|
||||
y2 = path->current_point.y + dy2;
|
||||
|
||||
return _cairo_path_fixed_curve_to (path,
|
||||
path->current_point.x + dx0,
|
||||
path->current_point.y + dy0,
|
||||
|
||||
path->current_point.x + dx1,
|
||||
path->current_point.y + dy1,
|
||||
|
||||
path->current_point.x + dx2,
|
||||
path->current_point.y + dy2);
|
||||
x0, y0,
|
||||
x1, y1,
|
||||
x2, y2);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -540,9 +522,13 @@ _cairo_path_fixed_close_path (cairo_path_fixed_t *path)
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
return _cairo_path_fixed_move_to (path,
|
||||
path->last_move_point.x,
|
||||
path->last_move_point.y);
|
||||
status = _cairo_path_fixed_move_to (path,
|
||||
path->last_move_point.x,
|
||||
path->last_move_point.y);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
@ -560,12 +546,12 @@ _cairo_path_fixed_get_current_point (cairo_path_fixed_t *path,
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_path_fixed_add (cairo_path_fixed_t *path,
|
||||
cairo_path_op_t op,
|
||||
const cairo_point_t *points,
|
||||
int num_points)
|
||||
_cairo_path_fixed_add (cairo_path_fixed_t *path,
|
||||
cairo_path_op_t op,
|
||||
cairo_point_t *points,
|
||||
int num_points)
|
||||
{
|
||||
cairo_path_buf_t *buf = cairo_path_tail (path);
|
||||
cairo_path_buf_t *buf = path->buf_tail;
|
||||
|
||||
if (buf->num_ops + 1 > buf->buf_size ||
|
||||
buf->num_points + num_points > 2 * buf->buf_size)
|
||||
@ -577,32 +563,6 @@ _cairo_path_fixed_add (cairo_path_fixed_t *path,
|
||||
_cairo_path_fixed_add_buf (path, buf);
|
||||
}
|
||||
|
||||
if (WATCH_PATH) {
|
||||
const char *op_str[] = {
|
||||
"move-to",
|
||||
"line-to",
|
||||
"curve-to",
|
||||
"close-path",
|
||||
};
|
||||
char buf[1024];
|
||||
int len = 0;
|
||||
int i;
|
||||
|
||||
len += snprintf (buf + len, sizeof (buf), "[");
|
||||
for (i = 0; i < num_points; i++) {
|
||||
if (i != 0)
|
||||
len += snprintf (buf + len, sizeof (buf), " ");
|
||||
len += snprintf (buf + len, sizeof (buf), "(%f, %f)",
|
||||
_cairo_fixed_to_double (points[i].x),
|
||||
_cairo_fixed_to_double (points[i].y));
|
||||
}
|
||||
len += snprintf (buf + len, sizeof (buf), "]");
|
||||
|
||||
fprintf (stderr,
|
||||
"_cairo_path_fixed_add (%s, %s)\n",
|
||||
op_str[(int) op], buf);
|
||||
}
|
||||
|
||||
_cairo_path_buf_add_op (buf, op);
|
||||
_cairo_path_buf_add_points (buf, points, num_points);
|
||||
|
||||
@ -613,7 +573,11 @@ static void
|
||||
_cairo_path_fixed_add_buf (cairo_path_fixed_t *path,
|
||||
cairo_path_buf_t *buf)
|
||||
{
|
||||
cairo_list_add_tail (&buf->link, &cairo_path_head (path)->link);
|
||||
buf->next = NULL;
|
||||
buf->prev = path->buf_tail;
|
||||
|
||||
path->buf_tail->next = buf;
|
||||
path->buf_tail = buf;
|
||||
}
|
||||
|
||||
static cairo_path_buf_t *
|
||||
@ -629,6 +593,8 @@ _cairo_path_buf_create (int buf_size)
|
||||
2 * sizeof (cairo_point_t),
|
||||
sizeof (cairo_path_buf_t));
|
||||
if (buf) {
|
||||
buf->next = NULL;
|
||||
buf->prev = NULL;
|
||||
buf->num_ops = 0;
|
||||
buf->num_points = 0;
|
||||
buf->buf_size = buf_size;
|
||||
@ -654,16 +620,25 @@ _cairo_path_buf_add_op (cairo_path_buf_t *buf,
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_path_buf_add_points (cairo_path_buf_t *buf,
|
||||
const cairo_point_t *points,
|
||||
int num_points)
|
||||
_cairo_path_buf_add_points (cairo_path_buf_t *buf,
|
||||
cairo_point_t *points,
|
||||
int num_points)
|
||||
{
|
||||
memcpy (buf->points + buf->num_points,
|
||||
points,
|
||||
sizeof (points[0]) * num_points);
|
||||
buf->num_points += num_points;
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_points; i++) {
|
||||
buf->points[buf->num_points++] = points[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int const num_args[] =
|
||||
{
|
||||
1, /* cairo_path_move_to */
|
||||
1, /* cairo_path_op_line_to */
|
||||
3, /* cairo_path_op_curve_to */
|
||||
0, /* cairo_path_op_close_path */
|
||||
};
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_interpret (const cairo_path_fixed_t *path,
|
||||
cairo_direction_t dir,
|
||||
@ -673,22 +648,18 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t *path,
|
||||
cairo_path_fixed_close_path_func_t *close_path,
|
||||
void *closure)
|
||||
{
|
||||
const uint8_t num_args[] = {
|
||||
1, /* cairo_path_move_to */
|
||||
1, /* cairo_path_op_line_to */
|
||||
3, /* cairo_path_op_curve_to */
|
||||
0, /* cairo_path_op_close_path */
|
||||
};
|
||||
cairo_status_t status;
|
||||
const cairo_path_buf_t *buf, *first;
|
||||
const cairo_path_buf_t *buf;
|
||||
cairo_path_op_t op;
|
||||
cairo_bool_t forward = (dir == CAIRO_DIRECTION_FORWARD);
|
||||
int step = forward ? 1 : -1;
|
||||
|
||||
buf = first = forward ? cairo_path_head (path) : cairo_path_tail (path);
|
||||
do {
|
||||
for (buf = forward ? &path->buf_head.base : path->buf_tail;
|
||||
buf;
|
||||
buf = forward ? buf->next : buf->prev)
|
||||
{
|
||||
cairo_point_t *points;
|
||||
int start, stop, i;
|
||||
|
||||
if (forward) {
|
||||
start = 0;
|
||||
stop = buf->num_ops;
|
||||
@ -699,11 +670,12 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t *path,
|
||||
points = buf->points + buf->num_points;
|
||||
}
|
||||
|
||||
for (i = start; i != stop; i += step) {
|
||||
cairo_path_op_t op = buf->op[i];
|
||||
for (i=start; i != stop; i += step) {
|
||||
op = buf->op[i];
|
||||
|
||||
if (! forward)
|
||||
if (! forward) {
|
||||
points -= num_args[(int) op];
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case CAIRO_PATH_OP_MOVE_TO:
|
||||
@ -715,19 +687,20 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t *path,
|
||||
case CAIRO_PATH_OP_CURVE_TO:
|
||||
status = (*curve_to) (closure, &points[0], &points[1], &points[2]);
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
case CAIRO_PATH_OP_CLOSE_PATH:
|
||||
default:
|
||||
status = (*close_path) (closure);
|
||||
break;
|
||||
}
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (forward)
|
||||
if (forward) {
|
||||
points += num_args[(int) op];
|
||||
}
|
||||
|
||||
}
|
||||
} while ((buf = forward ? cairo_path_buf_next (buf) : cairo_path_buf_prev (buf)) != first);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -736,14 +709,16 @@ static cairo_status_t
|
||||
_append_move_to (void *closure,
|
||||
const cairo_point_t *point)
|
||||
{
|
||||
return _cairo_path_fixed_move_to (closure, point->x, point->y);
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) closure;
|
||||
return _cairo_path_fixed_move_to (path, point->x, point->y);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_append_line_to (void *closure,
|
||||
const cairo_point_t *point)
|
||||
{
|
||||
return _cairo_path_fixed_line_to (closure, point->x, point->y);
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) closure;
|
||||
return _cairo_path_fixed_line_to (path, point->x, point->y);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -752,16 +727,15 @@ _append_curve_to (void *closure,
|
||||
const cairo_point_t *p1,
|
||||
const cairo_point_t *p2)
|
||||
{
|
||||
return _cairo_path_fixed_curve_to (closure,
|
||||
p0->x, p0->y,
|
||||
p1->x, p1->y,
|
||||
p2->x, p2->y);
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) closure;
|
||||
return _cairo_path_fixed_curve_to (path, p0->x, p0->y, p1->x, p1->y, p2->x, p2->y);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_append_close_path (void *closure)
|
||||
{
|
||||
return _cairo_path_fixed_close_path (closure);
|
||||
cairo_path_fixed_t *path = (cairo_path_fixed_t *) closure;
|
||||
return _cairo_path_fixed_close_path (path);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -784,10 +758,10 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||
cairo_fixed_t scalex,
|
||||
cairo_fixed_t scaley)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
unsigned int i;
|
||||
|
||||
cairo_path_foreach_buf_start (buf, path) {
|
||||
while (buf) {
|
||||
for (i = 0; i < buf->num_points; i++) {
|
||||
if (scalex != CAIRO_FIXED_ONE)
|
||||
buf->points[i].x = _cairo_fixed_mul (buf->points[i].x, scalex);
|
||||
@ -797,7 +771,9 @@ _cairo_path_fixed_offset_and_scale (cairo_path_fixed_t *path,
|
||||
buf->points[i].y = _cairo_fixed_mul (buf->points[i].y, scaley);
|
||||
buf->points[i].y += offy;
|
||||
}
|
||||
} cairo_path_foreach_buf_end (buf, path);
|
||||
|
||||
buf = buf->next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -827,7 +803,8 @@ _cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
||||
return;
|
||||
}
|
||||
|
||||
cairo_path_foreach_buf_start (buf, path) {
|
||||
buf = &path->buf_head.base;
|
||||
while (buf) {
|
||||
for (i = 0; i < buf->num_points; i++) {
|
||||
dx = _cairo_fixed_to_double (buf->points[i].x);
|
||||
dy = _cairo_fixed_to_double (buf->points[i].y);
|
||||
@ -837,7 +814,9 @@ _cairo_path_fixed_transform (cairo_path_fixed_t *path,
|
||||
buf->points[i].x = _cairo_fixed_from_double (dx);
|
||||
buf->points[i].y = _cairo_fixed_from_double (dy);
|
||||
}
|
||||
} cairo_path_foreach_buf_end (buf, path);
|
||||
|
||||
buf = buf->next;
|
||||
}
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
@ -850,15 +829,17 @@ _cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
|
||||
path->current_point.y != other->current_point.y ||
|
||||
path->has_current_point != other->has_current_point ||
|
||||
path->has_curve_to != other->has_curve_to ||
|
||||
path->is_box != other->is_box ||
|
||||
path->is_region != other->is_region ||
|
||||
path->last_move_point.x != other->last_move_point.x ||
|
||||
path->last_move_point.y != other->last_move_point.y)
|
||||
return FALSE;
|
||||
|
||||
other_buf = cairo_path_head (other);
|
||||
cairo_path_foreach_buf_start (path_buf, path) {
|
||||
if (path_buf->num_ops != other_buf->num_ops ||
|
||||
other_buf = &other->buf_head.base;
|
||||
for (path_buf = &path->buf_head.base;
|
||||
path_buf != NULL;
|
||||
path_buf = path_buf->next)
|
||||
{
|
||||
if (other_buf == NULL ||
|
||||
path_buf->num_ops != other_buf->num_ops ||
|
||||
path_buf->num_points != other_buf->num_points ||
|
||||
memcmp (path_buf->op, other_buf->op,
|
||||
sizeof (cairo_path_op_t) * path_buf->num_ops) != 0 ||
|
||||
@ -867,9 +848,8 @@ _cairo_path_fixed_is_equal (cairo_path_fixed_t *path,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
other_buf = cairo_path_buf_next (other_buf);
|
||||
} cairo_path_foreach_buf_end (path_buf, path);
|
||||
|
||||
other_buf = other_buf->next;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -937,6 +917,7 @@ _cpf_close_path (void *closure)
|
||||
return cpf->close_path (cpf->closure);
|
||||
}
|
||||
|
||||
|
||||
cairo_status_t
|
||||
_cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path,
|
||||
cairo_direction_t dir,
|
||||
@ -948,7 +929,7 @@ _cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path,
|
||||
{
|
||||
cpf_t flattener;
|
||||
|
||||
if (! path->has_curve_to) {
|
||||
if (!path->has_curve_to) {
|
||||
return _cairo_path_fixed_interpret (path, dir,
|
||||
move_to,
|
||||
line_to,
|
||||
@ -973,7 +954,7 @@ _cairo_path_fixed_interpret_flat (const cairo_path_fixed_t *path,
|
||||
cairo_bool_t
|
||||
_cairo_path_fixed_is_empty (cairo_path_fixed_t *path)
|
||||
{
|
||||
if (cairo_path_head (path)->num_ops == 0)
|
||||
if (path->buf_head.base.num_ops == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@ -986,9 +967,10 @@ cairo_bool_t
|
||||
_cairo_path_fixed_is_box (cairo_path_fixed_t *path,
|
||||
cairo_box_t *box)
|
||||
{
|
||||
cairo_path_buf_t *buf = cairo_path_head (path);
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
|
||||
if (! path->is_box)
|
||||
/* We can't have more than one buf for this check */
|
||||
if (buf->next != NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Do we have the right number of ops? */
|
||||
@ -1061,12 +1043,11 @@ cairo_bool_t
|
||||
_cairo_path_fixed_is_rectangle (cairo_path_fixed_t *path,
|
||||
cairo_box_t *box)
|
||||
{
|
||||
cairo_path_buf_t *buf;
|
||||
cairo_path_buf_t *buf = &path->buf_head.base;
|
||||
|
||||
if (!_cairo_path_fixed_is_box (path, box))
|
||||
return FALSE;
|
||||
|
||||
buf = cairo_path_head (path);
|
||||
if (buf->points[0].y == buf->points[1].y)
|
||||
return TRUE;
|
||||
|
||||
@ -1077,7 +1058,7 @@ void
|
||||
_cairo_path_fixed_iter_init (cairo_path_fixed_iter_t *iter,
|
||||
cairo_path_fixed_t *path)
|
||||
{
|
||||
iter->buf = cairo_path_head (path);
|
||||
iter->buf = &path->buf_head.base;
|
||||
iter->n_op = 0;
|
||||
iter->n_point = 0;
|
||||
}
|
||||
@ -1086,7 +1067,7 @@ static cairo_bool_t
|
||||
_cairo_path_fixed_iter_next_op (cairo_path_fixed_iter_t *iter)
|
||||
{
|
||||
if (++iter->n_op >= iter->buf->num_ops) {
|
||||
iter->buf = cairo_path_buf_next (iter->buf);
|
||||
iter->buf = iter->buf->next;
|
||||
iter->n_op = 0;
|
||||
iter->n_point = 0;
|
||||
}
|
||||
@ -1197,3 +1178,91 @@ _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,
|
||||
const 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->y = p2->y;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
} else if (p2->y == p1->y) {
|
||||
if (_cairo_fixed_is_integer (p2->x)) {
|
||||
p1->x = p2->x;
|
||||
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,
|
||||
const cairo_point_t *p)
|
||||
{
|
||||
cprt_t *self = closure;
|
||||
cairo_status_t status;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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;
|
||||
|
||||
return _cairo_path_fixed_interpret (path,
|
||||
CAIRO_DIRECTION_FORWARD,
|
||||
_cprt_move_to,
|
||||
_cprt_line_to,
|
||||
NULL,
|
||||
_cprt_close_path,
|
||||
&cprt) == CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -122,11 +122,11 @@ _cairo_in_fill_add_edge (cairo_in_fill_t *in_fill,
|
||||
}
|
||||
|
||||
/* First check whether the query is on an edge */
|
||||
if ((p1->x == in_fill->x && p1->y == in_fill->y) ||
|
||||
(p2->x == in_fill->x && p2->y == in_fill->y) ||
|
||||
(! (p2->y < in_fill->y || p1->y > in_fill->y ||
|
||||
(p1->x > in_fill->x && p2->x > in_fill->x) ||
|
||||
(p1->x < in_fill->x && p2->x < in_fill->x)) &&
|
||||
if ((p1->x == in_fill->x && p1->x == in_fill->y) ||
|
||||
(p2->x == in_fill->x && p2->x == in_fill->y) ||
|
||||
(! (p2->y < in_fill->y || p1->y > in_fill->y) &&
|
||||
! (p1->x > in_fill->x && p2->x > in_fill->x) &&
|
||||
! (p1->x < in_fill->x && p2->x < in_fill->x) &&
|
||||
edge_compare_for_y_against_x (p1, p2, in_fill->y, in_fill->x) == 0))
|
||||
{
|
||||
in_fill->on_edge = TRUE;
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
static const cairo_solid_pattern_t _cairo_pattern_nil = {
|
||||
const cairo_solid_pattern_t _cairo_pattern_nil = {
|
||||
{ CAIRO_PATTERN_TYPE_SOLID, /* type */
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
@ -96,23 +96,6 @@ _cairo_pattern_set_error (cairo_pattern_t *pattern,
|
||||
static void
|
||||
_cairo_pattern_init (cairo_pattern_t *pattern, cairo_pattern_type_t type)
|
||||
{
|
||||
#if HAVE_VALGRIND
|
||||
switch (type) {
|
||||
case CAIRO_PATTERN_TYPE_SOLID:
|
||||
VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_solid_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_surface_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_linear_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_radial_pattern_t));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
pattern->type = type;
|
||||
pattern->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
@ -185,16 +168,12 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
|
||||
cairo_solid_pattern_t *dst = (cairo_solid_pattern_t *) pattern;
|
||||
cairo_solid_pattern_t *src = (cairo_solid_pattern_t *) other;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_solid_pattern_t)));
|
||||
|
||||
*dst = *src;
|
||||
} break;
|
||||
case CAIRO_PATTERN_TYPE_SURFACE: {
|
||||
cairo_surface_pattern_t *dst = (cairo_surface_pattern_t *) pattern;
|
||||
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) other;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_surface_pattern_t)));
|
||||
|
||||
*dst = *src;
|
||||
cairo_surface_reference (dst->surface);
|
||||
} break;
|
||||
@ -204,12 +183,6 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
|
||||
cairo_gradient_pattern_t *src = (cairo_gradient_pattern_t *) other;
|
||||
cairo_status_t status;
|
||||
|
||||
if (other->type == CAIRO_PATTERN_TYPE_LINEAR) {
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_linear_pattern_t)));
|
||||
} else {
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (pattern, sizeof (cairo_radial_pattern_t)));
|
||||
}
|
||||
|
||||
status = _cairo_gradient_pattern_init_copy (dst, src);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
@ -224,37 +197,6 @@ _cairo_pattern_init_copy (cairo_pattern_t *pattern,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_pattern_init_static_copy (cairo_pattern_t *pattern,
|
||||
const cairo_pattern_t *other)
|
||||
{
|
||||
int size;
|
||||
|
||||
assert (other->status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
switch (other->type) {
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
case CAIRO_PATTERN_TYPE_SOLID:
|
||||
size = sizeof (cairo_solid_pattern_t);
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
size = sizeof (cairo_surface_pattern_t);
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
size = sizeof (cairo_linear_pattern_t);
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
size = sizeof (cairo_radial_pattern_t);
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy (pattern, other, size);
|
||||
|
||||
CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 0);
|
||||
_cairo_user_data_array_init (&pattern->user_data);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pattern_init_snapshot (cairo_pattern_t *pattern,
|
||||
const cairo_pattern_t *other)
|
||||
@ -308,40 +250,6 @@ _cairo_pattern_fini (cairo_pattern_t *pattern)
|
||||
free (gradient->stops);
|
||||
} break;
|
||||
}
|
||||
|
||||
#if HAVE_VALGRIND
|
||||
switch (pattern->type) {
|
||||
case CAIRO_PATTERN_TYPE_SOLID:
|
||||
VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_solid_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_surface_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_linear_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
VALGRIND_MAKE_MEM_NOACCESS (pattern, sizeof (cairo_radial_pattern_t));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_pattern_fini_snapshot (cairo_pattern_t *pattern)
|
||||
{
|
||||
/* XXX this is quite ugly, but currently necessary to break the circular
|
||||
* references with snapshot-cow and the meta-surface.
|
||||
* This operation remains safe only whilst _cairo_surface_snapshot() is
|
||||
* not public...
|
||||
*/
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||
cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) pattern;
|
||||
|
||||
cairo_surface_finish (spat->surface);
|
||||
}
|
||||
|
||||
_cairo_pattern_fini (pattern);
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -456,92 +364,10 @@ _cairo_pattern_init_radial (cairo_radial_pattern_t *pattern,
|
||||
/* We use a small freed pattern cache here, because we don't want to
|
||||
* constantly reallocate simple colors. */
|
||||
#define MAX_PATTERN_CACHE_SIZE 4
|
||||
typedef struct {
|
||||
void *pool[MAX_PATTERN_CACHE_SIZE];
|
||||
int top;
|
||||
} freed_pool_t;
|
||||
|
||||
static freed_pool_t freed_pattern_pool[4];
|
||||
|
||||
static void *
|
||||
_atomic_fetch (void **slot)
|
||||
{
|
||||
return _cairo_atomic_ptr_cmpxchg (slot, *slot, NULL);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_atomic_store (void **slot, void *pattern)
|
||||
{
|
||||
return _cairo_atomic_ptr_cmpxchg (slot, NULL, pattern) == NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
_freed_pattern_get (freed_pool_t *pool)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
int i;
|
||||
|
||||
i = pool->top - 1;
|
||||
if (i < 0)
|
||||
i = 0;
|
||||
|
||||
pattern = _atomic_fetch (&pool->pool[i]);
|
||||
if (pattern != NULL) {
|
||||
pool->top = i;
|
||||
return pattern;
|
||||
}
|
||||
|
||||
/* either empty or contended */
|
||||
for (i = ARRAY_LENGTH (pool->pool); i--;) {
|
||||
pattern = _atomic_fetch (&pool->pool[i]);
|
||||
if (pattern != NULL) {
|
||||
pool->top = i;
|
||||
return pattern;
|
||||
}
|
||||
}
|
||||
|
||||
/* empty */
|
||||
pool->top = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_freed_pattern_put (freed_pool_t *pool,
|
||||
cairo_pattern_t *pattern)
|
||||
{
|
||||
int i = pool->top;
|
||||
|
||||
if (_atomic_store (&pool->pool[i], pattern)) {
|
||||
pool->top = i + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* either full or contended */
|
||||
for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) {
|
||||
if (_atomic_store (&pool->pool[i], pattern)) {
|
||||
pool->top = i + 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* full */
|
||||
pool->top = ARRAY_LENGTH (pool->pool);
|
||||
free (pattern);
|
||||
}
|
||||
|
||||
static void
|
||||
_freed_patterns_reset (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH (freed_pattern_pool); i++) {
|
||||
freed_pool_t *pool = &freed_pattern_pool[i];
|
||||
for (j = 0; j < ARRAY_LENGTH (pool->pool); j++) {
|
||||
free (pool->pool[j]);
|
||||
pool->pool[j] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
static struct {
|
||||
cairo_solid_pattern_t *patterns[MAX_PATTERN_CACHE_SIZE];
|
||||
int size;
|
||||
} solid_pattern_cache;
|
||||
|
||||
cairo_pattern_t *
|
||||
_cairo_pattern_create_solid (const cairo_color_t *color,
|
||||
@ -549,8 +375,17 @@ _cairo_pattern_create_solid (const cairo_color_t *color,
|
||||
{
|
||||
cairo_solid_pattern_t *pattern = NULL;
|
||||
|
||||
pattern =
|
||||
_freed_pattern_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SOLID]);
|
||||
CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock);
|
||||
|
||||
if (solid_pattern_cache.size) {
|
||||
int i = --solid_pattern_cache.size %
|
||||
ARRAY_LENGTH (solid_pattern_cache.patterns);
|
||||
pattern = solid_pattern_cache.patterns[i];
|
||||
solid_pattern_cache.patterns[i] = NULL;
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock);
|
||||
|
||||
if (unlikely (pattern == NULL)) {
|
||||
/* None cached, need to create a new pattern. */
|
||||
pattern = malloc (sizeof (cairo_solid_pattern_t));
|
||||
@ -566,7 +401,24 @@ _cairo_pattern_create_solid (const cairo_color_t *color,
|
||||
return &pattern->base;
|
||||
}
|
||||
|
||||
cairo_pattern_t *
|
||||
static void
|
||||
_cairo_pattern_reset_solid_pattern_cache (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock);
|
||||
|
||||
for (i = 0; i < MIN (ARRAY_LENGTH (solid_pattern_cache.patterns), solid_pattern_cache.size); i++) {
|
||||
if (solid_pattern_cache.patterns[i])
|
||||
free (solid_pattern_cache.patterns[i]);
|
||||
solid_pattern_cache.patterns[i] = NULL;
|
||||
}
|
||||
solid_pattern_cache.size = 0;
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock);
|
||||
}
|
||||
|
||||
static const cairo_pattern_t *
|
||||
_cairo_pattern_create_in_error (cairo_status_t status)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
@ -686,16 +538,12 @@ cairo_pattern_create_for_surface (cairo_surface_t *surface)
|
||||
}
|
||||
|
||||
if (surface->status)
|
||||
return _cairo_pattern_create_in_error (surface->status);
|
||||
return (cairo_pattern_t*) _cairo_pattern_create_in_error (surface->status);
|
||||
|
||||
pattern =
|
||||
_freed_pattern_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_SURFACE]);
|
||||
pattern = malloc (sizeof (cairo_surface_pattern_t));
|
||||
if (unlikely (pattern == NULL)) {
|
||||
pattern = malloc (sizeof (cairo_surface_pattern_t));
|
||||
if (unlikely (pattern == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *)&_cairo_pattern_nil.base;
|
||||
}
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *)&_cairo_pattern_nil.base;
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
@ -738,14 +586,10 @@ cairo_pattern_create_linear (double x0, double y0, double x1, double y1)
|
||||
{
|
||||
cairo_linear_pattern_t *pattern;
|
||||
|
||||
pattern =
|
||||
_freed_pattern_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_LINEAR]);
|
||||
pattern = malloc (sizeof (cairo_linear_pattern_t));
|
||||
if (unlikely (pattern == NULL)) {
|
||||
pattern = malloc (sizeof (cairo_linear_pattern_t));
|
||||
if (unlikely (pattern == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
|
||||
}
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
@ -790,14 +634,10 @@ cairo_pattern_create_radial (double cx0, double cy0, double radius0,
|
||||
{
|
||||
cairo_radial_pattern_t *pattern;
|
||||
|
||||
pattern =
|
||||
_freed_pattern_get (&freed_pattern_pool[CAIRO_PATTERN_TYPE_RADIAL]);
|
||||
pattern = malloc (sizeof (cairo_radial_pattern_t));
|
||||
if (unlikely (pattern == NULL)) {
|
||||
pattern = malloc (sizeof (cairo_radial_pattern_t));
|
||||
if (unlikely (pattern == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
|
||||
}
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_pattern_t *) &_cairo_pattern_nil.base;
|
||||
}
|
||||
|
||||
CAIRO_MUTEX_INITIALIZE ();
|
||||
@ -881,8 +721,6 @@ slim_hidden_def (cairo_pattern_status);
|
||||
void
|
||||
cairo_pattern_destroy (cairo_pattern_t *pattern)
|
||||
{
|
||||
cairo_pattern_type_t type;
|
||||
|
||||
if (pattern == NULL ||
|
||||
CAIRO_REFERENCE_COUNT_IS_INVALID (&pattern->ref_count))
|
||||
return;
|
||||
@ -892,11 +730,26 @@ cairo_pattern_destroy (cairo_pattern_t *pattern)
|
||||
if (! _cairo_reference_count_dec_and_test (&pattern->ref_count))
|
||||
return;
|
||||
|
||||
type = pattern->type;
|
||||
_cairo_pattern_fini (pattern);
|
||||
|
||||
/* maintain a small cache of freed patterns */
|
||||
_freed_pattern_put (&freed_pattern_pool[type], pattern);
|
||||
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
|
||||
int i;
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_pattern_solid_pattern_cache_lock);
|
||||
|
||||
i = solid_pattern_cache.size++ %
|
||||
ARRAY_LENGTH (solid_pattern_cache.patterns);
|
||||
/* swap an old pattern for this 'cache-hot' pattern */
|
||||
if (solid_pattern_cache.patterns[i])
|
||||
free (solid_pattern_cache.patterns[i]);
|
||||
|
||||
solid_pattern_cache.patterns[i] = (cairo_solid_pattern_t *) pattern;
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_pattern_solid_pattern_cache_lock);
|
||||
} else {
|
||||
free (pattern);
|
||||
}
|
||||
}
|
||||
slim_hidden_def (cairo_pattern_destroy);
|
||||
|
||||
@ -1254,7 +1107,7 @@ cairo_pattern_get_matrix (cairo_pattern_t *pattern, cairo_matrix_t *matrix)
|
||||
*
|
||||
* <informalexample><programlisting>
|
||||
* cairo_set_source_surface (cr, image, x, y);
|
||||
* cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_NEAREST);
|
||||
* cairo_pattern_set_filter (cairo_get_source (cr), %CAIRO_FILTER_NEAREST);
|
||||
* </programlisting></informalexample>
|
||||
**/
|
||||
void
|
||||
@ -1941,7 +1794,6 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int flags,
|
||||
cairo_surface_t **out,
|
||||
cairo_surface_attributes_t *attr)
|
||||
{
|
||||
@ -2003,9 +1855,7 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
|
||||
* images such that the new image, when repeated, has the same effect
|
||||
* of reflecting the original pattern.
|
||||
*/
|
||||
if (flags & CAIRO_PATTERN_ACQUIRE_NO_REFLECT &&
|
||||
attr->extend == CAIRO_EXTEND_REFLECT)
|
||||
{
|
||||
if (attr->extend == CAIRO_EXTEND_REFLECT) {
|
||||
cairo_t *cr;
|
||||
cairo_surface_t *src;
|
||||
int w, h;
|
||||
@ -2122,28 +1972,13 @@ _cairo_pattern_acquire_surface_for_surface (const cairo_surface_pattern_t *pat
|
||||
/* Never acquire a larger area than the source itself */
|
||||
is_empty = _cairo_rectangle_intersect (&extents, &sampled_area);
|
||||
} else {
|
||||
int trim = 0;
|
||||
|
||||
if (sampled_area.x >= extents.x &&
|
||||
sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width)
|
||||
{
|
||||
/* source is horizontally contained within extents, trim */
|
||||
extents.x = sampled_area.x;
|
||||
extents.width = sampled_area.width;
|
||||
trim |= 0x1;
|
||||
}
|
||||
|
||||
if (sampled_area.y >= extents.y &&
|
||||
sampled_area.y >= extents.y &&
|
||||
sampled_area.x + (int) sampled_area.width <= extents.x + (int) extents.width &&
|
||||
sampled_area.y + (int) sampled_area.height <= extents.y + (int) extents.height)
|
||||
{
|
||||
/* source is vertically contained within extents, trim */
|
||||
extents.y = sampled_area.y;
|
||||
extents.height = sampled_area.height;
|
||||
trim |= 0x2;
|
||||
}
|
||||
|
||||
if (trim == 0x3) {
|
||||
/* source is wholly contained within extents, drop the REPEAT */
|
||||
extents = sampled_area;
|
||||
attr->extend = CAIRO_EXTEND_NONE;
|
||||
}
|
||||
|
||||
@ -2231,7 +2066,6 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int flags,
|
||||
cairo_surface_t **surface_out,
|
||||
cairo_surface_attributes_t *attributes)
|
||||
{
|
||||
@ -2321,9 +2155,7 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
|
||||
|
||||
status = _cairo_pattern_acquire_surface_for_surface (src, dst,
|
||||
content,
|
||||
x, y,
|
||||
width, height,
|
||||
flags,
|
||||
x, y, width, height,
|
||||
surface_out,
|
||||
attributes);
|
||||
} break;
|
||||
@ -2362,7 +2194,6 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
|
||||
int mask_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int flags,
|
||||
cairo_surface_t **src_out,
|
||||
cairo_surface_t **mask_out,
|
||||
cairo_surface_attributes_t *src_attributes,
|
||||
@ -2403,7 +2234,6 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
|
||||
src_content,
|
||||
src_x, src_y,
|
||||
width, height,
|
||||
flags,
|
||||
src_out, src_attributes);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
@ -2417,7 +2247,6 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
|
||||
CAIRO_CONTENT_ALPHA,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
flags,
|
||||
mask_out, mask_attributes);
|
||||
if (unlikely (status))
|
||||
_cairo_pattern_release_surface (src, *src_out, src_attributes);
|
||||
@ -2580,10 +2409,7 @@ static unsigned long
|
||||
_cairo_surface_pattern_hash (unsigned long hash,
|
||||
const cairo_pattern_t *pattern)
|
||||
{
|
||||
const cairo_surface_pattern_t *surface = (cairo_surface_pattern_t *) pattern;
|
||||
|
||||
hash ^= surface->surface->unique_id;
|
||||
|
||||
/* XXX requires cow-snapshots */
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -2737,10 +2563,8 @@ static cairo_bool_t
|
||||
_cairo_surface_pattern_equal (const cairo_pattern_t *A,
|
||||
const cairo_pattern_t *B)
|
||||
{
|
||||
const cairo_surface_pattern_t *a = (cairo_surface_pattern_t *) A;
|
||||
const cairo_surface_pattern_t *b = (cairo_surface_pattern_t *) B;
|
||||
|
||||
return a->surface->unique_id == b->surface->unique_id;
|
||||
/* XXX requires cow-snapshots */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cairo_bool_t
|
||||
@ -3031,6 +2855,6 @@ cairo_pattern_get_radial_circles (cairo_pattern_t *pattern,
|
||||
void
|
||||
_cairo_pattern_reset_static_data (void)
|
||||
{
|
||||
_freed_patterns_reset ();
|
||||
_cairo_pattern_reset_solid_pattern_cache ();
|
||||
_cairo_pattern_reset_solid_surface_cache ();
|
||||
}
|
||||
|
@ -60,20 +60,6 @@ typedef struct _cairo_pdf_group_resources {
|
||||
cairo_array_t fonts;
|
||||
} cairo_pdf_group_resources_t;
|
||||
|
||||
typedef struct _cairo_pdf_source_surface_entry {
|
||||
cairo_hash_entry_t base;
|
||||
unsigned int id;
|
||||
cairo_bool_t interpolate;
|
||||
cairo_pdf_resource_t surface_res;
|
||||
int width;
|
||||
int height;
|
||||
} cairo_pdf_source_surface_entry_t;
|
||||
|
||||
typedef struct _cairo_pdf_source_surface {
|
||||
cairo_surface_t *surface;
|
||||
cairo_pdf_source_surface_entry_t *hash_entry;
|
||||
} cairo_pdf_source_surface_t;
|
||||
|
||||
typedef struct _cairo_pdf_pattern {
|
||||
double width;
|
||||
double height;
|
||||
@ -132,9 +118,7 @@ struct _cairo_pdf_surface {
|
||||
cairo_array_t pages;
|
||||
cairo_array_t rgb_linear_functions;
|
||||
cairo_array_t alpha_linear_functions;
|
||||
cairo_array_t page_patterns;
|
||||
cairo_array_t page_surfaces;
|
||||
cairo_hash_table_t *all_surfaces;
|
||||
cairo_array_t patterns;
|
||||
cairo_array_t smask_groups;
|
||||
cairo_array_t knockout_group;
|
||||
|
||||
|
@ -194,9 +194,6 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface);
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_font_subsets (cairo_pdf_surface_t *surface);
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_pdf_source_surface_equal (const void *key_a, const void *key_b);
|
||||
|
||||
static const cairo_surface_backend_t cairo_pdf_surface_backend;
|
||||
static const cairo_paginated_surface_backend_t cairo_pdf_surface_paginated_backend;
|
||||
|
||||
@ -271,30 +268,23 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
|
||||
_cairo_array_init (&surface->rgb_linear_functions, sizeof (cairo_pdf_rgb_linear_function_t));
|
||||
_cairo_array_init (&surface->alpha_linear_functions, sizeof (cairo_pdf_alpha_linear_function_t));
|
||||
_cairo_array_init (&surface->fonts, sizeof (cairo_pdf_font_t));
|
||||
_cairo_array_init (&surface->patterns, sizeof (cairo_pdf_pattern_t));
|
||||
_cairo_array_init (&surface->smask_groups, sizeof (cairo_pdf_smask_group_t *));
|
||||
_cairo_array_init (&surface->knockout_group, sizeof (cairo_pdf_resource_t));
|
||||
|
||||
_cairo_array_init (&surface->page_patterns, sizeof (cairo_pdf_pattern_t));
|
||||
_cairo_array_init (&surface->page_surfaces, sizeof (cairo_pdf_source_surface_t));
|
||||
surface->all_surfaces = _cairo_hash_table_create (_cairo_pdf_source_surface_equal);
|
||||
if (unlikely (surface->all_surfaces == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL0;
|
||||
}
|
||||
|
||||
_cairo_pdf_group_resources_init (&surface->resources);
|
||||
|
||||
surface->font_subsets = _cairo_scaled_font_subsets_create_composite ();
|
||||
if (! surface->font_subsets) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL1;
|
||||
goto BAIL0;
|
||||
}
|
||||
|
||||
surface->next_available_resource.id = 1;
|
||||
surface->pages_resource = _cairo_pdf_surface_new_object (surface);
|
||||
if (surface->pages_resource.id == 0) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL2;
|
||||
goto BAIL1;
|
||||
}
|
||||
|
||||
surface->pdf_version = CAIRO_PDF_VERSION_1_5;
|
||||
@ -334,10 +324,8 @@ _cairo_pdf_surface_create_for_stream_internal (cairo_output_stream_t *output,
|
||||
return surface->paginated_surface;
|
||||
}
|
||||
|
||||
BAIL2:
|
||||
_cairo_scaled_font_subsets_destroy (surface->font_subsets);
|
||||
BAIL1:
|
||||
_cairo_hash_table_destroy (surface->all_surfaces);
|
||||
_cairo_scaled_font_subsets_destroy (surface->font_subsets);
|
||||
BAIL0:
|
||||
_cairo_array_fini (&surface->objects);
|
||||
free (surface);
|
||||
@ -583,22 +571,14 @@ _cairo_pdf_surface_clear (cairo_pdf_surface_t *surface)
|
||||
{
|
||||
int i, size;
|
||||
cairo_pdf_pattern_t *pattern;
|
||||
cairo_pdf_source_surface_t *src_surface;
|
||||
cairo_pdf_smask_group_t *group;
|
||||
|
||||
size = _cairo_array_num_elements (&surface->page_patterns);
|
||||
size = _cairo_array_num_elements (&surface->patterns);
|
||||
for (i = 0; i < size; i++) {
|
||||
pattern = (cairo_pdf_pattern_t *) _cairo_array_index (&surface->page_patterns, i);
|
||||
pattern = (cairo_pdf_pattern_t *) _cairo_array_index (&surface->patterns, i);
|
||||
cairo_pattern_destroy (pattern->pattern);
|
||||
}
|
||||
_cairo_array_truncate (&surface->page_patterns, 0);
|
||||
|
||||
size = _cairo_array_num_elements (&surface->page_surfaces);
|
||||
for (i = 0; i < size; i++) {
|
||||
src_surface = (cairo_pdf_source_surface_t *) _cairo_array_index (&surface->page_surfaces, i);
|
||||
cairo_surface_destroy (src_surface->surface);
|
||||
}
|
||||
_cairo_array_truncate (&surface->page_surfaces, 0);
|
||||
_cairo_array_truncate (&surface->patterns, 0);
|
||||
|
||||
size = _cairo_array_num_elements (&surface->smask_groups);
|
||||
for (i = 0; i < size; i++) {
|
||||
@ -881,176 +861,6 @@ _cairo_pdf_surface_add_smask_group (cairo_pdf_surface_t *surface,
|
||||
return _cairo_array_append (&surface->smask_groups, &group);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_pdf_source_surface_equal (const void *key_a, const void *key_b)
|
||||
{
|
||||
const cairo_pdf_source_surface_entry_t *a = key_a;
|
||||
const cairo_pdf_source_surface_entry_t *b = key_b;
|
||||
|
||||
return (a->id == b->id) && (a->interpolate == b->interpolate);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_pdf_source_surface_init_key (cairo_pdf_source_surface_entry_t *key)
|
||||
{
|
||||
key->base.hash = key->id;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_get_jpx_image_info (cairo_surface_t *source,
|
||||
cairo_image_info_t *info,
|
||||
const unsigned char **mime_data,
|
||||
unsigned int *mime_data_length)
|
||||
{
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JP2,
|
||||
mime_data, mime_data_length);
|
||||
if (*mime_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return _cairo_image_info_get_jpx_info (info, *mime_data, *mime_data_length);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_get_jpeg_image_info (cairo_surface_t *source,
|
||||
cairo_image_info_t *info,
|
||||
const unsigned char **mime_data,
|
||||
unsigned int *mime_data_length)
|
||||
{
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
|
||||
mime_data, mime_data_length);
|
||||
if (*mime_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
return _cairo_image_info_get_jpeg_info (info, *mime_data, *mime_data_length);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_get_source_surface_size (cairo_surface_t *source,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
cairo_status_t status;
|
||||
cairo_image_info_t info;
|
||||
const unsigned char *mime_data;
|
||||
unsigned int mime_data_length;
|
||||
|
||||
if (_cairo_surface_is_meta (source)) {
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
status = _cairo_surface_get_extents (source, &extents);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
*width = extents.width;
|
||||
*height = extents.height;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _get_jpx_image_info (source, &info, &mime_data, &mime_data_length);
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
*width = info.width;
|
||||
*height = info.height;
|
||||
} else if (_cairo_status_is_error (status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _get_jpeg_image_info (source, &info, &mime_data, &mime_data_length);
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
*width = info.width;
|
||||
*height = info.height;
|
||||
} else if (_cairo_status_is_error (status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_surface_acquire_source_image (source, &image, &image_extra);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
*width = image->width;
|
||||
*height = image->height;
|
||||
|
||||
_cairo_surface_release_source_image (source, image, image_extra);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_add_source_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *source,
|
||||
cairo_filter_t filter,
|
||||
cairo_pdf_resource_t *surface_res,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
cairo_pdf_source_surface_t src_surface;
|
||||
cairo_pdf_source_surface_entry_t surface_key;
|
||||
cairo_pdf_source_surface_entry_t *surface_entry;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t interpolate;
|
||||
|
||||
switch (filter) {
|
||||
case CAIRO_FILTER_GOOD:
|
||||
case CAIRO_FILTER_BEST:
|
||||
case CAIRO_FILTER_BILINEAR:
|
||||
interpolate = TRUE;
|
||||
break;
|
||||
case CAIRO_FILTER_FAST:
|
||||
case CAIRO_FILTER_NEAREST:
|
||||
case CAIRO_FILTER_GAUSSIAN:
|
||||
interpolate = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
surface_key.id = source->unique_id;
|
||||
surface_key.interpolate = interpolate;
|
||||
_cairo_pdf_source_surface_init_key (&surface_key);
|
||||
surface_entry = _cairo_hash_table_lookup (surface->all_surfaces, &surface_key.base);
|
||||
if (surface_entry) {
|
||||
*surface_res = surface_entry->surface_res;
|
||||
*width = surface_entry->width;
|
||||
*height = surface_entry->height;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
surface_entry = malloc (sizeof (cairo_pdf_source_surface_entry_t));
|
||||
if (surface_entry == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
surface_entry->id = surface_key.id;
|
||||
surface_entry->interpolate = interpolate;
|
||||
_cairo_pdf_source_surface_init_key (surface_entry);
|
||||
|
||||
src_surface.hash_entry = surface_entry;
|
||||
src_surface.surface = cairo_surface_reference (source);
|
||||
surface_entry->surface_res = _cairo_pdf_surface_new_object (surface);
|
||||
if (surface_entry->surface_res.id == 0) {
|
||||
free (surface_entry);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
status = _get_source_surface_size (source, &surface_entry->width,
|
||||
&surface_entry->height);
|
||||
|
||||
status = _cairo_array_append (&surface->page_surfaces, &src_surface);
|
||||
if (unlikely (status)) {
|
||||
free (surface_entry);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_hash_table_insert (surface->all_surfaces,
|
||||
&surface_entry->base);
|
||||
|
||||
*surface_res = surface_entry->surface_res;
|
||||
*width = surface_entry->width;
|
||||
*height = surface_entry->height;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
|
||||
const cairo_pattern_t *pattern,
|
||||
@ -1125,7 +935,7 @@ _cairo_pdf_surface_add_pdf_pattern (cairo_pdf_surface_t *surface,
|
||||
*pattern_res = pdf_pattern.pattern_res;
|
||||
*gstate_res = pdf_pattern.gstate_res;
|
||||
|
||||
status = _cairo_array_append (&surface->page_patterns, &pdf_pattern);
|
||||
status = _cairo_array_append (&surface->patterns, &pdf_pattern);
|
||||
if (unlikely (status)) {
|
||||
cairo_pattern_destroy (pdf_pattern.pattern);
|
||||
return status;
|
||||
@ -1395,7 +1205,6 @@ _cairo_pdf_surface_close_group (cairo_pdf_surface_t *surface,
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_resource_t *resource,
|
||||
cairo_bool_t is_form)
|
||||
{
|
||||
cairo_status_t status;
|
||||
@ -1410,7 +1219,7 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
|
||||
if (is_form) {
|
||||
status =
|
||||
_cairo_pdf_surface_open_stream (surface,
|
||||
resource,
|
||||
NULL,
|
||||
surface->compress_content,
|
||||
" /Type /XObject\n"
|
||||
" /Subtype /Form\n"
|
||||
@ -1427,7 +1236,7 @@ _cairo_pdf_surface_open_content_stream (cairo_pdf_surface_t *surface,
|
||||
} else {
|
||||
status =
|
||||
_cairo_pdf_surface_open_stream (surface,
|
||||
resource,
|
||||
NULL,
|
||||
surface->compress_content,
|
||||
NULL);
|
||||
}
|
||||
@ -1475,17 +1284,7 @@ _cairo_pdf_surface_create_similar (void *abstract_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return cairo_meta_surface_create (content, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_pdf_source_surface_entry_pluck (void *entry, void *closure)
|
||||
{
|
||||
cairo_pdf_source_surface_entry_t *surface_entry = entry;
|
||||
cairo_hash_table_t *patterns = closure;
|
||||
|
||||
_cairo_hash_table_remove (patterns, &surface_entry->base);
|
||||
free (surface_entry);
|
||||
return _cairo_meta_surface_create (content, width, height);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -1567,12 +1366,7 @@ _cairo_pdf_surface_finish (void *abstract_surface)
|
||||
_cairo_array_fini (&surface->pages);
|
||||
_cairo_array_fini (&surface->rgb_linear_functions);
|
||||
_cairo_array_fini (&surface->alpha_linear_functions);
|
||||
_cairo_array_fini (&surface->page_patterns);
|
||||
_cairo_array_fini (&surface->page_surfaces);
|
||||
_cairo_hash_table_foreach (surface->all_surfaces,
|
||||
_cairo_pdf_source_surface_entry_pluck,
|
||||
surface->all_surfaces);
|
||||
_cairo_hash_table_destroy (surface->all_surfaces);
|
||||
_cairo_array_fini (&surface->patterns);
|
||||
_cairo_array_fini (&surface->smask_groups);
|
||||
_cairo_array_fini (&surface->fonts);
|
||||
_cairo_array_fini (&surface->knockout_group);
|
||||
@ -1624,7 +1418,7 @@ _cairo_pdf_surface_has_fallback_images (void *abstract_surface,
|
||||
cairo_pdf_surface_t *surface = abstract_surface;
|
||||
|
||||
surface->has_fallback_images = has_fallbacks;
|
||||
status = _cairo_pdf_surface_open_content_stream (surface, NULL, has_fallbacks);
|
||||
status = _cairo_pdf_surface_open_content_stream (surface, has_fallbacks);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
@ -1744,7 +1538,7 @@ _cairo_pdf_surface_emit_smask (cairo_pdf_surface_t *surface,
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
|
||||
cairo_image_surface_t *image,
|
||||
cairo_pdf_resource_t *image_res,
|
||||
cairo_pdf_resource_t *image_ret,
|
||||
cairo_filter_t filter)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
@ -1842,7 +1636,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
|
||||
|
||||
if (need_smask)
|
||||
status = _cairo_pdf_surface_open_stream (surface,
|
||||
image_res,
|
||||
NULL,
|
||||
TRUE,
|
||||
IMAGE_DICTIONARY
|
||||
" /SMask %d 0 R\n",
|
||||
@ -1851,7 +1645,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
|
||||
smask.id);
|
||||
else
|
||||
status = _cairo_pdf_surface_open_stream (surface,
|
||||
image_res,
|
||||
NULL,
|
||||
TRUE,
|
||||
IMAGE_DICTIONARY,
|
||||
image->width, image->height,
|
||||
@ -1861,8 +1655,7 @@ _cairo_pdf_surface_emit_image (cairo_pdf_surface_t *surface,
|
||||
|
||||
#undef IMAGE_DICTIONARY
|
||||
|
||||
if (image_res == NULL)
|
||||
*image_res = surface->pdf_stream.self;
|
||||
*image_ret = surface->pdf_stream.self;
|
||||
_cairo_output_stream_write (surface->output, rgb, rgb_size);
|
||||
status = _cairo_pdf_surface_close_stream (surface);
|
||||
|
||||
@ -1875,7 +1668,9 @@ CLEANUP:
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *source,
|
||||
cairo_pdf_resource_t res)
|
||||
cairo_pdf_resource_t *res,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
cairo_status_t status;
|
||||
const unsigned char *mime_data;
|
||||
@ -1895,7 +1690,7 @@ _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_open_stream (surface,
|
||||
&res,
|
||||
NULL,
|
||||
FALSE,
|
||||
" /Type /XObject\n"
|
||||
" /Subtype /Image\n"
|
||||
@ -1908,17 +1703,23 @@ _cairo_pdf_surface_emit_jpx_image (cairo_pdf_surface_t *surface,
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
*res = surface->pdf_stream.self;
|
||||
_cairo_output_stream_write (surface->output, mime_data, mime_data_length);
|
||||
_cairo_output_stream_printf (surface->output, "\n");
|
||||
status = _cairo_pdf_surface_close_stream (surface);
|
||||
|
||||
*width = info.width;
|
||||
*height = info.height;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *source,
|
||||
cairo_pdf_resource_t res)
|
||||
cairo_pdf_resource_t *res,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
cairo_status_t status;
|
||||
const unsigned char *mime_data;
|
||||
@ -1940,7 +1741,7 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
status = _cairo_pdf_surface_open_stream (surface,
|
||||
&res,
|
||||
NULL,
|
||||
FALSE,
|
||||
" /Type /XObject\n"
|
||||
" /Subtype /Image\n"
|
||||
@ -1956,54 +1757,25 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
*res = surface->pdf_stream.self;
|
||||
_cairo_output_stream_write (surface->output, mime_data, mime_data_length);
|
||||
_cairo_output_stream_printf (surface->output, "\n");
|
||||
status = _cairo_pdf_surface_close_stream (surface);
|
||||
|
||||
*width = info.width;
|
||||
*height = info.height;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *source,
|
||||
cairo_pdf_resource_t resource,
|
||||
cairo_bool_t interpolate)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
void *image_extra;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_jpx_image (surface, source, resource);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_jpeg_image (surface, source, resource);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
status = _cairo_surface_acquire_source_image (source, &image, &image_extra);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_image (surface, image,
|
||||
&resource, interpolate);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
|
||||
BAIL:
|
||||
_cairo_surface_release_source_image (source, image, image_extra);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_pattern_t *pdf_pattern,
|
||||
cairo_pdf_resource_t *resource,
|
||||
int *width,
|
||||
int *height,
|
||||
int *origin_x,
|
||||
int *origin_y)
|
||||
cairo_pdf_pattern_t *pdf_pattern,
|
||||
cairo_pdf_resource_t *resource,
|
||||
int *width,
|
||||
int *height,
|
||||
int *origin_x,
|
||||
int *origin_y)
|
||||
{
|
||||
cairo_image_surface_t *image;
|
||||
cairo_surface_t *pad_image;
|
||||
@ -2012,73 +1784,63 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
cairo_bool_t interpolate;
|
||||
|
||||
status = _cairo_pdf_surface_emit_jpx_image (surface, pattern->surface,
|
||||
resource, width, height);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
status = _cairo_pdf_surface_emit_jpeg_image (surface, pattern->surface,
|
||||
resource, width, height);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
return status;
|
||||
|
||||
pad_image = &image->base;
|
||||
if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD) {
|
||||
cairo_box_t box;
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_surface_pattern_t pad_pattern;
|
||||
cairo_box_t box;
|
||||
cairo_rectangle_int_t rect;
|
||||
cairo_surface_pattern_t pad_pattern;
|
||||
|
||||
/* get the operation extents in pattern space */
|
||||
_cairo_box_from_rectangle (&box, &pdf_pattern->extents);
|
||||
_cairo_matrix_transform_bounding_box_fixed (&pattern->base.matrix, &box, NULL);
|
||||
_cairo_box_round_to_rectangle (&box, &rect);
|
||||
x = -rect.x;
|
||||
y = -rect.y;
|
||||
/* get the operation extents in pattern space */
|
||||
_cairo_box_from_rectangle (&box, &pdf_pattern->extents);
|
||||
_cairo_matrix_transform_bounding_box_fixed (&pattern->base.matrix, &box, NULL);
|
||||
_cairo_box_round_to_rectangle (&box, &rect);
|
||||
x = -rect.x;
|
||||
y = -rect.y;
|
||||
|
||||
pad_image = _cairo_image_surface_create_with_content (pattern->surface->content,
|
||||
rect.width,
|
||||
rect.height);
|
||||
if (pad_image->status) {
|
||||
status = pad_image->status;
|
||||
goto BAIL;
|
||||
}
|
||||
pad_image = _cairo_image_surface_create_with_content (pattern->surface->content,
|
||||
rect.width,
|
||||
rect.height);
|
||||
if (pad_image->status) {
|
||||
status = pad_image->status;
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
_cairo_pattern_init_for_surface (&pad_pattern, &image->base);
|
||||
cairo_matrix_init_translate (&pad_pattern.base.matrix, -x, -y);
|
||||
pad_pattern.base.extend = CAIRO_EXTEND_PAD;
|
||||
status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
|
||||
&pad_pattern.base,
|
||||
NULL,
|
||||
pad_image,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
rect.width,
|
||||
rect.height);
|
||||
_cairo_pattern_fini (&pad_pattern.base);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
switch (pdf_pattern->pattern->filter) {
|
||||
case CAIRO_FILTER_GOOD:
|
||||
case CAIRO_FILTER_BEST:
|
||||
case CAIRO_FILTER_BILINEAR:
|
||||
interpolate = TRUE;
|
||||
break;
|
||||
case CAIRO_FILTER_FAST:
|
||||
case CAIRO_FILTER_NEAREST:
|
||||
case CAIRO_FILTER_GAUSSIAN:
|
||||
interpolate = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
*resource = _cairo_pdf_surface_new_object (surface);
|
||||
if (resource->id == 0) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
_cairo_pattern_init_for_surface (&pad_pattern, &image->base);
|
||||
cairo_matrix_init_translate (&pad_pattern.base.matrix, -x, -y);
|
||||
pad_pattern.base.extend = CAIRO_EXTEND_PAD;
|
||||
status = _cairo_surface_composite (CAIRO_OPERATOR_SOURCE,
|
||||
&pad_pattern.base,
|
||||
NULL,
|
||||
pad_image,
|
||||
0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
rect.width,
|
||||
rect.height);
|
||||
_cairo_pattern_fini (&pad_pattern.base);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
}
|
||||
|
||||
status = _cairo_pdf_surface_emit_image (surface, (cairo_image_surface_t *)pad_image,
|
||||
resource, interpolate);
|
||||
resource, pattern->base.filter);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
goto BAIL;
|
||||
|
||||
*width = ((cairo_image_surface_t *)pad_image)->width;
|
||||
*height = ((cairo_image_surface_t *)pad_image)->height;
|
||||
@ -2087,18 +1849,17 @@ _cairo_pdf_surface_emit_padded_image_surface (cairo_pdf_surface_t *surface,
|
||||
|
||||
BAIL:
|
||||
if (pad_image != &image->base)
|
||||
cairo_surface_destroy (pad_image);
|
||||
cairo_surface_destroy (pad_image);
|
||||
|
||||
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_surface_t *meta_surface,
|
||||
cairo_pdf_resource_t resource)
|
||||
cairo_pdf_resource_t *resource)
|
||||
{
|
||||
double old_width, old_height;
|
||||
cairo_paginated_mode_t old_paginated_mode;
|
||||
@ -2124,10 +1885,11 @@ _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, &resource, TRUE);
|
||||
status = _cairo_pdf_surface_open_content_stream (surface, TRUE);
|
||||
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 (unlikely (status))
|
||||
@ -2160,32 +1922,17 @@ _cairo_pdf_surface_emit_meta_surface (cairo_pdf_surface_t *surface,
|
||||
return status;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_surface (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_source_surface_t *src_surface)
|
||||
{
|
||||
if (_cairo_surface_is_meta (src_surface->surface)) {
|
||||
return _cairo_pdf_surface_emit_meta_surface (surface,
|
||||
src_surface->surface,
|
||||
src_surface->hash_entry->surface_res);
|
||||
} else {
|
||||
return _cairo_pdf_surface_emit_image_surface (surface,
|
||||
src_surface->surface,
|
||||
src_surface->hash_entry->surface_res,
|
||||
src_surface->hash_entry->interpolate);
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
||||
cairo_pdf_pattern_t *pdf_pattern)
|
||||
{
|
||||
cairo_surface_pattern_t *pattern = (cairo_surface_pattern_t *) pdf_pattern->pattern;
|
||||
cairo_status_t status;
|
||||
cairo_pdf_resource_t pattern_resource = {0};
|
||||
cairo_pdf_resource_t pattern_resource = {0}; /* squelch bogus compiler warning */
|
||||
cairo_matrix_t cairo_p2d, pdf_p2d;
|
||||
cairo_extend_t extend = cairo_pattern_get_extend (&pattern->base);
|
||||
double xstep, ystep;
|
||||
cairo_rectangle_int_t surface_extents;
|
||||
int pattern_width = 0; /* squelch bogus compiler warning */
|
||||
int pattern_height = 0; /* squelch bogus compiler warning */
|
||||
int origin_x = 0; /* squelch bogus compiler warning */
|
||||
@ -2193,26 +1940,35 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
||||
int bbox_x, bbox_y;
|
||||
char draw_surface[200];
|
||||
|
||||
if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD &&
|
||||
! _cairo_surface_is_meta (pattern->surface))
|
||||
{
|
||||
status = _cairo_pdf_surface_emit_padded_image_surface (surface,
|
||||
pdf_pattern,
|
||||
&pattern_resource,
|
||||
&pattern_width,
|
||||
&pattern_height,
|
||||
&origin_x,
|
||||
&origin_y);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = _cairo_pdf_surface_add_source_surface (surface,
|
||||
pattern->surface,
|
||||
pdf_pattern->pattern->filter,
|
||||
if (_cairo_surface_is_meta (pattern->surface)) {
|
||||
cairo_surface_t *meta_surface = pattern->surface;
|
||||
cairo_rectangle_int_t pattern_extents;
|
||||
|
||||
status = _cairo_pdf_surface_emit_meta_surface (surface,
|
||||
meta_surface,
|
||||
&pattern_resource);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
status = _cairo_surface_get_extents (meta_surface, &pattern_extents);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
pattern_width = pattern_extents.width;
|
||||
pattern_height = pattern_extents.height;
|
||||
} else {
|
||||
status = _cairo_pdf_surface_emit_image_surface (surface,
|
||||
pdf_pattern,
|
||||
&pattern_resource,
|
||||
&pattern_width,
|
||||
&pattern_height);
|
||||
&pattern_height,
|
||||
&origin_x,
|
||||
&origin_y);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_surface_get_extents (&surface->base, &surface_extents);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
@ -2298,7 +2054,10 @@ _cairo_pdf_surface_emit_surface_pattern (cairo_pdf_surface_t *surface,
|
||||
/* cairo_pattern_set_matrix ensures the matrix is invertible */
|
||||
assert (status == CAIRO_STATUS_SUCCESS);
|
||||
|
||||
cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &surface->cairo_to_pdf);
|
||||
cairo_matrix_init_identity (&pdf_p2d);
|
||||
cairo_matrix_translate (&pdf_p2d, 0.0, surface_extents.height);
|
||||
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
|
||||
cairo_matrix_multiply (&pdf_p2d, &cairo_p2d, &pdf_p2d);
|
||||
cairo_matrix_translate (&pdf_p2d, -origin_x, -origin_y);
|
||||
cairo_matrix_translate (&pdf_p2d, 0.0, pattern_height);
|
||||
cairo_matrix_scale (&pdf_p2d, 1.0, -1.0);
|
||||
@ -4686,10 +4445,8 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
|
||||
group->height);
|
||||
/* _mask is a special case that requires two groups - source
|
||||
* and mask as well as a smask and gstate dictionary */
|
||||
if (group->operation == PDF_MASK) {
|
||||
status = _cairo_pdf_surface_write_mask_group (surface, group);
|
||||
goto RESTORE_SIZE;
|
||||
}
|
||||
if (group->operation == PDF_MASK)
|
||||
return _cairo_pdf_surface_write_mask_group (surface, group);
|
||||
|
||||
status = _cairo_pdf_surface_open_group (surface, &group->group_res);
|
||||
if (unlikely (status))
|
||||
@ -4741,7 +4498,6 @@ _cairo_pdf_surface_write_smask_group (cairo_pdf_surface_t *surface,
|
||||
|
||||
status = _cairo_pdf_surface_close_group (surface, NULL);
|
||||
|
||||
RESTORE_SIZE:
|
||||
_cairo_pdf_surface_set_size_internal (surface,
|
||||
old_width,
|
||||
old_height);
|
||||
@ -4754,8 +4510,7 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
|
||||
{
|
||||
cairo_pdf_pattern_t pattern;
|
||||
cairo_pdf_smask_group_t *group;
|
||||
cairo_pdf_source_surface_t src_surface;
|
||||
int pattern_index, group_index, surface_index;
|
||||
int pattern_index, group_index;
|
||||
cairo_status_t status;
|
||||
|
||||
/* Writing out PDF_MASK groups will cause additional smask groups
|
||||
@ -4767,8 +4522,7 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
|
||||
*/
|
||||
pattern_index = 0;
|
||||
group_index = 0;
|
||||
surface_index = 0;
|
||||
while ((pattern_index < _cairo_array_num_elements (&surface->page_patterns)) ||
|
||||
while ((pattern_index < _cairo_array_num_elements (&surface->patterns)) ||
|
||||
(group_index < _cairo_array_num_elements (&surface->smask_groups)))
|
||||
{
|
||||
for (; group_index < _cairo_array_num_elements (&surface->smask_groups); group_index++) {
|
||||
@ -4778,19 +4532,12 @@ _cairo_pdf_surface_write_patterns_and_smask_groups (cairo_pdf_surface_t *surface
|
||||
return status;
|
||||
}
|
||||
|
||||
for (; pattern_index < _cairo_array_num_elements (&surface->page_patterns); pattern_index++) {
|
||||
_cairo_array_copy_element (&surface->page_patterns, pattern_index, &pattern);
|
||||
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 (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
||||
for (; surface_index < _cairo_array_num_elements (&surface->page_surfaces); surface_index++) {
|
||||
_cairo_array_copy_element (&surface->page_surfaces, surface_index, &src_surface);
|
||||
status = _cairo_pdf_surface_emit_surface (surface, &src_surface);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -4831,7 +4578,7 @@ _cairo_pdf_surface_write_page (cairo_pdf_surface_t *surface)
|
||||
return status;
|
||||
|
||||
_cairo_pdf_group_resources_clear (&surface->resources);
|
||||
status = _cairo_pdf_surface_open_content_stream (surface, NULL, FALSE);
|
||||
status = _cairo_pdf_surface_open_content_stream (surface, FALSE);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
@ -5088,7 +4835,7 @@ _cairo_pdf_surface_start_fallback (cairo_pdf_surface_t *surface)
|
||||
return status;
|
||||
|
||||
_cairo_pdf_group_resources_clear (&surface->resources);
|
||||
return _cairo_pdf_surface_open_content_stream (surface, NULL, TRUE);
|
||||
return _cairo_pdf_surface_open_content_stream (surface, TRUE);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
|
@ -58,8 +58,6 @@ _cairo_pen_init (cairo_pen_t *pen,
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t)));
|
||||
|
||||
pen->radius = radius;
|
||||
pen->tolerance = tolerance;
|
||||
|
||||
@ -105,15 +103,13 @@ _cairo_pen_fini (cairo_pen_t *pen)
|
||||
if (pen->vertices != pen->vertices_embedded)
|
||||
free (pen->vertices);
|
||||
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (pen, sizeof (cairo_pen_t)));
|
||||
pen->vertices = pen->vertices_embedded;
|
||||
pen->num_vertices = 0;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other)
|
||||
{
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t)));
|
||||
|
||||
*pen = *other;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
|
@ -39,8 +39,6 @@
|
||||
void
|
||||
_cairo_polygon_init (cairo_polygon_t *polygon)
|
||||
{
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));
|
||||
|
||||
polygon->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
polygon->num_edges = 0;
|
||||
@ -56,8 +54,6 @@ _cairo_polygon_fini (cairo_polygon_t *polygon)
|
||||
{
|
||||
if (polygon->edges != polygon->edges_embedded)
|
||||
free (polygon->edges);
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (polygon, sizeof (cairo_polygon_t)));
|
||||
}
|
||||
|
||||
/* make room for at least one more edge */
|
||||
|
@ -1294,7 +1294,7 @@ _cairo_ps_surface_create_similar (void *abstract_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return cairo_meta_surface_create (content, width, height);
|
||||
return _cairo_meta_surface_create (content, width, height);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -1896,7 +1896,6 @@ _cairo_ps_surface_emit_image (cairo_ps_surface_t *surface,
|
||||
return image->base.status;
|
||||
|
||||
switch (filter) {
|
||||
default:
|
||||
case CAIRO_FILTER_GOOD:
|
||||
case CAIRO_FILTER_BEST:
|
||||
case CAIRO_FILTER_BILINEAR:
|
||||
|
@ -749,7 +749,7 @@ _cairo_quartz_scaled_font_get_cg_font_ref (cairo_scaled_font_t *abstract_font)
|
||||
return ffont->cgFont;
|
||||
}
|
||||
|
||||
#ifndef __LP64__
|
||||
|
||||
/*
|
||||
* compat with old ATSUI backend
|
||||
*/
|
||||
@ -789,4 +789,3 @@ cairo_atsui_font_face_create_for_atsu_font_id (ATSUFontID font_id)
|
||||
{
|
||||
return cairo_quartz_font_face_create_for_atsu_font_id (font_id);
|
||||
}
|
||||
#endif
|
||||
|
@ -1717,23 +1717,6 @@ _cairo_quartz_surface_acquire_source_image (void *abstract_surface,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_quartz_surface_snapshot (void *abstract_surface)
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
cairo_quartz_surface_t *surface = abstract_surface;
|
||||
cairo_image_surface_t *image;
|
||||
|
||||
if (surface->imageSurfaceEquiv)
|
||||
return NULL;
|
||||
|
||||
status = _cairo_quartz_get_image (surface, &image);
|
||||
if (unlikely (status))
|
||||
return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return &image->base;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_quartz_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
@ -2717,7 +2700,7 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = {
|
||||
NULL, /* show_glyphs */
|
||||
#endif
|
||||
|
||||
_cairo_quartz_surface_snapshot,
|
||||
NULL, /* snapshot */
|
||||
NULL, /* is_similar */
|
||||
NULL, /* reset */
|
||||
NULL /* fill_stroke */
|
||||
|
@ -66,10 +66,8 @@ cairo_quartz_surface_get_cg_context (cairo_surface_t *surface);
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_quartz_font_face_create_for_cgfont (CGFontRef font);
|
||||
|
||||
#ifndef __LP64__
|
||||
cairo_public cairo_font_face_t *
|
||||
cairo_quartz_font_face_create_for_atsu_font_id (ATSUFontID font_id);
|
||||
#endif
|
||||
|
||||
#endif /* CAIRO_HAS_QUARTZ_FONT */
|
||||
|
||||
|
@ -79,8 +79,6 @@ _cairo_region_set_error (cairo_region_t *region,
|
||||
void
|
||||
_cairo_region_init (cairo_region_t *region)
|
||||
{
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
|
||||
|
||||
region->status = CAIRO_STATUS_SUCCESS;
|
||||
pixman_region32_init (®ion->rgn);
|
||||
}
|
||||
@ -89,8 +87,6 @@ void
|
||||
_cairo_region_init_rectangle (cairo_region_t *region,
|
||||
const cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
|
||||
|
||||
region->status = CAIRO_STATUS_SUCCESS;
|
||||
pixman_region32_init_rect (®ion->rgn,
|
||||
rectangle->x, rectangle->y,
|
||||
@ -101,7 +97,6 @@ void
|
||||
_cairo_region_fini (cairo_region_t *region)
|
||||
{
|
||||
pixman_region32_fini (®ion->rgn);
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,51 +129,6 @@ cairo_region_create (void)
|
||||
}
|
||||
slim_hidden_def (cairo_region_create);
|
||||
|
||||
cairo_region_t *
|
||||
cairo_region_create_rectangles (cairo_rectangle_int_t *rects,
|
||||
int count)
|
||||
{
|
||||
pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
|
||||
pixman_box32_t *pboxes = stack_pboxes;
|
||||
cairo_region_t *region;
|
||||
int i;
|
||||
|
||||
region = _cairo_malloc (sizeof (cairo_region_t));
|
||||
|
||||
if (!region)
|
||||
return (cairo_region_t *)&_cairo_region_nil;
|
||||
|
||||
region->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (count > ARRAY_LENGTH (stack_pboxes)) {
|
||||
pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
|
||||
|
||||
if (unlikely (pboxes == NULL)) {
|
||||
free (region);
|
||||
return (cairo_region_t *)&_cairo_region_nil;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
pboxes[i].x1 = rects[i].x;
|
||||
pboxes[i].y1 = rects[i].y;
|
||||
pboxes[i].x2 = rects[i].x + rects[i].width;
|
||||
pboxes[i].y2 = rects[i].y + rects[i].height;
|
||||
}
|
||||
|
||||
if (! pixman_region32_init_rects (®ion->rgn, pboxes, count)) {
|
||||
free (region);
|
||||
|
||||
region = (cairo_region_t *)&_cairo_region_nil;
|
||||
}
|
||||
|
||||
if (pboxes != stack_pboxes)
|
||||
free (pboxes);
|
||||
|
||||
return region;
|
||||
}
|
||||
slim_hidden_def (cairo_region_create_rectangles);
|
||||
|
||||
/**
|
||||
* cairo_region_create_rectangle:
|
||||
* @rectangle: a #cairo_rectangle_int_t
|
||||
|
@ -92,9 +92,9 @@ struct _cairo_scaled_font {
|
||||
cairo_matrix_t ctm; /* user space => device space */
|
||||
cairo_font_options_t options;
|
||||
|
||||
unsigned int placeholder : 1; /* protected by fontmap mutex */
|
||||
unsigned int holdover : 1;
|
||||
unsigned int finished : 1;
|
||||
cairo_bool_t placeholder; /* protected by fontmap mutex */
|
||||
|
||||
cairo_bool_t finished;
|
||||
|
||||
/* "live" scaled_font members */
|
||||
cairo_matrix_t scale; /* font space => device space */
|
||||
|
@ -230,13 +230,11 @@ _cairo_sub_fonts_equal (const void *key_a, const void *key_b)
|
||||
{
|
||||
const cairo_sub_font_t *sub_font_a = key_a;
|
||||
const cairo_sub_font_t *sub_font_b = key_b;
|
||||
cairo_scaled_font_t *a = sub_font_a->scaled_font;
|
||||
cairo_scaled_font_t *b = sub_font_b->scaled_font;
|
||||
|
||||
if (sub_font_a->is_scaled)
|
||||
return a == b;
|
||||
return sub_font_a->scaled_font == sub_font_b->scaled_font;
|
||||
else
|
||||
return a->font_face == b->font_face || a->original_font_face == b->original_font_face;
|
||||
return sub_font_a->scaled_font->font_face == sub_font_b->scaled_font->font_face;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -64,7 +64,7 @@
|
||||
|
||||
/* XXX: This number is arbitrary---we've never done any measurement of this. */
|
||||
#define MAX_GLYPH_PAGES_CACHED 256
|
||||
static cairo_cache_t cairo_scaled_glyph_page_cache;
|
||||
static cairo_cache_t *cairo_scaled_glyph_page_cache;
|
||||
|
||||
#define CAIRO_SCALED_GLYPH_PAGE_SIZE 32
|
||||
struct _cairo_scaled_glyph_page {
|
||||
@ -218,7 +218,6 @@ static const cairo_scaled_font_t _cairo_scaled_font_nil = {
|
||||
CAIRO_HINT_STYLE_DEFAULT,
|
||||
CAIRO_HINT_METRICS_DEFAULT} ,
|
||||
FALSE, /* placeholder */
|
||||
FALSE, /* holdover */
|
||||
TRUE, /* finished */
|
||||
{ 1., 0., 0., 1., 0, 0}, /* scale */
|
||||
{ 1., 0., 0., 1., 0, 0}, /* scale_inverse */
|
||||
@ -644,23 +643,6 @@ _cairo_scaled_font_keys_equal (const void *abstract_key_a,
|
||||
cairo_font_options_equal (&key_a->options, &key_b->options);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_scaled_font_matches (const cairo_scaled_font_t *scaled_font,
|
||||
const cairo_font_face_t *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options)
|
||||
{
|
||||
return scaled_font->original_font_face == font_face &&
|
||||
memcmp ((unsigned char *)(&scaled_font->font_matrix.xx),
|
||||
(unsigned char *)(&font_matrix->xx),
|
||||
sizeof(cairo_matrix_t)) == 0 &&
|
||||
memcmp ((unsigned char *)(&scaled_font->ctm.xx),
|
||||
(unsigned char *)(&ctm->xx),
|
||||
sizeof(cairo_matrix_t)) == 0 &&
|
||||
cairo_font_options_equal (&scaled_font->options, options);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_scaled_glyphs_equal (const void *abstract_a, const void *abstract_b)
|
||||
{
|
||||
@ -727,7 +709,6 @@ _cairo_scaled_font_init (cairo_scaled_font_t *scaled_font,
|
||||
scaled_font->cache_frozen = FALSE;
|
||||
scaled_font->global_cache_frozen = FALSE;
|
||||
|
||||
scaled_font->holdover = FALSE;
|
||||
scaled_font->finished = FALSE;
|
||||
|
||||
CAIRO_REFERENCE_COUNT_INIT (&scaled_font->ref_count, 1);
|
||||
@ -764,7 +745,7 @@ _cairo_scaled_font_thaw_cache (cairo_scaled_font_t *scaled_font)
|
||||
|
||||
if (scaled_font->global_cache_frozen) {
|
||||
CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
_cairo_cache_thaw (&cairo_scaled_glyph_page_cache);
|
||||
_cairo_cache_thaw (cairo_scaled_glyph_page_cache);
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
|
||||
scaled_font->global_cache_frozen = FALSE;
|
||||
@ -780,7 +761,7 @@ _cairo_scaled_font_reset_cache (cairo_scaled_font_t *scaled_font)
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
while (scaled_font->glyph_pages != NULL) {
|
||||
_cairo_cache_remove (&cairo_scaled_glyph_page_cache,
|
||||
_cairo_cache_remove (cairo_scaled_glyph_page_cache,
|
||||
&scaled_font->glyph_pages->cache_entry);
|
||||
}
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
@ -899,18 +880,28 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
/* Note that degenerate ctm or font_matrix *are* allowed.
|
||||
* We want to support a font size of 0. */
|
||||
|
||||
if (font_face->backend->type == CAIRO_FONT_TYPE_TOY) {
|
||||
/* indirect implementation, lookup the face that is used for the toy face */
|
||||
font_face = _cairo_toy_font_face_get_implementation (font_face);
|
||||
|
||||
if (unlikely (font_face->status))
|
||||
return _cairo_scaled_font_create_in_error (font_face->status);
|
||||
}
|
||||
|
||||
font_map = _cairo_scaled_font_map_lock ();
|
||||
if (unlikely (font_map == NULL))
|
||||
return _cairo_scaled_font_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
|
||||
_cairo_scaled_font_init_key (&key, font_face,
|
||||
font_matrix, ctm, options);
|
||||
scaled_font = font_map->mru_scaled_font;
|
||||
if (scaled_font != NULL &&
|
||||
_cairo_scaled_font_matches (scaled_font,
|
||||
font_face, font_matrix, ctm, options))
|
||||
scaled_font->hash_entry.hash == key.hash_entry.hash &&
|
||||
_cairo_scaled_font_keys_equal (scaled_font, &key))
|
||||
{
|
||||
assert (! scaled_font->placeholder);
|
||||
|
||||
if (likely (scaled_font->status == CAIRO_STATUS_SUCCESS)) {
|
||||
if (scaled_font->status == CAIRO_STATUS_SUCCESS) {
|
||||
/* We increment the reference count manually here, (rather
|
||||
* than calling into cairo_scaled_font_reference), since we
|
||||
* must modify the reference count while our lock is still
|
||||
@ -924,26 +915,9 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
_cairo_hash_table_remove (font_map->hash_table,
|
||||
&scaled_font->hash_entry);
|
||||
scaled_font->hash_entry.hash = ZOMBIE;
|
||||
|
||||
if (font_face->backend->get_implementation != NULL) {
|
||||
font_face = font_face->backend->get_implementation (font_face,
|
||||
font_matrix,
|
||||
ctm,
|
||||
options);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (font_face->backend->get_implementation != NULL) {
|
||||
font_face = font_face->backend->get_implementation (font_face,
|
||||
font_matrix,
|
||||
ctm,
|
||||
options);
|
||||
}
|
||||
|
||||
_cairo_scaled_font_init_key (&key, font_face,
|
||||
font_matrix, ctm, options);
|
||||
|
||||
while ((scaled_font = _cairo_hash_table_lookup (font_map->hash_table,
|
||||
&key.hash_entry)))
|
||||
{
|
||||
@ -960,30 +934,25 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
/* If the original reference count is 0, then this font must have
|
||||
* been found in font_map->holdovers, (which means this caching is
|
||||
* actually working). So now we remove it from the holdovers
|
||||
* array, unless we caught the font in the middle of destruction.
|
||||
*/
|
||||
* array. */
|
||||
if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) {
|
||||
if (scaled_font->holdover) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < font_map->num_holdovers; i++) {
|
||||
if (font_map->holdovers[i] == scaled_font) {
|
||||
font_map->num_holdovers--;
|
||||
memmove (&font_map->holdovers[i],
|
||||
&font_map->holdovers[i+1],
|
||||
(font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*));
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < font_map->num_holdovers; i++)
|
||||
if (font_map->holdovers[i] == scaled_font)
|
||||
break;
|
||||
assert (i < font_map->num_holdovers);
|
||||
|
||||
scaled_font->holdover = FALSE;
|
||||
}
|
||||
font_map->num_holdovers--;
|
||||
memmove (&font_map->holdovers[i],
|
||||
&font_map->holdovers[i+1],
|
||||
(font_map->num_holdovers - i) * sizeof (cairo_scaled_font_t*));
|
||||
|
||||
/* reset any error status */
|
||||
scaled_font->status = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (likely (scaled_font->status == CAIRO_STATUS_SUCCESS)) {
|
||||
if (scaled_font->status == CAIRO_STATUS_SUCCESS) {
|
||||
/* We increment the reference count manually here, (rather
|
||||
* than calling into cairo_scaled_font_reference), since we
|
||||
* must modify the reference count while our lock is still
|
||||
@ -1024,12 +993,6 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
return scaled_font;
|
||||
}
|
||||
|
||||
/* Our caching above is defeated if the backend switches fonts on us -
|
||||
* e.g. old incarnations of toy-font-face and lazily resolved
|
||||
* ft-font-faces
|
||||
*/
|
||||
assert (scaled_font->font_face == font_face);
|
||||
|
||||
scaled_font->original_font_face =
|
||||
cairo_font_face_reference (original_font_face);
|
||||
|
||||
@ -1055,9 +1018,6 @@ cairo_scaled_font_create (cairo_font_face_t *font_face,
|
||||
|
||||
cairo_scaled_font_destroy (old);
|
||||
|
||||
if (font_face != original_font_face)
|
||||
cairo_font_face_destroy (font_face);
|
||||
|
||||
return scaled_font;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_create);
|
||||
@ -1112,9 +1072,9 @@ _cairo_scaled_font_reset_static_data (void)
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_scaled_font_error_mutex);
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
if (cairo_scaled_glyph_page_cache.hash_table != NULL) {
|
||||
_cairo_cache_fini (&cairo_scaled_glyph_page_cache);
|
||||
cairo_scaled_glyph_page_cache.hash_table = NULL;
|
||||
if (cairo_scaled_glyph_page_cache != NULL) {
|
||||
_cairo_cache_destroy (cairo_scaled_glyph_page_cache);
|
||||
cairo_scaled_glyph_page_cache = NULL;
|
||||
}
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
}
|
||||
@ -1170,21 +1130,13 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
|
||||
|
||||
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count));
|
||||
|
||||
if (! _cairo_reference_count_dec_and_test (&scaled_font->ref_count))
|
||||
return;
|
||||
|
||||
font_map = _cairo_scaled_font_map_lock ();
|
||||
assert (font_map != NULL);
|
||||
|
||||
/* Another thread may have resurrected the font whilst we waited */
|
||||
if (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&scaled_font->ref_count)) {
|
||||
if (_cairo_reference_count_dec_and_test (&scaled_font->ref_count)) {
|
||||
if (! scaled_font->placeholder &&
|
||||
scaled_font->hash_entry.hash != ZOMBIE)
|
||||
{
|
||||
/* Another thread may have already inserted us into the holdovers */
|
||||
if (scaled_font->holdover)
|
||||
goto unlock;
|
||||
|
||||
/* Rather than immediately destroying this object, we put it into
|
||||
* the font_map->holdovers array in case it will get used again
|
||||
* soon (and is why we must hold the lock over the atomic op on
|
||||
@ -1192,7 +1144,8 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
|
||||
* destroy the least-recently-used holdover.
|
||||
*/
|
||||
|
||||
if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS) {
|
||||
if (font_map->num_holdovers == CAIRO_SCALED_FONT_MAX_HOLDOVERS)
|
||||
{
|
||||
lru = font_map->holdovers[0];
|
||||
assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&lru->ref_count));
|
||||
|
||||
@ -1205,13 +1158,12 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
|
||||
font_map->num_holdovers * sizeof (cairo_scaled_font_t*));
|
||||
}
|
||||
|
||||
font_map->holdovers[font_map->num_holdovers++] = scaled_font;
|
||||
scaled_font->holdover = TRUE;
|
||||
font_map->holdovers[font_map->num_holdovers] = scaled_font;
|
||||
font_map->num_holdovers++;
|
||||
} else
|
||||
lru = scaled_font;
|
||||
}
|
||||
|
||||
unlock:
|
||||
_cairo_scaled_font_map_unlock ();
|
||||
|
||||
/* If we pulled an item from the holdovers array, (while the font
|
||||
@ -1220,7 +1172,7 @@ cairo_scaled_font_destroy (cairo_scaled_font_t *scaled_font)
|
||||
* safely call fini on it without any lock held. This is desirable
|
||||
* as we never want to call into any backend function with a lock
|
||||
* held. */
|
||||
if (lru != NULL) {
|
||||
if (lru) {
|
||||
_cairo_scaled_font_fini_internal (lru);
|
||||
free (lru);
|
||||
}
|
||||
@ -1906,48 +1858,37 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
|
||||
int i;
|
||||
cairo_point_int_t min = { CAIRO_RECT_INT_MAX, CAIRO_RECT_INT_MAX };
|
||||
cairo_point_int_t max = { CAIRO_RECT_INT_MIN, CAIRO_RECT_INT_MIN };
|
||||
cairo_scaled_glyph_t *glyph_cache[64];
|
||||
|
||||
if (unlikely (scaled_font->status))
|
||||
if (scaled_font->status)
|
||||
return scaled_font->status;
|
||||
|
||||
_cairo_scaled_font_freeze_cache (scaled_font);
|
||||
|
||||
memset (glyph_cache, 0, sizeof (glyph_cache));
|
||||
|
||||
for (i = 0; i < num_glyphs; i++) {
|
||||
cairo_scaled_glyph_t *scaled_glyph;
|
||||
int left, top;
|
||||
int right, bottom;
|
||||
int x, y;
|
||||
int cache_index = glyphs[i].index % ARRAY_LENGTH (glyph_cache);
|
||||
|
||||
scaled_glyph = glyph_cache[cache_index];
|
||||
if (scaled_glyph == NULL ||
|
||||
_cairo_scaled_glyph_index (scaled_glyph) != glyphs[i].index)
|
||||
{
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
break;
|
||||
|
||||
glyph_cache[cache_index] = scaled_glyph;
|
||||
}
|
||||
status = _cairo_scaled_glyph_lookup (scaled_font,
|
||||
glyphs[i].index,
|
||||
CAIRO_SCALED_GLYPH_INFO_METRICS,
|
||||
&scaled_glyph);
|
||||
if (unlikely (status))
|
||||
break;
|
||||
|
||||
/* XXX glyph images are snapped to pixel locations */
|
||||
x = _cairo_lround (glyphs[i].x);
|
||||
y = _cairo_lround (glyphs[i].y);
|
||||
|
||||
left = x + _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.x);
|
||||
left = x + _cairo_fixed_integer_floor(scaled_glyph->bbox.p1.x);
|
||||
top = y + _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y);
|
||||
right = x + _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.x);
|
||||
right = x + _cairo_fixed_integer_ceil(scaled_glyph->bbox.p2.x);
|
||||
bottom = y + _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.y);
|
||||
|
||||
if (left < min.x) min.x = left;
|
||||
if (right > max.x) max.x = right;
|
||||
if (top < min.y) min.y = top;
|
||||
if (left < min.x) min.x = left;
|
||||
if (right > max.x) max.x = right;
|
||||
if (top < min.y) min.y = top;
|
||||
if (bottom > max.y) max.y = bottom;
|
||||
}
|
||||
|
||||
@ -2528,24 +2469,24 @@ _cairo_scaled_font_allocate_glyph (cairo_scaled_font_t *scaled_font,
|
||||
|
||||
CAIRO_MUTEX_LOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
if (scaled_font->global_cache_frozen == FALSE) {
|
||||
if (unlikely (cairo_scaled_glyph_page_cache.hash_table == NULL)) {
|
||||
status = _cairo_cache_init (&cairo_scaled_glyph_page_cache,
|
||||
NULL,
|
||||
_cairo_scaled_glyph_page_can_remove,
|
||||
_cairo_scaled_glyph_page_destroy,
|
||||
MAX_GLYPH_PAGES_CACHED);
|
||||
if (unlikely (status)) {
|
||||
if (unlikely (cairo_scaled_glyph_page_cache == NULL)) {
|
||||
cairo_scaled_glyph_page_cache =
|
||||
_cairo_cache_create (NULL,
|
||||
_cairo_scaled_glyph_page_can_remove,
|
||||
_cairo_scaled_glyph_page_destroy,
|
||||
MAX_GLYPH_PAGES_CACHED);
|
||||
if (unlikely (cairo_scaled_glyph_page_cache == NULL)) {
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
free (page);
|
||||
return status;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
_cairo_cache_freeze (&cairo_scaled_glyph_page_cache);
|
||||
_cairo_cache_freeze (cairo_scaled_glyph_page_cache);
|
||||
scaled_font->global_cache_frozen = TRUE;
|
||||
}
|
||||
|
||||
status = _cairo_cache_insert (&cairo_scaled_glyph_page_cache,
|
||||
status = _cairo_cache_insert (cairo_scaled_glyph_page_cache,
|
||||
&page->cache_entry);
|
||||
CAIRO_MUTEX_UNLOCK (_cairo_scaled_glyph_page_cache_mutex);
|
||||
if (unlikely (status)) {
|
||||
@ -2575,8 +2516,7 @@ _cairo_scaled_font_free_last_glyph (cairo_scaled_font_t *scaled_font,
|
||||
_cairo_scaled_glyph_fini (scaled_font, scaled_glyph);
|
||||
|
||||
if (--page->num_glyphs == 0) {
|
||||
_cairo_cache_remove (&cairo_scaled_glyph_page_cache,
|
||||
&page->cache_entry);
|
||||
_cairo_cache_remove (cairo_scaled_glyph_page_cache, &page->cache_entry);
|
||||
assert (scaled_font->glyph_pages != page);
|
||||
}
|
||||
}
|
||||
@ -2751,9 +2691,6 @@ cairo_scaled_font_get_font_face (cairo_scaled_font_t *scaled_font)
|
||||
if (scaled_font->status)
|
||||
return (cairo_font_face_t*) &_cairo_font_face_nil;
|
||||
|
||||
if (scaled_font->original_font_face != NULL)
|
||||
return scaled_font->original_font_face;
|
||||
|
||||
return scaled_font->font_face;
|
||||
}
|
||||
slim_hidden_def (cairo_scaled_font_get_font_face);
|
||||
|
@ -290,7 +290,6 @@ _cairo_scan_converter_create_in_error (cairo_status_t status)
|
||||
case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL;
|
||||
case CAIRO_STATUS_NO_MEMORY: RETURN_NIL;
|
||||
case CAIRO_STATUS_INVALID_SIZE: RETURN_NIL;
|
||||
case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: RETURN_NIL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -396,7 +395,6 @@ _cairo_span_renderer_create_in_error (cairo_status_t status)
|
||||
case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL;
|
||||
case CAIRO_STATUS_NO_MEMORY: RETURN_NIL;
|
||||
case CAIRO_STATUS_INVALID_SIZE: RETURN_NIL;
|
||||
case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: RETURN_NIL;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -38,8 +38,6 @@
|
||||
void
|
||||
_cairo_stroke_style_init (cairo_stroke_style_t *style)
|
||||
{
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (style, sizeof (cairo_stroke_style_t)));
|
||||
|
||||
style->line_width = CAIRO_GSTATE_LINE_WIDTH_DEFAULT;
|
||||
style->line_cap = CAIRO_GSTATE_LINE_CAP_DEFAULT;
|
||||
style->line_join = CAIRO_GSTATE_LINE_JOIN_DEFAULT;
|
||||
@ -57,8 +55,6 @@ _cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (style, sizeof (cairo_stroke_style_t)));
|
||||
|
||||
style->line_width = other->line_width;
|
||||
style->line_cap = other->line_cap;
|
||||
style->line_join = other->line_join;
|
||||
@ -90,8 +86,6 @@ _cairo_stroke_style_fini (cairo_stroke_style_t *style)
|
||||
style->dash = NULL;
|
||||
}
|
||||
style->num_dashes = 0;
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (style, sizeof (cairo_stroke_style_t)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -398,6 +398,9 @@ _clip_and_composite (cairo_clip_t *clip,
|
||||
extents);
|
||||
}
|
||||
|
||||
if (src == &solid_pattern.base)
|
||||
_cairo_pattern_fini (&solid_pattern.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -418,9 +421,6 @@ _composite_trap_region (cairo_clip_t *clip,
|
||||
unsigned int clip_serial;
|
||||
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
|
||||
|
||||
if (num_rects == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip_surface && op == CAIRO_OPERATOR_CLEAR) {
|
||||
_cairo_pattern_init_solid (&solid_pattern, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
@ -428,6 +428,9 @@ _composite_trap_region (cairo_clip_t *clip,
|
||||
op = CAIRO_OPERATOR_DEST_OUT;
|
||||
}
|
||||
|
||||
if (num_rects == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (num_rects > 1) {
|
||||
if (_cairo_surface_get_clip_mode (dst) != CAIRO_CLIP_MODE_REGION)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
@ -463,6 +466,9 @@ _composite_trap_region (cairo_clip_t *clip,
|
||||
if (clip_surface)
|
||||
_cairo_pattern_fini (&mask.base);
|
||||
|
||||
if (src == &solid_pattern.base)
|
||||
_cairo_pattern_fini (&solid_pattern.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -482,23 +488,26 @@ _composite_traps_draw_func (void *closure,
|
||||
{
|
||||
cairo_composite_traps_info_t *info = closure;
|
||||
cairo_solid_pattern_t pattern;
|
||||
cairo_status_t status;
|
||||
|
||||
if (dst_x != 0 || dst_y != 0)
|
||||
_cairo_traps_translate (info->traps, - dst_x, - dst_y);
|
||||
|
||||
if (src == NULL) {
|
||||
_cairo_pattern_init_solid (&pattern, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
_cairo_pattern_init_solid (&pattern, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
if (!src)
|
||||
src = &pattern.base;
|
||||
}
|
||||
|
||||
return _cairo_surface_composite_trapezoids (op,
|
||||
src, dst, info->antialias,
|
||||
extents->x, extents->y,
|
||||
extents->x - dst_x, extents->y - dst_y,
|
||||
extents->width, extents->height,
|
||||
info->traps->traps,
|
||||
info->traps->num_traps);
|
||||
status = _cairo_surface_composite_trapezoids (op,
|
||||
src, dst, info->antialias,
|
||||
extents->x, extents->y,
|
||||
extents->x - dst_x, extents->y - dst_y,
|
||||
extents->width, extents->height,
|
||||
info->traps->traps,
|
||||
info->traps->num_traps);
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Warning: This call modifies the coordinates of traps */
|
||||
@ -675,7 +684,8 @@ _composite_spans_fill_func (void *closure,
|
||||
{
|
||||
cairo_composite_rectangles_t rects;
|
||||
cairo_composite_spans_fill_info_t *info = closure;
|
||||
cairo_solid_pattern_t pattern;
|
||||
cairo_pattern_union_t pattern;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
_cairo_composite_rectangles_init (
|
||||
&rects, extents->x, extents->y,
|
||||
@ -689,16 +699,18 @@ _composite_spans_fill_func (void *closure,
|
||||
|
||||
/* We're called without a source pattern from
|
||||
* _create_composite_mask_pattern(). */
|
||||
if (src == NULL) {
|
||||
_cairo_pattern_init_solid (&pattern, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
_cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
if (src == NULL)
|
||||
src = &pattern.base;
|
||||
}
|
||||
|
||||
return _cairo_path_fixed_fill_using_spans (
|
||||
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
|
||||
@ -1015,11 +1027,10 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure
|
||||
}
|
||||
}
|
||||
|
||||
if (src == NULL) {
|
||||
_cairo_pattern_init_solid (&pattern, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
_cairo_pattern_init_solid (&pattern, CAIRO_COLOR_WHITE,
|
||||
CAIRO_CONTENT_COLOR);
|
||||
if (!src)
|
||||
src = &pattern.base;
|
||||
}
|
||||
|
||||
status = _cairo_surface_old_show_glyphs (glyph_info->font, op, src,
|
||||
dst,
|
||||
@ -1030,18 +1041,24 @@ _cairo_surface_old_show_glyphs_draw_func (void *closure
|
||||
extents->height,
|
||||
glyph_info->glyphs,
|
||||
glyph_info->num_glyphs);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
return _cairo_scaled_font_show_glyphs (glyph_info->font,
|
||||
op,
|
||||
src, dst,
|
||||
extents->x, extents->y,
|
||||
extents->x - dst_x,
|
||||
extents->y - dst_y,
|
||||
extents->width, extents->height,
|
||||
glyph_info->glyphs,
|
||||
glyph_info->num_glyphs);
|
||||
status = _cairo_scaled_font_show_glyphs (glyph_info->font,
|
||||
op,
|
||||
src, dst,
|
||||
extents->x, extents->y,
|
||||
extents->x - dst_x,
|
||||
extents->y - dst_y,
|
||||
extents->width, extents->height,
|
||||
glyph_info->glyphs,
|
||||
glyph_info->num_glyphs);
|
||||
|
||||
if (src == &pattern.base)
|
||||
_cairo_pattern_fini (&pattern.base);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
@ -1196,7 +1213,7 @@ _cairo_surface_fallback_fill_rectangles (cairo_surface_t *surface,
|
||||
int x1, y1, x2, y2;
|
||||
int i;
|
||||
|
||||
assert (surface->snapshot_of == NULL);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (num_rects <= 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -43,8 +43,6 @@
|
||||
#include "cairo-types-private.h"
|
||||
#include "cairo-reference-count-private.h"
|
||||
|
||||
typedef void (*cairo_surface_func_t) (cairo_surface_t *);
|
||||
|
||||
struct _cairo_surface {
|
||||
const cairo_surface_backend_t *backend;
|
||||
|
||||
@ -58,8 +56,6 @@ struct _cairo_surface {
|
||||
cairo_reference_count_t ref_count;
|
||||
cairo_status_t status;
|
||||
cairo_bool_t finished;
|
||||
unsigned int unique_id;
|
||||
|
||||
cairo_user_data_array_t user_data;
|
||||
cairo_user_data_array_t mime_data;
|
||||
|
||||
@ -96,10 +92,7 @@ struct _cairo_surface {
|
||||
unsigned int current_clip_serial;
|
||||
|
||||
/* A "snapshot" surface is immutable. See _cairo_surface_snapshot. */
|
||||
cairo_surface_t *snapshot_of;
|
||||
cairo_surface_func_t snapshot_detach;
|
||||
/* current snapshots of this surface */
|
||||
cairo_array_t snapshots;
|
||||
cairo_bool_t is_snapshot;
|
||||
|
||||
/*
|
||||
* Surface font options, falling back to backend's default options,
|
||||
|
@ -50,7 +50,6 @@ const cairo_surface_t name = { \
|
||||
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */ \
|
||||
status, /* status */ \
|
||||
FALSE, /* finished */ \
|
||||
0, /* unique id */ \
|
||||
{ 0, 0, 0, NULL, }, /* user_data */ \
|
||||
{ 0, 0, 0, NULL, }, /* mime_data */ \
|
||||
{ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 }, /* device_transform */ \
|
||||
@ -62,13 +61,7 @@ const cairo_surface_t name = { \
|
||||
NULL, /* clip */ \
|
||||
0, /* next_clip_serial */ \
|
||||
0, /* current_clip_serial */ \
|
||||
NULL, /* snapshot_of */ \
|
||||
NULL, /* snapshot_detach */ \
|
||||
{ 0, /* size */ \
|
||||
0, /* num_elements */ \
|
||||
0, /* element_size */ \
|
||||
NULL, /* elements */ \
|
||||
}, /* snapshots */ \
|
||||
FALSE, /* is_snapshot */ \
|
||||
FALSE, /* has_font_options */ \
|
||||
{ CAIRO_ANTIALIAS_DEFAULT, /* antialias */ \
|
||||
CAIRO_SUBPIXEL_ORDER_DEFAULT, /* subpixel_order */ \
|
||||
@ -78,7 +71,6 @@ const cairo_surface_t name = { \
|
||||
}
|
||||
|
||||
static DEFINE_NIL_SURFACE(CAIRO_STATUS_NO_MEMORY, _cairo_surface_nil);
|
||||
static DEFINE_NIL_SURFACE(CAIRO_STATUS_SURFACE_TYPE_MISMATCH, _cairo_surface_nil_surface_type_mismatch);
|
||||
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_CONTENT, _cairo_surface_nil_invalid_content);
|
||||
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_FORMAT, _cairo_surface_nil_invalid_format);
|
||||
static DEFINE_NIL_SURFACE(CAIRO_STATUS_INVALID_VISUAL, _cairo_surface_nil_invalid_visual);
|
||||
@ -188,151 +180,6 @@ cairo_surface_status (cairo_surface_t *surface)
|
||||
}
|
||||
slim_hidden_def (cairo_surface_status);
|
||||
|
||||
static unsigned int
|
||||
_cairo_surface_allocate_unique_id (void)
|
||||
{
|
||||
static unsigned int unique_id;
|
||||
|
||||
#if CAIRO_NO_MUTEX
|
||||
if (++unique_id == 0)
|
||||
unique_id = 1;
|
||||
return unique_id;
|
||||
#else
|
||||
unsigned int old, id;
|
||||
|
||||
do {
|
||||
old = _cairo_atomic_uint_get (&unique_id);
|
||||
id = old + 1;
|
||||
if (id == 0)
|
||||
id = 1;
|
||||
} while (! _cairo_atomic_uint_cmpxchg (&unique_id, old, id));
|
||||
|
||||
return id;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_surface_has_snapshots (cairo_surface_t *surface)
|
||||
{
|
||||
return surface->snapshots.num_elements != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_surface_detach_snapshots (cairo_surface_t *surface)
|
||||
{
|
||||
cairo_surface_t **snapshots;
|
||||
unsigned int i;
|
||||
|
||||
if (! _cairo_surface_has_snapshots (surface))
|
||||
return;
|
||||
|
||||
/* XXX do something intelligent! */
|
||||
|
||||
snapshots = _cairo_array_index (&surface->snapshots, 0);
|
||||
for (i = 0; i < surface->snapshots.num_elements; i++) {
|
||||
snapshots[i]->snapshot_of = NULL;
|
||||
|
||||
if (snapshots[i]->snapshot_detach != NULL)
|
||||
snapshots[i]->snapshot_detach (snapshots[i]);
|
||||
|
||||
cairo_surface_destroy (snapshots[i]);
|
||||
}
|
||||
surface->snapshots.num_elements = 0;
|
||||
|
||||
assert (! _cairo_surface_has_snapshots (surface));
|
||||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_surface_attach_snapshot (cairo_surface_t *surface,
|
||||
cairo_surface_t *snapshot,
|
||||
cairo_surface_func_t detach_func)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
assert (surface != snapshot);
|
||||
|
||||
if (snapshot->snapshot_of != NULL)
|
||||
_cairo_surface_detach_snapshot (snapshot);
|
||||
|
||||
snapshot->snapshot_of = surface;
|
||||
snapshot->snapshot_detach = detach_func;
|
||||
|
||||
status = _cairo_array_append (&surface->snapshots, &snapshot);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_surface_reference (snapshot);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_surface_has_snapshot (cairo_surface_t *surface,
|
||||
const cairo_surface_backend_t *backend,
|
||||
cairo_content_t content)
|
||||
{
|
||||
cairo_surface_t **snapshots;
|
||||
unsigned int i;
|
||||
|
||||
snapshots = _cairo_array_index (&surface->snapshots, 0);
|
||||
for (i = 0; i < surface->snapshots.num_elements; i++) {
|
||||
if (snapshots[i]->backend == backend &&
|
||||
snapshots[i]->content == content)
|
||||
{
|
||||
return snapshots[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_surface_detach_snapshot (cairo_surface_t *snapshot)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t **snapshots;
|
||||
unsigned int i;
|
||||
|
||||
assert (snapshot->snapshot_of != NULL);
|
||||
surface = snapshot->snapshot_of;
|
||||
|
||||
snapshots = _cairo_array_index (&surface->snapshots, 0);
|
||||
for (i = 0; i < surface->snapshots.num_elements; i++) {
|
||||
if (snapshots[i] == snapshot)
|
||||
break;
|
||||
}
|
||||
assert (i < surface->snapshots.num_elements);
|
||||
|
||||
surface->snapshots.num_elements--;
|
||||
memmove (&snapshots[i],
|
||||
&snapshots[i+1],
|
||||
sizeof (cairo_surface_t *)*(surface->snapshots.num_elements - i));
|
||||
|
||||
snapshot->snapshot_of = NULL;
|
||||
|
||||
if (snapshot->snapshot_detach != NULL)
|
||||
snapshot->snapshot_detach (snapshot);
|
||||
|
||||
cairo_surface_destroy (snapshot);
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_surface_is_writable (cairo_surface_t *surface)
|
||||
{
|
||||
return ! surface->finished &&
|
||||
surface->snapshot_of == NULL &&
|
||||
! _cairo_surface_has_snapshots (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_surface_begin_modification (cairo_surface_t *surface)
|
||||
{
|
||||
assert (surface->status == CAIRO_STATUS_SUCCESS);
|
||||
assert (! surface->finished);
|
||||
assert (surface->snapshot_of == NULL);
|
||||
|
||||
_cairo_surface_detach_snapshots (surface);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_surface_init (cairo_surface_t *surface,
|
||||
const cairo_surface_backend_t *backend,
|
||||
@ -347,7 +194,6 @@ _cairo_surface_init (cairo_surface_t *surface,
|
||||
CAIRO_REFERENCE_COUNT_INIT (&surface->ref_count, 1);
|
||||
surface->status = CAIRO_STATUS_SUCCESS;
|
||||
surface->finished = FALSE;
|
||||
surface->unique_id = _cairo_surface_allocate_unique_id ();
|
||||
|
||||
_cairo_user_data_array_init (&surface->user_data);
|
||||
_cairo_user_data_array_init (&surface->mime_data);
|
||||
@ -365,8 +211,7 @@ _cairo_surface_init (cairo_surface_t *surface,
|
||||
surface->next_clip_serial = 0;
|
||||
surface->current_clip_serial = 0;
|
||||
|
||||
_cairo_array_init (&surface->snapshots, sizeof (cairo_surface_t *));
|
||||
surface->snapshot_of = NULL;
|
||||
surface->is_snapshot = FALSE;
|
||||
|
||||
surface->has_font_options = FALSE;
|
||||
}
|
||||
@ -591,14 +436,11 @@ cairo_surface_destroy (cairo_surface_t *surface)
|
||||
if (! _cairo_reference_count_dec_and_test (&surface->ref_count))
|
||||
return;
|
||||
|
||||
assert (surface->snapshot_of == NULL);
|
||||
|
||||
if (! surface->finished)
|
||||
cairo_surface_finish (surface);
|
||||
|
||||
_cairo_user_data_array_fini (&surface->user_data);
|
||||
_cairo_user_data_array_fini (&surface->mime_data);
|
||||
_cairo_array_fini (&surface->snapshots);
|
||||
|
||||
free (surface);
|
||||
}
|
||||
@ -698,9 +540,6 @@ cairo_surface_finish (cairo_surface_t *surface)
|
||||
}
|
||||
|
||||
surface->finished = TRUE;
|
||||
|
||||
if (surface->snapshot_of != NULL)
|
||||
_cairo_surface_detach_snapshot (surface);
|
||||
}
|
||||
slim_hidden_def (cairo_surface_finish);
|
||||
|
||||
@ -772,30 +611,27 @@ cairo_surface_get_mime_data (cairo_surface_t *surface,
|
||||
const unsigned char **data,
|
||||
unsigned int *length)
|
||||
{
|
||||
cairo_user_data_slot_t *slots;
|
||||
int i, num_slots;
|
||||
cairo_status_t status;
|
||||
cairo_mime_data_t *mime_data;
|
||||
|
||||
*data = NULL;
|
||||
*length = 0;
|
||||
if (unlikely (surface->status))
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
/* The number of mime-types attached to a surface is usually small,
|
||||
* typically zero. Therefore it is quicker to do a strcmp() against
|
||||
* each key than it is to intern the string (i.e. compute a hash,
|
||||
* search the hash table, and do a final strcmp).
|
||||
*/
|
||||
num_slots = surface->mime_data.num_elements;
|
||||
slots = _cairo_array_index (&surface->mime_data, 0);
|
||||
for (i = 0; i < num_slots; i++) {
|
||||
if (strcmp ((char *) slots[i].key, mime_type) == 0) {
|
||||
cairo_mime_data_t *mime_data = slots[i].user_data;
|
||||
|
||||
*data = mime_data->data;
|
||||
*length = mime_data->length;
|
||||
return;
|
||||
}
|
||||
status = _cairo_intern_string (&mime_type, -1);
|
||||
if (unlikely (status)) {
|
||||
status = _cairo_surface_set_error (surface, status);
|
||||
return;
|
||||
}
|
||||
|
||||
mime_data = _cairo_user_data_array_get_data (&surface->mime_data,
|
||||
(cairo_user_data_key_t *) mime_type);
|
||||
if (mime_data == NULL)
|
||||
return;
|
||||
|
||||
*data = mime_data->data;
|
||||
*length = mime_data->length;
|
||||
}
|
||||
slim_hidden_def (cairo_surface_get_mime_data);
|
||||
|
||||
@ -937,7 +773,7 @@ _cairo_surface_set_font_options (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
assert (surface->snapshot_of == NULL);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished) {
|
||||
status = _cairo_surface_set_error (surface,
|
||||
@ -1013,9 +849,6 @@ cairo_surface_flush (cairo_surface_t *surface)
|
||||
if (surface->finished)
|
||||
return;
|
||||
|
||||
/* update the current snapshots *before* the user updates the surface */
|
||||
_cairo_surface_detach_snapshots (surface);
|
||||
|
||||
if (surface->backend->flush) {
|
||||
status = surface->backend->flush (surface);
|
||||
if (unlikely (status))
|
||||
@ -1035,6 +868,11 @@ slim_hidden_def (cairo_surface_flush);
|
||||
void
|
||||
cairo_surface_mark_dirty (cairo_surface_t *surface)
|
||||
{
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
cairo_surface_mark_dirty_rectangle (surface, 0, 0, -1, -1);
|
||||
}
|
||||
|
||||
@ -1066,18 +904,13 @@ cairo_surface_mark_dirty_rectangle (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
assert (surface->snapshot_of == NULL);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished) {
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The application *should* have called cairo_surface_flush() before
|
||||
* modifying the surface independently of cairo (and thus having to
|
||||
* call mark_dirty()). */
|
||||
assert (! _cairo_surface_has_snapshots (surface));
|
||||
|
||||
/* Always reset the clip here, to avoid having external calls to
|
||||
* clip manipulation functions of the underlying device clip result
|
||||
* in a desync between the cairo clip and the backend clip, due to
|
||||
@ -1129,15 +962,13 @@ _cairo_surface_set_device_scale (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
assert (surface->snapshot_of == NULL);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished) {
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
|
||||
surface->device_transform.xx = sx;
|
||||
surface->device_transform.yy = sy;
|
||||
surface->device_transform.xy = 0.0;
|
||||
@ -1177,15 +1008,13 @@ cairo_surface_set_device_offset (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
assert (surface->snapshot_of == NULL);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished) {
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
|
||||
surface->device_transform.x0 = x_offset;
|
||||
surface->device_transform.y0 = y_offset;
|
||||
|
||||
@ -1262,15 +1091,13 @@ cairo_surface_set_fallback_resolution (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
assert (surface->snapshot_of == NULL);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished) {
|
||||
status = _cairo_surface_set_error (surface, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
return;
|
||||
}
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
|
||||
surface->x_fallback_resolution = x_pixels_per_inch;
|
||||
surface->y_fallback_resolution = y_pixels_per_inch;
|
||||
}
|
||||
@ -1414,7 +1241,7 @@ _cairo_surface_acquire_dest_image (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (surface));
|
||||
assert (!surface->finished);
|
||||
|
||||
if (surface->backend->acquire_dest_image == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
@ -1451,85 +1278,13 @@ _cairo_surface_release_dest_image (cairo_surface_t *surface,
|
||||
cairo_rectangle_int_t *image_rect,
|
||||
void *image_extra)
|
||||
{
|
||||
assert (_cairo_surface_is_writable (surface));
|
||||
assert (!surface->finished);
|
||||
|
||||
if (surface->backend->release_dest_image)
|
||||
surface->backend->release_dest_image (surface, interest_rect,
|
||||
image, image_rect, image_extra);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_meta_surface_clone_similar (cairo_surface_t *surface,
|
||||
cairo_surface_t *src,
|
||||
cairo_content_t content,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int width,
|
||||
int height,
|
||||
int *clone_offset_x,
|
||||
int *clone_offset_y,
|
||||
cairo_surface_t **clone_out)
|
||||
{
|
||||
cairo_meta_surface_t *meta = (cairo_meta_surface_t *) src;
|
||||
cairo_surface_t *similar;
|
||||
cairo_status_t status;
|
||||
|
||||
similar = _cairo_surface_has_snapshot (src,
|
||||
surface->backend,
|
||||
src->content & content);
|
||||
if (similar != NULL) {
|
||||
*clone_out = cairo_surface_reference (similar);
|
||||
*clone_offset_x = 0;
|
||||
*clone_offset_y = 0;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (width*height*8 < meta->extents.width*meta->extents.height) {
|
||||
similar = cairo_surface_create_similar (surface,
|
||||
src->content & content,
|
||||
width, height);
|
||||
status = similar->status;
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_surface_set_device_offset (similar, -src_x, -src_y);
|
||||
|
||||
status = cairo_meta_surface_replay (src, similar);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (similar);
|
||||
return status;
|
||||
}
|
||||
|
||||
} else {
|
||||
similar = cairo_surface_create_similar (surface,
|
||||
src->content & content,
|
||||
meta->extents.width,
|
||||
meta->extents.height);
|
||||
status = similar->status;
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
status = cairo_meta_surface_replay (src, similar);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (similar);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = _cairo_surface_attach_snapshot (src, similar, NULL);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (similar);
|
||||
return status;
|
||||
}
|
||||
|
||||
src_x = src_y = 0;
|
||||
}
|
||||
|
||||
*clone_out = similar;
|
||||
*clone_offset_x = src_x;
|
||||
*clone_offset_y = src_y;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
struct acquire_source_image_data
|
||||
{
|
||||
cairo_surface_t *src;
|
||||
@ -1586,6 +1341,7 @@ _wrap_image (cairo_surface_t *src,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* _cairo_surface_clone_similar:
|
||||
* @surface: a #cairo_surface_t
|
||||
@ -1644,13 +1400,27 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
|
||||
|
||||
/* First check to see if we can replay to a similar surface */
|
||||
if (_cairo_surface_is_meta (src)) {
|
||||
return _cairo_meta_surface_clone_similar (surface, src,
|
||||
content,
|
||||
src_x, src_y,
|
||||
width, height,
|
||||
clone_offset_x,
|
||||
clone_offset_y,
|
||||
clone_out);
|
||||
cairo_surface_t *similar;
|
||||
|
||||
similar = cairo_surface_create_similar (surface,
|
||||
src->content & content,
|
||||
width, height);
|
||||
status = similar->status;
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
cairo_surface_set_device_offset (similar, -src_x, -src_y);
|
||||
|
||||
status = _cairo_meta_surface_replay (src, similar);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (similar);
|
||||
return status;
|
||||
}
|
||||
|
||||
*clone_out = similar;
|
||||
*clone_offset_x = src_x;
|
||||
*clone_offset_y = src_y;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* If we failed, try again with an image surface */
|
||||
@ -1729,45 +1499,18 @@ _cairo_surface_snapshot (cairo_surface_t *surface)
|
||||
if (surface->finished)
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_FINISHED));
|
||||
|
||||
if (surface->snapshot_of != NULL)
|
||||
if (surface->is_snapshot)
|
||||
return cairo_surface_reference (surface);
|
||||
|
||||
snapshot = _cairo_surface_has_snapshot (surface,
|
||||
surface->backend,
|
||||
surface->content);
|
||||
if (snapshot != NULL)
|
||||
return cairo_surface_reference (snapshot);
|
||||
|
||||
if (surface->backend->snapshot != NULL) {
|
||||
snapshot = NULL;
|
||||
if (surface->backend->snapshot != NULL)
|
||||
snapshot = surface->backend->snapshot (surface);
|
||||
if (unlikely (snapshot->status))
|
||||
return snapshot;
|
||||
|
||||
/* Is this surface just a proxy - e.g. paginated surfaces? */
|
||||
if (snapshot->backend != surface->backend) {
|
||||
cairo_surface_t *previous;
|
||||
|
||||
previous = _cairo_surface_has_snapshot (surface,
|
||||
snapshot->backend,
|
||||
snapshot->content);
|
||||
if (previous != NULL) {
|
||||
cairo_surface_destroy (snapshot);
|
||||
return cairo_surface_reference (previous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (snapshot == NULL) {
|
||||
snapshot = _cairo_surface_has_snapshot (surface,
|
||||
&_cairo_image_surface_backend,
|
||||
surface->content);
|
||||
if (snapshot != NULL)
|
||||
return cairo_surface_reference (snapshot);
|
||||
|
||||
if (snapshot == NULL)
|
||||
snapshot = _cairo_surface_fallback_snapshot (surface);
|
||||
if (unlikely (snapshot->status))
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
if (unlikely (snapshot->status))
|
||||
return snapshot;
|
||||
|
||||
status = _cairo_surface_copy_mime_data (snapshot, surface);
|
||||
if (unlikely (status)) {
|
||||
@ -1778,11 +1521,7 @@ _cairo_surface_snapshot (cairo_surface_t *surface)
|
||||
snapshot->device_transform = surface->device_transform;
|
||||
snapshot->device_transform_inverse = surface->device_transform_inverse;
|
||||
|
||||
status = _cairo_surface_attach_snapshot (surface, snapshot, NULL);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (snapshot);
|
||||
return _cairo_surface_create_in_error (status);
|
||||
}
|
||||
snapshot->is_snapshot = TRUE;
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
@ -1832,11 +1571,6 @@ _cairo_surface_composite (cairo_operator_t op,
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (dst));
|
||||
|
||||
if (mask) {
|
||||
/* These operators aren't interpreted the same way by the backends;
|
||||
* they are implemented in terms of other operators in cairo-gstate.c
|
||||
@ -1844,6 +1578,14 @@ _cairo_surface_composite (cairo_operator_t op,
|
||||
assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);
|
||||
}
|
||||
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
if (dst->finished)
|
||||
return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (dst->backend->composite) {
|
||||
status = dst->backend->composite (op,
|
||||
src, mask, dst,
|
||||
@ -1893,7 +1635,10 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (surface));
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished)
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
@ -1931,7 +1676,7 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (surface));
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
num_rects = cairo_region_num_rectangles (region);
|
||||
if (num_rects == 0)
|
||||
@ -1986,7 +1731,10 @@ _cairo_surface_fill_rectangles (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (surface));
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished)
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (num_rects == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
@ -2015,7 +1763,7 @@ _cairo_surface_paint (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (&source,
|
||||
surface,
|
||||
@ -2052,7 +1800,7 @@ _cairo_surface_mask (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (&source,
|
||||
surface,
|
||||
@ -2107,8 +1855,6 @@ _cairo_surface_fill_stroke (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
|
||||
if (surface->backend->fill_stroke) {
|
||||
cairo_pattern_union_t dev_stroke_source;
|
||||
cairo_pattern_union_t dev_fill_source;
|
||||
@ -2187,7 +1933,7 @@ _cairo_surface_stroke (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (&source,
|
||||
surface,
|
||||
@ -2236,7 +1982,7 @@ _cairo_surface_fill (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (&source,
|
||||
surface,
|
||||
@ -2280,16 +2026,19 @@ _cairo_surface_composite_trapezoids (cairo_operator_t op,
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (dst));
|
||||
|
||||
/* These operators aren't interpreted the same way by the backends;
|
||||
* they are implemented in terms of other operators in cairo-gstate.c
|
||||
*/
|
||||
assert (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_CLEAR);
|
||||
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
if (dst->finished)
|
||||
return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (dst->backend->composite_trapezoids) {
|
||||
status = dst->backend->composite_trapezoids (op,
|
||||
pattern, dst,
|
||||
@ -2318,7 +2067,7 @@ _cairo_surface_create_span_renderer (cairo_operator_t op,
|
||||
cairo_antialias_t antialias,
|
||||
const cairo_composite_rectangles_t *rects)
|
||||
{
|
||||
assert (dst->snapshot_of == NULL);
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
if (dst->status)
|
||||
return _cairo_span_renderer_create_in_error (dst->status);
|
||||
@ -2345,7 +2094,7 @@ _cairo_surface_check_span_renderer (cairo_operator_t op,
|
||||
{
|
||||
cairo_int_status_t status;
|
||||
|
||||
assert (dst->snapshot_of == NULL);
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
if (dst->status)
|
||||
return FALSE;
|
||||
@ -2386,7 +2135,7 @@ cairo_surface_copy_page (cairo_surface_t *surface)
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
assert (surface->snapshot_of == NULL);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished) {
|
||||
status_ignored = _cairo_surface_set_error (surface,
|
||||
@ -2423,7 +2172,7 @@ cairo_surface_show_page (cairo_surface_t *surface)
|
||||
if (surface->status)
|
||||
return;
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
if (surface->finished) {
|
||||
status_ignored = _cairo_surface_set_error (surface,
|
||||
@ -2541,9 +2290,6 @@ _cairo_surface_set_clip_region (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
if (surface->finished)
|
||||
return _cairo_surface_set_error (surface,CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
assert (surface->backend->set_clip_region != NULL);
|
||||
|
||||
status = surface->backend->set_clip_region (surface, region);
|
||||
@ -2681,35 +2427,6 @@ _cairo_surface_set_empty_clip_path (cairo_surface_t *surface,
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
/**
|
||||
* _cairo_surface_set_empty_clip_region:
|
||||
* @surface: the #cairo_surface_t to set the clip on
|
||||
* @serial: the clip serial number associated with the clip path
|
||||
*
|
||||
* Create an empty clip region, one that represents the entire surface clipped
|
||||
* out, and assigns the given clipping serial to the surface.
|
||||
**/
|
||||
static cairo_status_t
|
||||
_cairo_surface_set_empty_clip_region (cairo_surface_t *surface,
|
||||
unsigned int serial)
|
||||
{
|
||||
cairo_region_t *region;
|
||||
cairo_status_t status;
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
region = cairo_region_create ();
|
||||
status = region->status;
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_surface_set_clip_region (surface, region, serial);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
|
||||
return _cairo_surface_set_error (surface, status);
|
||||
}
|
||||
|
||||
cairo_clip_t *
|
||||
_cairo_surface_get_clip (cairo_surface_t *surface)
|
||||
{
|
||||
@ -2745,8 +2462,9 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
||||
clip->serial);
|
||||
|
||||
if (surface->backend->set_clip_region != NULL)
|
||||
return _cairo_surface_set_empty_clip_region (surface,
|
||||
clip->serial);
|
||||
return _cairo_surface_set_clip_region (surface,
|
||||
clip->region,
|
||||
clip->serial);
|
||||
} else {
|
||||
if (clip->path)
|
||||
return _cairo_surface_set_clip_path (surface,
|
||||
@ -2892,10 +2610,10 @@ _cairo_surface_show_text_glyphs (cairo_surface_t *surface,
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
if (num_glyphs == 0 && utf8_len == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
_cairo_surface_begin_modification (surface);
|
||||
if (!num_glyphs && !utf8_len)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_surface_copy_pattern_for_destination (&source,
|
||||
surface,
|
||||
@ -3023,7 +2741,10 @@ _cairo_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (dst));
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
if (dst->finished)
|
||||
return _cairo_surface_set_error (dst, CAIRO_STATUS_SURFACE_FINISHED);
|
||||
|
||||
if (dst->backend->old_show_glyphs) {
|
||||
status = dst->backend->old_show_glyphs (scaled_font,
|
||||
@ -3048,7 +2769,7 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
||||
unsigned int height)
|
||||
{
|
||||
cairo_rectangle_int_t dst_rectangle;
|
||||
cairo_region_t clear_region;
|
||||
cairo_region_t *clear_region;
|
||||
cairo_status_t status;
|
||||
|
||||
/* The area that was drawn is the area in the destination rectangle but
|
||||
@ -3059,7 +2780,10 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
||||
dst_rectangle.width = width;
|
||||
dst_rectangle.height = height;
|
||||
|
||||
_cairo_region_init_rectangle (&clear_region, &dst_rectangle);
|
||||
clear_region = cairo_region_create_rectangle (&dst_rectangle);
|
||||
status = clear_region->status;
|
||||
if (unlikely (status))
|
||||
goto CLEANUP_REGIONS;
|
||||
|
||||
if (src_rectangle) {
|
||||
if (! _cairo_rectangle_intersect (&dst_rectangle, src_rectangle))
|
||||
@ -3072,17 +2796,17 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
||||
}
|
||||
|
||||
/* Now compute the area that is in dst but not drawn */
|
||||
status = cairo_region_subtract_rectangle (&clear_region, &dst_rectangle);
|
||||
status = cairo_region_subtract_rectangle (clear_region, &dst_rectangle);
|
||||
if (unlikely (status))
|
||||
goto CLEANUP_REGIONS;
|
||||
|
||||
EMPTY:
|
||||
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE,
|
||||
CAIRO_COLOR_TRANSPARENT,
|
||||
&clear_region);
|
||||
clear_region);
|
||||
|
||||
CLEANUP_REGIONS:
|
||||
_cairo_region_fini (&clear_region);
|
||||
cairo_region_destroy (clear_region);
|
||||
|
||||
return _cairo_surface_set_error (dst, status);
|
||||
}
|
||||
@ -3135,7 +2859,7 @@ _cairo_surface_composite_fixup_unbounded (cairo_surface_t *dst,
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (dst));
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
|
||||
* non-repeating sources and masks. Other sources and masks can be ignored.
|
||||
@ -3213,7 +2937,7 @@ _cairo_surface_composite_shape_fixup_unbounded (cairo_surface_t *dst,
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
assert (_cairo_surface_is_writable (dst));
|
||||
assert (! dst->is_snapshot);
|
||||
|
||||
/* The RENDER/libpixman operators are clipped to the bounds of the untransformed,
|
||||
* non-repeating sources and masks. Other sources and masks can be ignored.
|
||||
@ -3299,8 +3023,6 @@ _cairo_surface_create_in_error (cairo_status_t status)
|
||||
switch (status) {
|
||||
case CAIRO_STATUS_NO_MEMORY:
|
||||
return (cairo_surface_t *) &_cairo_surface_nil;
|
||||
case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
|
||||
return (cairo_surface_t *) &_cairo_surface_nil_surface_type_mismatch;
|
||||
case CAIRO_STATUS_INVALID_CONTENT:
|
||||
return (cairo_surface_t *) &_cairo_surface_nil_invalid_content;
|
||||
case CAIRO_STATUS_INVALID_FORMAT:
|
||||
@ -3332,6 +3054,7 @@ _cairo_surface_create_in_error (cairo_status_t status)
|
||||
case CAIRO_STATUS_INVALID_STRING:
|
||||
case CAIRO_STATUS_INVALID_PATH_DATA:
|
||||
case CAIRO_STATUS_SURFACE_FINISHED:
|
||||
case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
|
||||
case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
|
||||
case CAIRO_STATUS_INVALID_DASH:
|
||||
case CAIRO_STATUS_INVALID_DSC_COMMENT:
|
||||
|
@ -856,7 +856,7 @@ _cairo_svg_surface_create_similar (void *abstract_src,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return cairo_meta_surface_create (content, width, height);
|
||||
return _cairo_meta_surface_create (content, width, height);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
@ -1200,9 +1200,6 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
||||
}
|
||||
|
||||
meta = (cairo_meta_surface_t *) _cairo_surface_snapshot (&surface->base);
|
||||
if (unlikely (meta->base.status))
|
||||
return meta->base.status;
|
||||
|
||||
paginated_surface = _cairo_svg_surface_create_for_document (document,
|
||||
meta->content,
|
||||
meta->width_pixels,
|
||||
@ -1217,7 +1214,7 @@ _cairo_svg_surface_emit_meta_surface (cairo_svg_document_t *document,
|
||||
document->owner->x_fallback_resolution,
|
||||
document->owner->y_fallback_resolution);
|
||||
|
||||
status = cairo_meta_surface_replay (&meta->base, paginated_surface);
|
||||
status = _cairo_meta_surface_replay (&meta->base, paginated_surface);
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy (&meta->base);
|
||||
cairo_surface_destroy (paginated_surface);
|
||||
@ -1334,8 +1331,8 @@ _cairo_svg_surface_emit_composite_meta_pattern (cairo_output_stream_t *output,
|
||||
"patternUnits=\"userSpaceOnUse\" "
|
||||
"width=\"%d\" height=\"%d\"",
|
||||
pattern_id,
|
||||
(int) ceil (meta_surface->width_pixels),
|
||||
(int) ceil (meta_surface->height_pixels));
|
||||
meta_surface->width_pixels,
|
||||
meta_surface->height_pixels);
|
||||
_cairo_svg_surface_emit_transform (output, " patternTransform", &p2u, parent_matrix);
|
||||
_cairo_output_stream_printf (output, ">\n");
|
||||
}
|
||||
@ -2658,7 +2655,6 @@ _cairo_svg_document_finish (cairo_svg_document_t *document)
|
||||
|
||||
for (i = 0; i < document->meta_snapshots.num_elements; i++) {
|
||||
snapshot = _cairo_array_index (&document->meta_snapshots, i);
|
||||
cairo_surface_finish (&snapshot->meta->base);
|
||||
status2 = cairo_surface_status (&snapshot->meta->base);
|
||||
cairo_surface_destroy (&snapshot->meta->base);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
|
@ -387,36 +387,28 @@ _cairo_toy_font_face_scaled_font_create (void *abstract_font_face
|
||||
return _cairo_font_face_set_error (&font_face->base, CAIRO_STATUS_FONT_TYPE_MISMATCH);
|
||||
}
|
||||
|
||||
static cairo_font_face_t *
|
||||
_cairo_toy_font_face_get_implementation (void *abstract_font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options)
|
||||
{
|
||||
cairo_toy_font_face_t *font_face = abstract_font_face;
|
||||
|
||||
if (font_face->impl_face) {
|
||||
cairo_font_face_t *impl = font_face->impl_face;
|
||||
|
||||
if (impl->backend->get_implementation != NULL) {
|
||||
return impl->backend->get_implementation (impl,
|
||||
font_matrix,
|
||||
ctm,
|
||||
options);
|
||||
}
|
||||
|
||||
return cairo_font_face_reference (impl);
|
||||
}
|
||||
|
||||
return abstract_font_face;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_font_face_is_toy (cairo_font_face_t *font_face)
|
||||
{
|
||||
return font_face->backend == &_cairo_toy_font_face_backend;
|
||||
}
|
||||
|
||||
cairo_font_face_t *
|
||||
_cairo_toy_font_face_get_implementation (cairo_font_face_t *font_face)
|
||||
{
|
||||
cairo_toy_font_face_t *toy_font_face;
|
||||
|
||||
if (font_face->status)
|
||||
return NULL;
|
||||
|
||||
toy_font_face = (cairo_toy_font_face_t *) font_face;
|
||||
if (! _cairo_font_face_is_toy (font_face)) {
|
||||
if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
|
||||
return NULL;
|
||||
}
|
||||
return toy_font_face->impl_face ? toy_font_face->impl_face : font_face;
|
||||
}
|
||||
|
||||
/**
|
||||
* cairo_toy_font_face_get_family:
|
||||
* @font_face: A toy font face
|
||||
@ -503,8 +495,7 @@ static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
|
||||
CAIRO_FONT_TYPE_TOY,
|
||||
NULL, /* create_for_toy */
|
||||
_cairo_toy_font_face_destroy,
|
||||
_cairo_toy_font_face_scaled_font_create,
|
||||
_cairo_toy_font_face_get_implementation
|
||||
_cairo_toy_font_face_scaled_font_create
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -47,8 +47,6 @@ _compare_point_fixed_by_y (const void *av, const void *bv);
|
||||
void
|
||||
_cairo_traps_init (cairo_traps_t *traps)
|
||||
{
|
||||
VG (VALGRIND_MAKE_MEM_UNDEFINED (traps, sizeof (cairo_traps_t)));
|
||||
|
||||
traps->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
traps->num_traps = 0;
|
||||
@ -93,8 +91,6 @@ _cairo_traps_fini (cairo_traps_t *traps)
|
||||
{
|
||||
if (traps->traps != traps->traps_embedded)
|
||||
free (traps->traps);
|
||||
|
||||
VG (VALGRIND_MAKE_MEM_NOACCESS (traps, sizeof (cairo_traps_t)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -619,10 +615,9 @@ cairo_int_status_t
|
||||
_cairo_traps_extract_region (const cairo_traps_t *traps,
|
||||
cairo_region_t **region)
|
||||
{
|
||||
cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
|
||||
cairo_rectangle_int_t *rects = stack_rects;
|
||||
cairo_int_status_t status;
|
||||
int i, rect_count;
|
||||
cairo_region_t *r;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < traps->num_traps; i++) {
|
||||
if (traps->traps[i].left.p1.x != traps->traps[i].left.p2.x ||
|
||||
@ -636,15 +631,13 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
|
||||
}
|
||||
}
|
||||
|
||||
if (traps->num_traps > ARRAY_LENGTH (stack_rects)) {
|
||||
rects = _cairo_malloc_ab (traps->num_traps, sizeof (cairo_rectangle_int_t));
|
||||
r = cairo_region_create ();
|
||||
if (unlikely (r->status))
|
||||
return r->status;
|
||||
|
||||
if (unlikely (rects == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
rect_count = 0;
|
||||
for (i = 0; i < traps->num_traps; i++) {
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x);
|
||||
int y1 = _cairo_fixed_integer_part (traps->traps[i].top);
|
||||
int x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x);
|
||||
@ -655,27 +648,21 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
|
||||
*/
|
||||
if (x1 == x2 || y1 == y2)
|
||||
continue;
|
||||
|
||||
rects[rect_count].x = x1;
|
||||
rects[rect_count].y = y1;
|
||||
rects[rect_count].width = x2 - x1;
|
||||
rects[rect_count].height = y2 - y1;
|
||||
|
||||
rect_count++;
|
||||
rect.x = x1;
|
||||
rect.y = y1;
|
||||
rect.width = x2 - x1;
|
||||
rect.height = y2 - y1;
|
||||
|
||||
status = cairo_region_union_rectangle (r, &rect);
|
||||
if (unlikely (status)) {
|
||||
cairo_region_destroy (r);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
*region = cairo_region_create_rectangles (rects, rect_count);
|
||||
status = cairo_region_status (*region);
|
||||
|
||||
if (rects != stack_rects)
|
||||
free (rects);
|
||||
|
||||
if (unlikely (status)) {
|
||||
cairo_region_destroy (*region);
|
||||
*region = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
*region = r;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* moves trap points such that they become the actual corners of the trapezoid */
|
||||
|
@ -647,7 +647,7 @@ cairo_truetype_font_write_head_table (cairo_truetype_font_t *font,
|
||||
if (unlikely (status))
|
||||
return _cairo_truetype_font_set_error (font, status);
|
||||
|
||||
/* set checkSumAdjustment to 0 for table checksum calculation */
|
||||
/* set checkSumAdjustment to 0 for table checksum calcualtion */
|
||||
*(uint32_t *)(buffer + 8) = 0;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -425,8 +425,8 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
status = cairo_meta_surface_replay (scaled_glyph->meta_surface,
|
||||
&surface->base);
|
||||
status = _cairo_meta_surface_replay (scaled_glyph->meta_surface,
|
||||
&surface->base);
|
||||
if (unlikely (status))
|
||||
goto cleanup;
|
||||
|
||||
@ -520,8 +520,8 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
|
||||
_cairo_type3_glyph_surface_set_stream (surface, mem_stream);
|
||||
|
||||
_cairo_output_stream_printf (surface->stream, "q\n");
|
||||
status = cairo_meta_surface_replay (scaled_glyph->meta_surface,
|
||||
&surface->base);
|
||||
status = _cairo_meta_surface_replay (scaled_glyph->meta_surface,
|
||||
&surface->base);
|
||||
|
||||
status2 = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
|
@ -122,6 +122,20 @@ struct _cairo_font_options {
|
||||
cairo_hint_metrics_t hint_metrics;
|
||||
};
|
||||
|
||||
typedef cairo_bool_t (*cairo_cache_predicate_func_t) (const void *entry);
|
||||
|
||||
struct _cairo_cache {
|
||||
cairo_hash_table_t *hash_table;
|
||||
|
||||
cairo_cache_predicate_func_t predicate;
|
||||
cairo_destroy_func_t entry_destroy;
|
||||
|
||||
unsigned long max_size;
|
||||
unsigned long size;
|
||||
|
||||
int freeze_count;
|
||||
};
|
||||
|
||||
/* XXX: Right now, the _cairo_color structure puts unpremultiplied
|
||||
color in the doubles and premultiplied color in the shorts. Yes,
|
||||
this is crazy insane, (but at least we don't export this
|
||||
@ -162,7 +176,8 @@ typedef enum _cairo_int_status {
|
||||
} cairo_int_status_t;
|
||||
|
||||
typedef enum _cairo_internal_surface_type {
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED = 0x1000,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_META = 0x1000,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_PAGINATED,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_META,
|
||||
CAIRO_INTERNAL_SURFACE_TYPE_TEST_FALLBACK,
|
||||
|
@ -85,14 +85,13 @@ _cairo_user_scaled_font_create_meta_context (cairo_user_scaled_font_t *scaled_fo
|
||||
CAIRO_CONTENT_COLOR_ALPHA :
|
||||
CAIRO_CONTENT_ALPHA;
|
||||
|
||||
meta_surface = cairo_meta_surface_create (content, -1, -1);
|
||||
meta_surface = _cairo_meta_surface_create (content, -1, -1);
|
||||
cr = cairo_create (meta_surface);
|
||||
cairo_surface_destroy (meta_surface);
|
||||
|
||||
cairo_set_matrix (cr, &scaled_font->base.scale);
|
||||
cairo_set_font_size (cr, 1.0);
|
||||
cairo_set_font_options (cr, &scaled_font->base.options);
|
||||
cairo_set_source_rgb (cr, 1., 1., 1.);
|
||||
|
||||
return cr;
|
||||
}
|
||||
@ -158,7 +157,8 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
|
||||
|
||||
_cairo_analysis_surface_set_ctm (analysis_surface,
|
||||
&scaled_font->extent_scale);
|
||||
status = cairo_meta_surface_replay (meta_surface, analysis_surface);
|
||||
status = _cairo_meta_surface_replay (meta_surface,
|
||||
analysis_surface);
|
||||
_cairo_analysis_surface_get_bounding_box (analysis_surface, &bbox);
|
||||
cairo_surface_destroy (analysis_surface);
|
||||
|
||||
@ -213,7 +213,7 @@ _cairo_user_scaled_glyph_init (void *abstract_font,
|
||||
cairo_surface_set_device_offset (surface,
|
||||
- _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.x),
|
||||
- _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y));
|
||||
status = cairo_meta_surface_replay (meta_surface, surface);
|
||||
status = _cairo_meta_surface_replay (meta_surface, surface);
|
||||
|
||||
if (unlikely (status)) {
|
||||
cairo_surface_destroy(surface);
|
||||
|
@ -977,7 +977,8 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
|
||||
if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
|
||||
GGO_METRICS | GGO_GLYPH_INDEX,
|
||||
&metrics, 0, NULL, &matrix) == GDI_ERROR) {
|
||||
memset (&metrics, 0, sizeof (GLYPHMETRICS));
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetGlyphOutlineW");
|
||||
memset (&metrics, 0, sizeof (GLYPHMETRICS));
|
||||
} else {
|
||||
if (metrics.gmBlackBoxX > 0 && scaled_font->base.options.antialias != CAIRO_ANTIALIAS_NONE) {
|
||||
/* The bounding box reported by Windows supposedly contains the glyph's "black" area;
|
||||
@ -993,6 +994,8 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
|
||||
}
|
||||
}
|
||||
cairo_win32_scaled_font_done_font (&scaled_font->base);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
if (scaled_font->swap_axes) {
|
||||
extents.x_bearing = - metrics.gmptGlyphOrigin.y / scaled_font->y_scale;
|
||||
@ -1031,9 +1034,12 @@ _cairo_win32_scaled_font_init_glyph_metrics (cairo_win32_scaled_font_t *scaled_f
|
||||
if (GetGlyphOutlineW (hdc, _cairo_scaled_glyph_index (scaled_glyph),
|
||||
GGO_METRICS | GGO_GLYPH_INDEX,
|
||||
&metrics, 0, NULL, &matrix) == GDI_ERROR) {
|
||||
memset (&metrics, 0, sizeof (GLYPHMETRICS));
|
||||
status = _cairo_win32_print_gdi_error ("_cairo_win32_scaled_font_init_glyph_metrics:GetGlyphOutlineW");
|
||||
memset (&metrics, 0, sizeof (GLYPHMETRICS));
|
||||
}
|
||||
_cairo_win32_scaled_font_done_unscaled_font (&scaled_font->base);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
extents.x_bearing = (double)metrics.gmptGlyphOrigin.x / scaled_font->em_square;
|
||||
extents.y_bearing = - (double)metrics.gmptGlyphOrigin.y / scaled_font->em_square;
|
||||
|
@ -1607,7 +1607,7 @@ _cairo_win32_printing_surface_create_similar (void *abstract_surface,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return cairo_meta_surface_create (content, width, height);
|
||||
return _cairo_meta_surface_create (content, width, height);
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
|
@ -2102,7 +2102,7 @@ _cairo_win32_surface_span_renderer_finish (void *abstract_renderer)
|
||||
cairo_pattern_t *mask_pattern = cairo_pattern_create_for_surface (&renderer->mask->base);
|
||||
/* composite onto the image surface directly if we can */
|
||||
if (dst->image) {
|
||||
GdiFlush(); /* XXX: I'm not sure if this needed or not */
|
||||
GdiFlush();
|
||||
|
||||
status = dst->image->backend->composite (renderer->op,
|
||||
renderer->pattern, mask_pattern, dst->image,
|
||||
|
@ -74,6 +74,7 @@ cairo_win32_surface_set_can_convert_to_dib (cairo_surface_t *surface, cairo_bool
|
||||
cairo_public cairo_status_t
|
||||
cairo_win32_surface_get_can_convert_to_dib (cairo_surface_t *surface, cairo_bool_t *can_convert);
|
||||
|
||||
|
||||
#if CAIRO_HAS_WIN32_FONT
|
||||
|
||||
/*
|
||||
|
@ -101,8 +101,6 @@ typedef struct cairo_xcb_surface {
|
||||
|
||||
#define CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 6)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_FILTERS(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 6)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_REPEAT_PAD(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 10)
|
||||
#define CAIRO_SURFACE_RENDER_HAS_REPEAT_REFLECT(surface) CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 10)
|
||||
|
||||
static void
|
||||
_cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface);
|
||||
@ -613,20 +611,6 @@ _cairo_xcb_surface_acquire_source_image (void *abstract_surfa
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_xcb_surface_snapshot (void *abstract_surface)
|
||||
{
|
||||
cairo_xcb_surface_t *surface = abstract_surface;
|
||||
cairo_image_surface_t *image;
|
||||
cairo_status_t status;
|
||||
|
||||
status = _get_image_surface (surface, NULL, &image, NULL);
|
||||
if (unlikely (status))
|
||||
return _cairo_surface_create_in_error (status);
|
||||
|
||||
return &image->base;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xcb_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
@ -856,22 +840,13 @@ _cairo_xcb_surface_set_attributes (cairo_xcb_surface_t *surface,
|
||||
|
||||
switch (attributes->extend) {
|
||||
case CAIRO_EXTEND_NONE:
|
||||
_cairo_xcb_surface_set_repeat (surface, XCB_RENDER_REPEAT_NONE);
|
||||
_cairo_xcb_surface_set_repeat (surface, 0);
|
||||
break;
|
||||
case CAIRO_EXTEND_REPEAT:
|
||||
_cairo_xcb_surface_set_repeat (surface, XCB_RENDER_REPEAT_NORMAL);
|
||||
_cairo_xcb_surface_set_repeat (surface, 1);
|
||||
break;
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_REPEAT_REFLECT(surface))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
_cairo_xcb_surface_set_repeat (surface, XCB_RENDER_REPEAT_REFLECT);
|
||||
break;
|
||||
case CAIRO_EXTEND_PAD:
|
||||
if (!CAIRO_SURFACE_RENDER_HAS_REPEAT_PAD(surface))
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
_cairo_xcb_surface_set_repeat (surface, XCB_RENDER_REPEAT_PAD);
|
||||
break;
|
||||
default:
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -1149,7 +1124,6 @@ _cairo_xcb_surface_composite (cairo_operator_t op,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
|
||||
(cairo_surface_t **) &src,
|
||||
(cairo_surface_t **) &mask,
|
||||
&src_attr, &mask_attr);
|
||||
@ -1437,7 +1411,6 @@ _cairo_xcb_surface_composite_trapezoids (cairo_operator_t op,
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
src_x, src_y, width, height,
|
||||
CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
if (status)
|
||||
@ -1585,6 +1558,7 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
||||
xcb_render_change_picture (surface->dpy, surface->dst_picture,
|
||||
XCB_RENDER_CP_CLIP_MASK, none);
|
||||
} else {
|
||||
cairo_status_t status;
|
||||
xcb_rectangle_t *rects = NULL;
|
||||
int n_rects, i;
|
||||
|
||||
@ -1602,13 +1576,13 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
|
||||
rects[i].x = rect.x;
|
||||
rects[i].y = rect.y;
|
||||
rects[i].width = rect.width;
|
||||
rects[i].height = rect.height;
|
||||
}
|
||||
|
||||
|
||||
surface->have_clip_rects = TRUE;
|
||||
surface->clip_rects = rects;
|
||||
surface->num_clip_rects = n_rects;
|
||||
@ -1654,8 +1628,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
int *remaining_glyphs,
|
||||
cairo_rectangle_int_t *extents);
|
||||
int *remaining_glyphs);
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_xcb_surface_is_similar (void *surface_a,
|
||||
@ -1729,8 +1702,7 @@ static const cairo_surface_backend_t cairo_xcb_surface_backend = {
|
||||
NULL, /* stroke */
|
||||
NULL, /* fill */
|
||||
_cairo_xcb_surface_show_glyphs,
|
||||
|
||||
_cairo_xcb_surface_snapshot,
|
||||
NULL, /* snapshot */
|
||||
|
||||
_cairo_xcb_surface_is_similar,
|
||||
|
||||
@ -2463,8 +2435,7 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||
cairo_glyph_t *glyphs,
|
||||
int num_glyphs,
|
||||
cairo_scaled_font_t *scaled_font,
|
||||
int *remaining_glyphs,
|
||||
cairo_rectangle_int_t *extents)
|
||||
int *remaining_glyphs)
|
||||
{
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_xcb_surface_t *dst = abstract_dst;
|
||||
@ -2533,7 +2504,6 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||
status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
0, 0, 1, 1,
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
} else {
|
||||
@ -2550,7 +2520,6 @@ _cairo_xcb_surface_show_glyphs (void *abstract_dst,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
glyph_extents.x, glyph_extents.y,
|
||||
glyph_extents.width, glyph_extents.height,
|
||||
CAIRO_PATTERN_ACQUIRE_NO_REFLECT,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
}
|
||||
|
@ -287,7 +287,6 @@ _cairo_xlib_display_get (Display *dpy,
|
||||
sizeof (display->cached_xrender_formats));
|
||||
|
||||
display->buggy_repeat = FALSE;
|
||||
display->buggy_pad_reflect = TRUE;
|
||||
|
||||
/* This buggy_repeat condition is very complicated because there
|
||||
* are multiple X server code bases (with multiple versioning
|
||||
@ -334,19 +333,13 @@ _cairo_xlib_display_get (Display *dpy,
|
||||
* (just using VendorRelase < 70000000), as buggy_repeat=TRUE.
|
||||
*/
|
||||
if (strstr (ServerVendor (dpy), "X.Org") != NULL) {
|
||||
if (VendorRelease (dpy) >= 60700000) {
|
||||
if (VendorRelease (dpy) < 70000000)
|
||||
display->buggy_repeat = TRUE;
|
||||
} else {
|
||||
if (VendorRelease (dpy) < 10400000)
|
||||
display->buggy_repeat = TRUE;
|
||||
if (VendorRelease (dpy) >= 10699000)
|
||||
display->buggy_pad_reflect = FALSE;
|
||||
}
|
||||
if (VendorRelease (dpy) >= 60700000 && VendorRelease (dpy) < 70000000)
|
||||
display->buggy_repeat = TRUE;
|
||||
if (VendorRelease (dpy) < 10400000)
|
||||
display->buggy_repeat = TRUE;
|
||||
} else if (strstr (ServerVendor (dpy), "XFree86") != NULL) {
|
||||
if (VendorRelease (dpy) <= 40500000)
|
||||
display->buggy_repeat = TRUE;
|
||||
|
||||
}
|
||||
|
||||
/* XXX workaround; see https://bugzilla.mozilla.org/show_bug.cgi?id=413583 */
|
||||
|
@ -73,7 +73,6 @@ struct _cairo_xlib_display {
|
||||
|
||||
cairo_xlib_hook_t *close_display_hooks;
|
||||
unsigned int buggy_repeat :1;
|
||||
unsigned int buggy_pad_reflect :1;
|
||||
unsigned int closed :1;
|
||||
};
|
||||
|
||||
@ -103,8 +102,8 @@ struct _cairo_xlib_screen_info {
|
||||
cairo_bool_t has_font_options;
|
||||
cairo_font_options_t font_options;
|
||||
|
||||
GC gc[4];
|
||||
int gc_depths; /* 4 x uint8_t, high bit == needs reset */
|
||||
GC gc[9];
|
||||
unsigned int gc_needs_clip_reset;
|
||||
|
||||
cairo_array_t visuals;
|
||||
};
|
||||
@ -154,13 +153,12 @@ _cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info);
|
||||
|
||||
cairo_private GC
|
||||
_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
|
||||
unsigned int depth,
|
||||
Drawable drawable,
|
||||
int depth,
|
||||
unsigned int *need_reset);
|
||||
|
||||
cairo_private void
|
||||
cairo_private cairo_status_t
|
||||
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
|
||||
unsigned int depth,
|
||||
int depth,
|
||||
GC gc,
|
||||
cairo_bool_t reset_clip);
|
||||
|
||||
|
@ -268,29 +268,19 @@ void
|
||||
_cairo_xlib_screen_info_close_display (cairo_xlib_screen_info_t *info)
|
||||
{
|
||||
cairo_xlib_visual_info_t **visuals;
|
||||
Display *dpy;
|
||||
int i, old;
|
||||
int i;
|
||||
|
||||
CAIRO_MUTEX_LOCK (info->mutex);
|
||||
|
||||
dpy = info->display->display;
|
||||
|
||||
#if HAS_ATOMIC_OPS
|
||||
do {
|
||||
old = info->gc_depths;
|
||||
} while (_cairo_atomic_int_cmpxchg (&info->gc_depths, old, 0) != old);
|
||||
#else
|
||||
old = info->gc_depths;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
|
||||
if (old >> (8*i) & 0x7f)
|
||||
XFreeGC (dpy, info->gc[i]);
|
||||
if (info->gc[i] != NULL) {
|
||||
XFreeGC (info->display->display, info->gc[i]);
|
||||
info->gc[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
visuals = _cairo_array_index (&info->visuals, 0);
|
||||
for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++)
|
||||
_cairo_xlib_visual_info_destroy (dpy, visuals[i]);
|
||||
_cairo_xlib_visual_info_destroy (info->display->display, visuals[i]);
|
||||
_cairo_array_truncate (&info->visuals, 0);
|
||||
|
||||
CAIRO_MUTEX_UNLOCK (info->mutex);
|
||||
@ -368,8 +358,8 @@ _cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
|
||||
info->screen = screen;
|
||||
info->has_render = FALSE;
|
||||
info->has_font_options = FALSE;
|
||||
info->gc_depths = 0;
|
||||
memset (info->gc, 0, sizeof (info->gc));
|
||||
info->gc_needs_clip_reset = 0;
|
||||
|
||||
_cairo_array_init (&info->visuals,
|
||||
sizeof (cairo_xlib_visual_info_t*));
|
||||
@ -396,165 +386,71 @@ _cairo_xlib_screen_info_get (cairo_xlib_display_t *display,
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
#if HAS_ATOMIC_OPS
|
||||
static int
|
||||
depth_to_index (int depth)
|
||||
{
|
||||
switch(depth){
|
||||
case 1: return 1;
|
||||
case 8: return 2;
|
||||
case 12: return 3;
|
||||
case 15: return 4;
|
||||
case 16: return 5;
|
||||
case 24: return 6;
|
||||
case 30: return 7;
|
||||
case 32: return 8;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GC
|
||||
_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
|
||||
unsigned int depth,
|
||||
Drawable drawable,
|
||||
int depth,
|
||||
unsigned int *dirty)
|
||||
{
|
||||
XGCValues gcv;
|
||||
int i, new, old;
|
||||
GC gc;
|
||||
cairo_bool_t needs_reset;
|
||||
|
||||
do {
|
||||
gc = NULL;
|
||||
old = info->gc_depths;
|
||||
if (old == 0)
|
||||
break;
|
||||
|
||||
if (((old >> 0) & 0x7f) == depth)
|
||||
i = 0;
|
||||
else if (((old >> 8) & 0x7f) == depth)
|
||||
i = 1;
|
||||
else if (((old >> 16) & 0x7f) == depth)
|
||||
i = 2;
|
||||
else if (((old >> 24) & 0x7f) == depth)
|
||||
i = 3;
|
||||
else
|
||||
break;
|
||||
|
||||
gc = info->gc[i];
|
||||
new = old & ~(0xff << (8*i));
|
||||
} while (_cairo_atomic_int_cmpxchg (&info->gc_depths, old, new) != old);
|
||||
|
||||
if (likely (gc != NULL)) {
|
||||
(void) _cairo_atomic_ptr_cmpxchg (&info->gc[i], gc, NULL);
|
||||
|
||||
if (old & 0x80 << (8 * i))
|
||||
*dirty |= CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC;
|
||||
|
||||
return gc;
|
||||
}
|
||||
|
||||
gcv.graphics_exposures = False;
|
||||
return XCreateGC (info->display->display, drawable,
|
||||
GCGraphicsExposures, &gcv);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
|
||||
unsigned int depth,
|
||||
GC gc,
|
||||
cairo_bool_t reset_clip)
|
||||
{
|
||||
int i, old, new;
|
||||
|
||||
depth |= reset_clip ? 0x80 : 0;
|
||||
do {
|
||||
do {
|
||||
i = -1;
|
||||
old = info->gc_depths;
|
||||
|
||||
if (((old >> 0) & 0x7f) == 0)
|
||||
i = 0;
|
||||
else if (((old >> 8) & 0x7f) == 0)
|
||||
i = 1;
|
||||
else if (((old >> 16) & 0x7f) == 0)
|
||||
i = 2;
|
||||
else if (((old >> 24) & 0x7f) == 0)
|
||||
i = 3;
|
||||
else
|
||||
goto out;
|
||||
|
||||
new = old | (depth << (8*i));
|
||||
} while (_cairo_atomic_ptr_cmpxchg (&info->gc[i], NULL, gc) != NULL);
|
||||
} while (_cairo_atomic_int_cmpxchg (&info->gc_depths, old, new) != old);
|
||||
|
||||
return;
|
||||
|
||||
out:
|
||||
if (unlikely (_cairo_xlib_display_queue_work (info->display,
|
||||
(cairo_xlib_notify_func) XFreeGC,
|
||||
gc,
|
||||
NULL)))
|
||||
{
|
||||
/* leak the server side resource... */
|
||||
XFree ((char *) gc);
|
||||
}
|
||||
}
|
||||
#else
|
||||
GC
|
||||
_cairo_xlib_screen_get_gc (cairo_xlib_screen_info_t *info,
|
||||
unsigned int depth,
|
||||
Drawable drawable,
|
||||
unsigned int *dirty)
|
||||
{
|
||||
GC gc = NULL;
|
||||
int i;
|
||||
depth = depth_to_index (depth);
|
||||
|
||||
CAIRO_MUTEX_LOCK (info->mutex);
|
||||
for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
|
||||
if (((info->gc_depths >> (8*i)) & 0x7f) == depth) {
|
||||
if (info->gc_depths & 0x80 << (8*i))
|
||||
*dirty |= CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC;
|
||||
|
||||
info->gc_depths &= ~(0xff << (8*i));
|
||||
gc = info->gc[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
gc = info->gc[depth];
|
||||
info->gc[depth] = NULL;
|
||||
needs_reset = info->gc_needs_clip_reset & (1 << depth);
|
||||
info->gc_needs_clip_reset &= ~(1 << depth);
|
||||
CAIRO_MUTEX_UNLOCK (info->mutex);
|
||||
|
||||
if (gc == NULL) {
|
||||
XGCValues gcv;
|
||||
|
||||
gcv.graphics_exposures = False;
|
||||
gc = XCreateGC (info->display->display, drawable,
|
||||
GCGraphicsExposures, &gcv);
|
||||
}
|
||||
if (needs_reset)
|
||||
*dirty |= CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC;
|
||||
|
||||
return gc;
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info,
|
||||
unsigned int depth,
|
||||
GC gc,
|
||||
cairo_bool_t reset_clip)
|
||||
cairo_status_t
|
||||
_cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cairo_bool_t reset_clip)
|
||||
{
|
||||
int i;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
GC oldgc;
|
||||
|
||||
depth |= reset_clip ? 0x80 : 0;
|
||||
depth = depth_to_index (depth);
|
||||
|
||||
CAIRO_MUTEX_LOCK (info->mutex);
|
||||
for (i = 0; i < ARRAY_LENGTH (info->gc); i++) {
|
||||
if (((info->gc_depths >> (8*i)) & 0x7f) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAY_LENGTH (info->gc)) {
|
||||
cairo_status_t status;
|
||||
|
||||
/* perform random substitution to ensure fair caching over depths */
|
||||
i = rand () % ARRAY_LENGTH (info->gc);
|
||||
status =
|
||||
_cairo_xlib_display_queue_work (info->display,
|
||||
(cairo_xlib_notify_func) XFreeGC,
|
||||
info->gc[i],
|
||||
NULL);
|
||||
if (unlikely (status)) {
|
||||
/* leak the server side resource... */
|
||||
XFree ((char *) info->gc[i]);
|
||||
}
|
||||
}
|
||||
|
||||
info->gc[i] = gc;
|
||||
info->gc_depths &= ~(0xff << (8*i));
|
||||
info->gc_depths |= depth << (8*i);
|
||||
oldgc = info->gc[depth];
|
||||
info->gc[depth] = gc;
|
||||
if (reset_clip)
|
||||
info->gc_needs_clip_reset |= 1 << depth;
|
||||
else
|
||||
info->gc_needs_clip_reset &= ~(1 << depth);
|
||||
CAIRO_MUTEX_UNLOCK (info->mutex);
|
||||
|
||||
if (oldgc != NULL) {
|
||||
status = _cairo_xlib_display_queue_work (info->display,
|
||||
(cairo_xlib_notify_func) XFreeGC,
|
||||
oldgc,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
cairo_status_t
|
||||
_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info,
|
||||
|
@ -76,7 +76,6 @@ struct _cairo_xlib_surface {
|
||||
* we can reuse the test for now.
|
||||
*/
|
||||
cairo_bool_t buggy_repeat;
|
||||
cairo_bool_t buggy_pad_reflect;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
|
@ -67,9 +67,6 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface);
|
||||
|
||||
static void
|
||||
_cairo_xlib_surface_maybe_put_gc (cairo_xlib_surface_t *surface);
|
||||
|
||||
static void
|
||||
_cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t *surface);
|
||||
|
||||
@ -92,10 +89,6 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
||||
int *remaining_glyphs,
|
||||
cairo_rectangle_int_t *extents);
|
||||
|
||||
/* XXX temporarily used by cairo-qt-surface.c */
|
||||
slim_hidden_proto (cairo_xlib_surface_create);
|
||||
slim_hidden_proto (cairo_xlib_surface_create_with_xrender_format);
|
||||
|
||||
/*
|
||||
* Instead of taking two round trips for each blending request,
|
||||
* assume that if a particular drawable fails GetImage that it will
|
||||
@ -210,7 +203,7 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
|
||||
int height)
|
||||
{
|
||||
cairo_xlib_surface_t *src = abstract_src;
|
||||
XRenderPictFormat *xrender_format;
|
||||
XRenderPictFormat *xrender_format = src->xrender_format;
|
||||
cairo_xlib_surface_t *surface;
|
||||
Pixmap pix;
|
||||
|
||||
@ -219,12 +212,17 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
|
||||
|
||||
_cairo_xlib_display_notify (src->display);
|
||||
|
||||
/* Start by examining the surface's XRenderFormat, or if it
|
||||
* doesn't have one, then look one up through its visual (in the
|
||||
* case of a bitmap, it won't even have that). */
|
||||
if (xrender_format == NULL && src->visual != NULL)
|
||||
xrender_format = XRenderFindVisualFormat (src->dpy, src->visual);
|
||||
|
||||
/* If we never found an XRenderFormat or if it isn't compatible
|
||||
* with the content being requested, then we fallback to just
|
||||
* constructing a cairo_format_t instead, (which will fairly
|
||||
* arbitrarily pick a visual/depth for the similar surface.
|
||||
*/
|
||||
xrender_format = src->xrender_format;
|
||||
if (xrender_format == NULL ||
|
||||
_xrender_format_to_content (xrender_format) != content)
|
||||
{
|
||||
@ -303,11 +301,14 @@ _cairo_xlib_surface_finish (void *abstract_surface)
|
||||
}
|
||||
|
||||
if (surface->gc != NULL) {
|
||||
_cairo_xlib_screen_put_gc (surface->screen_info,
|
||||
surface->depth,
|
||||
surface->gc,
|
||||
surface->gc_has_clip_rects);
|
||||
cairo_status_t status2;
|
||||
status2 = _cairo_xlib_screen_put_gc (surface->screen_info,
|
||||
surface->depth,
|
||||
surface->gc,
|
||||
surface->gc_has_clip_rects);
|
||||
surface->gc = NULL;
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = status2;
|
||||
}
|
||||
|
||||
if (surface->clip_rects != surface->embedded_clip_rects)
|
||||
@ -657,7 +658,8 @@ _get_image_surface (cairo_xlib_surface_t *surface,
|
||||
ximage = NULL;
|
||||
}
|
||||
|
||||
if (!ximage) {
|
||||
if (!ximage)
|
||||
{
|
||||
|
||||
/* XGetImage from a window is dangerous because it can
|
||||
* produce errors if the window is unmapped or partially
|
||||
@ -691,12 +693,9 @@ _get_image_surface (cairo_xlib_surface_t *surface,
|
||||
|
||||
XFreePixmap (surface->dpy, pixmap);
|
||||
}
|
||||
|
||||
if (!ximage)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_xlib_surface_maybe_put_gc (surface);
|
||||
}
|
||||
if (!ximage)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_swap_ximage_to_native (ximage);
|
||||
|
||||
@ -836,7 +835,8 @@ _get_image_surface (cairo_xlib_surface_t *surface,
|
||||
static void
|
||||
_cairo_xlib_surface_ensure_src_picture (cairo_xlib_surface_t *surface)
|
||||
{
|
||||
if (!surface->src_picture) {
|
||||
if (!surface->src_picture)
|
||||
{
|
||||
XRenderPictureAttributes pa;
|
||||
int mask = 0;
|
||||
|
||||
@ -900,14 +900,19 @@ _cairo_xlib_surface_ensure_dst_picture (cairo_xlib_surface_t *surface)
|
||||
static cairo_status_t
|
||||
_cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface)
|
||||
{
|
||||
XGCValues gcv;
|
||||
|
||||
if (surface->gc == NULL) {
|
||||
surface->gc = _cairo_xlib_screen_get_gc (surface->screen_info,
|
||||
surface->depth,
|
||||
surface->drawable,
|
||||
&surface->clip_dirty);
|
||||
if (unlikely (surface->gc == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
if (surface->gc == NULL) {
|
||||
gcv.graphics_exposures = False;
|
||||
surface->gc = XCreateGC (surface->dpy, surface->drawable,
|
||||
GCGraphicsExposures, &gcv);
|
||||
if (unlikely (surface->gc == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface->clip_dirty & CAIRO_XLIB_SURFACE_CLIP_DIRTY_GC)
|
||||
@ -916,21 +921,6 @@ _cairo_xlib_surface_ensure_gc (cairo_xlib_surface_t *surface)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xlib_surface_maybe_put_gc (cairo_xlib_surface_t *surface)
|
||||
{
|
||||
/* return the GC back to the common pool if clean */
|
||||
|
||||
if (surface->gc_has_clip_rects)
|
||||
return;
|
||||
|
||||
_cairo_xlib_screen_put_gc (surface->screen_info,
|
||||
surface->depth,
|
||||
surface->gc,
|
||||
FALSE);
|
||||
surface->gc = NULL;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_draw_image_surface (cairo_xlib_surface_t *surface,
|
||||
cairo_image_surface_t *image,
|
||||
@ -1089,8 +1079,6 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
|
||||
&ximage, src_x, src_y, dst_x, dst_y,
|
||||
width, height);
|
||||
|
||||
_cairo_xlib_surface_maybe_put_gc (surface);
|
||||
|
||||
BAIL:
|
||||
if (own_data)
|
||||
free (ximage.data);
|
||||
@ -1119,22 +1107,6 @@ _cairo_xlib_surface_acquire_source_image (void *abstract_surf
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
_cairo_xlib_surface_snapshot (void *abstract_surface)
|
||||
{
|
||||
cairo_xlib_surface_t *surface = abstract_surface;
|
||||
cairo_image_surface_t *image;
|
||||
cairo_status_t status;
|
||||
|
||||
_cairo_xlib_display_notify (surface->display);
|
||||
|
||||
status = _get_image_surface (surface, NULL, &image, NULL);
|
||||
if (unlikely (status))
|
||||
return _cairo_surface_create_in_error (status);
|
||||
|
||||
return &image->base;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_xlib_surface_release_source_image (void *abstract_surface,
|
||||
cairo_image_surface_t *image,
|
||||
@ -1362,6 +1334,9 @@ _cairo_xlib_surface_set_matrix (cairo_xlib_surface_t *surface,
|
||||
{
|
||||
XTransform xtransform;
|
||||
|
||||
if (!surface->src_picture)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
/* Casting between pixman_transform_t and XTransform is safe because
|
||||
* they happen to be the exact same type.
|
||||
*/
|
||||
@ -1387,6 +1362,9 @@ _cairo_xlib_surface_set_filter (cairo_xlib_surface_t *surface,
|
||||
{
|
||||
const char *render_filter;
|
||||
|
||||
if (!surface->src_picture)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (surface->filter == filter)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
@ -1438,6 +1416,9 @@ _cairo_xlib_surface_set_repeat (cairo_xlib_surface_t *surface, int repeat)
|
||||
XRenderPictureAttributes pa;
|
||||
unsigned long mask;
|
||||
|
||||
if (!surface->src_picture)
|
||||
return;
|
||||
|
||||
if (surface->repeat == repeat)
|
||||
return;
|
||||
|
||||
@ -1471,15 +1452,7 @@ _cairo_xlib_surface_set_attributes (cairo_xlib_surface_t *surface,
|
||||
_cairo_xlib_surface_set_repeat (surface, RepeatNormal);
|
||||
break;
|
||||
case CAIRO_EXTEND_REFLECT:
|
||||
if (surface->buggy_pad_reflect)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
_cairo_xlib_surface_set_repeat (surface, RepeatReflect);
|
||||
break;
|
||||
case CAIRO_EXTEND_PAD:
|
||||
if (surface->buggy_pad_reflect)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
_cairo_xlib_surface_set_repeat (surface, RepeatPad);
|
||||
break;
|
||||
default:
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
@ -1781,9 +1754,6 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
|
||||
src_x, src_y,
|
||||
mask_x, mask_y,
|
||||
width, height,
|
||||
dst->buggy_pad_reflect ?
|
||||
CAIRO_PATTERN_ACQUIRE_NO_REFLECT :
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &src,
|
||||
(cairo_surface_t **) &mask,
|
||||
&src_attr, &mask_attr);
|
||||
@ -1871,8 +1841,6 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
|
||||
src_y + src_attr.y_offset + ity,
|
||||
width, height,
|
||||
dst_x, dst_y);
|
||||
|
||||
_cairo_xlib_surface_maybe_put_gc (dst);
|
||||
break;
|
||||
|
||||
case DO_XTILE:
|
||||
@ -1899,8 +1867,6 @@ _cairo_xlib_surface_composite (cairo_operator_t op,
|
||||
|
||||
XFillRectangle (dst->dpy, dst->drawable, dst->gc,
|
||||
dst_x, dst_y, width, height);
|
||||
|
||||
_cairo_xlib_surface_maybe_put_gc (dst);
|
||||
break;
|
||||
|
||||
case DO_UNSUPPORTED:
|
||||
@ -1950,7 +1916,6 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface,
|
||||
0, 0,
|
||||
ARRAY_LENGTH (dither_pattern[0]),
|
||||
ARRAY_LENGTH (dither_pattern),
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
&solid_surface,
|
||||
&attrs);
|
||||
if (unlikely (status))
|
||||
@ -1974,8 +1939,6 @@ _cairo_xlib_surface_solid_fill_rectangles (cairo_xlib_surface_t *surface,
|
||||
rects[i].width, rects[i].height);
|
||||
}
|
||||
|
||||
_cairo_xlib_surface_maybe_put_gc (surface);
|
||||
|
||||
BAIL:
|
||||
_cairo_pattern_release_surface (&solid.base, solid_surface, &attrs);
|
||||
|
||||
@ -2202,9 +2165,6 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
|
||||
status = _cairo_pattern_acquire_surface (pattern, &dst->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
src_x, src_y, width, height,
|
||||
dst->buggy_pad_reflect ?
|
||||
CAIRO_PATTERN_ACQUIRE_NO_REFLECT :
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
if (unlikely (status))
|
||||
@ -2544,9 +2504,7 @@ static const cairo_surface_backend_t cairo_xlib_surface_backend = {
|
||||
NULL, /* stroke */
|
||||
NULL, /* fill */
|
||||
_cairo_xlib_surface_show_glyphs,
|
||||
|
||||
_cairo_xlib_surface_snapshot,
|
||||
|
||||
NULL, /* snapshot */
|
||||
_cairo_xlib_surface_is_similar,
|
||||
_cairo_xlib_surface_reset,
|
||||
NULL, /* fill_stroke */
|
||||
@ -2709,7 +2667,6 @@ _cairo_xlib_surface_create_internal (Display *dpy,
|
||||
/* so we can use the XTile fallback */
|
||||
surface->buggy_repeat = TRUE;
|
||||
}
|
||||
surface->buggy_pad_reflect = screen_info->display->buggy_pad_reflect;
|
||||
|
||||
surface->dst_picture = None;
|
||||
surface->src_picture = None;
|
||||
@ -2827,7 +2784,6 @@ cairo_xlib_surface_create (Display *dpy,
|
||||
return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
|
||||
visual, NULL, width, height, 0);
|
||||
}
|
||||
slim_hidden_def (cairo_xlib_surface_create);
|
||||
|
||||
/**
|
||||
* cairo_xlib_surface_create_for_bitmap:
|
||||
@ -2885,7 +2841,6 @@ cairo_xlib_surface_create_with_xrender_format (Display *dpy,
|
||||
return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
|
||||
NULL, format, width, height, 0);
|
||||
}
|
||||
slim_hidden_def (cairo_xlib_surface_create_with_xrender_format);
|
||||
|
||||
/**
|
||||
* cairo_xlib_surface_get_xrender_format:
|
||||
@ -3645,13 +3600,14 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
}
|
||||
n = new;
|
||||
d = data;
|
||||
do {
|
||||
while (c--)
|
||||
{
|
||||
char b = *d++;
|
||||
b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55);
|
||||
b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33);
|
||||
b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f);
|
||||
*n++ = b;
|
||||
} while (--c);
|
||||
}
|
||||
data = new;
|
||||
}
|
||||
break;
|
||||
@ -3659,21 +3615,28 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
|
||||
break;
|
||||
case CAIRO_FORMAT_ARGB32:
|
||||
if (_native_byte_order_lsb() != (ImageByteOrder (dpy) == LSBFirst)) {
|
||||
unsigned int c = glyph_surface->stride * glyph_surface->height / 4;
|
||||
const uint32_t *d;
|
||||
uint32_t *new, *n;
|
||||
unsigned int c = glyph_surface->stride * glyph_surface->height;
|
||||
unsigned char *d;
|
||||
unsigned char *new, *n;
|
||||
|
||||
new = malloc (4 * c);
|
||||
new = malloc (c);
|
||||
if (unlikely (new == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto BAIL;
|
||||
}
|
||||
n = new;
|
||||
d = (uint32_t *) data;
|
||||
do {
|
||||
*n++ = bswap_32 (*d++);
|
||||
} while (--c);
|
||||
data = (uint8_t *) new;
|
||||
d = data;
|
||||
while (c >= 4)
|
||||
{
|
||||
n[3] = d[0];
|
||||
n[2] = d[1];
|
||||
n[1] = d[2];
|
||||
n[0] = d[3];
|
||||
d += 4;
|
||||
n += 4;
|
||||
c -= 4;
|
||||
}
|
||||
data = new;
|
||||
}
|
||||
break;
|
||||
case CAIRO_FORMAT_RGB24:
|
||||
@ -4132,7 +4095,6 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
||||
status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
0, 0, 1, 1,
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
if (unlikely (status))
|
||||
@ -4151,9 +4113,6 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
|
||||
CAIRO_CONTENT_COLOR_ALPHA,
|
||||
glyph_extents.x, glyph_extents.y,
|
||||
glyph_extents.width, glyph_extents.height,
|
||||
dst->buggy_pad_reflect ?
|
||||
CAIRO_PATTERN_ACQUIRE_NO_REFLECT :
|
||||
CAIRO_PATTERN_ACQUIRE_NONE,
|
||||
(cairo_surface_t **) &src,
|
||||
&attributes);
|
||||
if (unlikely (status))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -210,7 +210,7 @@ typedef struct _cairo_user_data_key {
|
||||
* @CAIRO_STATUS_SUCCESS: no error has occurred
|
||||
* @CAIRO_STATUS_NO_MEMORY: out of memory
|
||||
* @CAIRO_STATUS_INVALID_RESTORE: cairo_restore() called without matching cairo_save()
|
||||
* @CAIRO_STATUS_INVALID_POP_GROUP: no saved group to pop, i.e. cairo_pop_group() without matching cairo_push_group()
|
||||
* @CAIRO_STATUS_INVALID_POP_GROUP: no saved group to pop
|
||||
* @CAIRO_STATUS_NO_CURRENT_POINT: no current point defined
|
||||
* @CAIRO_STATUS_INVALID_MATRIX: invalid matrix (not invertible)
|
||||
* @CAIRO_STATUS_INVALID_STATUS: invalid value for an input #cairo_status_t
|
||||
@ -239,7 +239,7 @@ typedef struct _cairo_user_data_key {
|
||||
* @CAIRO_STATUS_INVALID_CLUSTERS: input clusters do not represent the accompanying text and glyph array (Since 1.8)
|
||||
* @CAIRO_STATUS_INVALID_SLANT: invalid value for an input #cairo_font_slant_t (Since 1.8)
|
||||
* @CAIRO_STATUS_INVALID_WEIGHT: invalid value for an input #cairo_font_weight_t (Since 1.8)
|
||||
* @CAIRO_STATUS_INVALID_SIZE: invalid value (typically too big) for the size of the input (surface, pattern, etc.) (Since 1.10)
|
||||
* @CAIRO_STATUS_INVALID_SIZE: invalid value (typically too big) for a size (Since 1.10)
|
||||
* @CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: user-font method not implemented (Since 1.10)
|
||||
* @CAIRO_STATUS_LAST_STATUS: this is a special value indicating the number of
|
||||
* status values defined in this enumeration. When using this value, note
|
||||
@ -1889,8 +1889,7 @@ cairo_surface_status (cairo_surface_t *surface);
|
||||
* @CAIRO_SURFACE_TYPE_WIN32_PRINTING: The surface is a win32 printing surface
|
||||
* @CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: The surface is of type quartz_image
|
||||
* @CAIRO_SURFACE_TYPE_SCRIPT: The surface is of type script, since 1.10
|
||||
* @CAIRO_SURFACE_TYPE_QT: The surface is of type Qt, since 1.10
|
||||
* @CAIRO_SURFACE_TYPE_META: The surface is a meta-type, since 1.10
|
||||
* @CAIRO_SURFACE_TYPE_QPAINTER: The surface is of type qpainter
|
||||
* @CAIRO_SURFACE_TYPE_DDRAW: The surface is of type ddraw
|
||||
*
|
||||
* #cairo_surface_type_t is used to describe the type of a given
|
||||
@ -1932,8 +1931,7 @@ typedef enum _cairo_surface_type {
|
||||
CAIRO_SURFACE_TYPE_WIN32_PRINTING,
|
||||
CAIRO_SURFACE_TYPE_QUARTZ_IMAGE,
|
||||
CAIRO_SURFACE_TYPE_SCRIPT,
|
||||
CAIRO_SURFACE_TYPE_QT,
|
||||
CAIRO_SURFACE_TYPE_META,
|
||||
CAIRO_SURFACE_TYPE_QPAINTER,
|
||||
CAIRO_SURFACE_TYPE_DDRAW
|
||||
} cairo_surface_type_t;
|
||||
|
||||
@ -2112,24 +2110,6 @@ cairo_image_surface_create_from_png_stream (cairo_read_func_t read_func,
|
||||
|
||||
#endif
|
||||
|
||||
/* Meta-surface functions */
|
||||
|
||||
cairo_public cairo_surface_t *
|
||||
cairo_meta_surface_create (cairo_content_t content,
|
||||
double width_pixels,
|
||||
double height_pixels);
|
||||
|
||||
cairo_public void
|
||||
cairo_meta_surface_ink_extents (cairo_surface_t *surface,
|
||||
double *x0,
|
||||
double *y0,
|
||||
double *width,
|
||||
double *height);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_meta_surface_replay (cairo_surface_t *surface,
|
||||
cairo_surface_t *target);
|
||||
|
||||
/* Pattern creation functions */
|
||||
|
||||
cairo_public cairo_pattern_t *
|
||||
@ -2397,10 +2377,6 @@ cairo_region_create (void);
|
||||
cairo_public cairo_region_t *
|
||||
cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_public cairo_region_t *
|
||||
cairo_region_create_rectangles (cairo_rectangle_int_t *rects,
|
||||
int count);
|
||||
|
||||
cairo_public cairo_region_t *
|
||||
cairo_region_copy (cairo_region_t *original);
|
||||
|
||||
|
@ -181,7 +181,7 @@ do { \
|
||||
* in libgcc in case a target does not have one, which should be just as
|
||||
* good as the open-coded solution below, (which is "HACKMEM 169").
|
||||
*/
|
||||
static inline int cairo_const
|
||||
static inline int
|
||||
_cairo_popcount (uint32_t mask)
|
||||
{
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
@ -210,25 +210,25 @@ _cairo_popcount (uint32_t mask)
|
||||
|
||||
#else
|
||||
|
||||
static inline uint16_t cairo_const
|
||||
static inline uint16_t
|
||||
cpu_to_be16(uint16_t v)
|
||||
{
|
||||
return (v << 8) | (v >> 8);
|
||||
}
|
||||
|
||||
static inline uint16_t cairo_const
|
||||
static inline uint16_t
|
||||
be16_to_cpu(uint16_t v)
|
||||
{
|
||||
return cpu_to_be16 (v);
|
||||
}
|
||||
|
||||
static inline uint32_t cairo_const
|
||||
static inline uint32_t
|
||||
cpu_to_be32(uint32_t v)
|
||||
{
|
||||
return (cpu_to_be16 (v) << 16) | cpu_to_be16 (v >> 16);
|
||||
}
|
||||
|
||||
static inline uint32_t cairo_const
|
||||
static inline uint32_t
|
||||
be32_to_cpu(uint32_t v)
|
||||
{
|
||||
return cpu_to_be32 (v);
|
||||
@ -264,12 +264,10 @@ _cairo_rectangle_intersect (cairo_rectangle_int_t *dst,
|
||||
const cairo_rectangle_int_t *src);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_box_intersects_line_segment (cairo_box_t *box,
|
||||
cairo_line_t *line) cairo_pure;
|
||||
_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,
|
||||
const cairo_point_t *point) cairo_pure;
|
||||
_cairo_box_contains_point (cairo_box_t *box, const cairo_point_t *point);
|
||||
|
||||
cairo_private void
|
||||
_cairo_composite_rectangles_init (cairo_composite_rectangles_t *rects,
|
||||
@ -321,12 +319,6 @@ _cairo_array_num_elements (cairo_array_t *array);
|
||||
cairo_private int
|
||||
_cairo_array_size (cairo_array_t *array);
|
||||
|
||||
typedef struct {
|
||||
const cairo_user_data_key_t *key;
|
||||
void *user_data;
|
||||
cairo_destroy_func_t destroy;
|
||||
} cairo_user_data_slot_t;
|
||||
|
||||
cairo_private void
|
||||
_cairo_user_data_array_init (cairo_user_data_array_t *array);
|
||||
|
||||
@ -532,12 +524,6 @@ struct _cairo_font_face_backend {
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options,
|
||||
cairo_scaled_font_t **scaled_font);
|
||||
|
||||
cairo_font_face_t *
|
||||
(*get_implementation) (void *font_face,
|
||||
const cairo_matrix_t *font_matrix,
|
||||
const cairo_matrix_t *ctm,
|
||||
const cairo_font_options_t *options);
|
||||
};
|
||||
|
||||
extern const cairo_private struct _cairo_font_face_backend _cairo_user_font_face_backend;
|
||||
@ -923,6 +909,7 @@ struct _cairo_solid_pattern {
|
||||
cairo_content_t content;
|
||||
};
|
||||
|
||||
extern const cairo_private cairo_solid_pattern_t _cairo_pattern_nil;
|
||||
extern const cairo_private cairo_solid_pattern_t _cairo_pattern_black;
|
||||
|
||||
typedef struct _cairo_surface_pattern {
|
||||
@ -1052,7 +1039,7 @@ typedef struct _cairo_stroke_face {
|
||||
|
||||
/* cairo.c */
|
||||
|
||||
static inline double cairo_const
|
||||
static inline double
|
||||
_cairo_restrict_value (double value, double min, double max)
|
||||
{
|
||||
if (value < min)
|
||||
@ -1066,14 +1053,14 @@ _cairo_restrict_value (double value, double min, double max)
|
||||
/* C99 round() rounds to the nearest integral value with halfway cases rounded
|
||||
* away from 0. _cairo_round rounds halfway cases toward negative infinity.
|
||||
* This matches the rounding behaviour of _cairo_lround. */
|
||||
static inline double cairo_const
|
||||
static inline double
|
||||
_cairo_round (double r)
|
||||
{
|
||||
return floor (r + .5);
|
||||
}
|
||||
|
||||
cairo_private int
|
||||
_cairo_lround (double d) cairo_const;
|
||||
_cairo_lround (double d);
|
||||
|
||||
/* cairo-gstate.c */
|
||||
cairo_private cairo_status_t
|
||||
@ -1367,21 +1354,21 @@ 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_const;
|
||||
_cairo_operator_bounded_by_mask (cairo_operator_t op) cairo_pure;
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_operator_bounded_by_source (cairo_operator_t op) cairo_const;
|
||||
_cairo_operator_bounded_by_source (cairo_operator_t op) cairo_pure;
|
||||
|
||||
/* cairo-color.c */
|
||||
cairo_private const cairo_color_t *
|
||||
_cairo_stock_color (cairo_stock_t stock) cairo_pure;
|
||||
_cairo_stock_color (cairo_stock_t stock);
|
||||
|
||||
#define CAIRO_COLOR_WHITE _cairo_stock_color (CAIRO_STOCK_WHITE)
|
||||
#define CAIRO_COLOR_BLACK _cairo_stock_color (CAIRO_STOCK_BLACK)
|
||||
#define CAIRO_COLOR_TRANSPARENT _cairo_stock_color (CAIRO_STOCK_TRANSPARENT)
|
||||
|
||||
cairo_private uint16_t
|
||||
_cairo_color_double_to_short (double d) cairo_const;
|
||||
_cairo_color_double_to_short (double d) cairo_pure;
|
||||
|
||||
cairo_private void
|
||||
_cairo_color_init (cairo_color_t *color);
|
||||
@ -1415,7 +1402,7 @@ _cairo_color_get_rgba_premultiplied (cairo_color_t *color,
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_color_equal (const cairo_color_t *color_a,
|
||||
const cairo_color_t *color_b) cairo_pure;
|
||||
const cairo_color_t *color_b);
|
||||
|
||||
/* cairo-font-face.c */
|
||||
|
||||
@ -1439,10 +1426,10 @@ _cairo_unscaled_font_reference (cairo_unscaled_font_t *font);
|
||||
cairo_private void
|
||||
_cairo_unscaled_font_destroy (cairo_unscaled_font_t *font);
|
||||
|
||||
/* cairo-font-face-twin.c */
|
||||
|
||||
cairo_private cairo_font_face_t *
|
||||
_cairo_font_face_twin_create_fallback (void);
|
||||
_cairo_toy_font_face_get_implementation (cairo_font_face_t *font_face);
|
||||
|
||||
/* cairo-font-face-twin.c */
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_font_face_twin_create_for_toy (cairo_toy_font_face_t *toy_face,
|
||||
@ -1624,6 +1611,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,
|
||||
@ -1994,19 +1984,6 @@ _cairo_surface_clone_similar (cairo_surface_t *surface,
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_surface_snapshot (cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_surface_attach_snapshot (cairo_surface_t *surface,
|
||||
cairo_surface_t *snapshot,
|
||||
cairo_surface_func_t detach_func);
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_surface_has_snapshot (cairo_surface_t *surface,
|
||||
const cairo_surface_backend_t *backend,
|
||||
cairo_content_t content);
|
||||
|
||||
cairo_private void
|
||||
_cairo_surface_detach_snapshot (cairo_surface_t *snapshot);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_similar (cairo_surface_t *surface_a,
|
||||
cairo_surface_t *surface_b,
|
||||
@ -2105,7 +2082,7 @@ _cairo_surface_set_device_scale (cairo_surface_t *surface,
|
||||
double sy);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_has_device_transform (cairo_surface_t *surface) cairo_pure;
|
||||
_cairo_surface_has_device_transform (cairo_surface_t *surface);
|
||||
|
||||
/* cairo-image-surface.c */
|
||||
|
||||
@ -2154,13 +2131,13 @@ _cairo_surface_has_device_transform (cairo_surface_t *surface) cairo_pure;
|
||||
== 0))
|
||||
|
||||
cairo_private int
|
||||
_cairo_format_bits_per_pixel (cairo_format_t format) cairo_const;
|
||||
_cairo_format_bits_per_pixel (cairo_format_t format) cairo_pure;
|
||||
|
||||
cairo_private cairo_format_t
|
||||
_cairo_format_from_content (cairo_content_t content) cairo_const;
|
||||
_cairo_format_from_content (cairo_content_t content) cairo_pure;
|
||||
|
||||
cairo_private cairo_content_t
|
||||
_cairo_content_from_format (cairo_format_t format) cairo_const;
|
||||
_cairo_content_from_format (cairo_format_t format) cairo_pure;
|
||||
|
||||
cairo_private cairo_surface_t *
|
||||
_cairo_image_surface_create_for_pixman_image (pixman_image_t *pixman_image,
|
||||
@ -2230,10 +2207,10 @@ cairo_private cairo_image_transparency_t
|
||||
_cairo_image_analyze_transparency (cairo_image_surface_t *image);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_image (const cairo_surface_t *surface) cairo_pure;
|
||||
_cairo_surface_is_image (const cairo_surface_t *surface);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_surface_is_meta (const cairo_surface_t *surface) cairo_pure;
|
||||
_cairo_surface_is_meta (const cairo_surface_t *surface);
|
||||
|
||||
/* cairo-pen.c */
|
||||
cairo_private cairo_status_t
|
||||
@ -2358,31 +2335,31 @@ _cairo_matrix_transform_bounding_box_fixed (const cairo_matrix_t *matrix,
|
||||
cairo_bool_t *is_tight);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_invertible (const cairo_matrix_t *matrix) cairo_pure;
|
||||
_cairo_matrix_is_invertible (const cairo_matrix_t *matrix);
|
||||
|
||||
cairo_private double
|
||||
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix) cairo_pure;
|
||||
_cairo_matrix_compute_determinant (const cairo_matrix_t *matrix);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_matrix_compute_basis_scale_factors (const cairo_matrix_t *matrix,
|
||||
double *sx, double *sy, int x_major);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_identity (const cairo_matrix_t *matrix) cairo_pure;
|
||||
_cairo_matrix_is_identity (const cairo_matrix_t *matrix);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_translation (const cairo_matrix_t *matrix) cairo_pure;
|
||||
_cairo_matrix_is_translation (const cairo_matrix_t *matrix);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_integer_translation(const cairo_matrix_t *matrix,
|
||||
int *itx, int *ity);
|
||||
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix) cairo_pure;
|
||||
_cairo_matrix_is_pixel_exact (const cairo_matrix_t *matrix);
|
||||
|
||||
cairo_private double
|
||||
_cairo_matrix_transformed_circle_major_axis (const cairo_matrix_t *matrix,
|
||||
double radius) cairo_pure;
|
||||
double radius);
|
||||
|
||||
cairo_private void
|
||||
_cairo_matrix_to_pixman_matrix (const cairo_matrix_t *matrix,
|
||||
@ -2470,14 +2447,10 @@ _cairo_slope_init (cairo_slope_t *slope,
|
||||
const cairo_point_t *b);
|
||||
|
||||
cairo_private int
|
||||
_cairo_slope_compare (const cairo_slope_t *a,
|
||||
const cairo_slope_t *b) cairo_pure;
|
||||
_cairo_slope_compare (const cairo_slope_t *a, const cairo_slope_t *b);
|
||||
|
||||
/* cairo-pattern.c */
|
||||
|
||||
cairo_private cairo_pattern_t *
|
||||
_cairo_pattern_create_in_error (cairo_status_t status);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pattern_create_copy (cairo_pattern_t **pattern,
|
||||
const cairo_pattern_t *other);
|
||||
@ -2486,10 +2459,6 @@ cairo_private cairo_status_t
|
||||
_cairo_pattern_init_copy (cairo_pattern_t *pattern,
|
||||
const cairo_pattern_t *other);
|
||||
|
||||
cairo_private void
|
||||
_cairo_pattern_init_static_copy (cairo_pattern_t *pattern,
|
||||
const cairo_pattern_t *other);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_pattern_init_snapshot (cairo_pattern_t *pattern,
|
||||
const cairo_pattern_t *other);
|
||||
@ -2515,9 +2484,6 @@ _cairo_pattern_init_radial (cairo_radial_pattern_t *pattern,
|
||||
cairo_private void
|
||||
_cairo_pattern_fini (cairo_pattern_t *pattern);
|
||||
|
||||
cairo_private void
|
||||
_cairo_pattern_fini_snapshot (cairo_pattern_t *pattern);
|
||||
|
||||
cairo_private cairo_pattern_t *
|
||||
_cairo_pattern_create_solid (const cairo_color_t *color,
|
||||
cairo_content_t content);
|
||||
@ -2532,10 +2498,6 @@ _cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern);
|
||||
cairo_private cairo_bool_t
|
||||
_cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern);
|
||||
|
||||
enum {
|
||||
CAIRO_PATTERN_ACQUIRE_NONE = 0x0,
|
||||
CAIRO_PATTERN_ACQUIRE_NO_REFLECT = 0x1,
|
||||
};
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
|
||||
cairo_surface_t *dst,
|
||||
@ -2544,7 +2506,6 @@ _cairo_pattern_acquire_surface (const cairo_pattern_t *pattern,
|
||||
int y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int flags,
|
||||
cairo_surface_t **surface_out,
|
||||
cairo_surface_attributes_t *attributes);
|
||||
|
||||
@ -2564,7 +2525,6 @@ _cairo_pattern_acquire_surfaces (const cairo_pattern_t *src,
|
||||
int mask_y,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int flags,
|
||||
cairo_surface_t **src_out,
|
||||
cairo_surface_t **mask_out,
|
||||
cairo_surface_attributes_t *src_attributes,
|
||||
@ -2728,7 +2688,6 @@ slim_hidden_proto (cairo_set_line_width);
|
||||
slim_hidden_proto (cairo_set_matrix);
|
||||
slim_hidden_proto (cairo_set_operator);
|
||||
slim_hidden_proto (cairo_set_source);
|
||||
slim_hidden_proto (cairo_set_source_rgb);
|
||||
slim_hidden_proto (cairo_set_source_surface);
|
||||
slim_hidden_proto (cairo_set_tolerance);
|
||||
slim_hidden_proto (cairo_status);
|
||||
@ -2768,7 +2727,6 @@ slim_hidden_proto (cairo_user_to_device_distance);
|
||||
slim_hidden_proto (cairo_version_string);
|
||||
slim_hidden_proto (cairo_region_create);
|
||||
slim_hidden_proto (cairo_region_create_rectangle);
|
||||
slim_hidden_proto (cairo_region_create_rectangles);
|
||||
slim_hidden_proto (cairo_region_copy);
|
||||
slim_hidden_proto (cairo_region_destroy);
|
||||
slim_hidden_proto (cairo_region_status);
|
||||
@ -2801,16 +2759,12 @@ CAIRO_END_DECLS
|
||||
#include "cairo-hash-private.h"
|
||||
|
||||
#if HAVE_VALGRIND
|
||||
#include <memcheck.h>
|
||||
|
||||
#define VG(x) x
|
||||
|
||||
cairo_private void
|
||||
_cairo_debug_check_image_surface_is_defined (const cairo_surface_t *surface);
|
||||
|
||||
#else
|
||||
|
||||
#define VG(x)
|
||||
#define _cairo_debug_check_image_surface_is_defined(X)
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user