зеркало из https://github.com/mozilla/gecko-dev.git
Bug 493079 - Update cairo to 1ae2ddc1dd4c90d50b8c57c4de677f8ab96b1fa2 r=joe
This commit is contained in:
Родитель
94b6dbbe61
Коммит
b30669d3f7
|
@ -38,7 +38,6 @@
|
|||
|
||||
#include "cairo-analysis-surface-private.h"
|
||||
#include "cairo-paginated-private.h"
|
||||
#include "cairo-region-private.h"
|
||||
#include "cairo-meta-surface-private.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -215,7 +214,7 @@ _add_operation (cairo_analysis_surface_t *surface,
|
|||
* region there is no benefit in emitting a native operation as
|
||||
* the fallback image will be painted on top.
|
||||
*/
|
||||
if (_cairo_region_contains_rectangle (&surface->fallback_region, rect) == PIXMAN_REGION_IN)
|
||||
if (cairo_region_contains_rectangle (&surface->fallback_region, rect) == CAIRO_REGION_OVERLAP_IN)
|
||||
return CAIRO_INT_STATUS_IMAGE_FALLBACK;
|
||||
|
||||
if (backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY) {
|
||||
|
@ -226,7 +225,7 @@ _add_operation (cairo_analysis_surface_t *surface,
|
|||
* natively supported and the backend will blend the
|
||||
* transparency into the white background.
|
||||
*/
|
||||
if (_cairo_region_contains_rectangle (&surface->supported_region, rect) == PIXMAN_REGION_OUT)
|
||||
if (cairo_region_contains_rectangle (&surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT)
|
||||
backend_status = CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -235,9 +234,7 @@ _add_operation (cairo_analysis_surface_t *surface,
|
|||
* this region will be emitted as native operations.
|
||||
*/
|
||||
surface->has_supported = TRUE;
|
||||
status = _cairo_region_union_rect (&surface->supported_region,
|
||||
&surface->supported_region,
|
||||
rect);
|
||||
status = cairo_region_union_rectangle (&surface->supported_region, rect);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -246,9 +243,7 @@ _add_operation (cairo_analysis_surface_t *surface,
|
|||
* emitted.
|
||||
*/
|
||||
surface->has_unsupported = TRUE;
|
||||
status = _cairo_region_union_rect (&surface->fallback_region,
|
||||
&surface->fallback_region,
|
||||
rect);
|
||||
status = cairo_region_union_rectangle (&surface->fallback_region, rect);
|
||||
|
||||
/* The status CAIRO_INT_STATUS_IMAGE_FALLBACK is used to indicate
|
||||
* unsupported operations to the meta surface as using
|
||||
|
@ -778,14 +773,14 @@ _cairo_analysis_surface_create (cairo_surface_t *target,
|
|||
surface->has_supported = FALSE;
|
||||
surface->has_unsupported = FALSE;
|
||||
|
||||
_cairo_region_init (&surface->supported_region);
|
||||
_cairo_region_init (&surface->fallback_region);
|
||||
|
||||
surface->page_bbox.p1.x = 0;
|
||||
surface->page_bbox.p1.y = 0;
|
||||
surface->page_bbox.p2.x = 0;
|
||||
surface->page_bbox.p2.y = 0;
|
||||
|
||||
_cairo_region_init (&surface->supported_region);
|
||||
_cairo_region_init (&surface->fallback_region);
|
||||
|
||||
if (width == -1 && height == -1) {
|
||||
surface->current_clip.x = CAIRO_RECT_INT_MIN;
|
||||
surface->current_clip.y = CAIRO_RECT_INT_MIN;
|
||||
|
|
|
@ -125,6 +125,9 @@ _cairo_array_grow_by (cairo_array_t *array, unsigned int additional)
|
|||
if (required_size > INT_MAX || required_size < array->num_elements)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (required_size <= old_size)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
|
|
|
@ -1660,6 +1660,9 @@ _cairo_bentley_ottmann_tessellate_polygon (cairo_traps_t *traps,
|
|||
if (0 == polygon->num_edges)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
has_limits = _cairo_traps_get_limit (traps, &limit);
|
||||
|
||||
edges = stack_edges;
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
#include "cairo-compiler-private.h"
|
||||
#include "cairo-path-fixed-private.h"
|
||||
#include "cairo-reference-count-private.h"
|
||||
#include "cairo-region-private.h"
|
||||
|
||||
extern const cairo_private cairo_rectangle_list_t _cairo_rectangles_nil;
|
||||
|
||||
|
@ -78,8 +77,7 @@ struct _cairo_clip {
|
|||
/*
|
||||
* A clip region that can be placed in the surface
|
||||
*/
|
||||
cairo_region_t region;
|
||||
cairo_bool_t has_region;
|
||||
cairo_region_t *region;
|
||||
/*
|
||||
* If the surface supports path clipping, we store the list of
|
||||
* clipping paths that has been set here as a linked list.
|
||||
|
|
|
@ -64,8 +64,7 @@ _cairo_clip_init (cairo_clip_t *clip, cairo_surface_t *target)
|
|||
|
||||
clip->serial = 0;
|
||||
|
||||
_cairo_region_init (&clip->region);
|
||||
clip->has_region = FALSE;
|
||||
clip->region = NULL;
|
||||
|
||||
clip->path = NULL;
|
||||
}
|
||||
|
@ -76,28 +75,29 @@ _cairo_clip_init_copy (cairo_clip_t *clip, cairo_clip_t *other)
|
|||
clip->mode = other->mode;
|
||||
|
||||
clip->all_clipped = other->all_clipped;
|
||||
|
||||
|
||||
clip->surface = cairo_surface_reference (other->surface);
|
||||
clip->surface_rect = other->surface_rect;
|
||||
|
||||
clip->serial = other->serial;
|
||||
|
||||
_cairo_region_init (&clip->region);
|
||||
|
||||
if (other->has_region) {
|
||||
if (other->region) {
|
||||
cairo_status_t status;
|
||||
|
||||
clip->region = cairo_region_copy (other->region);
|
||||
|
||||
status = _cairo_region_copy (&clip->region, &other->region);
|
||||
status = cairo_region_status (clip->region);
|
||||
if (unlikely (status)) {
|
||||
_cairo_region_fini (&clip->region);
|
||||
cairo_surface_destroy (clip->surface);
|
||||
cairo_region_destroy (clip->region);
|
||||
clip->region = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
clip->has_region = TRUE;
|
||||
} else {
|
||||
clip->has_region = FALSE;
|
||||
clip->region = NULL;
|
||||
}
|
||||
|
||||
|
||||
clip->path = _cairo_clip_path_reference (other->path);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -114,14 +114,10 @@ _cairo_clip_reset (cairo_clip_t *clip)
|
|||
|
||||
clip->serial = 0;
|
||||
|
||||
if (clip->has_region) {
|
||||
/* _cairo_region_fini just releases the resources used but
|
||||
* doesn't bother with leaving the region in a valid state.
|
||||
* So _cairo_region_init has to be called afterwards. */
|
||||
_cairo_region_fini (&clip->region);
|
||||
_cairo_region_init (&clip->region);
|
||||
if (clip->region) {
|
||||
cairo_region_destroy (clip->region);
|
||||
|
||||
clip->has_region = FALSE;
|
||||
clip->region = NULL;
|
||||
}
|
||||
|
||||
_cairo_clip_path_destroy (clip->path);
|
||||
|
@ -178,10 +174,10 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
|||
return status;
|
||||
}
|
||||
|
||||
if (clip->has_region) {
|
||||
if (clip->region) {
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
_cairo_region_get_extents (&clip->region, &extents);
|
||||
cairo_region_get_extents (clip->region, &extents);
|
||||
is_empty = _cairo_rectangle_intersect (rectangle, &extents);
|
||||
if (is_empty)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -194,7 +190,7 @@ _cairo_clip_intersect_to_rectangle (cairo_clip_t *clip,
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
_cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
@ -202,40 +198,21 @@ _cairo_clip_intersect_to_region (cairo_clip_t *clip,
|
|||
if (!clip)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (clip->all_clipped) {
|
||||
cairo_region_t clip_rect;
|
||||
|
||||
_cairo_region_init_rect (&clip_rect, &clip->surface_rect);
|
||||
|
||||
status = _cairo_region_intersect (region, &clip_rect, region);
|
||||
|
||||
_cairo_region_fini (&clip_rect);
|
||||
|
||||
return status;
|
||||
}
|
||||
if (clip->all_clipped)
|
||||
return cairo_region_intersect_rectangle (region, &clip->surface_rect);
|
||||
|
||||
if (clip->path) {
|
||||
/* Intersect clip path into region. */
|
||||
}
|
||||
|
||||
if (clip->has_region) {
|
||||
status = _cairo_region_intersect (region, &clip->region, region);
|
||||
if (clip->region) {
|
||||
status = cairo_region_intersect (region, clip->region);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
|
||||
if (clip->surface) {
|
||||
cairo_region_t clip_rect;
|
||||
|
||||
_cairo_region_init_rect (&clip_rect, &clip->surface_rect);
|
||||
|
||||
status = _cairo_region_intersect (region, &clip_rect, region);
|
||||
|
||||
_cairo_region_fini (&clip_rect);
|
||||
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
}
|
||||
if (clip->surface)
|
||||
return cairo_region_intersect_rectangle (region, &clip->surface_rect);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -344,7 +321,7 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
|
|||
cairo_traps_t *traps,
|
||||
cairo_surface_t *target)
|
||||
{
|
||||
cairo_region_t region;
|
||||
cairo_region_t *region;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (clip->all_clipped)
|
||||
|
@ -357,29 +334,21 @@ _cairo_clip_intersect_region (cairo_clip_t *clip,
|
|||
if (status)
|
||||
return status;
|
||||
|
||||
if (!clip->has_region) {
|
||||
status = _cairo_region_copy (&clip->region, ®ion);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
clip->has_region = TRUE;
|
||||
if (clip->region) {
|
||||
status = cairo_region_intersect (clip->region, region);
|
||||
} else {
|
||||
cairo_region_t intersection;
|
||||
clip->region = cairo_region_copy (region);
|
||||
|
||||
_cairo_region_init (&intersection);
|
||||
|
||||
status = _cairo_region_intersect (&intersection,
|
||||
&clip->region,
|
||||
®ion);
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = _cairo_region_copy (&clip->region, &intersection);
|
||||
|
||||
_cairo_region_fini (&intersection);
|
||||
assert (clip->region != NULL);
|
||||
|
||||
if ((status = cairo_region_status (clip->region)))
|
||||
clip->region = NULL;
|
||||
}
|
||||
|
||||
clip->serial = _cairo_surface_allocate_clip_serial (target);
|
||||
_cairo_region_fini (®ion);
|
||||
cairo_region_destroy (region);
|
||||
|
||||
if (! _cairo_region_not_empty (&clip->region))
|
||||
if (!clip->region || cairo_region_is_empty (clip->region))
|
||||
_cairo_clip_set_all_clipped (clip, target);
|
||||
|
||||
return status;
|
||||
|
@ -736,10 +705,10 @@ _cairo_clip_translate (cairo_clip_t *clip,
|
|||
if (clip->all_clipped)
|
||||
return;
|
||||
|
||||
if (clip->has_region) {
|
||||
_cairo_region_translate (&clip->region,
|
||||
_cairo_fixed_integer_part (tx),
|
||||
_cairo_fixed_integer_part (ty));
|
||||
if (clip->region) {
|
||||
cairo_region_translate (clip->region,
|
||||
_cairo_fixed_integer_part (tx),
|
||||
_cairo_fixed_integer_part (ty));
|
||||
}
|
||||
|
||||
if (clip->surface) {
|
||||
|
@ -794,12 +763,10 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
|
|||
/* We should reapply the original clip path in this case, and let
|
||||
* whatever the right handling is happen */
|
||||
} else {
|
||||
if (other->has_region) {
|
||||
status = _cairo_region_copy (&clip->region, &other->region);
|
||||
if (unlikely (status))
|
||||
if (other->region) {
|
||||
clip->region = cairo_region_copy (other->region);
|
||||
if (unlikely ((status = cairo_region_status (clip->region))))
|
||||
goto BAIL;
|
||||
|
||||
clip->has_region = TRUE;
|
||||
}
|
||||
|
||||
if (other->surface) {
|
||||
|
@ -831,8 +798,8 @@ _cairo_clip_init_deep_copy (cairo_clip_t *clip,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
BAIL:
|
||||
if (clip->has_region)
|
||||
_cairo_region_fini (&clip->region);
|
||||
if (clip->region)
|
||||
cairo_region_destroy (clip->region);
|
||||
if (clip->surface)
|
||||
cairo_surface_destroy (clip->surface);
|
||||
|
||||
|
@ -873,7 +840,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
|||
{
|
||||
cairo_rectangle_list_t *list;
|
||||
cairo_rectangle_t *rectangles = NULL;
|
||||
int n_boxes = 0;
|
||||
int n_rects = 0;
|
||||
|
||||
if (clip->all_clipped)
|
||||
goto DONE;
|
||||
|
@ -883,28 +850,22 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
|||
return (cairo_rectangle_list_t*) &_cairo_rectangles_not_representable;
|
||||
}
|
||||
|
||||
if (clip->has_region) {
|
||||
if (clip->region) {
|
||||
int i;
|
||||
|
||||
n_boxes = _cairo_region_num_boxes (&clip->region);
|
||||
n_rects = cairo_region_num_rectangles (clip->region);
|
||||
|
||||
if (n_boxes) {
|
||||
rectangles = _cairo_malloc_ab (n_boxes, sizeof (cairo_rectangle_t));
|
||||
if (n_rects) {
|
||||
rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
|
||||
if (unlikely (rectangles == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
return (cairo_rectangle_list_t*) &_cairo_rectangles_nil;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_boxes; ++i) {
|
||||
cairo_box_int_t box;
|
||||
for (i = 0; i < n_rects; ++i) {
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
|
||||
_cairo_region_get_box (&clip->region, i, &box);
|
||||
|
||||
clip_rect.x = box.p1.x;
|
||||
clip_rect.y = box.p1.y;
|
||||
clip_rect.width = box.p2.x - box.p1.x;
|
||||
clip_rect.height = box.p2.y - box.p1.y;
|
||||
cairo_region_get_rectangle (clip->region, i, &clip_rect);
|
||||
|
||||
if (!_cairo_clip_int_rect_to_user(gstate, &clip_rect, &rectangles[i])) {
|
||||
_cairo_error_throw (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
|
||||
|
@ -916,7 +877,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
|||
} else {
|
||||
cairo_rectangle_int_t extents;
|
||||
|
||||
n_boxes = 1;
|
||||
n_rects = 1;
|
||||
|
||||
rectangles = malloc(sizeof (cairo_rectangle_t));
|
||||
if (unlikely (rectangles == NULL)) {
|
||||
|
@ -943,7 +904,7 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
|
|||
|
||||
list->status = CAIRO_STATUS_SUCCESS;
|
||||
list->rectangles = rectangles;
|
||||
list->num_rectangles = n_boxes;
|
||||
list->num_rectangles = n_rects;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@
|
|||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(WINCE)
|
||||
#if defined(_MSC_VER) && defined(_M_IX86)
|
||||
/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together.
|
||||
The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and
|
||||
will never be folded into another one. Something like this might eventually
|
||||
|
|
|
@ -1299,39 +1299,39 @@ _cairo_directfb_surface_set_clip_region (void *abstract_surface,
|
|||
__FUNCTION__, surface, region);
|
||||
|
||||
if (region) {
|
||||
int n_boxes;
|
||||
int n_rects;
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
||||
surface->has_clip = TRUE;
|
||||
|
||||
n_boxes = _cairo_region_num_boxes (region);
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
if (n_boxes == 0)
|
||||
if (n_rects == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (surface->n_clips != n_boxes) {
|
||||
if (surface->n_clips != n_rects) {
|
||||
if (surface->clips)
|
||||
free (surface->clips);
|
||||
|
||||
surface->clips = _cairo_malloc_ab (n_boxes, sizeof (DFBRegion));
|
||||
surface->clips = _cairo_malloc_ab (n_rects, sizeof (DFBRegion));
|
||||
if (!surface->clips) {
|
||||
surface->n_clips = 0;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
surface->n_clips = n_boxes;
|
||||
surface->n_clips = n_rects;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_boxes; i++) {
|
||||
cairo_box_int_t box;
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
_cairo_region_get_box (region, i, &box);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
surface->clips[i].x1 = box.p1.x;
|
||||
surface->clips[i].y1 = box.p1.y;
|
||||
surface->clips[i].x2 = box.p2.x - 1;
|
||||
surface->clips[i].y2 = box.p2.y - 1;
|
||||
surface->clips[i].x1 = rect.x;
|
||||
surface->clips[i].y1 = rect.y;
|
||||
surface->clips[i].x2 = rect.x + rect.width - 1;
|
||||
surface->clips[i].y2 = rect.y + rect.height - 1;
|
||||
}
|
||||
} else {
|
||||
surface->has_clip = FALSE;
|
||||
|
|
|
@ -418,11 +418,12 @@ _cairo_ft_unscaled_font_keys_equal (const void *key_a,
|
|||
/* Finds or creates a #cairo_ft_unscaled_font_t for the filename/id from
|
||||
* pattern. Returns a new reference to the unscaled font.
|
||||
*/
|
||||
static cairo_ft_unscaled_font_t *
|
||||
static cairo_status_t
|
||||
_cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
|
||||
char *filename,
|
||||
int id,
|
||||
FT_Face font_face)
|
||||
FT_Face font_face,
|
||||
cairo_ft_unscaled_font_t **out)
|
||||
{
|
||||
cairo_ft_unscaled_font_t key, *unscaled;
|
||||
cairo_ft_unscaled_font_map_t *font_map;
|
||||
|
@ -430,7 +431,7 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
|
|||
|
||||
font_map = _cairo_ft_unscaled_font_map_lock ();
|
||||
if (unlikely (font_map == NULL))
|
||||
goto UNWIND;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
_cairo_ft_unscaled_font_init_key (&key, from_face, filename, id, font_face);
|
||||
|
||||
|
@ -439,14 +440,13 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
|
|||
&key.base.hash_entry);
|
||||
if (unscaled != NULL) {
|
||||
_cairo_unscaled_font_reference (&unscaled->base);
|
||||
_cairo_ft_unscaled_font_map_unlock ();
|
||||
return unscaled;
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
/* Otherwise create it and insert into hash table. */
|
||||
unscaled = malloc (sizeof (cairo_ft_unscaled_font_t));
|
||||
if (unlikely (unscaled == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
goto UNWIND_FONT_MAP_LOCK;
|
||||
}
|
||||
|
||||
|
@ -460,9 +460,10 @@ _cairo_ft_unscaled_font_create_internal (cairo_bool_t from_face,
|
|||
if (unlikely (status))
|
||||
goto UNWIND_UNSCALED_FONT_INIT;
|
||||
|
||||
DONE:
|
||||
_cairo_ft_unscaled_font_map_unlock ();
|
||||
|
||||
return unscaled;
|
||||
*out = unscaled;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
UNWIND_UNSCALED_FONT_INIT:
|
||||
_cairo_ft_unscaled_font_fini (unscaled);
|
||||
|
@ -470,39 +471,52 @@ UNWIND_UNSCALED_MALLOC:
|
|||
free (unscaled);
|
||||
UNWIND_FONT_MAP_LOCK:
|
||||
_cairo_ft_unscaled_font_map_unlock ();
|
||||
UNWIND:
|
||||
return NULL;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
#if CAIRO_HAS_FC_FONT
|
||||
static cairo_ft_unscaled_font_t *
|
||||
_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern)
|
||||
static cairo_status_t
|
||||
_cairo_ft_unscaled_font_create_for_pattern (FcPattern *pattern,
|
||||
cairo_ft_unscaled_font_t **out)
|
||||
{
|
||||
FT_Face font_face = NULL;
|
||||
char *filename = NULL;
|
||||
int id = 0;
|
||||
FcResult ret;
|
||||
|
||||
if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face) == FcResultMatch)
|
||||
goto DONE;
|
||||
|
||||
if (FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &filename) == FcResultMatch) {
|
||||
/* If FC_INDEX is not set, we just use 0 */
|
||||
FcPatternGetInteger (pattern, FC_INDEX, 0, &id);
|
||||
ret = FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &font_face);
|
||||
switch ((int) ret) {
|
||||
case FcResultMatch:
|
||||
goto DONE;
|
||||
case FcResultOutOfMemory:
|
||||
break;
|
||||
default:
|
||||
if (FcPatternGetString (pattern, FC_FILE, 0,
|
||||
(FcChar8 **) &filename) == FcResultMatch)
|
||||
{
|
||||
/* If FC_INDEX is not set, we just use 0 */
|
||||
if (FcPatternGetInteger (pattern,
|
||||
FC_INDEX, 0, &id) != FcResultOutOfMemory)
|
||||
goto DONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
DONE:
|
||||
return _cairo_ft_unscaled_font_create_internal (font_face != NULL, filename, id, font_face);
|
||||
return _cairo_ft_unscaled_font_create_internal (font_face != NULL,
|
||||
filename, id, font_face,
|
||||
out);
|
||||
}
|
||||
#endif
|
||||
|
||||
static cairo_ft_unscaled_font_t *
|
||||
_cairo_ft_unscaled_font_create_from_face (FT_Face face)
|
||||
static cairo_status_t
|
||||
_cairo_ft_unscaled_font_create_from_face (FT_Face face,
|
||||
cairo_ft_unscaled_font_t **out)
|
||||
{
|
||||
return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face);
|
||||
return _cairo_ft_unscaled_font_create_internal (TRUE, NULL, 0, face, out);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2317,7 +2331,6 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face,
|
|||
*scaled_font = _cairo_scaled_font_create_in_error (status);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -2325,11 +2338,11 @@ _cairo_ft_font_face_scaled_font_create (void *abstract_face,
|
|||
ft_options = font_face->ft_options;
|
||||
}
|
||||
|
||||
return _cairo_ft_scaled_font_create (unscaled,
|
||||
&font_face->base,
|
||||
font_matrix, ctm,
|
||||
options, ft_options,
|
||||
scaled_font);
|
||||
return _cairo_ft_scaled_font_create (unscaled,
|
||||
&font_face->base,
|
||||
font_matrix, ctm,
|
||||
options, ft_options,
|
||||
scaled_font);
|
||||
}
|
||||
|
||||
const cairo_font_face_backend_t _cairo_ft_font_face_backend = {
|
||||
|
@ -2358,7 +2371,7 @@ _cairo_ft_font_face_create_for_pattern (FcPattern *pattern,
|
|||
font_face->next = NULL;
|
||||
|
||||
font_face->pattern = FcPatternDuplicate (pattern);
|
||||
if (unlikely (pattern == NULL)) {
|
||||
if (unlikely (font_face->pattern == NULL)) {
|
||||
free (font_face);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
@ -2564,6 +2577,8 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
|
|||
return status;
|
||||
|
||||
pattern = FcPatternDuplicate (pattern);
|
||||
if (pattern == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (! FcPatternAddDouble (pattern, FC_PIXEL_SIZE, sf.y_scale)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
@ -2587,11 +2602,9 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
|
|||
goto FREE_PATTERN;
|
||||
}
|
||||
|
||||
*unscaled = _cairo_ft_unscaled_font_create_for_pattern (resolved);
|
||||
if (!*unscaled) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
status = _cairo_ft_unscaled_font_create_for_pattern (resolved, unscaled);
|
||||
if (unlikely (status))
|
||||
goto FREE_RESOLVED;
|
||||
}
|
||||
|
||||
_get_pattern_ft_options (resolved, ft_options);
|
||||
|
||||
|
@ -2647,10 +2660,12 @@ cairo_ft_font_face_create_for_pattern (FcPattern *pattern)
|
|||
cairo_ft_unscaled_font_t *unscaled;
|
||||
cairo_font_face_t *font_face;
|
||||
cairo_ft_options_t ft_options;
|
||||
cairo_status_t status;
|
||||
|
||||
unscaled = _cairo_ft_unscaled_font_create_for_pattern (pattern);
|
||||
status = _cairo_ft_unscaled_font_create_for_pattern (pattern, &unscaled);
|
||||
if (unlikely (status))
|
||||
return (cairo_font_face_t *) &_cairo_font_face_nil;
|
||||
if (unlikely (unscaled == NULL)) {
|
||||
cairo_status_t status;
|
||||
/* Store the pattern. We will resolve it and create unscaled
|
||||
* font when creating scaled fonts */
|
||||
status = _cairo_ft_font_face_create_for_pattern (pattern,
|
||||
|
@ -2722,12 +2737,11 @@ cairo_ft_font_face_create_for_ft_face (FT_Face face,
|
|||
cairo_ft_unscaled_font_t *unscaled;
|
||||
cairo_font_face_t *font_face;
|
||||
cairo_ft_options_t ft_options;
|
||||
cairo_status_t status;
|
||||
|
||||
unscaled = _cairo_ft_unscaled_font_create_from_face (face);
|
||||
if (unlikely (unscaled == NULL)) {
|
||||
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
|
||||
status = _cairo_ft_unscaled_font_create_from_face (face, &unscaled);
|
||||
if (unlikely (status))
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
}
|
||||
|
||||
ft_options.load_flags = load_flags;
|
||||
ft_options.extra_flags = 0;
|
||||
|
|
|
@ -222,6 +222,9 @@ _cairo_gstate_save (cairo_gstate_t **gstate, cairo_gstate_t **freelist)
|
|||
cairo_gstate_t *top;
|
||||
cairo_status_t status;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
top = *freelist;
|
||||
if (top == NULL) {
|
||||
top = malloc (sizeof (cairo_gstate_t));
|
||||
|
|
|
@ -198,6 +198,9 @@ _cairo_hull_compute (cairo_pen_vertex_t *vertices, int *num_vertices)
|
|||
cairo_hull_t *hull;
|
||||
int num_hull = *num_vertices;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (num_hull > ARRAY_LENGTH (hull_stack)) {
|
||||
hull = _cairo_malloc_ab (num_hull, sizeof (cairo_hull_t));
|
||||
if (unlikely (hull == NULL))
|
||||
|
|
|
@ -1044,6 +1044,9 @@ _cairo_image_surface_fill_rectangles (void *abstract_surface,
|
|||
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
pixman_color.red = color->red_short;
|
||||
pixman_color.green = color->green_short;
|
||||
pixman_color.blue = color->blue_short;
|
||||
|
@ -1112,6 +1115,9 @@ _cairo_image_surface_composite_trapezoids (cairo_operator_t op,
|
|||
if (height == 0 || width == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
/* Convert traps to pixman traps */
|
||||
if (num_traps > ARRAY_LENGTH (stack_traps)) {
|
||||
pixman_traps = _cairo_malloc_ab (num_traps, sizeof (pixman_trapezoid_t));
|
||||
|
@ -1427,7 +1433,7 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
|
|||
{
|
||||
cairo_image_surface_t *surface = (cairo_image_surface_t *) abstract_surface;
|
||||
|
||||
if (! pixman_image_set_clip_region32 (surface->pixman_image, ®ion->rgn))
|
||||
if (! pixman_image_set_clip_region32 (surface->pixman_image, region? ®ion->rgn : NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
surface->has_clip = region != NULL;
|
||||
|
|
|
@ -39,6 +39,13 @@
|
|||
|
||||
#include "cairo-wideint-private.h"
|
||||
|
||||
#if HAVE_MEMFAULT
|
||||
#include <memfault.h>
|
||||
#define CAIRO_INJECT_FAULT() VALGRIND_INJECT_FAULT()
|
||||
#else
|
||||
#define CAIRO_INJECT_FAULT() 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* _cairo_malloc:
|
||||
* @size: size in bytes
|
||||
|
|
|
@ -123,9 +123,10 @@ cairo_status_to_string (cairo_status_t status)
|
|||
return "invalid value for an input #cairo_font_weight_t";
|
||||
case CAIRO_STATUS_INVALID_SIZE:
|
||||
return "invalid value for the size of the input (surface, pattern, etc.)";
|
||||
default:
|
||||
case CAIRO_STATUS_LAST_STATUS:
|
||||
return "<unknown error status>";
|
||||
}
|
||||
|
||||
return "<unknown error status>";
|
||||
}
|
||||
|
||||
|
||||
|
@ -610,7 +611,7 @@ _cairo_lround (double d)
|
|||
#include <windows.h>
|
||||
#include <io.h>
|
||||
|
||||
#if !WINCE
|
||||
#if !_WIN32_WCE
|
||||
/* tmpfile() replacement for Windows.
|
||||
*
|
||||
* On Windows tmpfile() creates the file in the root directory. This
|
||||
|
@ -660,7 +661,7 @@ _cairo_win32_tmpfile (void)
|
|||
|
||||
return fp;
|
||||
}
|
||||
#endif /* !WINCE */
|
||||
#endif /* !_WIN32_WCE */
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
@ -703,6 +704,9 @@ _cairo_intern_string (const char **str_inout, int len)
|
|||
cairo_intern_string_t tmpl, *istring;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (str);
|
||||
tmpl.hash_entry.hash = _intern_string_hash (str, len);
|
||||
|
|
|
@ -244,7 +244,7 @@ _cairo_paginated_surface_release_source_image (void *abstract_surface,
|
|||
|
||||
static cairo_int_status_t
|
||||
_paint_fallback_image (cairo_paginated_surface_t *surface,
|
||||
cairo_box_int_t *box)
|
||||
cairo_rectangle_int_t *rect)
|
||||
{
|
||||
double x_scale = surface->base.x_fallback_resolution / surface->target->x_resolution;
|
||||
double y_scale = surface->base.y_fallback_resolution / surface->target->y_resolution;
|
||||
|
@ -254,10 +254,10 @@ _paint_fallback_image (cairo_paginated_surface_t *surface,
|
|||
cairo_surface_t *image;
|
||||
cairo_surface_pattern_t pattern;
|
||||
|
||||
x = box->p1.x;
|
||||
y = box->p1.y;
|
||||
width = box->p2.x - x;
|
||||
height = box->p2.y - y;
|
||||
x = rect->x;
|
||||
y = rect->y;
|
||||
width = rect->width;
|
||||
height = rect->height;
|
||||
image = _cairo_paginated_surface_create_image_surface (surface,
|
||||
ceil (width * x_scale),
|
||||
ceil (height * y_scale));
|
||||
|
@ -365,23 +365,23 @@ _paint_page (cairo_paginated_surface_t *surface)
|
|||
}
|
||||
|
||||
if (has_page_fallback) {
|
||||
cairo_box_int_t box;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
surface->backend->set_paginated_mode (surface->target,
|
||||
CAIRO_PAGINATED_MODE_FALLBACK);
|
||||
|
||||
box.p1.x = 0;
|
||||
box.p1.y = 0;
|
||||
box.p2.x = surface->width;
|
||||
box.p2.y = surface->height;
|
||||
status = _paint_fallback_image (surface, &box);
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = surface->width;
|
||||
rect.height = surface->height;
|
||||
status = _paint_fallback_image (surface, &rect);
|
||||
if (unlikely (status))
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if (has_finegrained_fallback) {
|
||||
cairo_region_t *region;
|
||||
int num_boxes, i;
|
||||
int num_rects, i;
|
||||
|
||||
surface->backend->set_paginated_mode (surface->target,
|
||||
CAIRO_PAGINATED_MODE_FALLBACK);
|
||||
|
@ -397,13 +397,13 @@ _paint_page (cairo_paginated_surface_t *surface)
|
|||
|
||||
region = _cairo_analysis_surface_get_unsupported (analysis);
|
||||
|
||||
num_boxes = _cairo_region_num_boxes (region);
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
cairo_box_int_t box;
|
||||
num_rects = cairo_region_num_rectangles (region);
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
_cairo_region_get_box (region, i, &box);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
status = _paint_fallback_image (surface, &box);
|
||||
status = _paint_fallback_image (surface, &rect);
|
||||
|
||||
if (unlikely (status))
|
||||
goto FAIL;
|
||||
|
|
|
@ -201,15 +201,19 @@ _cairo_in_fill_curve_to (void *closure,
|
|||
if (c->y > bot) bot = c->y;
|
||||
if (d->y < top) top = d->y;
|
||||
if (d->y > bot) bot = d->y;
|
||||
if (bot < in_fill->y || top > in_fill->y)
|
||||
if (bot < in_fill->y || top > in_fill->y) {
|
||||
in_fill->current_point = *d;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
left = in_fill->current_point.x;
|
||||
if (b->x < left) left = b->x;
|
||||
if (c->x < left) left = c->x;
|
||||
if (d->x < left) left = d->x;
|
||||
if (left > in_fill->x)
|
||||
if (left > in_fill->x) {
|
||||
in_fill->current_point = *d;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* XXX Investigate direct inspection of the inflections? */
|
||||
if (! _cairo_spline_init (&spline,
|
||||
|
|
|
@ -1278,6 +1278,8 @@ _cairo_rectilinear_stroker_add_segment (cairo_rectilinear_stroker_t *stroker,
|
|||
cairo_bool_t is_horizontal,
|
||||
cairo_bool_t has_join)
|
||||
{
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (stroker->num_segments == stroker->segments_size) {
|
||||
int new_size = stroker->segments_size * 2;
|
||||
|
|
|
@ -119,6 +119,9 @@ static cairo_status_t
|
|||
_cairo_gradient_pattern_init_copy (cairo_gradient_pattern_t *pattern,
|
||||
const cairo_gradient_pattern_t *other)
|
||||
{
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (other->base.type == CAIRO_PATTERN_TYPE_LINEAR)
|
||||
{
|
||||
cairo_linear_pattern_t *dst = (cairo_linear_pattern_t *) pattern;
|
||||
|
@ -250,9 +253,10 @@ _cairo_pattern_fini (cairo_pattern_t *pattern)
|
|||
}
|
||||
|
||||
cairo_status_t
|
||||
_cairo_pattern_create_copy (cairo_pattern_t **pattern,
|
||||
_cairo_pattern_create_copy (cairo_pattern_t **pattern_out,
|
||||
const cairo_pattern_t *other)
|
||||
{
|
||||
cairo_pattern_t *pattern;
|
||||
cairo_status_t status;
|
||||
|
||||
if (other->status)
|
||||
|
@ -260,29 +264,32 @@ _cairo_pattern_create_copy (cairo_pattern_t **pattern,
|
|||
|
||||
switch (other->type) {
|
||||
case CAIRO_PATTERN_TYPE_SOLID:
|
||||
*pattern = malloc (sizeof (cairo_solid_pattern_t));
|
||||
pattern = malloc (sizeof (cairo_solid_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_SURFACE:
|
||||
*pattern = malloc (sizeof (cairo_surface_pattern_t));
|
||||
pattern = malloc (sizeof (cairo_surface_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_LINEAR:
|
||||
*pattern = malloc (sizeof (cairo_linear_pattern_t));
|
||||
pattern = malloc (sizeof (cairo_linear_pattern_t));
|
||||
break;
|
||||
case CAIRO_PATTERN_TYPE_RADIAL:
|
||||
*pattern = malloc (sizeof (cairo_radial_pattern_t));
|
||||
pattern = malloc (sizeof (cairo_radial_pattern_t));
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED;
|
||||
return _cairo_error (CAIRO_STATUS_PATTERN_TYPE_MISMATCH);
|
||||
}
|
||||
if (unlikely (*pattern == NULL))
|
||||
if (unlikely (pattern == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _cairo_pattern_init_copy (*pattern, other);
|
||||
status = _cairo_pattern_init_copy (pattern, other);
|
||||
if (unlikely (status)) {
|
||||
free (*pattern);
|
||||
free (pattern);
|
||||
return status;
|
||||
}
|
||||
|
||||
CAIRO_REFERENCE_COUNT_INIT (&(*pattern)->ref_count, 1);
|
||||
|
||||
CAIRO_REFERENCE_COUNT_INIT (&pattern->ref_count, 1);
|
||||
*pattern_out = pattern;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -837,6 +844,9 @@ _cairo_pattern_gradient_grow (cairo_gradient_pattern_t *pattern)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
assert (pattern->n_stops <= pattern->stops_size);
|
||||
|
||||
if (pattern->stops == pattern->stops_embedded) {
|
||||
|
@ -1253,6 +1263,9 @@ _cairo_pattern_acquire_surface_for_gradient (const cairo_gradient_pattern_t *pat
|
|||
int clone_offset_x, clone_offset_y;
|
||||
cairo_matrix_t matrix = pattern->base.matrix;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (pattern->n_stops > ARRAY_LENGTH(pixman_stops_static)) {
|
||||
pixman_stops = _cairo_malloc_ab (pattern->n_stops,
|
||||
sizeof(pixman_gradient_stop_t));
|
||||
|
|
|
@ -1015,18 +1015,21 @@ _cairo_pdf_surface_open_stream (cairo_pdf_surface_t *surface,
|
|||
static cairo_status_t
|
||||
_cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
cairo_status_t status;
|
||||
long length;
|
||||
|
||||
if (! surface->pdf_stream.active)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = _cairo_pdf_operators_flush (&surface->pdf_operators);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (surface->pdf_stream.compressed) {
|
||||
status = _cairo_output_stream_destroy (surface->output);
|
||||
cairo_status_t status2;
|
||||
|
||||
status2 = _cairo_output_stream_destroy (surface->output);
|
||||
if (likely (status == CAIRO_STATUS_SUCCESS))
|
||||
status = status2;
|
||||
|
||||
surface->output = surface->pdf_stream.old_output;
|
||||
_cairo_pdf_operators_set_stream (&surface->pdf_operators, surface->output);
|
||||
surface->pdf_stream.old_output = NULL;
|
||||
|
@ -1051,7 +1054,7 @@ _cairo_pdf_surface_close_stream (cairo_pdf_surface_t *surface)
|
|||
|
||||
surface->pdf_stream.active = FALSE;
|
||||
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
if (likely (status == CAIRO_STATUS_SUCCESS))
|
||||
status = _cairo_output_stream_get_status (surface->output);
|
||||
|
||||
return status;
|
||||
|
@ -1324,10 +1327,12 @@ _cairo_pdf_surface_finish (void *abstract_surface)
|
|||
"%%%%EOF\n",
|
||||
offset);
|
||||
|
||||
status2 = _cairo_pdf_operators_fini (&surface->pdf_operators);
|
||||
/* pdf_operators has already been flushed when the last stream was
|
||||
* closed so we should never be writing anything here. */
|
||||
assert(status2 == CAIRO_STATUS_SUCCESS);
|
||||
* closed so we should never be writing anything here - however,
|
||||
* the stream may itself be in an error state. */
|
||||
status2 = _cairo_pdf_operators_fini (&surface->pdf_operators);
|
||||
if (status == CAIRO_STATUS_SUCCESS)
|
||||
status = status2;
|
||||
|
||||
/* close any active streams still open due to fatal errors */
|
||||
status2 = _cairo_pdf_surface_close_stream (surface);
|
||||
|
@ -1723,6 +1728,8 @@ _cairo_pdf_surface_emit_jpeg_image (cairo_pdf_surface_t *surface,
|
|||
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
|
||||
&mime_data, &mime_data_length);
|
||||
if (unlikely (source->status))
|
||||
return source->status;
|
||||
if (mime_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
@ -1790,7 +1797,7 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
|
|||
|
||||
status = _cairo_surface_acquire_source_image (pattern->surface, &image, &image_extra);
|
||||
if (unlikely (status))
|
||||
goto BAIL;
|
||||
return status;
|
||||
|
||||
pad_image = &image->base;
|
||||
if (cairo_pattern_get_extend (&pattern->base) == CAIRO_EXTEND_PAD) {
|
||||
|
@ -1840,10 +1847,10 @@ _cairo_pdf_surface_emit_image_surface (cairo_pdf_surface_t *surface,
|
|||
*origin_x = x;
|
||||
*origin_y = y;
|
||||
|
||||
BAIL:
|
||||
if (pad_image != &image->base)
|
||||
cairo_surface_destroy (pad_image);
|
||||
|
||||
BAIL:
|
||||
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
|
||||
|
||||
return status;
|
||||
|
@ -3927,6 +3934,11 @@ _cairo_pdf_surface_analyze_user_font_subset (cairo_scaled_font_subset_t *font_su
|
|||
null_stream,
|
||||
_cairo_pdf_emit_imagemask,
|
||||
surface->font_subsets);
|
||||
if (unlikely (type3_surface->status)) {
|
||||
status2 = _cairo_output_stream_destroy (null_stream);
|
||||
return type3_surface->status;
|
||||
}
|
||||
|
||||
_cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface,
|
||||
_cairo_pdf_surface_add_font,
|
||||
surface);
|
||||
|
@ -3983,6 +3995,12 @@ _cairo_pdf_surface_emit_type3_font_subset (cairo_pdf_surface_t *surface,
|
|||
NULL,
|
||||
_cairo_pdf_emit_imagemask,
|
||||
surface->font_subsets);
|
||||
if (unlikely (type3_surface->status)) {
|
||||
free (glyphs);
|
||||
free (widths);
|
||||
return type3_surface->status;
|
||||
}
|
||||
|
||||
_cairo_type3_glyph_surface_set_font_subsets_callback (type3_surface,
|
||||
_cairo_pdf_surface_add_font,
|
||||
surface);
|
||||
|
|
|
@ -55,6 +55,9 @@ _cairo_pen_init (cairo_pen_t *pen,
|
|||
int i;
|
||||
int reflect;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
pen->radius = radius;
|
||||
pen->tolerance = tolerance;
|
||||
|
||||
|
@ -109,6 +112,9 @@ _cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other)
|
|||
{
|
||||
*pen = *other;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
pen->vertices = pen->vertices_embedded;
|
||||
if (pen->num_vertices) {
|
||||
if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
|
||||
|
@ -132,6 +138,9 @@ _cairo_pen_add_points (cairo_pen_t *pen, cairo_point_t *point, int num_points)
|
|||
int num_vertices;
|
||||
int i;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
num_vertices = pen->num_vertices + num_points;
|
||||
if (num_vertices > ARRAY_LENGTH (pen->vertices_embedded) ||
|
||||
pen->vertices != pen->vertices_embedded)
|
||||
|
|
|
@ -64,6 +64,11 @@ _cairo_polygon_grow (cairo_polygon_t *polygon)
|
|||
int old_size = polygon->edges_size;
|
||||
int new_size = 4 * old_size;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ()) {
|
||||
polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (polygon->edges == polygon->edges_embedded) {
|
||||
new_edges = _cairo_malloc_ab (new_size, sizeof (cairo_edge_t));
|
||||
if (new_edges != NULL)
|
||||
|
|
|
@ -2138,6 +2138,8 @@ _cairo_ps_surface_emit_jpeg_image (cairo_ps_surface_t *surface,
|
|||
|
||||
cairo_surface_get_mime_data (source, CAIRO_MIME_TYPE_JPEG,
|
||||
&mime_data, &mime_data_length);
|
||||
if (unlikely (source->status))
|
||||
return source->status;
|
||||
if (mime_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
@ -3315,6 +3317,9 @@ _cairo_ps_surface_stroke (void *abstract_surface,
|
|||
if (status == CAIRO_INT_STATUS_NOTHING_TO_DO)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
return _cairo_pdf_operators_stroke (&surface->pdf_operators,
|
||||
path,
|
||||
style,
|
||||
|
|
|
@ -33,55 +33,64 @@
|
|||
* Contributor(s):
|
||||
* Owen Taylor <otaylor@redhat.com>
|
||||
* Vladimir Vukicevic <vladimir@pobox.com>
|
||||
* Søren Sandmann <sandmann@daimi.au.dk>
|
||||
*/
|
||||
|
||||
#include "cairoint.h"
|
||||
|
||||
static const cairo_region_t _cairo_region_nil = {
|
||||
CAIRO_STATUS_NO_MEMORY, /* status */
|
||||
};
|
||||
|
||||
/**
|
||||
* _cairo_region_set_error:
|
||||
* @region: a region
|
||||
* @status: a status value indicating an error
|
||||
*
|
||||
* Atomically sets region->status to @status and calls _cairo_error;
|
||||
* Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal
|
||||
* status values.
|
||||
*
|
||||
* All assignments of an error status to region->status should happen
|
||||
* through _cairo_region_set_error(). Note that due to the nature of
|
||||
* the atomic operation, it is not safe to call this function on the
|
||||
* nil objects.
|
||||
*
|
||||
* The purpose of this function is to allow the user to set a
|
||||
* breakpoint in _cairo_error() to generate a stack trace for when the
|
||||
* user causes cairo to detect an error.
|
||||
*
|
||||
* Return value: the error status.
|
||||
**/
|
||||
static cairo_status_t
|
||||
_cairo_region_set_error (cairo_region_t *region,
|
||||
cairo_status_t status)
|
||||
{
|
||||
if (! _cairo_status_is_error (status))
|
||||
return status;
|
||||
|
||||
/* Don't overwrite an existing error. This preserves the first
|
||||
* error, which is the most significant. */
|
||||
_cairo_status_set_error (®ion->status, status);
|
||||
|
||||
return _cairo_error (status);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_region_init (cairo_region_t *region)
|
||||
{
|
||||
region->status = CAIRO_STATUS_SUCCESS;
|
||||
pixman_region32_init (®ion->rgn);
|
||||
}
|
||||
|
||||
void
|
||||
_cairo_region_init_rect (cairo_region_t *region,
|
||||
cairo_rectangle_int_t *rect)
|
||||
_cairo_region_init_rectangle (cairo_region_t *region,
|
||||
const cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
region->status = CAIRO_STATUS_SUCCESS;
|
||||
pixman_region32_init_rect (®ion->rgn,
|
||||
rect->x, rect->y,
|
||||
rect->width, rect->height);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_init_boxes (cairo_region_t *region,
|
||||
cairo_box_int_t *boxes,
|
||||
int count)
|
||||
{
|
||||
pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
|
||||
pixman_box32_t *pboxes = stack_pboxes;
|
||||
cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
int i;
|
||||
|
||||
if (count > ARRAY_LENGTH (stack_pboxes)) {
|
||||
pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
|
||||
if (unlikely (pboxes == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
pboxes[i].x1 = boxes[i].p1.x;
|
||||
pboxes[i].y1 = boxes[i].p1.y;
|
||||
pboxes[i].x2 = boxes[i].p2.x;
|
||||
pboxes[i].y2 = boxes[i].p2.y;
|
||||
}
|
||||
|
||||
if (! pixman_region32_init_rects (®ion->rgn, pboxes, count))
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (pboxes != stack_pboxes)
|
||||
free (pboxes);
|
||||
|
||||
return status;
|
||||
rectangle->x, rectangle->y,
|
||||
rectangle->width, rectangle->height);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -90,108 +99,512 @@ _cairo_region_fini (cairo_region_t *region)
|
|||
pixman_region32_fini (®ion->rgn);
|
||||
}
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_copy (cairo_region_t *dst, cairo_region_t *src)
|
||||
/**
|
||||
* cairo_region_create:
|
||||
*
|
||||
* Allocates a new empty region object.
|
||||
*
|
||||
* Return value: A newly allocated #cairo_region_t. Free with
|
||||
* cairo_region_destroy(). This function always returns a
|
||||
* valid pointer; if memory cannot be allocated, then a special
|
||||
* error object is returned where all operations on the object do nothing.
|
||||
* You can check for this with cairo_region_status().
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_region_t *
|
||||
cairo_region_create (void)
|
||||
{
|
||||
if (!pixman_region32_copy (&dst->rgn, &src->rgn))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
cairo_region_t *region;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
region = _cairo_malloc (sizeof (cairo_region_t));
|
||||
if (region == NULL)
|
||||
return (cairo_region_t *) &_cairo_region_nil;
|
||||
|
||||
region->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
pixman_region32_init (®ion->rgn);
|
||||
|
||||
return region;
|
||||
}
|
||||
slim_hidden_def (cairo_region_create);
|
||||
|
||||
int
|
||||
_cairo_region_num_boxes (cairo_region_t *region)
|
||||
/**
|
||||
* cairo_region_create_rectangle:
|
||||
* @rectangle: a #cairo_rectangle_int_t
|
||||
*
|
||||
* Allocates a new region object containing @rectangle.
|
||||
*
|
||||
* Return value: A newly allocated #cairo_region_t. Free with
|
||||
* cairo_region_destroy(). This function always returns a
|
||||
* valid pointer; if memory cannot be allocated, then a special
|
||||
* error object is returned where all operations on the object do nothing.
|
||||
* You can check for this with cairo_region_status().
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_region_t *
|
||||
cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
cairo_region_t *region;
|
||||
|
||||
region = _cairo_malloc (sizeof (cairo_region_t));
|
||||
if (region == NULL)
|
||||
return (cairo_region_t *) &_cairo_region_nil;
|
||||
|
||||
region->status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
pixman_region32_init_rect (®ion->rgn,
|
||||
rectangle->x, rectangle->y,
|
||||
rectangle->width, rectangle->height);
|
||||
|
||||
return region;
|
||||
}
|
||||
slim_hidden_def (cairo_region_create_rectangle);
|
||||
|
||||
/**
|
||||
* cairo_region_copy:
|
||||
* @original: a #cairo_region_t
|
||||
*
|
||||
* Allocates a new region object copying the area from @original.
|
||||
*
|
||||
* Return value: A newly allocated #cairo_region_t. Free with
|
||||
* cairo_region_destroy(). This function always returns a
|
||||
* valid pointer; if memory cannot be allocated, then a special
|
||||
* error object is returned where all operations on the object do nothing.
|
||||
* You can check for this with cairo_region_status().
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_region_t *
|
||||
cairo_region_copy (cairo_region_t *original)
|
||||
{
|
||||
cairo_region_t *copy;
|
||||
|
||||
if (original->status)
|
||||
return (cairo_region_t *) &_cairo_region_nil;
|
||||
|
||||
copy = cairo_region_create ();
|
||||
if (copy->status)
|
||||
return copy;
|
||||
|
||||
if (! pixman_region32_copy (©->rgn, &original->rgn)) {
|
||||
cairo_region_destroy (copy);
|
||||
return (cairo_region_t *) &_cairo_region_nil;
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
slim_hidden_def (cairo_region_copy);
|
||||
|
||||
/**
|
||||
* cairo_region_destroy:
|
||||
* @region: a #cairo_region_t
|
||||
*
|
||||
* Destroys a #cairo_region_t object created with
|
||||
* cairo_region_create(), cairo_region_copy(), or
|
||||
* or cairo_region_create_rectangle().
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
cairo_region_destroy (cairo_region_t *region)
|
||||
{
|
||||
if (region == (cairo_region_t *) &_cairo_region_nil)
|
||||
return;
|
||||
|
||||
pixman_region32_fini (®ion->rgn);
|
||||
free (region);
|
||||
}
|
||||
slim_hidden_def (cairo_region_destroy);
|
||||
|
||||
/**
|
||||
* cairo_region_num_rectangles:
|
||||
* @region: a #cairo_region_t
|
||||
*
|
||||
* Returns the number of rectangles contained in @region.
|
||||
*
|
||||
* Return value: The number of rectangles contained in @region.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
int
|
||||
cairo_region_num_rectangles (cairo_region_t *region)
|
||||
{
|
||||
if (region->status)
|
||||
return 0;
|
||||
|
||||
return pixman_region32_n_rects (®ion->rgn);
|
||||
}
|
||||
slim_hidden_def (cairo_region_num_rectangles);
|
||||
|
||||
cairo_private void
|
||||
_cairo_region_get_box (cairo_region_t *region,
|
||||
int nth_box,
|
||||
cairo_box_int_t *box)
|
||||
/**
|
||||
* cairo_region_get_rectangle:
|
||||
* @region: a #cairo_region_t
|
||||
* @nth: a number indicating which rectangle should be returned
|
||||
* @rectangle: return location for a #cairo_rectangle_int_t
|
||||
*
|
||||
* Stores the @nth rectangle from the region in @rectangle.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
cairo_region_get_rectangle (cairo_region_t *region,
|
||||
int nth,
|
||||
cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
pixman_box32_t *pbox;
|
||||
|
||||
pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth_box;
|
||||
if (region->status) {
|
||||
rectangle->x = rectangle->y = 0;
|
||||
rectangle->width = rectangle->height = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
box->p1.x = pbox->x1;
|
||||
box->p1.y = pbox->y1;
|
||||
box->p2.x = pbox->x2;
|
||||
box->p2.y = pbox->y2;
|
||||
pbox = pixman_region32_rectangles (®ion->rgn, NULL) + nth;
|
||||
|
||||
rectangle->x = pbox->x1;
|
||||
rectangle->y = pbox->y1;
|
||||
rectangle->width = pbox->x2 - pbox->x1;
|
||||
rectangle->height = pbox->y2 - pbox->y1;
|
||||
}
|
||||
slim_hidden_def (cairo_region_get_rectangle);
|
||||
|
||||
/**
|
||||
* _cairo_region_get_extents:
|
||||
* cairo_region_get_extents:
|
||||
* @region: a #cairo_region_t
|
||||
* @rect: rectangle into which to store the extents
|
||||
* @rectangle: rectangle into which to store the extents
|
||||
*
|
||||
* Gets the bounding box of a region as a #cairo_rectangle_int_t
|
||||
* Gets the bounding rectangle of @region as a #cairo_rectangle_int_t
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
_cairo_region_get_extents (cairo_region_t *region, cairo_rectangle_int_t *extents)
|
||||
cairo_region_get_extents (cairo_region_t *region,
|
||||
cairo_rectangle_int_t *extents)
|
||||
{
|
||||
pixman_box32_t *pextents = pixman_region32_extents (®ion->rgn);
|
||||
pixman_box32_t *pextents;
|
||||
|
||||
if (region->status) {
|
||||
extents->x = extents->y = 0;
|
||||
extents->width = extents->height = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
pextents = pixman_region32_extents (®ion->rgn);
|
||||
|
||||
extents->x = pextents->x1;
|
||||
extents->y = pextents->y1;
|
||||
extents->width = pextents->x2 - pextents->x1;
|
||||
extents->height = pextents->y2 - pextents->y1;
|
||||
}
|
||||
slim_hidden_def (cairo_region_get_extents);
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_subtract (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
|
||||
/**
|
||||
* cairo_region_status:
|
||||
* @region: a #cairo_region_t
|
||||
*
|
||||
* Checks whether an error has previous occured for this
|
||||
* region object.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_region_status (cairo_region_t *region)
|
||||
{
|
||||
if (!pixman_region32_subtract (&dst->rgn, &a->rgn, &b->rgn))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return region->status;
|
||||
}
|
||||
slim_hidden_def (cairo_region_status);
|
||||
|
||||
/**
|
||||
* cairo_region_subtract:
|
||||
* @dst: a #cairo_region_t
|
||||
* @other: another #cairo_region_t
|
||||
*
|
||||
* Subtracts @other from @dst and places the result in @dst
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other)
|
||||
{
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
if (other->status)
|
||||
return _cairo_region_set_error (dst, other->status);
|
||||
|
||||
if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, &other->rgn))
|
||||
return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def (cairo_region_subtract);
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_intersect (cairo_region_t *dst, cairo_region_t *a, cairo_region_t *b)
|
||||
/**
|
||||
* cairo_region_subtract_rectangle:
|
||||
* @dst: a #cairo_region_t
|
||||
* @rectangle: a #cairo_rectangle_int_t
|
||||
*
|
||||
* Subtracts @rectangle from @dst and places the result in @dst
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_region_subtract_rectangle (cairo_region_t *dst,
|
||||
const cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
if (!pixman_region32_intersect (&dst->rgn, &a->rgn, &b->rgn))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
pixman_region32_t region;
|
||||
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
pixman_region32_init_rect (®ion,
|
||||
rectangle->x, rectangle->y,
|
||||
rectangle->width, rectangle->height);
|
||||
|
||||
if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion))
|
||||
status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
pixman_region32_fini (®ion);
|
||||
|
||||
return status;
|
||||
}
|
||||
slim_hidden_def (cairo_region_subtract_rectangle);
|
||||
|
||||
/**
|
||||
* cairo_region_intersect:
|
||||
* @dst: a #cairo_region_t
|
||||
* @other: another #cairo_region_t
|
||||
*
|
||||
* Computes the intersection of @dst with @other and places the result in @dst
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other)
|
||||
{
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
if (other->status)
|
||||
return _cairo_region_set_error (dst, other->status);
|
||||
|
||||
if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, &other->rgn))
|
||||
return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def (cairo_region_intersect);
|
||||
|
||||
cairo_int_status_t
|
||||
_cairo_region_union_rect (cairo_region_t *dst,
|
||||
cairo_region_t *src,
|
||||
cairo_rectangle_int_t *rect)
|
||||
/**
|
||||
* cairo_region_intersect_rectangle:
|
||||
* @dst: a #cairo_region_t
|
||||
* @rectangle: a #cairo_rectangle_int_t
|
||||
*
|
||||
* Computes the intersection of @dst with @rectangle and places the
|
||||
* result in @dst
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_region_intersect_rectangle (cairo_region_t *dst,
|
||||
const cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
if (!pixman_region32_union_rect (&dst->rgn, &src->rgn,
|
||||
rect->x, rect->y,
|
||||
rect->width, rect->height))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
pixman_region32_t region;
|
||||
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
pixman_region32_init_rect (®ion,
|
||||
rectangle->x, rectangle->y,
|
||||
rectangle->width, rectangle->height);
|
||||
|
||||
if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, ®ion))
|
||||
status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
pixman_region32_fini (®ion);
|
||||
|
||||
return status;
|
||||
}
|
||||
slim_hidden_def (cairo_region_intersect_rectangle);
|
||||
|
||||
/**
|
||||
* cairo_region_union:
|
||||
* @dst: a #cairo_region_t
|
||||
* @other: another #cairo_region_t
|
||||
*
|
||||
* Computes the union of @dst with @other and places the result in @dst
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_region_union (cairo_region_t *dst,
|
||||
cairo_region_t *other)
|
||||
{
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
if (other->status)
|
||||
return _cairo_region_set_error (dst, other->status);
|
||||
|
||||
if (! pixman_region32_union (&dst->rgn, &dst->rgn, &other->rgn))
|
||||
return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
slim_hidden_def (cairo_region_union);
|
||||
|
||||
/**
|
||||
* cairo_region_union_rectangle:
|
||||
* @dst: a #cairo_region_t
|
||||
* @rectangle: a #cairo_rectangle_int_t
|
||||
*
|
||||
* Computes the union of @dst with @rectangle and places the result in @dst.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_status_t
|
||||
cairo_region_union_rectangle (cairo_region_t *dst,
|
||||
const cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
pixman_region32_t region;
|
||||
|
||||
if (dst->status)
|
||||
return dst->status;
|
||||
|
||||
pixman_region32_init_rect (®ion,
|
||||
rectangle->x, rectangle->y,
|
||||
rectangle->width, rectangle->height);
|
||||
|
||||
if (! pixman_region32_union (&dst->rgn, &dst->rgn, ®ion))
|
||||
status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
pixman_region32_fini (®ion);
|
||||
|
||||
return status;
|
||||
}
|
||||
slim_hidden_def (cairo_region_union_rectangle);
|
||||
|
||||
/**
|
||||
* cairo_region_is_empty:
|
||||
* @region: a #cairo_region_t
|
||||
*
|
||||
* Checks whether @region is empty.
|
||||
*
|
||||
* Return value: %TRUE if @region is empty, %FALSE if it isn't.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_bool_t
|
||||
_cairo_region_not_empty (cairo_region_t *region)
|
||||
cairo_region_is_empty (cairo_region_t *region)
|
||||
{
|
||||
return (cairo_bool_t) pixman_region32_not_empty (®ion->rgn);
|
||||
}
|
||||
if (region->status)
|
||||
return TRUE;
|
||||
|
||||
return ! pixman_region32_not_empty (®ion->rgn);
|
||||
}
|
||||
slim_hidden_def (cairo_region_is_empty);
|
||||
|
||||
/**
|
||||
* cairo_region_translate:
|
||||
* @region: a #cairo_region_t
|
||||
* @dx: Amount to translate in the x direction
|
||||
* @dy: Amount to translate in the y direction
|
||||
*
|
||||
* Translates @region by (@dx, @dy).
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
void
|
||||
_cairo_region_translate (cairo_region_t *region,
|
||||
int x, int y)
|
||||
cairo_region_translate (cairo_region_t *region,
|
||||
int dx, int dy)
|
||||
{
|
||||
pixman_region32_translate (®ion->rgn, x, y);
|
||||
}
|
||||
if (region->status)
|
||||
return;
|
||||
|
||||
pixman_region_overlap_t
|
||||
_cairo_region_contains_rectangle (cairo_region_t *region,
|
||||
const cairo_rectangle_int_t *rect)
|
||||
pixman_region32_translate (®ion->rgn, dx, dy);
|
||||
}
|
||||
slim_hidden_def (cairo_region_translate);
|
||||
|
||||
/**
|
||||
* cairo_region_contains_rectangle:
|
||||
* @region: a #cairo_region_t
|
||||
* @rectangle: a #cairo_rectangle_int_t
|
||||
*
|
||||
* Checks whether @rectangle is inside, outside or partially contained
|
||||
* in @region
|
||||
*
|
||||
* Return value:
|
||||
* %CAIRO_REGION_OVERLAP_IN if @rectangle is entirely inside @region,
|
||||
* %CAIRO_REGION_OVERLAP_OUT if @rectangle is entirely outside @region, or
|
||||
* %CAIRO_REGION_OVERLAP_PART if @rectangle is partially inside and partially outside @region.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_region_overlap_t
|
||||
cairo_region_contains_rectangle (cairo_region_t *region,
|
||||
const cairo_rectangle_int_t *rectangle)
|
||||
{
|
||||
pixman_box32_t pbox;
|
||||
pixman_region_overlap_t poverlap;
|
||||
|
||||
pbox.x1 = rect->x;
|
||||
pbox.y1 = rect->y;
|
||||
pbox.x2 = rect->x + rect->width;
|
||||
pbox.y2 = rect->y + rect->height;
|
||||
if (region->status)
|
||||
return CAIRO_REGION_OVERLAP_OUT;
|
||||
|
||||
return pixman_region32_contains_rectangle (®ion->rgn, &pbox);
|
||||
pbox.x1 = rectangle->x;
|
||||
pbox.y1 = rectangle->y;
|
||||
pbox.x2 = rectangle->x + rectangle->width;
|
||||
pbox.y2 = rectangle->y + rectangle->height;
|
||||
|
||||
poverlap = pixman_region32_contains_rectangle (®ion->rgn, &pbox);
|
||||
switch (poverlap) {
|
||||
default:
|
||||
case PIXMAN_REGION_OUT: return CAIRO_REGION_OVERLAP_OUT;
|
||||
case PIXMAN_REGION_IN: return CAIRO_REGION_OVERLAP_IN;
|
||||
case PIXMAN_REGION_PART: return CAIRO_REGION_OVERLAP_PART;
|
||||
}
|
||||
}
|
||||
slim_hidden_def (cairo_region_contains_rectangle);
|
||||
|
||||
/**
|
||||
* cairo_region_contains_point:
|
||||
* @region: a #cairo_region_t
|
||||
* @x: the x coordinate of a point
|
||||
* @y: the y coordinate of a point
|
||||
*
|
||||
* Checks whether (@x, @y) is contained in @region.
|
||||
*
|
||||
* Return value: %TRUE if (@x, @y) is contained in @region, %FALSE if it is not.
|
||||
*
|
||||
* Since: 1.10
|
||||
**/
|
||||
cairo_bool_t
|
||||
cairo_region_contains_point (cairo_region_t *region,
|
||||
int x, int y)
|
||||
{
|
||||
pixman_box32_t box;
|
||||
|
||||
if (region->status)
|
||||
return FALSE;
|
||||
|
||||
return pixman_region32_contains_point (®ion->rgn, x, y, &box);
|
||||
}
|
||||
slim_hidden_def (cairo_region_contains_point);
|
||||
|
|
|
@ -372,13 +372,16 @@ _cairo_sub_font_glyph_lookup_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
static cairo_status_t
|
||||
_cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
|
||||
const char *utf8,
|
||||
int utf8_len)
|
||||
int utf8_len,
|
||||
cairo_bool_t *is_mapped)
|
||||
{
|
||||
*is_mapped = FALSE;
|
||||
|
||||
if (utf8_len < 0)
|
||||
return FALSE;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (utf8 != NULL && utf8_len != 0 && utf8[utf8_len - 1] == '\0')
|
||||
utf8_len--;
|
||||
|
@ -389,28 +392,25 @@ _cairo_sub_font_glyph_map_to_unicode (cairo_sub_font_glyph_t *sub_font_glyph,
|
|||
memcmp (utf8, sub_font_glyph->utf8, utf8_len) == 0)
|
||||
{
|
||||
/* Requested utf8 mapping matches the existing mapping */
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Requested utf8 mapping does not match the existing mapping */
|
||||
return FALSE;
|
||||
*is_mapped = TRUE;
|
||||
}
|
||||
} else {
|
||||
/* No existing mapping. Use the requested mapping */
|
||||
sub_font_glyph->utf8 = malloc (utf8_len + 1);
|
||||
if (unlikely (sub_font_glyph->utf8 == NULL))
|
||||
return CAIRO_STATUS_NO_MEMORY;
|
||||
|
||||
memcpy (sub_font_glyph->utf8, utf8, utf8_len);
|
||||
sub_font_glyph->utf8[utf8_len] = 0;
|
||||
sub_font_glyph->utf8_len = utf8_len;
|
||||
return TRUE;
|
||||
*is_mapped = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* No mapping was requested. */
|
||||
return FALSE;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
static cairo_int_status_t
|
||||
_cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
|
||||
unsigned long scaled_font_glyph_index,
|
||||
const char *utf8,
|
||||
|
@ -418,6 +418,7 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
|
|||
cairo_scaled_font_subsets_glyph_t *subset_glyph)
|
||||
{
|
||||
cairo_sub_font_glyph_t key, *sub_font_glyph;
|
||||
cairo_int_status_t status;
|
||||
|
||||
_cairo_sub_font_glyph_init_key (&key, scaled_font_glyph_index);
|
||||
sub_font_glyph = _cairo_hash_table_lookup (sub_font->sub_font_glyphs,
|
||||
|
@ -430,13 +431,15 @@ _cairo_sub_font_lookup_glyph (cairo_sub_font_t *sub_font,
|
|||
subset_glyph->is_composite = sub_font->is_composite;
|
||||
subset_glyph->x_advance = sub_font_glyph->x_advance;
|
||||
subset_glyph->y_advance = sub_font_glyph->y_advance;
|
||||
subset_glyph->utf8_is_mapped = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, utf8, utf8_len);
|
||||
status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph,
|
||||
utf8, utf8_len,
|
||||
&subset_glyph->utf8_is_mapped);
|
||||
subset_glyph->unicode = sub_font_glyph->unicode;
|
||||
|
||||
return TRUE;
|
||||
return status;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
|
@ -524,10 +527,12 @@ _cairo_sub_font_map_glyph (cairo_sub_font_t *sub_font,
|
|||
subset_glyph->is_composite = sub_font->is_composite;
|
||||
subset_glyph->x_advance = sub_font_glyph->x_advance;
|
||||
subset_glyph->y_advance = sub_font_glyph->y_advance;
|
||||
subset_glyph->utf8_is_mapped = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph, utf8, utf8_len);
|
||||
status = _cairo_sub_font_glyph_map_to_unicode (sub_font_glyph,
|
||||
utf8, utf8_len,
|
||||
&subset_glyph->utf8_is_mapped);
|
||||
subset_glyph->unicode = sub_font_glyph->unicode;
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -539,6 +544,10 @@ _cairo_sub_font_collect (void *entry, void *closure)
|
|||
int i;
|
||||
unsigned int j;
|
||||
|
||||
if (collection->status)
|
||||
return;
|
||||
|
||||
collection->status = sub_font->scaled_font->status;
|
||||
if (collection->status)
|
||||
return;
|
||||
|
||||
|
@ -682,11 +691,12 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
|||
sub_font = _cairo_hash_table_lookup (subsets->unscaled_sub_fonts,
|
||||
&key.base);
|
||||
if (sub_font != NULL) {
|
||||
if (_cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
utf8, utf8_len,
|
||||
subset_glyph))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
status = _cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
utf8, utf8_len,
|
||||
subset_glyph);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -696,11 +706,12 @@ _cairo_scaled_font_subsets_map_glyph (cairo_scaled_font_subsets_t *subsets,
|
|||
sub_font = _cairo_hash_table_lookup (subsets->scaled_sub_fonts,
|
||||
&key.base);
|
||||
if (sub_font != NULL) {
|
||||
if (_cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
utf8, utf8_len,
|
||||
subset_glyph))
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
status = _cairo_sub_font_lookup_glyph (sub_font,
|
||||
scaled_font_glyph_index,
|
||||
utf8, utf8_len,
|
||||
subset_glyph);
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Glyph not found. Determine whether the glyph is outline or
|
||||
|
@ -1021,7 +1032,7 @@ _cairo_scaled_font_subset_create_glyph_names (cairo_scaled_font_subset_t *subset
|
|||
if (utf8 && *utf8) {
|
||||
status = _cairo_utf8_to_utf16 (utf8, -1, &utf16, &utf16_len);
|
||||
if (unlikely (status))
|
||||
return status; /* FIXME */
|
||||
goto CLEANUP_HASH;
|
||||
}
|
||||
|
||||
if (utf16_len == 1) {
|
||||
|
|
|
@ -2558,6 +2558,9 @@ _cairo_scaled_glyph_lookup (cairo_scaled_font_t *scaled_font,
|
|||
if (unlikely (scaled_font->status))
|
||||
return scaled_font->status;
|
||||
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
/*
|
||||
* Check cache for glyph
|
||||
*/
|
||||
|
|
|
@ -255,6 +255,7 @@ _cairo_scan_converter_create_in_error (cairo_status_t status)
|
|||
}
|
||||
switch (status) {
|
||||
case CAIRO_STATUS_SUCCESS:
|
||||
case CAIRO_STATUS_LAST_STATUS:
|
||||
ASSERT_NOT_REACHED;
|
||||
break;
|
||||
case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL;
|
||||
|
@ -359,6 +360,7 @@ _cairo_span_renderer_create_in_error (cairo_status_t status)
|
|||
}
|
||||
switch (status) {
|
||||
case CAIRO_STATUS_SUCCESS:
|
||||
case CAIRO_STATUS_LAST_STATUS:
|
||||
ASSERT_NOT_REACHED;
|
||||
break;
|
||||
case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL;
|
||||
|
|
|
@ -289,7 +289,7 @@ _cairo_spline_bound (cairo_spline_add_point_func_t add_point_func,
|
|||
* 0 < (-b±√delta)/a < 1 \
|
||||
*/ \
|
||||
if (_2ab >= 0) \
|
||||
feasible = delta > b2 && delta < a*a + b2 - _2ab; \
|
||||
feasible = delta > b2 && delta < a*a + b2 + _2ab; \
|
||||
else if (-b / a >= 1) \
|
||||
feasible = delta < b2 && delta > a*a + b2 + _2ab; \
|
||||
else \
|
||||
|
|
|
@ -52,6 +52,9 @@ cairo_status_t
|
|||
_cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
|
||||
cairo_stroke_style_t *other)
|
||||
{
|
||||
if (CAIRO_INJECT_FAULT ())
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
style->line_width = other->line_width;
|
||||
style->line_cap = other->line_cap;
|
||||
style->line_join = other->line_join;
|
||||
|
|
|
@ -417,7 +417,7 @@ _composite_trap_region (cairo_clip_t *clip,
|
|||
cairo_status_t status;
|
||||
cairo_solid_pattern_t solid_pattern;
|
||||
cairo_surface_pattern_t mask;
|
||||
int num_rects = _cairo_region_num_boxes (trap_region);
|
||||
int num_rects = cairo_region_num_rectangles (trap_region);
|
||||
unsigned int clip_serial;
|
||||
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
|
||||
|
||||
|
@ -520,10 +520,8 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
|
|||
cairo_antialias_t antialias)
|
||||
{
|
||||
cairo_status_t status;
|
||||
cairo_region_t trap_region;
|
||||
cairo_region_t clear_region;
|
||||
cairo_bool_t has_trap_region = FALSE;
|
||||
cairo_bool_t has_clear_region = FALSE;
|
||||
cairo_region_t *trap_region = NULL;
|
||||
cairo_region_t *clear_region = NULL;
|
||||
cairo_rectangle_int_t extents;
|
||||
cairo_composite_traps_info_t traps_info;
|
||||
|
||||
|
@ -535,23 +533,18 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
|
|||
return status;
|
||||
|
||||
status = _cairo_traps_extract_region (traps, &trap_region);
|
||||
if (CAIRO_INT_STATUS_UNSUPPORTED == status) {
|
||||
has_trap_region = FALSE;
|
||||
} else if (status) {
|
||||
return status;
|
||||
} else {
|
||||
has_trap_region = TRUE;
|
||||
}
|
||||
if (status && status != CAIRO_INT_STATUS_UNSUPPORTED)
|
||||
return status;
|
||||
|
||||
if (_cairo_operator_bounded_by_mask (op)) {
|
||||
cairo_rectangle_int_t trap_extents;
|
||||
|
||||
if (has_trap_region) {
|
||||
status = _cairo_clip_intersect_to_region (clip, &trap_region);
|
||||
if (trap_region) {
|
||||
status = _cairo_clip_intersect_to_region (clip, trap_region);
|
||||
if (unlikely (status))
|
||||
goto out;
|
||||
|
||||
_cairo_region_get_extents (&trap_region, &trap_extents);
|
||||
cairo_region_get_extents (trap_region, &trap_extents);
|
||||
} else {
|
||||
cairo_box_t trap_box;
|
||||
_cairo_traps_extents (traps, &trap_box);
|
||||
|
@ -569,27 +562,30 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
|
|||
} else {
|
||||
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
|
||||
|
||||
if (has_trap_region && !clip_surface) {
|
||||
if (trap_region && !clip_surface) {
|
||||
/* If we optimize drawing with an unbounded operator to
|
||||
* _cairo_surface_fill_rectangles() or to drawing with a
|
||||
* clip region, then we have an additional region to clear.
|
||||
*/
|
||||
_cairo_region_init_rect (&clear_region, &extents);
|
||||
clear_region = cairo_region_create_rectangle (&extents);
|
||||
|
||||
has_clear_region = TRUE;
|
||||
status = _cairo_clip_intersect_to_region (clip, &clear_region);
|
||||
status = cairo_region_status (clear_region);
|
||||
if (unlikely (status))
|
||||
goto out;
|
||||
|
||||
status = _cairo_clip_intersect_to_region (clip, clear_region);
|
||||
if (unlikely (status))
|
||||
goto out;
|
||||
|
||||
_cairo_region_get_extents (&clear_region, &extents);
|
||||
cairo_region_get_extents (clear_region, &extents);
|
||||
|
||||
status = _cairo_region_subtract (&clear_region, &clear_region, &trap_region);
|
||||
status = cairo_region_subtract (clear_region, trap_region);
|
||||
if (unlikely (status))
|
||||
goto out;
|
||||
|
||||
if (!_cairo_region_not_empty (&clear_region)) {
|
||||
_cairo_region_fini (&clear_region);
|
||||
has_clear_region = FALSE;
|
||||
if (cairo_region_is_empty (clear_region)) {
|
||||
cairo_region_destroy (clear_region);
|
||||
clear_region = NULL;
|
||||
}
|
||||
} else {
|
||||
status = _cairo_clip_intersect_to_rectangle (clip, &extents);
|
||||
|
@ -599,7 +595,7 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
|
|||
if (unlikely (status))
|
||||
goto out;
|
||||
|
||||
if (has_trap_region) {
|
||||
if (trap_region) {
|
||||
cairo_surface_t *clip_surface = clip ? clip->surface : NULL;
|
||||
|
||||
if ((src->type == CAIRO_PATTERN_TYPE_SOLID ||
|
||||
|
@ -613,12 +609,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
|
|||
}
|
||||
|
||||
/* Solid rectangles special case */
|
||||
status = _cairo_surface_fill_region (dst, op, color, &trap_region);
|
||||
status = _cairo_surface_fill_region (dst, op, color, trap_region);
|
||||
|
||||
if (!status && has_clear_region)
|
||||
if (!status && clear_region) {
|
||||
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
|
||||
CAIRO_COLOR_TRANSPARENT,
|
||||
&clear_region);
|
||||
clear_region);
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
@ -641,13 +638,13 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
|
|||
* regions. In that case, we fall through.
|
||||
*/
|
||||
status = _composite_trap_region (clip, src, op, dst,
|
||||
&trap_region, &extents);
|
||||
trap_region, &extents);
|
||||
|
||||
if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||
if (!status && has_clear_region)
|
||||
if (!status && clear_region)
|
||||
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_CLEAR,
|
||||
CAIRO_COLOR_TRANSPARENT,
|
||||
&clear_region);
|
||||
clear_region);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
@ -661,10 +658,10 @@ _clip_and_composite_trapezoids (const cairo_pattern_t *src,
|
|||
&traps_info, dst, &extents);
|
||||
|
||||
out:
|
||||
if (has_trap_region)
|
||||
_cairo_region_fini (&trap_region);
|
||||
if (has_clear_region)
|
||||
_cairo_region_fini (&clear_region);
|
||||
if (trap_region)
|
||||
cairo_region_destroy (trap_region);
|
||||
if (clear_region)
|
||||
cairo_region_destroy (clear_region);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -1637,14 +1637,13 @@ _cairo_surface_fill_rectangle (cairo_surface_t *surface,
|
|||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS or the error that occurred
|
||||
**/
|
||||
COMPILE_TIME_ASSERT (sizeof (cairo_box_int_t) <= sizeof (cairo_rectangle_int_t));
|
||||
cairo_status_t
|
||||
_cairo_surface_fill_region (cairo_surface_t *surface,
|
||||
cairo_operator_t op,
|
||||
const cairo_color_t *color,
|
||||
cairo_region_t *region)
|
||||
{
|
||||
int num_boxes;
|
||||
int num_rects;
|
||||
cairo_rectangle_int_t stack_rects[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)];
|
||||
cairo_rectangle_int_t *rects = stack_rects;
|
||||
cairo_status_t status;
|
||||
|
@ -1655,12 +1654,12 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
|
|||
|
||||
assert (! surface->is_snapshot);
|
||||
|
||||
num_boxes = _cairo_region_num_boxes (region);
|
||||
if (num_boxes == 0)
|
||||
num_rects = cairo_region_num_rectangles (region);
|
||||
if (num_rects == 0)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (num_boxes > ARRAY_LENGTH (stack_rects)) {
|
||||
rects = _cairo_malloc_ab (num_boxes,
|
||||
if (num_rects > ARRAY_LENGTH (stack_rects)) {
|
||||
rects = _cairo_malloc_ab (num_rects,
|
||||
sizeof (cairo_rectangle_int_t));
|
||||
if (rects == NULL) {
|
||||
return _cairo_surface_set_error (surface,
|
||||
|
@ -1668,19 +1667,11 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
cairo_box_int_t box;
|
||||
|
||||
_cairo_region_get_box (region, i, &box);
|
||||
|
||||
rects[i].x = box.p1.x;
|
||||
rects[i].y = box.p1.y;
|
||||
rects[i].width = box.p2.x - rects[i].x;
|
||||
rects[i].height = box.p2.y - rects[i].y;
|
||||
}
|
||||
for (i = 0; i < num_rects; i++)
|
||||
cairo_region_get_rectangle (region, i, &rects[i]);
|
||||
|
||||
status = _cairo_surface_fill_rectangles (surface, op,
|
||||
color, rects, num_boxes);
|
||||
color, rects, num_rects);
|
||||
|
||||
if (rects != stack_rects)
|
||||
free (rects);
|
||||
|
@ -2268,10 +2259,10 @@ _cairo_surface_reset_clip (cairo_surface_t *surface)
|
|||
cairo_status_t
|
||||
_cairo_surface_set_clip_region (cairo_surface_t *surface,
|
||||
cairo_region_t *region,
|
||||
unsigned int serial)
|
||||
unsigned int serial)
|
||||
{
|
||||
cairo_status_t status;
|
||||
|
||||
|
||||
if (surface->status)
|
||||
return surface->status;
|
||||
|
||||
|
@ -2448,7 +2439,7 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
|||
|
||||
if (surface->backend->set_clip_region != NULL)
|
||||
return _cairo_surface_set_clip_region (surface,
|
||||
&clip->region,
|
||||
clip->region,
|
||||
clip->serial);
|
||||
} else {
|
||||
if (clip->path)
|
||||
|
@ -2456,9 +2447,9 @@ _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip)
|
|||
clip->path,
|
||||
clip->serial);
|
||||
|
||||
if (clip->has_region)
|
||||
if (clip->region)
|
||||
return _cairo_surface_set_clip_region (surface,
|
||||
&clip->region,
|
||||
clip->region,
|
||||
clip->serial);
|
||||
}
|
||||
}
|
||||
|
@ -2754,53 +2745,44 @@ _cairo_surface_composite_fixup_unbounded_internal (cairo_surface_t *dst,
|
|||
unsigned int height)
|
||||
{
|
||||
cairo_rectangle_int_t dst_rectangle;
|
||||
cairo_rectangle_int_t drawn_rectangle;
|
||||
cairo_bool_t has_drawn_region = FALSE;
|
||||
cairo_region_t drawn_region;
|
||||
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 not within
|
||||
* the source or the mask.
|
||||
/* The area that was drawn is the area in the destination rectangle but
|
||||
* not within the source or the mask.
|
||||
*/
|
||||
dst_rectangle.x = dst_x;
|
||||
dst_rectangle.y = dst_y;
|
||||
dst_rectangle.width = width;
|
||||
dst_rectangle.height = height;
|
||||
_cairo_region_init_rect (&clear_region, &dst_rectangle);
|
||||
|
||||
drawn_rectangle = 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 (&drawn_rectangle, src_rectangle))
|
||||
if (! _cairo_rectangle_intersect (&dst_rectangle, src_rectangle))
|
||||
goto EMPTY;
|
||||
}
|
||||
|
||||
if (mask_rectangle) {
|
||||
if (! _cairo_rectangle_intersect (&drawn_rectangle, mask_rectangle))
|
||||
if (! _cairo_rectangle_intersect (&dst_rectangle, mask_rectangle))
|
||||
goto EMPTY;
|
||||
}
|
||||
|
||||
/* Now compute the area that is in dst_rectangle but not in drawn_rectangle
|
||||
*/
|
||||
_cairo_region_init_rect (&drawn_region, &drawn_rectangle);
|
||||
has_drawn_region = TRUE;
|
||||
|
||||
status = _cairo_region_subtract (&clear_region,
|
||||
&clear_region,
|
||||
&drawn_region);
|
||||
/* Now compute the area that is in dst but not drawn */
|
||||
status = cairo_region_subtract_rectangle (clear_region, &dst_rectangle);
|
||||
if (unlikely (status))
|
||||
goto CLEANUP_REGIONS;
|
||||
|
||||
EMPTY:
|
||||
status = _cairo_surface_fill_region (dst, CAIRO_OPERATOR_SOURCE,
|
||||
CAIRO_COLOR_TRANSPARENT,
|
||||
&clear_region);
|
||||
clear_region);
|
||||
|
||||
CLEANUP_REGIONS:
|
||||
if (has_drawn_region)
|
||||
_cairo_region_fini (&drawn_region);
|
||||
_cairo_region_fini (&clear_region);
|
||||
cairo_region_destroy (clear_region);
|
||||
|
||||
return _cairo_surface_set_error (dst, status);
|
||||
}
|
||||
|
@ -3034,6 +3016,7 @@ _cairo_surface_create_in_error (cairo_status_t status)
|
|||
case CAIRO_STATUS_INVALID_STRIDE:
|
||||
return (cairo_surface_t *) &_cairo_surface_nil_invalid_stride;
|
||||
case CAIRO_STATUS_SUCCESS:
|
||||
case CAIRO_STATUS_LAST_STATUS:
|
||||
ASSERT_NOT_REACHED;
|
||||
/* fall-through */
|
||||
case CAIRO_STATUS_INVALID_RESTORE:
|
||||
|
|
|
@ -1025,6 +1025,8 @@ _cairo_surface_base64_encode_png (cairo_surface_t *surface,
|
|||
|
||||
cairo_surface_get_mime_data (surface, CAIRO_MIME_TYPE_PNG,
|
||||
&mime_data, &mime_data_length);
|
||||
if (unlikely (surface->status))
|
||||
return surface->status;
|
||||
if (mime_data == NULL)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
|
|
|
@ -131,6 +131,11 @@ _cairo_traps_grow (cairo_traps_t *traps)
|
|||
cairo_trapezoid_t *new_traps;
|
||||
int new_size = 2 * MAX (traps->traps_size, 16);
|
||||
|
||||
if (CAIRO_INJECT_FAULT ()) {
|
||||
traps->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (traps->traps == traps->traps_embedded) {
|
||||
new_traps = _cairo_malloc_ab (new_size, sizeof (cairo_trapezoid_t));
|
||||
if (new_traps != NULL)
|
||||
|
@ -600,7 +605,7 @@ _cairo_traps_extents (const cairo_traps_t *traps,
|
|||
* Determines if a set of trapezoids are exactly representable as a
|
||||
* cairo region. If so, the passed-in region is initialized to
|
||||
* the area representing the given traps. It should be finalized
|
||||
* with _cairo_region_fini(). If not, %CAIRO_INT_STATUS_UNSUPPORTED
|
||||
* with cairo_region_fini(). If not, %CAIRO_INT_STATUS_UNSUPPORTED
|
||||
* is returned.
|
||||
*
|
||||
* Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_INT_STATUS_UNSUPPORTED
|
||||
|
@ -608,17 +613,11 @@ _cairo_traps_extents (const cairo_traps_t *traps,
|
|||
**/
|
||||
cairo_int_status_t
|
||||
_cairo_traps_extract_region (const cairo_traps_t *traps,
|
||||
cairo_region_t *region)
|
||||
cairo_region_t **region)
|
||||
{
|
||||
cairo_box_int_t stack_boxes[CAIRO_STACK_ARRAY_LENGTH (cairo_box_int_t)];
|
||||
cairo_box_int_t *boxes = stack_boxes;
|
||||
int i, box_count;
|
||||
cairo_int_status_t status;
|
||||
|
||||
if (traps->num_traps == 0) {
|
||||
_cairo_region_init (region);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
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 ||
|
||||
|
@ -632,16 +631,13 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
|
|||
}
|
||||
}
|
||||
|
||||
if (traps->num_traps > ARRAY_LENGTH (stack_boxes)) {
|
||||
boxes = _cairo_malloc_ab (traps->num_traps, sizeof (cairo_box_int_t));
|
||||
|
||||
if (unlikely (boxes == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
box_count = 0;
|
||||
r = cairo_region_create ();
|
||||
if (unlikely (r->status))
|
||||
return r->status;
|
||||
|
||||
for (i = 0; i < traps->num_traps; i++) {
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
int x1 = _cairo_fixed_integer_part (traps->traps[i].left.p1.x);
|
||||
int y1 = _cairo_fixed_integer_part (traps->traps[i].top);
|
||||
int x2 = _cairo_fixed_integer_part (traps->traps[i].right.p1.x);
|
||||
|
@ -653,23 +649,20 @@ _cairo_traps_extract_region (const cairo_traps_t *traps,
|
|||
if (x1 == x2 || y1 == y2)
|
||||
continue;
|
||||
|
||||
boxes[box_count].p1.x = x1;
|
||||
boxes[box_count].p1.y = y1;
|
||||
boxes[box_count].p2.x = x2;
|
||||
boxes[box_count].p2.y = y2;
|
||||
rect.x = x1;
|
||||
rect.y = y1;
|
||||
rect.width = x2 - x1;
|
||||
rect.height = y2 - y1;
|
||||
|
||||
box_count++;
|
||||
status = cairo_region_union_rectangle (r, &rect);
|
||||
if (unlikely (status)) {
|
||||
cairo_region_destroy (r);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = _cairo_region_init_boxes (region, boxes, box_count);
|
||||
|
||||
if (boxes != stack_boxes)
|
||||
free (boxes);
|
||||
|
||||
if (unlikely (status))
|
||||
_cairo_region_fini (region);
|
||||
|
||||
return status;
|
||||
*region = r;
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* moves trap points such that they become the actual corners of the trapezoid */
|
||||
|
|
|
@ -185,7 +185,7 @@ typedef struct _tt_name {
|
|||
typedef struct _tt_composite_glyph {
|
||||
uint16_t flags;
|
||||
uint16_t index;
|
||||
uint16_t args[7]; /* 1 to 7 arguments depending on value of flags */
|
||||
uint16_t args[6]; /* 1 to 6 arguments depending on value of flags */
|
||||
} tt_composite_glyph_t;
|
||||
|
||||
typedef struct _tt_glyph_data {
|
||||
|
|
|
@ -105,8 +105,8 @@ check (tt_maxp_t, 32);
|
|||
check (tt_name_record_t, 12);
|
||||
check (tt_name_t, 18);
|
||||
check (tt_name_t, 18);
|
||||
check (tt_composite_glyph_t, 18);
|
||||
check (tt_glyph_data_t, 28);
|
||||
check (tt_composite_glyph_t, 16);
|
||||
check (tt_glyph_data_t, 26);
|
||||
#undef check
|
||||
|
||||
static cairo_status_t
|
||||
|
@ -495,7 +495,7 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
|
|||
|
||||
composite_glyph = &glyph_data->glyph;
|
||||
do {
|
||||
if ((unsigned char *)(&composite_glyph->args[1]) >= end)
|
||||
if ((unsigned char *)(&composite_glyph->args[1]) > end)
|
||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||
|
||||
flags = be16_to_cpu (composite_glyph->flags);
|
||||
|
@ -508,13 +508,15 @@ cairo_truetype_font_remap_composite_glyph (cairo_truetype_font_t *font,
|
|||
num_args = 1;
|
||||
if (flags & TT_ARG_1_AND_2_ARE_WORDS)
|
||||
num_args += 1;
|
||||
if (flags & TT_WE_HAVE_A_SCALE)
|
||||
|
||||
if (flags & TT_WE_HAVE_A_SCALE)
|
||||
num_args += 1;
|
||||
else if (flags & TT_WE_HAVE_AN_X_AND_Y_SCALE)
|
||||
num_args += 2;
|
||||
else if (flags & TT_WE_HAVE_A_TWO_BY_TWO)
|
||||
num_args += 3;
|
||||
composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
|
||||
num_args += 4;
|
||||
|
||||
composite_glyph = (tt_composite_glyph_t *) &(composite_glyph->args[num_args]);
|
||||
} while (has_more_components);
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
@ -1329,8 +1331,8 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
|
|||
tt_name_record_t *record;
|
||||
unsigned long size;
|
||||
int i, j;
|
||||
char *ps_name;
|
||||
char *font_name;
|
||||
char *ps_name = NULL;
|
||||
char *font_name = NULL;
|
||||
|
||||
backend = scaled_font->backend;
|
||||
if (!backend->load_truetype_table)
|
||||
|
@ -1360,8 +1362,6 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
|
|||
* name. It should be extended to use any suitable font name in
|
||||
* the name table.
|
||||
*/
|
||||
ps_name = NULL;
|
||||
font_name = NULL;
|
||||
for (i = 0; i < be16_to_cpu(name->num_records); i++) {
|
||||
record = &(name->records[i]);
|
||||
if ((be16_to_cpu (record->platform) == 1) &&
|
||||
|
@ -1415,6 +1415,13 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
|
|||
|
||||
fail:
|
||||
free (name);
|
||||
|
||||
if (ps_name != NULL)
|
||||
free (ps_name);
|
||||
|
||||
if (font_name != NULL)
|
||||
free (font_name);
|
||||
|
||||
*ps_name_out = NULL;
|
||||
*font_name_out = NULL;
|
||||
|
||||
|
|
|
@ -449,14 +449,14 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
|
|||
/* four "random" bytes required by encryption algorithm */
|
||||
status = _cairo_array_append_multiple (&data, zeros, 4);
|
||||
if (unlikely (status))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
status = cairo_type1_font_create_charstring (font, i,
|
||||
font->scaled_font_subset->glyphs[i],
|
||||
CAIRO_CHARSTRING_TYPE1,
|
||||
&data);
|
||||
if (unlikely (status))
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
charstring_encrypt (&data);
|
||||
length = _cairo_array_num_elements (&data);
|
||||
|
@ -474,9 +474,9 @@ cairo_type1_font_write_charstrings (cairo_type1_font_t *font,
|
|||
length);
|
||||
_cairo_output_stream_printf (encrypted_output, " ND\n");
|
||||
}
|
||||
_cairo_scaled_font_thaw_cache (font->type1_scaled_font);
|
||||
|
||||
fail:
|
||||
_cairo_scaled_font_thaw_cache (font->type1_scaled_font);
|
||||
_cairo_array_fini (&data);
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -46,14 +46,17 @@
|
|||
static const cairo_surface_backend_t cairo_type3_glyph_surface_backend;
|
||||
|
||||
cairo_surface_t *
|
||||
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||
cairo_output_stream_t *stream,
|
||||
_cairo_type3_glyph_surface_create (cairo_scaled_font_t *scaled_font,
|
||||
cairo_output_stream_t *stream,
|
||||
cairo_type3_glyph_surface_emit_image_t emit_image,
|
||||
cairo_scaled_font_subsets_t *font_subsets)
|
||||
cairo_scaled_font_subsets_t *font_subsets)
|
||||
{
|
||||
cairo_type3_glyph_surface_t *surface;
|
||||
cairo_matrix_t invert_y_axis;
|
||||
|
||||
if (unlikely (stream != NULL && stream->status))
|
||||
return _cairo_surface_create_in_error (stream->status);
|
||||
|
||||
surface = malloc (sizeof (cairo_type3_glyph_surface_t));
|
||||
if (unlikely (surface == NULL))
|
||||
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
|
||||
|
@ -88,6 +91,12 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
|
|||
{
|
||||
cairo_status_t status;
|
||||
|
||||
/* The only image type supported by Type 3 fonts are 1-bit masks */
|
||||
image = _cairo_image_surface_coerce (image, CAIRO_FORMAT_A1);
|
||||
status = image->base.status;
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
_cairo_output_stream_printf (surface->stream,
|
||||
"q %f %f %f %f %f %f cm\n",
|
||||
image_matrix->xx,
|
||||
|
@ -97,8 +106,6 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
|
|||
image_matrix->x0,
|
||||
image_matrix->y0);
|
||||
|
||||
/* The only image type supported by Type 3 fonts are 1-bit masks */
|
||||
image = _cairo_image_surface_coerce (image, CAIRO_FORMAT_A1);
|
||||
status = surface->emit_image (image, surface->stream);
|
||||
cairo_surface_destroy (&image->base);
|
||||
|
||||
|
@ -278,6 +285,8 @@ _cairo_type3_glyph_surface_show_glyphs (void *abstract_surface,
|
|||
&scaled_font->font_matrix,
|
||||
&new_ctm,
|
||||
&scaled_font->options);
|
||||
if (unlikely (font->status))
|
||||
return font->status;
|
||||
|
||||
status = _cairo_pdf_operators_show_text_glyphs (&surface->pdf_operators,
|
||||
NULL, 0,
|
||||
|
@ -375,6 +384,9 @@ _cairo_type3_glyph_surface_set_font_subsets_callback (void *abstract
|
|||
{
|
||||
cairo_type3_glyph_surface_t *surface = abstract_surface;
|
||||
|
||||
if (unlikely (surface->base.status))
|
||||
return;
|
||||
|
||||
_cairo_pdf_operators_set_font_subsets_callback (&surface->pdf_operators,
|
||||
use_font_subset,
|
||||
closure);
|
||||
|
@ -389,7 +401,13 @@ _cairo_type3_glyph_surface_analyze_glyph (void *abstract_surface,
|
|||
cairo_status_t status, status2;
|
||||
cairo_output_stream_t *null_stream;
|
||||
|
||||
if (unlikely (surface->base.status))
|
||||
return surface->base.status;
|
||||
|
||||
null_stream = _cairo_null_stream_create ();
|
||||
if (unlikely (null_stream->status))
|
||||
return null_stream->status;
|
||||
|
||||
_cairo_type3_glyph_surface_set_stream (surface, null_stream);
|
||||
|
||||
_cairo_scaled_font_freeze_cache (surface->scaled_font);
|
||||
|
@ -442,6 +460,9 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
|
|||
double x_advance, y_advance;
|
||||
cairo_matrix_t font_matrix_inverse;
|
||||
|
||||
if (unlikely (surface->base.status))
|
||||
return surface->base.status;
|
||||
|
||||
_cairo_type3_glyph_surface_set_stream (surface, stream);
|
||||
|
||||
_cairo_scaled_font_freeze_cache (surface->scaled_font);
|
||||
|
@ -492,6 +513,10 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
|
|||
cairo_output_stream_t *mem_stream;
|
||||
|
||||
mem_stream = _cairo_memory_stream_create ();
|
||||
status = mem_stream->status;
|
||||
if (unlikely (status))
|
||||
goto FAIL;
|
||||
|
||||
_cairo_type3_glyph_surface_set_stream (surface, mem_stream);
|
||||
|
||||
_cairo_output_stream_printf (surface->stream, "q\n");
|
||||
|
@ -516,6 +541,7 @@ _cairo_type3_glyph_surface_emit_glyph (void *abstract_surface,
|
|||
if (status == CAIRO_INT_STATUS_IMAGE_FALLBACK)
|
||||
status = _cairo_type3_glyph_surface_emit_fallback_image (surface, glyph_index);
|
||||
|
||||
FAIL:
|
||||
_cairo_scaled_font_thaw_cache (surface->scaled_font);
|
||||
|
||||
return status;
|
||||
|
|
|
@ -59,7 +59,6 @@ typedef struct _cairo_output_stream cairo_output_stream_t;
|
|||
typedef struct _cairo_paginated_surface_backend cairo_paginated_surface_backend_t;
|
||||
typedef struct _cairo_path_fixed cairo_path_fixed_t;
|
||||
typedef struct _cairo_rectangle_int16 cairo_glyph_size_t;
|
||||
typedef struct _cairo_region cairo_region_t;
|
||||
typedef struct _cairo_scaled_font_backend cairo_scaled_font_backend_t;
|
||||
typedef struct _cairo_scaled_font_subsets cairo_scaled_font_subsets_t;
|
||||
typedef struct _cairo_solid_pattern cairo_solid_pattern_t;
|
||||
|
@ -218,43 +217,12 @@ typedef struct _cairo_trapezoid {
|
|||
cairo_line_t left, right;
|
||||
} cairo_trapezoid_t;
|
||||
|
||||
struct _cairo_rectangle_int16 {
|
||||
int16_t x, y;
|
||||
uint16_t width, height;
|
||||
};
|
||||
|
||||
struct _cairo_rectangle_int32 {
|
||||
int32_t x, y;
|
||||
uint32_t width, height;
|
||||
};
|
||||
|
||||
struct _cairo_point_int16 {
|
||||
int16_t x, y;
|
||||
};
|
||||
|
||||
struct _cairo_point_int32 {
|
||||
int32_t x, y;
|
||||
};
|
||||
|
||||
#if CAIRO_FIXED_BITS == 32 && CAIRO_FIXED_FRAC_BITS >= 16
|
||||
typedef struct _cairo_rectangle_int16 cairo_rectangle_int_t;
|
||||
typedef struct _cairo_point_int16 cairo_point_int_t;
|
||||
#define CAIRO_RECT_INT_MIN (INT16_MIN >> (CAIRO_FIXED_FRAC_BITS - 16))
|
||||
#define CAIRO_RECT_INT_MAX (INT16_MAX >> (CAIRO_FIXED_FRAC_BITS - 16))
|
||||
#elif CAIRO_FIXED_BITS == 32
|
||||
typedef struct _cairo_rectangle_int32 cairo_rectangle_int_t;
|
||||
typedef struct _cairo_point_int32 cairo_point_int_t;
|
||||
#define CAIRO_RECT_INT_MIN (INT32_MIN >> CAIRO_FIXED_FRAC_BITS)
|
||||
#define CAIRO_RECT_INT_MAX (INT32_MAX >> CAIRO_FIXED_FRAC_BITS)
|
||||
#else
|
||||
#error Not sure how to pick a cairo_rectangle_int_t and cairo_point_int_t for your CAIRO_FIXED_BITS!
|
||||
#endif
|
||||
|
||||
typedef struct _cairo_box_int {
|
||||
cairo_point_int_t p1;
|
||||
cairo_point_int_t p2;
|
||||
} cairo_box_int_t;
|
||||
typedef struct _cairo_point_int {
|
||||
int x, y;
|
||||
} cairo_point_int_t;
|
||||
|
||||
#define CAIRO_RECT_INT_MIN (INT_MIN >> CAIRO_FIXED_FRAC_BITS)
|
||||
#define CAIRO_RECT_INT_MAX (INT_MAX >> CAIRO_FIXED_FRAC_BITS)
|
||||
|
||||
/* Rectangles that take part in a composite operation.
|
||||
*
|
||||
|
|
|
@ -1522,36 +1522,36 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
/* Then combine any new region with it */
|
||||
if (region) {
|
||||
cairo_rectangle_int_t extents;
|
||||
int num_boxes;
|
||||
int num_rects;
|
||||
RGNDATA *data;
|
||||
size_t data_size;
|
||||
RECT *rects;
|
||||
int i;
|
||||
HRGN gdi_region;
|
||||
cairo_box_int_t box0;
|
||||
cairo_rectangle_int_t rect0;
|
||||
|
||||
/* Create a GDI region for the cairo region */
|
||||
|
||||
_cairo_region_get_extents (region, &extents);
|
||||
num_boxes = _cairo_region_num_boxes (region);
|
||||
cairo_region_get_extents (region, &extents);
|
||||
num_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
if (num_boxes == 1)
|
||||
_cairo_region_get_box (region, 0, &box0);
|
||||
if (num_rects == 1)
|
||||
cairo_region_get_rectangle (region, 0, &rect0);
|
||||
|
||||
if (num_boxes == 1 &&
|
||||
box0.p1.x == 0 &&
|
||||
box0.p1.y == 0 &&
|
||||
box0.p2.x == surface->extents.width &&
|
||||
box0.p2.y == surface->extents.height)
|
||||
if (num_rects == 1 &&
|
||||
rect0.x == 0 &&
|
||||
rect0.y == 0 &&
|
||||
rect0.width == surface->extents.width &&
|
||||
rect0.width == surface->extents.height)
|
||||
{
|
||||
gdi_region = NULL;
|
||||
|
||||
SelectClipRgn (surface->dc, NULL);
|
||||
IntersectClipRect (surface->dc,
|
||||
box0.p1.x,
|
||||
box0.p1.y,
|
||||
box0.p2.x,
|
||||
box0.p2.y);
|
||||
rect0.x,
|
||||
rect0.y,
|
||||
rect0.x + rect0.width,
|
||||
rect0.y + rect0.height);
|
||||
} else {
|
||||
/* XXX see notes in _cairo_win32_save_initial_clip --
|
||||
* this code will interact badly with a HDC which had an initial
|
||||
|
@ -1560,7 +1560,7 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
* logical units (unlike IntersectClipRect).
|
||||
*/
|
||||
|
||||
data_size = sizeof (RGNDATAHEADER) + num_boxes * sizeof (RECT);
|
||||
data_size = sizeof (RGNDATAHEADER) + num_rects * sizeof (RECT);
|
||||
data = malloc (data_size);
|
||||
if (!data)
|
||||
return _cairo_error(CAIRO_STATUS_NO_MEMORY);
|
||||
|
@ -1568,22 +1568,22 @@ _cairo_win32_surface_set_clip_region (void *abstract_surface,
|
|||
|
||||
data->rdh.dwSize = sizeof (RGNDATAHEADER);
|
||||
data->rdh.iType = RDH_RECTANGLES;
|
||||
data->rdh.nCount = num_boxes;
|
||||
data->rdh.nRgnSize = num_boxes * sizeof (RECT);
|
||||
data->rdh.nCount = num_rects;
|
||||
data->rdh.nRgnSize = num_rects * sizeof (RECT);
|
||||
data->rdh.rcBound.left = extents.x;
|
||||
data->rdh.rcBound.top = extents.y;
|
||||
data->rdh.rcBound.right = extents.x + extents.width;
|
||||
data->rdh.rcBound.bottom = extents.y + extents.height;
|
||||
|
||||
for (i = 0; i < num_boxes; i++) {
|
||||
cairo_box_int_t box;
|
||||
for (i = 0; i < num_rects; i++) {
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
_cairo_region_get_box (region, i, &box);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
rects[i].left = box.p1.x;
|
||||
rects[i].top = box.p1.y;
|
||||
rects[i].right = box.p2.x;
|
||||
rects[i].bottom = box.p2.y;
|
||||
rects[i].left = rect.x;
|
||||
rects[i].top = rect.y;
|
||||
rects[i].right = rect.x + rect.width;
|
||||
rects[i].bottom = rect.y + rect.height;
|
||||
}
|
||||
|
||||
gdi_region = ExtCreateRegion (NULL, data_size, data);
|
||||
|
|
|
@ -1557,32 +1557,32 @@ _cairo_xcb_surface_set_clip_region (void *abstract_surface,
|
|||
} else {
|
||||
cairo_status_t status;
|
||||
xcb_rectangle_t *rects = NULL;
|
||||
int n_boxes, i;
|
||||
int n_rects, i;
|
||||
|
||||
n_boxes = _cairo_region_num_boxes (region);
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
|
||||
if (n_boxes > 0) {
|
||||
rects = _cairo_malloc_ab (n_boxes, sizeof(xcb_rectangle_t));
|
||||
if (n_rects > 0) {
|
||||
rects = _cairo_malloc_ab (n_rects, sizeof(xcb_rectangle_t));
|
||||
if (rects == NULL)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
} else {
|
||||
rects = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_boxes; i++) {
|
||||
cairo_box_int_t box;
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
_cairo_region_get_box (region, i, &box);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
rects[i].x = box.p1.x;
|
||||
rects[i].y = box.p1.y;
|
||||
rects[i].width = box.p2.x - box.p1.x;
|
||||
rects[i].height = box.p2.y - box.p1.y;
|
||||
rects[i].x = rect.x;
|
||||
rects[i].y = rect.y;
|
||||
rects[i].width = rect.width;
|
||||
rects[i].height = rect.height;
|
||||
}
|
||||
|
||||
surface->have_clip_rects = TRUE;
|
||||
surface->clip_rects = rects;
|
||||
surface->num_clip_rects = n_boxes;
|
||||
surface->num_clip_rects = n_rects;
|
||||
|
||||
if (surface->gc)
|
||||
_cairo_xcb_surface_set_gc_clip_rects (surface);
|
||||
|
|
|
@ -2271,7 +2271,32 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
|
|||
return status;
|
||||
}
|
||||
|
||||
COMPILE_TIME_ASSERT (sizeof (XRectangle) <= sizeof (cairo_box_int_t));
|
||||
static cairo_region_t *
|
||||
_surface_maybe_clip_region (cairo_xlib_surface_t *surface,
|
||||
cairo_region_t *clip,
|
||||
cairo_region_t *bounded)
|
||||
{
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
cairo_region_get_extents (clip, &rect);
|
||||
if (rect.x >= 0 &&
|
||||
rect.y >= 0 &&
|
||||
rect.x + rect.width <= surface->width &&
|
||||
rect.y + rect.height <= surface->height)
|
||||
{
|
||||
return clip;
|
||||
}
|
||||
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = surface->width;
|
||||
rect.height = surface->height;
|
||||
_cairo_region_init_rectangle (bounded, &rect);
|
||||
|
||||
bounded->status = cairo_region_intersect (bounded, clip);
|
||||
|
||||
return bounded;
|
||||
}
|
||||
|
||||
static cairo_int_status_t
|
||||
_cairo_xlib_surface_set_clip_region (void *abstract_surface,
|
||||
cairo_region_t *region)
|
||||
|
@ -2291,58 +2316,50 @@ _cairo_xlib_surface_set_clip_region (void *abstract_surface,
|
|||
surface->num_clip_rects = 0;
|
||||
|
||||
if (region != NULL) {
|
||||
cairo_status_t status;
|
||||
XRectangle *rects = NULL;
|
||||
int n_boxes, i;
|
||||
cairo_rectangle_int_t rect;
|
||||
int n_rects, i;
|
||||
cairo_region_t bounded;
|
||||
|
||||
rect.x = rect.y = 0;
|
||||
rect.width = surface->width;
|
||||
rect.height = surface->height;
|
||||
|
||||
/* Intersect the region with the bounds of the surface. This
|
||||
* is necessary so we don't wrap around when we convert cairo's
|
||||
* 32 bit region into 16 bit rectangles.
|
||||
*/
|
||||
_cairo_region_init_rect (&bounded, &rect);
|
||||
status = _cairo_region_intersect (&bounded, &bounded, region);
|
||||
if (unlikely (status)) {
|
||||
_cairo_region_fini (&bounded);
|
||||
return status;
|
||||
}
|
||||
region = _surface_maybe_clip_region (surface, region, &bounded);
|
||||
if (unlikely (region->status))
|
||||
return region->status;
|
||||
|
||||
n_boxes = _cairo_region_num_boxes (&bounded);
|
||||
|
||||
if (n_boxes > ARRAY_LENGTH (surface->embedded_clip_rects)) {
|
||||
rects = _cairo_malloc_ab (n_boxes, sizeof (XRectangle));
|
||||
n_rects = cairo_region_num_rectangles (region);
|
||||
if (n_rects > ARRAY_LENGTH (surface->embedded_clip_rects)) {
|
||||
rects = _cairo_malloc_ab (n_rects, sizeof (XRectangle));
|
||||
if (unlikely (rects == NULL)) {
|
||||
_cairo_region_fini (&bounded);
|
||||
if (unlikely (region == &bounded))
|
||||
_cairo_region_fini (&bounded);
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
} else {
|
||||
rects = surface->embedded_clip_rects;
|
||||
}
|
||||
|
||||
for (i = 0; i < n_boxes; i++) {
|
||||
cairo_box_int_t box;
|
||||
for (i = 0; i < n_rects; i++) {
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
_cairo_region_get_box (&bounded, i, &box);
|
||||
cairo_region_get_rectangle (region, i, &rect);
|
||||
|
||||
rects[i].x = box.p1.x;
|
||||
rects[i].y = box.p1.y;
|
||||
rects[i].width = box.p2.x - rects[i].x;
|
||||
rects[i].height = box.p2.y - rects[i].y;
|
||||
rects[i].x = rect.x;
|
||||
rects[i].y = rect.y;
|
||||
rects[i].width = rect.width;
|
||||
rects[i].height = rect.height;
|
||||
}
|
||||
|
||||
_cairo_region_fini (&bounded);
|
||||
|
||||
if (unlikely (region == &bounded))
|
||||
_cairo_region_fini (&bounded);
|
||||
|
||||
surface->have_clip_rects = TRUE;
|
||||
surface->clip_rects = rects;
|
||||
surface->num_clip_rects = n_boxes;
|
||||
surface->num_clip_rects = n_rects;
|
||||
|
||||
/* Discard the trivial clip rectangle that covers the entire surface */
|
||||
if (n_boxes == 1 &&
|
||||
if (n_rects == 1 &&
|
||||
rects[0].x == 0 &&
|
||||
rects[0].y == 0 &&
|
||||
rects[0].width == surface->width &&
|
||||
|
|
|
@ -2353,10 +2353,88 @@ cairo_public void
|
|||
cairo_matrix_transform_point (const cairo_matrix_t *matrix,
|
||||
double *x, double *y);
|
||||
|
||||
/* Region functions */
|
||||
|
||||
typedef struct _cairo_region cairo_region_t;
|
||||
|
||||
typedef struct _cairo_rectangle_int {
|
||||
int x, y;
|
||||
int width, height;
|
||||
} cairo_rectangle_int_t;
|
||||
|
||||
typedef enum _cairo_region_overlap {
|
||||
CAIRO_REGION_OVERLAP_IN, /* completely inside region */
|
||||
CAIRO_REGION_OVERLAP_OUT, /* completely outside region */
|
||||
CAIRO_REGION_OVERLAP_PART /* partly inside region */
|
||||
} cairo_region_overlap_t;
|
||||
|
||||
cairo_public cairo_region_t *
|
||||
cairo_region_create (void);
|
||||
|
||||
cairo_public cairo_region_t *
|
||||
cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_public cairo_region_t *
|
||||
cairo_region_copy (cairo_region_t *original);
|
||||
|
||||
cairo_public void
|
||||
cairo_region_destroy (cairo_region_t *region);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_region_status (cairo_region_t *region);
|
||||
|
||||
cairo_public void
|
||||
cairo_region_get_extents (cairo_region_t *region,
|
||||
cairo_rectangle_int_t *extents);
|
||||
|
||||
cairo_public int
|
||||
cairo_region_num_rectangles (cairo_region_t *region);
|
||||
|
||||
cairo_public void
|
||||
cairo_region_get_rectangle (cairo_region_t *region,
|
||||
int nth_rectangle,
|
||||
cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_public cairo_bool_t
|
||||
cairo_region_is_empty (cairo_region_t *region);
|
||||
|
||||
cairo_public cairo_region_overlap_t
|
||||
cairo_region_contains_rectangle (cairo_region_t *region,
|
||||
const cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_public cairo_bool_t
|
||||
cairo_region_contains_point (cairo_region_t *region, int x, int y);
|
||||
|
||||
cairo_public void
|
||||
cairo_region_translate (cairo_region_t *region, int dx, int dy);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_region_subtract (cairo_region_t *dst, cairo_region_t *other);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_region_subtract_rectangle (cairo_region_t *dst,
|
||||
const cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_region_intersect (cairo_region_t *dst, cairo_region_t *other);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_region_intersect_rectangle (cairo_region_t *dst,
|
||||
const cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_region_union (cairo_region_t *dst, cairo_region_t *other);
|
||||
|
||||
cairo_public cairo_status_t
|
||||
cairo_region_union_rectangle (cairo_region_t *dst,
|
||||
const cairo_rectangle_int_t *rectangle);
|
||||
|
||||
|
||||
/* Functions to be used while debugging (not intended for use in production code) */
|
||||
cairo_public void
|
||||
cairo_debug_reset_static_data (void);
|
||||
|
||||
|
||||
CAIRO_END_DECLS
|
||||
|
||||
#endif /* CAIRO_H */
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
|
||||
CAIRO_BEGIN_DECLS
|
||||
|
||||
#if _WIN32 && !WINCE // we don't have to worry about permissions on WINCE
|
||||
#if _WIN32 && !_WIN32_WCE // we don't have to worry about permissions on WinCE
|
||||
cairo_private FILE *
|
||||
_cairo_win32_tmpfile (void);
|
||||
#define tmpfile() _cairo_win32_tmpfile()
|
||||
|
@ -2418,7 +2418,7 @@ _cairo_traps_extents (const cairo_traps_t *traps,
|
|||
|
||||
cairo_private cairo_int_status_t
|
||||
_cairo_traps_extract_region (const cairo_traps_t *tr,
|
||||
cairo_region_t *region);
|
||||
cairo_region_t **region);
|
||||
|
||||
cairo_private cairo_status_t
|
||||
_cairo_traps_path (const cairo_traps_t *traps,
|
||||
|
@ -2538,7 +2538,21 @@ _cairo_pattern_reset_static_data (void);
|
|||
|
||||
/* cairo-region.c */
|
||||
|
||||
#include "cairo-region-private.h"
|
||||
struct _cairo_region {
|
||||
cairo_status_t status;
|
||||
|
||||
pixman_region32_t rgn;
|
||||
};
|
||||
|
||||
cairo_private void
|
||||
_cairo_region_init (cairo_region_t *region);
|
||||
|
||||
cairo_private void
|
||||
_cairo_region_init_rectangle (cairo_region_t *region,
|
||||
const cairo_rectangle_int_t *rectangle);
|
||||
|
||||
cairo_private void
|
||||
_cairo_region_fini (cairo_region_t *region);
|
||||
|
||||
/* cairo-unicode.c */
|
||||
|
||||
|
@ -2700,6 +2714,24 @@ slim_hidden_proto (cairo_user_font_face_set_unicode_to_glyph_func);
|
|||
slim_hidden_proto (cairo_user_to_device);
|
||||
slim_hidden_proto (cairo_user_to_device_distance);
|
||||
slim_hidden_proto (cairo_version_string);
|
||||
slim_hidden_proto (cairo_region_create);
|
||||
slim_hidden_proto (cairo_region_create_rectangle);
|
||||
slim_hidden_proto (cairo_region_copy);
|
||||
slim_hidden_proto (cairo_region_destroy);
|
||||
slim_hidden_proto (cairo_region_status);
|
||||
slim_hidden_proto (cairo_region_get_extents);
|
||||
slim_hidden_proto (cairo_region_num_rectangles);
|
||||
slim_hidden_proto (cairo_region_get_rectangle);
|
||||
slim_hidden_proto (cairo_region_is_empty);
|
||||
slim_hidden_proto (cairo_region_contains_rectangle);
|
||||
slim_hidden_proto (cairo_region_contains_point);
|
||||
slim_hidden_proto (cairo_region_translate);
|
||||
slim_hidden_proto (cairo_region_subtract);
|
||||
slim_hidden_proto (cairo_region_subtract_rectangle);
|
||||
slim_hidden_proto (cairo_region_intersect);
|
||||
slim_hidden_proto (cairo_region_intersect_rectangle);
|
||||
slim_hidden_proto (cairo_region_union);
|
||||
slim_hidden_proto (cairo_region_union_rectangle);
|
||||
|
||||
#if CAIRO_HAS_PNG_FUNCTIONS
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче