LCOV - code coverage report
Current view: top level - gfx/cairo/cairo/src - cairo-region.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 232 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
       2             : /* cairo - a vector graphics library with display and print output
       3             :  *
       4             :  * Copyright © 2005 Red Hat, Inc.
       5             :  *
       6             :  * This library is free software; you can redistribute it and/or
       7             :  * modify it either under the terms of the GNU Lesser General Public
       8             :  * License version 2.1 as published by the Free Software Foundation
       9             :  * (the "LGPL") or, at your option, under the terms of the Mozilla
      10             :  * Public License Version 1.1 (the "MPL"). If you do not alter this
      11             :  * notice, a recipient may use your version of this file under either
      12             :  * the MPL or the LGPL.
      13             :  *
      14             :  * You should have received a copy of the LGPL along with this library
      15             :  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
      16             :  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
      17             :  * You should have received a copy of the MPL along with this library
      18             :  * in the file COPYING-MPL-1.1
      19             :  *
      20             :  * The contents of this file are subject to the Mozilla Public License
      21             :  * Version 1.1 (the "License"); you may not use this file except in
      22             :  * compliance with the License. You may obtain a copy of the License at
      23             :  * http://www.mozilla.org/MPL/
      24             :  *
      25             :  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
      26             :  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
      27             :  * the specific language governing rights and limitations.
      28             :  *
      29             :  * The Original Code is the cairo graphics library.
      30             :  *
      31             :  * The Initial Developer of the Original Code is Red Hat, Inc.
      32             :  *
      33             :  * Contributor(s):
      34             :  *      Owen Taylor <otaylor@redhat.com>
      35             :  *      Vladimir Vukicevic <vladimir@pobox.com>
      36             :  *      Søren Sandmann <sandmann@daimi.au.dk>
      37             :  */
      38             : 
      39             : #include "cairoint.h"
      40             : 
      41             : #include "cairo-error-private.h"
      42             : #include "cairo-region-private.h"
      43             : 
      44             : /* XXX need to update pixman headers to be const as appropriate */
      45             : #define CONST_CAST (pixman_region32_t *)
      46             : 
      47             : /**
      48             :  * SECTION:cairo-region
      49             :  * @Title: Regions
      50             :  * @Short_Description: Representing a pixel-aligned area
      51             :  *
      52             :  * Regions are a simple graphical data type representing an area of 
      53             :  * integer-aligned rectangles. They are often used on raster surfaces 
      54             :  * to track areas of interest, such as change or clip areas.
      55             :  */
      56             : 
      57             : static const cairo_region_t _cairo_region_nil = {
      58             :     CAIRO_REFERENCE_COUNT_INVALID,      /* ref_count */
      59             :     CAIRO_STATUS_NO_MEMORY,             /* status */
      60             : };
      61             : 
      62             : cairo_region_t *
      63           0 : _cairo_region_create_in_error (cairo_status_t status)
      64             : {
      65           0 :     switch (status) {
      66             :     case CAIRO_STATUS_NO_MEMORY:
      67           0 :         return (cairo_region_t *) &_cairo_region_nil;
      68             : 
      69             :     case CAIRO_STATUS_SUCCESS:
      70             :     case CAIRO_STATUS_LAST_STATUS:
      71           0 :         ASSERT_NOT_REACHED;
      72             :         /* fall-through */
      73             :     case CAIRO_STATUS_SURFACE_TYPE_MISMATCH:
      74             :     case CAIRO_STATUS_INVALID_STATUS:
      75             :     case CAIRO_STATUS_INVALID_CONTENT:
      76             :     case CAIRO_STATUS_INVALID_FORMAT:
      77             :     case CAIRO_STATUS_INVALID_VISUAL:
      78             :     case CAIRO_STATUS_READ_ERROR:
      79             :     case CAIRO_STATUS_WRITE_ERROR:
      80             :     case CAIRO_STATUS_FILE_NOT_FOUND:
      81             :     case CAIRO_STATUS_TEMP_FILE_ERROR:
      82             :     case CAIRO_STATUS_INVALID_STRIDE:
      83             :     case CAIRO_STATUS_INVALID_SIZE:
      84             :     case CAIRO_STATUS_DEVICE_TYPE_MISMATCH:
      85             :     case CAIRO_STATUS_DEVICE_ERROR:
      86             :     case CAIRO_STATUS_INVALID_RESTORE:
      87             :     case CAIRO_STATUS_INVALID_POP_GROUP:
      88             :     case CAIRO_STATUS_NO_CURRENT_POINT:
      89             :     case CAIRO_STATUS_INVALID_MATRIX:
      90             :     case CAIRO_STATUS_NULL_POINTER:
      91             :     case CAIRO_STATUS_INVALID_STRING:
      92             :     case CAIRO_STATUS_INVALID_PATH_DATA:
      93             :     case CAIRO_STATUS_SURFACE_FINISHED:
      94             :     case CAIRO_STATUS_PATTERN_TYPE_MISMATCH:
      95             :     case CAIRO_STATUS_INVALID_DASH:
      96             :     case CAIRO_STATUS_INVALID_DSC_COMMENT:
      97             :     case CAIRO_STATUS_INVALID_INDEX:
      98             :     case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE:
      99             :     case CAIRO_STATUS_FONT_TYPE_MISMATCH:
     100             :     case CAIRO_STATUS_USER_FONT_IMMUTABLE:
     101             :     case CAIRO_STATUS_USER_FONT_ERROR:
     102             :     case CAIRO_STATUS_NEGATIVE_COUNT:
     103             :     case CAIRO_STATUS_INVALID_CLUSTERS:
     104             :     case CAIRO_STATUS_INVALID_SLANT:
     105             :     case CAIRO_STATUS_INVALID_WEIGHT:
     106             :     case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED:
     107             :     default:
     108           0 :         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
     109           0 :         return (cairo_region_t *) &_cairo_region_nil;
     110             :     }
     111             : }
     112             : 
     113             : /**
     114             :  * _cairo_region_set_error:
     115             :  * @region: a region
     116             :  * @status: a status value indicating an error
     117             :  *
     118             :  * Atomically sets region->status to @status and calls _cairo_error;
     119             :  * Does nothing if status is %CAIRO_STATUS_SUCCESS or any of the internal
     120             :  * status values.
     121             :  *
     122             :  * All assignments of an error status to region->status should happen
     123             :  * through _cairo_region_set_error(). Note that due to the nature of
     124             :  * the atomic operation, it is not safe to call this function on the
     125             :  * nil objects.
     126             :  *
     127             :  * The purpose of this function is to allow the user to set a
     128             :  * breakpoint in _cairo_error() to generate a stack trace for when the
     129             :  * user causes cairo to detect an error.
     130             :  *
     131             :  * Return value: the error status.
     132             :  **/
     133             : static cairo_status_t
     134           0 : _cairo_region_set_error (cairo_region_t *region,
     135             :                         cairo_status_t status)
     136             : {
     137           0 :     if (! _cairo_status_is_error (status))
     138           0 :         return status;
     139             : 
     140             :     /* Don't overwrite an existing error. This preserves the first
     141             :      * error, which is the most significant. */
     142           0 :     _cairo_status_set_error (&region->status, status);
     143             : 
     144           0 :     return _cairo_error (status);
     145             : }
     146             : 
     147             : void
     148           0 : _cairo_region_init (cairo_region_t *region)
     149             : {
     150             :     VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
     151             : 
     152           0 :     region->status = CAIRO_STATUS_SUCCESS;
     153           0 :     CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 0);
     154           0 :     pixman_region32_init (&region->rgn);
     155           0 : }
     156             : 
     157             : void
     158           0 : _cairo_region_init_rectangle (cairo_region_t *region,
     159             :                               const cairo_rectangle_int_t *rectangle)
     160             : {
     161             :     VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));
     162             : 
     163           0 :     region->status = CAIRO_STATUS_SUCCESS;
     164           0 :     CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 0);
     165           0 :     pixman_region32_init_rect (&region->rgn,
     166             :                                rectangle->x, rectangle->y,
     167           0 :                                rectangle->width, rectangle->height);
     168           0 : }
     169             : 
     170             : void
     171           0 : _cairo_region_fini (cairo_region_t *region)
     172             : {
     173           0 :     assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&region->ref_count));
     174           0 :     pixman_region32_fini (&region->rgn);
     175             :     VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t)));
     176           0 : }
     177             : 
     178             : /**
     179             :  * cairo_region_create:
     180             :  *
     181             :  * Allocates a new empty region object.
     182             :  *
     183             :  * Return value: A newly allocated #cairo_region_t. Free with
     184             :  *   cairo_region_destroy(). This function always returns a
     185             :  *   valid pointer; if memory cannot be allocated, then a special
     186             :  *   error object is returned where all operations on the object do nothing.
     187             :  *   You can check for this with cairo_region_status().
     188             :  *
     189             :  * Since: 1.10
     190             :  **/
     191             : cairo_region_t *
     192           0 : cairo_region_create (void)
     193             : {
     194             :     cairo_region_t *region;
     195             : 
     196           0 :     region = _cairo_malloc (sizeof (cairo_region_t));
     197           0 :     if (region == NULL)
     198           0 :         return (cairo_region_t *) &_cairo_region_nil;
     199             : 
     200           0 :     region->status = CAIRO_STATUS_SUCCESS;
     201           0 :     CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);
     202             : 
     203           0 :     pixman_region32_init (&region->rgn);
     204             : 
     205           0 :     return region;
     206             : }
     207             : slim_hidden_def (cairo_region_create);
     208             : 
     209             : /**
     210             :  * cairo_region_create_rectangles:
     211             :  * @rects: an array of @count rectangles
     212             :  * @count: number of rectangles
     213             :  *
     214             :  * Allocates a new region object containing the union of all given @rects.
     215             :  *
     216             :  * Return value: A newly allocated #cairo_region_t. Free with
     217             :  *   cairo_region_destroy(). This function always returns a
     218             :  *   valid pointer; if memory cannot be allocated, then a special
     219             :  *   error object is returned where all operations on the object do nothing.
     220             :  *   You can check for this with cairo_region_status().
     221             :  *
     222             :  * Since: 1.10
     223             :  **/
     224             : cairo_region_t *
     225           0 : cairo_region_create_rectangles (const cairo_rectangle_int_t *rects,
     226             :                                 int count)
     227             : {
     228             :     pixman_box32_t stack_pboxes[CAIRO_STACK_ARRAY_LENGTH (pixman_box32_t)];
     229           0 :     pixman_box32_t *pboxes = stack_pboxes;
     230             :     cairo_region_t *region;
     231             :     int i;
     232             : 
     233           0 :     region = _cairo_malloc (sizeof (cairo_region_t));
     234           0 :     if (unlikely (region == NULL))
     235           0 :         return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
     236             : 
     237           0 :     if (count > ARRAY_LENGTH (stack_pboxes)) {
     238           0 :         pboxes = _cairo_malloc_ab (count, sizeof (pixman_box32_t));
     239           0 :         if (unlikely (pboxes == NULL)) {
     240           0 :             free (region);
     241           0 :             return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
     242             :         }
     243             :     }
     244             : 
     245           0 :     for (i = 0; i < count; i++) {
     246           0 :         pboxes[i].x1 = rects[i].x;
     247           0 :         pboxes[i].y1 = rects[i].y;
     248           0 :         pboxes[i].x2 = rects[i].x + rects[i].width;
     249           0 :         pboxes[i].y2 = rects[i].y + rects[i].height;
     250             :     }
     251             : 
     252           0 :     i = pixman_region32_init_rects (&region->rgn, pboxes, count);
     253             : 
     254           0 :     if (pboxes != stack_pboxes)
     255           0 :         free (pboxes);
     256             : 
     257           0 :     if (unlikely (i == 0)) {
     258           0 :         free (region);
     259           0 :         return _cairo_region_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
     260             :     }
     261             : 
     262           0 :     CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);
     263           0 :     region->status = CAIRO_STATUS_SUCCESS;
     264           0 :     return region;
     265             : }
     266             : slim_hidden_def (cairo_region_create_rectangles);
     267             : 
     268             : /**
     269             :  * cairo_region_create_rectangle:
     270             :  * @rectangle: a #cairo_rectangle_int_t
     271             :  *
     272             :  * Allocates a new region object containing @rectangle.
     273             :  *
     274             :  * Return value: A newly allocated #cairo_region_t. Free with
     275             :  *   cairo_region_destroy(). This function always returns a
     276             :  *   valid pointer; if memory cannot be allocated, then a special
     277             :  *   error object is returned where all operations on the object do nothing.
     278             :  *   You can check for this with cairo_region_status().
     279             :  *
     280             :  * Since: 1.10
     281             :  **/
     282             : cairo_region_t *
     283           0 : cairo_region_create_rectangle (const cairo_rectangle_int_t *rectangle)
     284             : {
     285             :     cairo_region_t *region;
     286             : 
     287           0 :     region = _cairo_malloc (sizeof (cairo_region_t));
     288           0 :     if (unlikely (region == NULL))
     289           0 :         return (cairo_region_t *) &_cairo_region_nil;
     290             : 
     291           0 :     region->status = CAIRO_STATUS_SUCCESS;
     292           0 :     CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 1);
     293             : 
     294           0 :     pixman_region32_init_rect (&region->rgn,
     295             :                                rectangle->x, rectangle->y,
     296           0 :                                rectangle->width, rectangle->height);
     297             : 
     298           0 :     return region;
     299             : }
     300             : slim_hidden_def (cairo_region_create_rectangle);
     301             : 
     302             : /**
     303             :  * cairo_region_copy:
     304             :  * @original: a #cairo_region_t
     305             :  *
     306             :  * Allocates a new region object copying the area from @original.
     307             :  *
     308             :  * Return value: A newly allocated #cairo_region_t. Free with
     309             :  *   cairo_region_destroy(). This function always returns a
     310             :  *   valid pointer; if memory cannot be allocated, then a special
     311             :  *   error object is returned where all operations on the object do nothing.
     312             :  *   You can check for this with cairo_region_status().
     313             :  *
     314             :  * Since: 1.10
     315             :  **/
     316             : cairo_region_t *
     317           0 : cairo_region_copy (const cairo_region_t *original)
     318             : {
     319             :     cairo_region_t *copy;
     320             : 
     321           0 :     if (original != NULL && original->status)
     322           0 :         return (cairo_region_t *) &_cairo_region_nil;
     323             : 
     324           0 :     copy = cairo_region_create ();
     325           0 :     if (unlikely (copy->status))
     326           0 :         return copy;
     327             : 
     328           0 :     if (original != NULL &&
     329           0 :         ! pixman_region32_copy (&copy->rgn, CONST_CAST &original->rgn))
     330             :     {
     331           0 :         cairo_region_destroy (copy);
     332           0 :         return (cairo_region_t *) &_cairo_region_nil;
     333             :     }
     334             : 
     335           0 :     return copy;
     336             : }
     337             : slim_hidden_def (cairo_region_copy);
     338             : 
     339             : /**
     340             :  * cairo_region_reference:
     341             :  * @region: a #cairo_region_t
     342             :  *
     343             :  * Increases the reference count on @region by one. This prevents
     344             :  * @region from being destroyed until a matching call to
     345             :  * cairo_region_destroy() is made.
     346             :  *
     347             :  * Return value: the referenced #cairo_region_t.
     348             :  *
     349             :  * Since: 1.10
     350             :  **/
     351             : cairo_region_t *
     352           0 : cairo_region_reference (cairo_region_t *region)
     353             : {
     354           0 :     if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&region->ref_count))
     355           0 :         return NULL;
     356             : 
     357           0 :     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&region->ref_count));
     358             : 
     359           0 :     _cairo_reference_count_inc (&region->ref_count);
     360           0 :     return region;
     361             : }
     362             : slim_hidden_def (cairo_region_reference);
     363             : 
     364             : /**
     365             :  * cairo_region_destroy:
     366             :  * @region: a #cairo_region_t
     367             :  *
     368             :  * Destroys a #cairo_region_t object created with
     369             :  * cairo_region_create(), cairo_region_copy(), or
     370             :  * or cairo_region_create_rectangle().
     371             :  *
     372             :  * Since: 1.10
     373             :  **/
     374             : void
     375           0 : cairo_region_destroy (cairo_region_t *region)
     376             : {
     377           0 :     if (region == NULL || CAIRO_REFERENCE_COUNT_IS_INVALID (&region->ref_count))
     378           0 :         return;
     379             : 
     380           0 :     assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&region->ref_count));
     381             : 
     382           0 :     if (! _cairo_reference_count_dec_and_test (&region->ref_count))
     383           0 :         return;
     384             : 
     385           0 :     _cairo_region_fini (region);
     386           0 :     free (region);
     387             : }
     388             : slim_hidden_def (cairo_region_destroy);
     389             : 
     390             : /**
     391             :  * cairo_region_num_rectangles:
     392             :  * @region: a #cairo_region_t
     393             :  *
     394             :  * Returns the number of rectangles contained in @region.
     395             :  *
     396             :  * Return value: The number of rectangles contained in @region.
     397             :  *
     398             :  * Since: 1.10
     399             :  **/
     400             : int
     401           0 : cairo_region_num_rectangles (const cairo_region_t *region)
     402             : {
     403           0 :     if (region->status)
     404           0 :         return 0;
     405             : 
     406           0 :     return pixman_region32_n_rects (CONST_CAST &region->rgn);
     407             : }
     408             : slim_hidden_def (cairo_region_num_rectangles);
     409             : 
     410             : /**
     411             :  * cairo_region_get_rectangle:
     412             :  * @region: a #cairo_region_t
     413             :  * @nth: a number indicating which rectangle should be returned
     414             :  * @rectangle: return location for a #cairo_rectangle_int_t
     415             :  *
     416             :  * Stores the @nth rectangle from the region in @rectangle.
     417             :  *
     418             :  * Since: 1.10
     419             :  **/
     420             : void
     421           0 : cairo_region_get_rectangle (const cairo_region_t *region,
     422             :                             int nth,
     423             :                             cairo_rectangle_int_t *rectangle)
     424             : {
     425             :     pixman_box32_t *pbox;
     426             : 
     427           0 :     if (region->status) {
     428           0 :         rectangle->x = rectangle->y = 0;
     429           0 :         rectangle->width = rectangle->height = 0;
     430           0 :         return;
     431             :     }
     432             : 
     433           0 :     pbox = pixman_region32_rectangles (CONST_CAST &region->rgn, NULL) + nth;
     434             : 
     435           0 :     rectangle->x = pbox->x1;
     436           0 :     rectangle->y = pbox->y1;
     437           0 :     rectangle->width = pbox->x2 - pbox->x1;
     438           0 :     rectangle->height = pbox->y2 - pbox->y1;
     439             : }
     440             : slim_hidden_def (cairo_region_get_rectangle);
     441             : 
     442             : /**
     443             :  * cairo_region_get_extents:
     444             :  * @region: a #cairo_region_t
     445             :  * @extents: rectangle into which to store the extents
     446             :  *
     447             :  * Gets the bounding rectangle of @region as a #cairo_rectangle_int_t
     448             :  *
     449             :  * Since: 1.10
     450             :  **/
     451             : void
     452           0 : cairo_region_get_extents (const cairo_region_t *region,
     453             :                           cairo_rectangle_int_t *extents)
     454             : {
     455             :     pixman_box32_t *pextents;
     456             : 
     457           0 :     if (region->status) {
     458           0 :         extents->x = extents->y = 0;
     459           0 :         extents->width = extents->height = 0;
     460           0 :         return;
     461             :     }
     462             : 
     463           0 :     pextents = pixman_region32_extents (CONST_CAST &region->rgn);
     464             : 
     465           0 :     extents->x = pextents->x1;
     466           0 :     extents->y = pextents->y1;
     467           0 :     extents->width = pextents->x2 - pextents->x1;
     468           0 :     extents->height = pextents->y2 - pextents->y1;
     469             : }
     470             : slim_hidden_def (cairo_region_get_extents);
     471             : 
     472             : /**
     473             :  * cairo_region_status:
     474             :  * @region: a #cairo_region_t
     475             :  *
     476             :  * Checks whether an error has previous occured for this
     477             :  * region object.
     478             :  *
     479             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     480             :  *
     481             :  * Since: 1.10
     482             :  **/
     483             : cairo_status_t
     484           0 : cairo_region_status (const cairo_region_t *region)
     485             : {
     486           0 :     return region->status;
     487             : }
     488             : slim_hidden_def (cairo_region_status);
     489             : 
     490             : /**
     491             :  * cairo_region_subtract:
     492             :  * @dst: a #cairo_region_t
     493             :  * @other: another #cairo_region_t
     494             :  *
     495             :  * Subtracts @other from @dst and places the result in @dst
     496             :  *
     497             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     498             :  *
     499             :  * Since: 1.10
     500             :  **/
     501             : cairo_status_t
     502           0 : cairo_region_subtract (cairo_region_t *dst, const cairo_region_t *other)
     503             : {
     504           0 :     if (dst->status)
     505           0 :         return dst->status;
     506             : 
     507           0 :     if (other->status)
     508           0 :         return _cairo_region_set_error (dst, other->status);
     509             : 
     510           0 :     if (! pixman_region32_subtract (&dst->rgn,
     511             :                                     &dst->rgn,
     512           0 :                                     CONST_CAST &other->rgn))
     513             :     {
     514           0 :         return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
     515             :     }
     516             : 
     517           0 :     return CAIRO_STATUS_SUCCESS;
     518             : }
     519             : slim_hidden_def (cairo_region_subtract);
     520             : 
     521             : /**
     522             :  * cairo_region_subtract_rectangle:
     523             :  * @dst: a #cairo_region_t
     524             :  * @rectangle: a #cairo_rectangle_int_t
     525             :  *
     526             :  * Subtracts @rectangle from @dst and places the result in @dst
     527             :  *
     528             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     529             :  *
     530             :  * Since: 1.10
     531             :  **/
     532             : cairo_status_t
     533           0 : cairo_region_subtract_rectangle (cairo_region_t *dst,
     534             :                                  const cairo_rectangle_int_t *rectangle)
     535             : {
     536           0 :     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     537             :     pixman_region32_t region;
     538             : 
     539           0 :     if (dst->status)
     540           0 :         return dst->status;
     541             : 
     542           0 :     pixman_region32_init_rect (&region,
     543             :                                rectangle->x, rectangle->y,
     544           0 :                                rectangle->width, rectangle->height);
     545             : 
     546           0 :     if (! pixman_region32_subtract (&dst->rgn, &dst->rgn, &region))
     547           0 :         status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
     548             : 
     549           0 :     pixman_region32_fini (&region);
     550             : 
     551           0 :     return status;
     552             : }
     553             : slim_hidden_def (cairo_region_subtract_rectangle);
     554             : 
     555             : /**
     556             :  * cairo_region_intersect:
     557             :  * @dst: a #cairo_region_t
     558             :  * @other: another #cairo_region_t
     559             :  *
     560             :  * Computes the intersection of @dst with @other and places the result in @dst
     561             :  *
     562             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     563             :  *
     564             :  * Since: 1.10
     565             :  **/
     566             : cairo_status_t
     567           0 : cairo_region_intersect (cairo_region_t *dst, const cairo_region_t *other)
     568             : {
     569           0 :     if (dst->status)
     570           0 :         return dst->status;
     571             : 
     572           0 :     if (other->status)
     573           0 :         return _cairo_region_set_error (dst, other->status);
     574             : 
     575           0 :     if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, CONST_CAST &other->rgn))
     576           0 :         return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
     577             : 
     578           0 :     return CAIRO_STATUS_SUCCESS;
     579             : }
     580             : slim_hidden_def (cairo_region_intersect);
     581             : 
     582             : /**
     583             :  * cairo_region_intersect_rectangle:
     584             :  * @dst: a #cairo_region_t
     585             :  * @rectangle: a #cairo_rectangle_int_t
     586             :  *
     587             :  * Computes the intersection of @dst with @rectangle and places the
     588             :  * result in @dst
     589             :  *
     590             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     591             :  *
     592             :  * Since: 1.10
     593             :  **/
     594             : cairo_status_t
     595           0 : cairo_region_intersect_rectangle (cairo_region_t *dst,
     596             :                                   const cairo_rectangle_int_t *rectangle)
     597             : {
     598           0 :     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     599             :     pixman_region32_t region;
     600             : 
     601           0 :     if (dst->status)
     602           0 :         return dst->status;
     603             : 
     604           0 :     pixman_region32_init_rect (&region,
     605             :                                rectangle->x, rectangle->y,
     606           0 :                                rectangle->width, rectangle->height);
     607             : 
     608           0 :     if (! pixman_region32_intersect (&dst->rgn, &dst->rgn, &region))
     609           0 :         status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
     610             : 
     611           0 :     pixman_region32_fini (&region);
     612             : 
     613           0 :     return status;
     614             : }
     615             : slim_hidden_def (cairo_region_intersect_rectangle);
     616             : 
     617             : /**
     618             :  * cairo_region_union:
     619             :  * @dst: a #cairo_region_t
     620             :  * @other: another #cairo_region_t
     621             :  *
     622             :  * Computes the union of @dst with @other and places the result in @dst
     623             :  *
     624             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     625             :  *
     626             :  * Since: 1.10
     627             :  **/
     628             : cairo_status_t
     629           0 : cairo_region_union (cairo_region_t *dst,
     630             :                     const cairo_region_t *other)
     631             : {
     632           0 :     if (dst->status)
     633           0 :         return dst->status;
     634             : 
     635           0 :     if (other->status)
     636           0 :         return _cairo_region_set_error (dst, other->status);
     637             : 
     638           0 :     if (! pixman_region32_union (&dst->rgn, &dst->rgn, CONST_CAST &other->rgn))
     639           0 :         return _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
     640             : 
     641           0 :     return CAIRO_STATUS_SUCCESS;
     642             : }
     643             : slim_hidden_def (cairo_region_union);
     644             : 
     645             : /**
     646             :  * cairo_region_union_rectangle:
     647             :  * @dst: a #cairo_region_t
     648             :  * @rectangle: a #cairo_rectangle_int_t
     649             :  *
     650             :  * Computes the union of @dst with @rectangle and places the result in @dst.
     651             :  *
     652             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     653             :  *
     654             :  * Since: 1.10
     655             :  **/
     656             : cairo_status_t
     657           0 : cairo_region_union_rectangle (cairo_region_t *dst,
     658             :                               const cairo_rectangle_int_t *rectangle)
     659             : {
     660           0 :     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     661             :     pixman_region32_t region;
     662             : 
     663           0 :     if (dst->status)
     664           0 :         return dst->status;
     665             : 
     666           0 :     pixman_region32_init_rect (&region,
     667             :                                rectangle->x, rectangle->y,
     668           0 :                                rectangle->width, rectangle->height);
     669             : 
     670           0 :     if (! pixman_region32_union (&dst->rgn, &dst->rgn, &region))
     671           0 :         status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
     672             : 
     673           0 :     pixman_region32_fini (&region);
     674             : 
     675           0 :     return status;
     676             : }
     677             : slim_hidden_def (cairo_region_union_rectangle);
     678             : 
     679             : /**
     680             :  * cairo_region_xor:
     681             :  * @dst: a #cairo_region_t
     682             :  * @other: another #cairo_region_t
     683             :  *
     684             :  * Computes the exclusive difference of @dst with @other and places the
     685             :  * result in @dst. That is, @dst will be set to contain all areas that
     686             :  * are either in @dst or in @other, but not in both.
     687             :  *
     688             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     689             :  *
     690             :  * Since: 1.10
     691             :  **/
     692             : cairo_status_t
     693           0 : cairo_region_xor (cairo_region_t *dst, const cairo_region_t *other)
     694             : {
     695           0 :     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     696             :     pixman_region32_t tmp;
     697             : 
     698           0 :     if (dst->status)
     699           0 :         return dst->status;
     700             : 
     701           0 :     if (other->status)
     702           0 :         return _cairo_region_set_error (dst, other->status);
     703             : 
     704           0 :     pixman_region32_init (&tmp);
     705             : 
     706             :     /* XXX: get an xor function into pixman */
     707           0 :     if (! pixman_region32_subtract (&tmp, CONST_CAST &other->rgn, &dst->rgn) ||
     708           0 :         ! pixman_region32_subtract (&dst->rgn, &dst->rgn, CONST_CAST &other->rgn) || 
     709           0 :         ! pixman_region32_union (&dst->rgn, &dst->rgn, &tmp))
     710           0 :         status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
     711             : 
     712           0 :     pixman_region32_fini (&tmp);
     713             : 
     714           0 :     return status;
     715             : }
     716             : slim_hidden_def (cairo_region_xor);
     717             : 
     718             : /**
     719             :  * cairo_region_xor_rectangle:
     720             :  * @dst: a #cairo_region_t
     721             :  * @rectangle: a #cairo_rectangle_int_t
     722             :  *
     723             :  * Computes the exclusive difference of @dst with @rectangle and places the
     724             :  * result in @dst. That is, @dst will be set to contain all areas that are 
     725             :  * either in @dst or in @rectangle, but not in both.
     726             :  *
     727             :  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
     728             :  *
     729             :  * Since: 1.10
     730             :  **/
     731             : cairo_status_t
     732           0 : cairo_region_xor_rectangle (cairo_region_t *dst,
     733             :                             const cairo_rectangle_int_t *rectangle)
     734             : {
     735           0 :     cairo_status_t status = CAIRO_STATUS_SUCCESS;
     736             :     pixman_region32_t region, tmp;
     737             : 
     738           0 :     if (dst->status)
     739           0 :         return dst->status;
     740             : 
     741           0 :     pixman_region32_init_rect (&region,
     742             :                                rectangle->x, rectangle->y,
     743           0 :                                rectangle->width, rectangle->height);
     744           0 :     pixman_region32_init (&tmp);
     745             : 
     746             :     /* XXX: get an xor function into pixman */
     747           0 :     if (! pixman_region32_subtract (&tmp, &region, &dst->rgn) ||
     748           0 :         ! pixman_region32_subtract (&dst->rgn, &dst->rgn, &region) || 
     749           0 :         ! pixman_region32_union (&dst->rgn, &dst->rgn, &tmp))
     750           0 :         status = _cairo_region_set_error (dst, CAIRO_STATUS_NO_MEMORY);
     751             : 
     752           0 :     pixman_region32_fini (&tmp);
     753           0 :     pixman_region32_fini (&region);
     754             : 
     755           0 :     return status;
     756             : }
     757             : slim_hidden_def (cairo_region_xor_rectangle);
     758             : 
     759             : /**
     760             :  * cairo_region_is_empty:
     761             :  * @region: a #cairo_region_t
     762             :  *
     763             :  * Checks whether @region is empty.
     764             :  *
     765             :  * Return value: %TRUE if @region is empty, %FALSE if it isn't.
     766             :  *
     767             :  * Since: 1.10
     768             :  **/
     769             : cairo_bool_t
     770           0 : cairo_region_is_empty (const cairo_region_t *region)
     771             : {
     772           0 :     if (region->status)
     773           0 :         return TRUE;
     774             : 
     775           0 :     return ! pixman_region32_not_empty (CONST_CAST &region->rgn);
     776             : }
     777             : slim_hidden_def (cairo_region_is_empty);
     778             : 
     779             : /**
     780             :  * cairo_region_translate:
     781             :  * @region: a #cairo_region_t
     782             :  * @dx: Amount to translate in the x direction
     783             :  * @dy: Amount to translate in the y direction
     784             :  *
     785             :  * Translates @region by (@dx, @dy).
     786             :  *
     787             :  * Since: 1.10
     788             :  **/
     789             : void
     790           0 : cairo_region_translate (cairo_region_t *region,
     791             :                         int dx, int dy)
     792             : {
     793           0 :     if (region->status)
     794           0 :         return;
     795             : 
     796           0 :     pixman_region32_translate (&region->rgn, dx, dy);
     797             : }
     798             : slim_hidden_def (cairo_region_translate);
     799             : 
     800             : /**
     801             :  * cairo_region_overlap_t:
     802             :  * @CAIRO_REGION_OVERLAP_IN: The contents are entirely inside the region
     803             :  * @CAIRO_REGION_OVERLAP_OUT: The contents are entirely outside the region
     804             :  * @CAIRO_REGION_OVERLAP_PART: The contents are partially inside and
     805             :  *     partially outside the region.
     806             :  * 
     807             :  * Used as the return value for cairo_region_contains_rectangle().
     808             :  */
     809             : 
     810             : /**
     811             :  * cairo_region_contains_rectangle:
     812             :  * @region: a #cairo_region_t
     813             :  * @rectangle: a #cairo_rectangle_int_t
     814             :  *
     815             :  * Checks whether @rectangle is inside, outside or partially contained
     816             :  * in @region
     817             :  *
     818             :  * Return value:
     819             :  *   %CAIRO_REGION_OVERLAP_IN if @rectangle is entirely inside @region,
     820             :  *   %CAIRO_REGION_OVERLAP_OUT if @rectangle is entirely outside @region, or
     821             :  *   %CAIRO_REGION_OVERLAP_PART if @rectangle is partially inside and partially outside @region.
     822             :  *
     823             :  * Since: 1.10
     824             :  **/
     825             : cairo_region_overlap_t
     826           0 : cairo_region_contains_rectangle (const cairo_region_t *region,
     827             :                                  const cairo_rectangle_int_t *rectangle)
     828             : {
     829             :     pixman_box32_t pbox;
     830             :     pixman_region_overlap_t poverlap;
     831             : 
     832           0 :     if (region->status)
     833           0 :         return CAIRO_REGION_OVERLAP_OUT;
     834             : 
     835           0 :     pbox.x1 = rectangle->x;
     836           0 :     pbox.y1 = rectangle->y;
     837           0 :     pbox.x2 = rectangle->x + rectangle->width;
     838           0 :     pbox.y2 = rectangle->y + rectangle->height;
     839             : 
     840           0 :     poverlap = pixman_region32_contains_rectangle (CONST_CAST &region->rgn,
     841             :                                                    &pbox);
     842           0 :     switch (poverlap) {
     843             :     default:
     844           0 :     case PIXMAN_REGION_OUT:  return CAIRO_REGION_OVERLAP_OUT;
     845           0 :     case PIXMAN_REGION_IN:   return CAIRO_REGION_OVERLAP_IN;
     846           0 :     case PIXMAN_REGION_PART: return CAIRO_REGION_OVERLAP_PART;
     847             :     }
     848             : }
     849             : slim_hidden_def (cairo_region_contains_rectangle);
     850             : 
     851             : /**
     852             :  * cairo_region_contains_point:
     853             :  * @region: a #cairo_region_t
     854             :  * @x: the x coordinate of a point
     855             :  * @y: the y coordinate of a point
     856             :  *
     857             :  * Checks whether (@x, @y) is contained in @region.
     858             :  *
     859             :  * Return value: %TRUE if (@x, @y) is contained in @region, %FALSE if it is not.
     860             :  *
     861             :  * Since: 1.10
     862             :  **/
     863             : cairo_bool_t
     864           0 : cairo_region_contains_point (const cairo_region_t *region,
     865             :                              int x, int y)
     866             : {
     867             :     pixman_box32_t box;
     868             : 
     869           0 :     if (region->status)
     870           0 :         return FALSE;
     871             : 
     872           0 :     return pixman_region32_contains_point (CONST_CAST &region->rgn, x, y, &box);
     873             : }
     874             : slim_hidden_def (cairo_region_contains_point);
     875             : 
     876             : /**
     877             :  * cairo_region_equal:
     878             :  * @a: a #cairo_region_t or %NULL
     879             :  * @b: a #cairo_region_t or %NULL
     880             :  *
     881             :  * Compares whether region_a is equivalent to region_b. %NULL as an argument
     882             :  * is equal to itself, but not to any non-%NULL region.
     883             :  *
     884             :  * Return value: %TRUE if both regions contained the same coverage,
     885             :  * %FALSE if it is not or any region is in an error status.
     886             :  *
     887             :  * Since: 1.10
     888             :  **/
     889             : cairo_bool_t
     890           0 : cairo_region_equal (const cairo_region_t *a,
     891             :                     const cairo_region_t *b)
     892             : {
     893             :     /* error objects are never equal */
     894           0 :     if ((a != NULL && a->status) || (b != NULL && b->status))
     895           0 :         return FALSE;
     896             : 
     897           0 :     if (a == b)
     898           0 :         return TRUE;
     899             : 
     900           0 :     if (a == NULL || b == NULL)
     901           0 :         return FALSE;
     902             : 
     903           0 :     return pixman_region32_equal (CONST_CAST &a->rgn, CONST_CAST &b->rgn);
     904             : }
     905             : slim_hidden_def (cairo_region_equal);

Generated by: LCOV version 1.13