LCOV - code coverage report
Current view: directory - gfx/cairo/cairo/src - cairo-region.c (source / functions) Found Hit Coverage
Test: app.info Lines: 232 0 0.0 %
Date: 2012-06-02 Functions: 51 0 0.0 %

       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.7