Quelle cairo-region.c
Sprache: C
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
/* cairo - a vector graphics library with display and print output
*
* Copyright © 2005 Red Hat , Inc .
*
* This library is free software ; you can redistribute it and / or
* modify it either under the terms of the GNU Lesser General Public
* License version 2 . 1 as published by the Free Software Foundation
* ( the " LGPL " ) or , at your option , under the terms of the Mozilla
* Public License Version 1 . 1 ( the " MPL " ) . If you do not alter this
* notice , a recipient may use your version of this file under either
* the MPL or the LGPL .
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING - LGPL - 2 . 1 ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Suite 500 , Boston , MA 02110 - 1335 , USA
* You should have received a copy of the MPL along with this library
* in the file COPYING - MPL - 1 . 1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1 . 1 ( the " License " ) ; you may not use this file except in
* compliance with the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* This software is distributed on an " AS IS " basis , WITHOUT WARRANTY
* OF ANY KIND , either express or implied . See the LGPL or the MPL for
* the specific language governing rights and limitations .
*
* The Original Code is the cairo graphics library .
*
* The Initial Developer of the Original Code is Red Hat , Inc .
*
* Contributor ( s ) :
* Owen Taylor < otaylor @ redhat . com >
* Vladimir Vukicevic < vladimir @ pobox . com >
* S ø ren Sandmann < sandmann @ daimi . au . dk >
*/
#include "cairoint.h"
#include "cairo-error-private.h"
#include "cairo-region-private.h"
/* XXX need to update pixman headers to be const as appropriate */
#define CONST_CAST (pixman_region32_t *)
/**
* SECTION : cairo - region
* @ Title : Regions
* @ Short_Description : Representing a pixel - aligned area
*
* Regions are a simple graphical data type representing an area of
* integer - aligned rectangles . They are often used on raster surfaces
* to track areas of interest , such as change or clip areas .
**/
static const cairo_region_t _cairo_region_nil = {
CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
CAIRO_STATUS_NO_MEMORY, /* status */
};
cairo_region_t *
_cairo_region_create_in_error (cairo_status_t status)
{
switch (status) {
case CAIRO_STATUS_NO_MEMORY:
return (cairo_region_t *) &_cairo_region_nil;
case CAIRO_STATUS_SUCCESS:
case CAIRO_STATUS_LAST_STATUS:
ASSERT_NOT_REACHED;
/* fall-through */
case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
case CAIRO_STATUS_INVALID_STATUS:
case CAIRO_STATUS_INVALID_CONTENT:
case CAIRO_STATUS_INVALID_FORMAT:
case CAIRO_STATUS_INVALID_VISUAL:
case CAIRO_STATUS_READ_ERROR:
case CAIRO_STATUS_WRITE_ERROR:
case CAIRO_STATUS_FILE_NOT_FOUND:
case CAIRO_STATUS_TEMP_FILE_ERROR:
case CAIRO_STATUS_INVALID_STRIDE:
case CAIRO_STATUS_INVALID_SIZE:
case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
case CAIRO_STATUS_DEVICE_ERROR:
case CAIRO_STATUS_INVALID_RESTORE:
case CAIRO_STATUS_INVALID_POP_GROUP:
case CAIRO_STATUS_NO_CURRENT_POINT:
case CAIRO_STATUS_INVALID_MATRIX:
case CAIRO_STATUS_NULL_POINTER:
case CAIRO_STATUS_INVALID_STRING:
case CAIRO_STATUS_INVALID_PATH_DATA:
case CAIRO_STATUS_SURFACE_FINISHED:
case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
case CAIRO_STATUS_INVALID_DASH:
case CAIRO_STATUS_INVALID_DSC_COMMENT:
case CAIRO_STATUS_INVALID_INDEX:
case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
case CAIRO_STATUS_FONT_TYPE_MISMATCH:
case CAIRO_STATUS_USER_FONT_IMMUTABLE:
case CAIRO_STATUS_USER_FONT_ERROR:
case CAIRO_STATUS_NEGATIVE_COUNT:
case CAIRO_STATUS_INVALID_CLUSTERS:
case CAIRO_STATUS_INVALID_SLANT:
case CAIRO_STATUS_INVALID_WEIGHT:
case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
case CAIRO_STATUS_INVALID_MESH_CONSTRUCTION:
case CAIRO_STATUS_DEVICE_FINISHED:
case CAIRO_STATUS_JBIG2_GLOBAL_MISSING:
case CAIRO_STATUS_PNG_ERROR:
case CAIRO_STATUS_FREETYPE_ERROR:
case CAIRO_STATUS_WIN32_GDI_ERROR:
case CAIRO_STATUS_TAG_ERROR:
case CAIRO_STATUS_DWRITE_ERROR:
case CAIRO_STATUS_SVG_FONT_ERROR:
default :
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_region_t *) &_cairo_region_nil;
}
}
/**
* _ cairo_region_set_error :
* @ region : a region
* @ status : a status value indicating an error
*
* Atomically sets region - > status to @ status and calls _ cairo_error ;
* Does nothing if status is % CAIRO_STATUS_SUCCESS or any of the internal
* status values .
*
* All assignments of an error status to region - > status should happen
* through _ cairo_region_set_error ( ) . Note that due to the nature of
* the atomic operation , it is not safe to call this function on the
* nil objects .
*
* The purpose of this function is to allow the user to set a
* breakpoint in _ cairo_error ( ) to generate a stack trace for when the
* user causes cairo to detect an error .
*
* Return value : the error status .
**/
static cairo_status_t
_cairo_region_set_error (cairo_region_t *region,
cairo_status_t status)
{
if (status == CAIRO_STATUS_SUCCESS)
return CAIRO_STATUS_SUCCESS;
/* 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)
{
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
region->status = CAIRO_STATUS_SUCCESS;
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0 );
pixman_region32_init (®ion->rgn);
}
void
_cairo_region_init_rectangle (cairo_region_t *region,
const cairo_rectangle_int_t *rectangle)
{
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
region->status = CAIRO_STATUS_SUCCESS;
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 0 );
pixman_region32_init_rect (®ion->rgn,
rectangle->x, rectangle->y,
rectangle->width, rectangle->height);
}
void
_cairo_region_fini (cairo_region_t *region)
{
assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count));
pixman_region32_fini (®ion->rgn);
VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
}
/**
* cairo_region_create :
*
* Allocates a new empty region object .
*
* Return value : A newly allocated # cairo_region_t . Free with
* cairo_region_destroy ( ) . This function always returns a
* valid pointer ; if memory cannot be allocated , then a special
* error object is returned where all operations on the object do nothing .
* You can check for this with cairo_region_status ( ) .
*
* Since : 1 . 10
**/
cairo_region_t *
cairo_region_create (void )
{
cairo_region_t *region;
region = _cairo_calloc (sizeof (cairo_region_t));
if (region == NULL)
return (cairo_region_t *) &_cairo_region_nil;
region->status = CAIRO_STATUS_SUCCESS;
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1 );
pixman_region32_init (®ion->rgn);
return region;
}
/**
* cairo_region_create_rectangles :
* @ rects : an array of @ count rectangles
* @ count : number of rectangles
*
* Allocates a new region object containing the union of all given @ rects .
*
* 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_rectangles (const cairo_rectangle_int_t *rects,
int count)
{
pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
pixman_box32_t *pboxes = stack_pboxes;
cairo_region_t *region;
int i;
region = _cairo_calloc (sizeof (cairo_region_t));
if (unlikely (region == NULL))
return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1 );
region->status = CAIRO_STATUS_SUCCESS;
if (count == 1 ) {
pixman_region32_init_rect (®ion->rgn,
rects->x, rects->y,
rects->width, rects->height);
return region;
}
if (count > ARRAY_LENGTH (stack_pboxes)) {
pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
if (unlikely (pboxes == NULL)) {
free (region);
return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
}
for (i = 0 ; i < count; i++) {
pboxes[i].x1 = rects[i].x;
pboxes[i].y1 = rects[i].y;
pboxes[i].x2 = rects[i].x + rects[i].width;
pboxes[i].y2 = rects[i].y + rects[i].height;
}
i = pixman_region32_init_rects (®ion->rgn, pboxes, count);
if (pboxes != stack_pboxes)
free (pboxes);
if (unlikely (i == 0 )) {
free (region);
return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
return region;
}
cairo_region_t *
_cairo_region_create_from_boxes (const cairo_box_t *boxes, int count)
{
cairo_region_t *region;
region = _cairo_calloc (sizeof (cairo_region_t));
if (unlikely (region == NULL))
return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1 );
region->status = CAIRO_STATUS_SUCCESS;
if (! pixman_region32_init_rects (®ion->rgn,
(pixman_box32_t *)boxes, count)) {
free (region);
return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
}
return region;
}
cairo_box_t *
_cairo_region_get_boxes (const cairo_region_t *region, int *nbox)
{
if (region->status) {
nbox = 0 ;
return NULL;
}
return (cairo_box_t *) pixman_region32_rectangles (CONST_CAST ®ion->rgn, nbox);
}
/**
* 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_calloc (sizeof (cairo_region_t));
if (unlikely (region == NULL))
return (cairo_region_t *) &_cairo_region_nil;
region->status = CAIRO_STATUS_SUCCESS;
CAIRO_REFERENCE_COUNT_INIT (®ion->ref_count, 1 );
pixman_region32_init_rect (®ion->rgn,
rectangle->x, rectangle->y,
rectangle->width, rectangle->height);
return region;
}
/**
* cairo_region_copy :
* @ original : a # cairo_region_t
*
* Allocates a new region object copying the area from @ original .
*
* Return value : A newly allocated # cairo_region_t . Free with
* cairo_region_destroy ( ) . This function always returns a
* valid pointer ; if memory cannot be allocated , then a special
* error object is returned where all operations on the object do nothing .
* You can check for this with cairo_region_status ( ) .
*
* Since : 1 . 10
**/
cairo_region_t *
cairo_region_copy (const cairo_region_t *original)
{
cairo_region_t *copy;
if (original != NULL && original->status)
return (cairo_region_t *) &_cairo_region_nil;
copy = cairo_region_create ();
if (unlikely (copy->status))
return copy;
if (original != NULL &&
! pixman_region32_copy (©->rgn, CONST_CAST &original->rgn))
{
cairo_region_destroy (copy);
return (cairo_region_t *) &_cairo_region_nil;
}
return copy;
}
/**
* cairo_region_reference :
* @ region : a # cairo_region_t
*
* Increases the reference count on @ region by one . This prevents
* @ region from being destroyed until a matching call to
* cairo_region_destroy ( ) is made .
*
* Return value : the referenced # cairo_region_t .
*
* Since : 1 . 10
**/
cairo_region_t *
cairo_region_reference (cairo_region_t *region)
{
if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (®ion->ref_count))
return NULL;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count));
_cairo_reference_count_inc (®ion->ref_count);
return region;
}
/**
* 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 == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (®ion->ref_count))
return ;
assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (®ion->ref_count));
if (! _cairo_reference_count_dec_and_test (®ion->ref_count))
return ;
_cairo_region_fini (region);
free (region);
}
/**
* cairo_region_num_rectangles :
* @ region : a # cairo_region_t
*
* Returns the number of rectangles contained in @ region .
*
* Return value : The number of rectangles contained in @ region .
*
* Since : 1 . 10
**/
int
cairo_region_num_rectangles (const cairo_region_t *region)
{
if (region->status)
return 0 ;
return pixman_region32_n_rects (CONST_CAST ®ion->rgn);
}
/**
* cairo_region_get_rectangle :
* @ region : a # cairo_region_t
* @ nth : a number indicating which rectangle should be returned
* @ rectangle : return location for a # cairo_rectangle_int_t
*
* Stores the @ nth rectangle from the region in @ rectangle .
*
* Since : 1 . 10
**/
void
cairo_region_get_rectangle (const cairo_region_t *region,
int nth,
cairo_rectangle_int_t *rectangle)
{
pixman_box32_t *pbox;
if (region->status) {
rectangle->x = rectangle->y = 0 ;
rectangle->width = rectangle->height = 0 ;
return ;
}
pbox = pixman_region32_rectangles (CONST_CAST ®ion->rgn, NULL) + nth;
rectangle->x = pbox->x1;
rectangle->y = pbox->y1;
rectangle->width = pbox->x2 - pbox->x1;
rectangle->height = pbox->y2 - pbox->y1;
}
/**
* cairo_region_get_extents :
* @ region : a # cairo_region_t
* @ extents : rectangle into which to store the extents
*
* Gets the bounding rectangle of @ region as a # cairo_rectangle_int_t
*
* Since : 1 . 10
**/
void
cairo_region_get_extents (const cairo_region_t *region,
cairo_rectangle_int_t *extents)
{
pixman_box32_t *pextents;
if (region->status) {
extents->x = extents->y = 0 ;
extents->width = extents->height = 0 ;
return ;
}
pextents = pixman_region32_extents (CONST_CAST ®ion->rgn);
extents->x = pextents->x1;
extents->y = pextents->y1;
extents->width = pextents->x2 - pextents->x1;
extents->height = pextents->y2 - pextents->y1;
}
/**
* cairo_region_status :
* @ region : a # cairo_region_t
*
* Checks whether an error has previous occurred for this
* region object .
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_status (const cairo_region_t *region)
{
return region->status;
}
/**
* cairo_region_subtract :
* @ dst : a # cairo_region_t
* @ other : another # cairo_region_t
*
* Subtracts @ other from @ dst and places the result in @ dst
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_subtract (cairo_region_t *dst, const 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,
CONST_CAST &other->rgn))
{
return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
}
return CAIRO_STATUS_SUCCESS;
}
/**
* cairo_region_subtract_rectangle :
* @ dst : a # cairo_region_t
* @ rectangle : a # cairo_rectangle_int_t
*
* Subtracts @ rectangle from @ dst and places the result in @ dst
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_subtract_rectangle (cairo_region_t *dst,
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_subtract (&dst->rgn, &dst->rgn, ®ion))
status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
pixman_region32_fini (®ion);
return status;
}
/**
* cairo_region_intersect :
* @ dst : a # cairo_region_t
* @ other : another # cairo_region_t
*
* Computes the intersection of @ dst with @ other and places the result in @ dst
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_intersect (cairo_region_t *dst, const 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, CONST_CAST &other->rgn))
return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_SUCCESS;
}
/**
* cairo_region_intersect_rectangle :
* @ dst : a # cairo_region_t
* @ rectangle : a # cairo_rectangle_int_t
*
* Computes the intersection of @ dst with @ rectangle and places the
* result in @ dst
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_intersect_rectangle (cairo_region_t *dst,
const cairo_rectangle_int_t *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_intersect (&dst->rgn, &dst->rgn, ®ion))
status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
pixman_region32_fini (®ion);
return status;
}
/**
* cairo_region_union :
* @ dst : a # cairo_region_t
* @ other : another # cairo_region_t
*
* Computes the union of @ dst with @ other and places the result in @ dst
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_union (cairo_region_t *dst,
const 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, CONST_CAST &other->rgn))
return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
return CAIRO_STATUS_SUCCESS;
}
/**
* cairo_region_union_rectangle :
* @ dst : a # cairo_region_t
* @ rectangle : a # cairo_rectangle_int_t
*
* Computes the union of @ dst with @ rectangle and places the result in @ dst .
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_union_rectangle (cairo_region_t *dst,
const cairo_rectangle_int_t *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;
}
/**
* cairo_region_xor :
* @ dst : a # cairo_region_t
* @ other : another # cairo_region_t
*
* Computes the exclusive difference of @ dst with @ other and places the
* result in @ dst . That is , @ dst will be set to contain all areas that
* are either in @ dst or in @ other , but not in both .
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_xor (cairo_region_t *dst, const cairo_region_t *other)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
pixman_region32_t tmp;
if (dst->status)
return dst->status;
if (other->status)
return _cairo_region_set_error (dst, other->status);
pixman_region32_init (&tmp);
/* XXX: get an xor function into pixman */
if (! pixman_region32_subtract (&tmp, CONST_CAST &other->rgn, &dst->rgn) ||
! pixman_region32_subtract (&dst->rgn, &dst->rgn, CONST_CAST &other->rgn) ||
! pixman_region32_union (&dst->rgn, &dst->rgn, &tmp))
status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
pixman_region32_fini (&tmp);
return status;
}
/**
* cairo_region_xor_rectangle :
* @ dst : a # cairo_region_t
* @ rectangle : a # cairo_rectangle_int_t
*
* Computes the exclusive difference of @ dst with @ rectangle and places the
* result in @ dst . That is , @ dst will be set to contain all areas that are
* either in @ dst or in @ rectangle , but not in both .
*
* Return value : % CAIRO_STATUS_SUCCESS or % CAIRO_STATUS_NO_MEMORY
*
* Since : 1 . 10
**/
cairo_status_t
cairo_region_xor_rectangle (cairo_region_t *dst,
const cairo_rectangle_int_t *rectangle)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
pixman_region32_t region, tmp;
if (dst->status)
return dst->status;
pixman_region32_init_rect (®ion,
rectangle->x, rectangle->y,
rectangle->width, rectangle->height);
pixman_region32_init (&tmp);
/* XXX: get an xor function into pixman */
if (! pixman_region32_subtract (&tmp, ®ion, &dst->rgn) ||
! pixman_region32_subtract (&dst->rgn, &dst->rgn, ®ion) ||
! pixman_region32_union (&dst->rgn, &dst->rgn, &tmp))
status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
pixman_region32_fini (&tmp);
pixman_region32_fini (®ion);
return status;
}
/**
* 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_is_empty (const cairo_region_t *region)
{
if (region->status)
return TRUE ;
return ! pixman_region32_not_empty (CONST_CAST ®ion->rgn);
}
/**
* cairo_region_translate :
* @ region : a # cairo_region_t
* @ dx : Amount to translate in the x direction
* @ dy : Amount to translate in the y direction
*
* Translates @ region by ( @ dx , @ dy ) .
*
* Since : 1 . 10
**/
void
cairo_region_translate (cairo_region_t *region,
int dx, int dy)
{
if (region->status)
return ;
pixman_region32_translate (®ion->rgn, dx, dy);
}
/**
* cairo_region_contains_rectangle :
* @ region : a # cairo_region_t
* @ rectangle : a # cairo_rectangle_int_t
*
* Checks whether @ rectangle is inside , outside or partially contained
* in @ region
*
* Return value :
* % CAIRO_REGION_OVERLAP_IN if @ rectangle is entirely inside @ region ,
* % CAIRO_REGION_OVERLAP_OUT if @ rectangle is entirely outside @ region , or
* % CAIRO_REGION_OVERLAP_PART if @ rectangle is partially inside and partially outside @ region .
*
* Since : 1 . 10
**/
cairo_region_overlap_t
cairo_region_contains_rectangle (const cairo_region_t *region,
const cairo_rectangle_int_t *rectangle)
{
pixman_box32_t pbox;
pixman_region_overlap_t poverlap;
if (region->status)
return CAIRO_REGION_OVERLAP_OUT;
pbox.x1 = rectangle->x;
pbox.y1 = rectangle->y;
pbox.x2 = rectangle->x + rectangle->width;
pbox.y2 = rectangle->y + rectangle->height;
poverlap = pixman_region32_contains_rectangle (CONST_CAST ®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;
}
}
/**
* 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 (const cairo_region_t *region,
int x, int y)
{
pixman_box32_t box;
if (region->status)
return FALSE ;
return pixman_region32_contains_point (CONST_CAST ®ion->rgn, x, y, &box);
}
/**
* cairo_region_equal :
* @ a : a # cairo_region_t or % NULL
* @ b : a # cairo_region_t or % NULL
*
* Compares whether region_a is equivalent to region_b . % NULL as an argument
* is equal to itself , but not to any non - % NULL region .
*
* Return value : % TRUE if both regions contained the same coverage ,
* % FALSE if it is not or any region is in an error status .
*
* Since : 1 . 10
**/
cairo_bool_t
cairo_region_equal (const cairo_region_t *a,
const cairo_region_t *b)
{
/* error objects are never equal */
if ((a != NULL && a->status) || (b != NULL && b->status))
return FALSE ;
if (a == b)
return TRUE ;
if (a == NULL || b == NULL)
return FALSE ;
return pixman_region32_equal (CONST_CAST &a->rgn, CONST_CAST &b->rgn);
}
Messung V0.5 in Prozent C=97 H=100 G=98
¤ Dauer der Verarbeitung: 0.31 Sekunden
(vorverarbeitet am 2026-08-23)
¤
*© Formatika GbR, Deutschland
2026-08-25
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=277311
#Domains=752002