LCOV - code coverage report
Current view: top level - src - region.c (source / functions) Coverage Total Hit
Test: PHP Cairo Extension Coverage Lines: 89.5 % 276 247
Test Date: 2025-09-10 21:28:33 Functions: 100.0 % 25 25

            Line data    Source code
       1              : /*
       2              :   +----------------------------------------------------------------------+
       3              :   | For PHP Version 8                                                    |
       4              :   +----------------------------------------------------------------------+
       5              :   | Copyright (c) 2015 Elizabeth M Smith                                 |
       6              :   +----------------------------------------------------------------------+
       7              :   | http://www.opensource.org/licenses/mit-license.php  MIT License      |
       8              :   | Also available in LICENSE                                            |
       9              :   +----------------------------------------------------------------------+
      10              :   | Authors: Elizabeth M Smith <auroraeosrose@gmail.com>                 |
      11              :   |          Swen Zanon <swen.zanon@geoglis.de>                          |
      12              :   +----------------------------------------------------------------------+
      13              : */
      14              : 
      15              : #ifdef HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : #include <cairo.h>
      20              : #include <php.h>
      21              : #include <zend_exceptions.h>
      22              : 
      23              : #include "php_cairo.h"
      24              : #include "php_cairo_internal.h"
      25              : #include "region_arginfo.h"
      26              : 
      27              : zend_class_entry *ce_cairo_region;
      28              : zend_class_entry *ce_cairo_region_overlap;
      29              : 
      30              : static zend_object_handlers cairo_region_object_handlers;
      31              : 
      32              : typedef struct _cairo_region_object {
      33              :     cairo_region_t *region;
      34              :     zend_object std;
      35              : } cairo_region_object;
      36              : 
      37          197 : static inline cairo_region_object *cairo_region_fetch_object(zend_object *object)
      38              : {
      39          197 :     return (cairo_region_object *) ((char*)(object) - XtOffsetOf(cairo_region_object, std));
      40              : }
      41              : 
      42              : #define Z_CAIRO_REGION_P(zv) cairo_region_fetch_object(Z_OBJ_P(zv))
      43              : 
      44           92 : cairo_region_object *cairo_region_object_get(zval *zv)
      45              : {
      46           92 :     cairo_region_object *object = Z_CAIRO_REGION_P(zv);
      47           92 :     if (object->region == NULL) {
      48            0 :         zend_throw_exception_ex(ce_cairo_exception, 0,
      49              :             "Internal region object missing in %s, you must call parent::__construct in extended classes.",
      50            0 :             ZSTR_VAL(Z_OBJCE_P(zv)->name));
      51            0 :         return NULL;
      52              :     }
      53           92 :     return object;
      54              : }
      55              : 
      56              : /* ----------------------------------------------------------------
      57              :     \Cairo\Region Object management
      58              : ------------------------------------------------------------------*/
      59              : 
      60              : /* {{{ */
      61           47 : static void cairo_region_free_obj(zend_object *object)
      62              : {
      63           47 :     cairo_region_object *intern = cairo_region_fetch_object(object);
      64              : 
      65           47 :     if (!intern) {
      66            0 :         return;
      67              :     }
      68              : 
      69           47 :     if (intern->region) {
      70           44 :         cairo_region_destroy(intern->region);
      71           44 :         intern->region = NULL;
      72              :     }
      73              : 
      74           47 :     zend_object_std_dtor(&intern->std);
      75              : }
      76              : 
      77              : /* {{{ */
      78           47 : static zend_object* cairo_region_obj_ctor(zend_class_entry *ce, cairo_region_object **intern)
      79              : {
      80           47 :     cairo_region_object *object = ecalloc(1, sizeof(cairo_region_object) + zend_object_properties_size(ce));
      81              : 
      82           47 :     object->region = NULL;
      83              : 
      84           47 :     zend_object_std_init(&object->std, ce);
      85           47 :     object->std.handlers = &cairo_region_object_handlers;
      86           47 :     *intern = object;
      87              : 
      88           47 :     return &object->std;
      89              : }
      90              : /* }}} */
      91              : 
      92              : /* {{{ */
      93           45 : static zend_object* cairo_region_create_object(zend_class_entry *ce)
      94              : {
      95           45 :     cairo_region_object *region_obj = NULL;
      96           45 :     zend_object *return_value = cairo_region_obj_ctor(ce, &region_obj);
      97              : 
      98           45 :     object_properties_init(&region_obj->std, ce);
      99           45 :     return return_value;
     100              : }
     101              : /* }}} */
     102              : 
     103              : /* {{{ */
     104            2 : static zend_object* cairo_region_clone_obj(zend_object *old_object)
     105              : {
     106              :     cairo_region_object *new_region;
     107            2 :     cairo_region_object *old_region = cairo_region_fetch_object(old_object);
     108            2 :     zend_object *return_value = cairo_region_obj_ctor(old_object->ce, &new_region);
     109              : 
     110            2 :     new_region->region = old_region->region;
     111            2 :     cairo_region_reference(old_region->region);
     112              : 
     113            2 :     zend_objects_clone_members(&new_region->std, &old_region->std);
     114              : 
     115            2 :     return return_value;
     116              : }
     117              : /* }}} */
     118              : 
     119              : 
     120              : /* ----------------------------------------------------------------
     121              :     \Cairo\Region Class API
     122              : ------------------------------------------------------------------ */
     123              : 
     124              : /* {{{ proto void __contruct([void | Cairo\Rectangle $rect | array Cairo\Rectangle $rects])
     125              :     Creates a new region - optionally with a single or union of multiple rectangles inside */
     126           45 : PHP_METHOD(Cairo_Region, __construct)
     127              : {
     128              :     cairo_region_object *region_object;
     129           45 :     zval *rectangles_zval = NULL;
     130           45 :     long num_rectangles = 0;
     131              :     HashTable *rectangles_hash;
     132              :     cairo_rectangle_t *rectangle;
     133              :     cairo_rectangle_int_t *rectangles_array;
     134              :     cairo_rectangle_int_t int_rect;
     135           45 :     int i = 0;
     136              :     zval *pzval;
     137              : 
     138           45 :     ZEND_PARSE_PARAMETERS_START(0, 1)
     139           44 :         Z_PARAM_OPTIONAL
     140           44 :         Z_PARAM_ZVAL(rectangles_zval)
     141           47 :     ZEND_PARSE_PARAMETERS_END();
     142              : 
     143           88 :     region_object = Z_CAIRO_REGION_P(getThis());
     144           44 :     if (!region_object) {
     145            0 :         RETURN_NULL();
     146              :     }
     147              : 
     148           44 :     if (rectangles_zval == NULL) {
     149           17 :         region_object->region = cairo_region_create();
     150           54 :     } else if (Z_TYPE_P(rectangles_zval) == IS_OBJECT) {
     151           19 :         rectangle = cairo_rectangle_object_get_rect(rectangles_zval);
     152           19 :         int_rect = cairo_expand_to_rectangle_int(rectangle);
     153           19 :         region_object->region = cairo_region_create_rectangle(&int_rect);
     154           16 :     } else if (Z_TYPE_P(rectangles_zval) == IS_ARRAY) {
     155              : 
     156              :         /* Grab the zend hash and see how big our array will be */
     157            7 :         rectangles_hash = Z_ARRVAL_P(rectangles_zval);
     158            7 :         num_rectangles = zend_hash_num_elements(rectangles_hash);
     159            7 :         rectangles_array = ecalloc(num_rectangles, sizeof(cairo_rectangle_int_t));
     160              : 
     161              :         /* iterate over the array*/
     162           34 :         ZEND_HASH_FOREACH_VAL(rectangles_hash, pzval) {
     163           14 :             if (Z_TYPE_P(pzval) != IS_OBJECT || Z_OBJCE_P(pzval) != ce_cairo_rectangle) {
     164            1 :                 zend_throw_exception(zend_ce_type_error, "Cairo\\Region::__construct(): Argument #1 ($rectangle) must be empty, a Cairo\\Rectangle object, or an array of Cairo\\Rectangle objects.", 0);
     165            1 :                 efree(rectangles_array);
     166            1 :                 RETURN_THROWS();
     167              :             }
     168           13 :             rectangles_array[i++] = cairo_expand_to_rectangle_int(cairo_rectangle_object_get_rect(pzval));
     169              :         } ZEND_HASH_FOREACH_END();
     170              : 
     171            6 :         region_object->region = cairo_region_create_rectangles(rectangles_array, i);
     172            6 :         efree(rectangles_array);
     173              : 
     174              :     } else {
     175            1 :         zend_throw_exception(zend_ce_type_error, "Cairo\\Region::__construct(): Argument #1 ($rectangle) must be empty, a Cairo\\Rectangle object, or an array of Cairo\\Rectangle objects.", 0);
     176            1 :         RETURN_THROWS();
     177              :     }
     178              : 
     179           42 :     if (php_cairo_throw_exception(cairo_region_status(region_object->region))) {
     180            0 :         RETURN_THROWS();
     181              :     }
     182              : }
     183              : /* }}} */
     184              : 
     185              : /* {{{ proto \Cairo\Status \Cairo\Region::getStatus()
     186              :    Checks whether an error has previous occurred for this region object. Returns CAIRO_STATUS_SUCCESS or CAIRO_STATUS_NO_MEMORY */
     187            2 : PHP_METHOD(Cairo_Region, getStatus)
     188              : {
     189              :     cairo_region_object *region_object;
     190              :     zval status_case;
     191              : 
     192            3 :     ZEND_PARSE_PARAMETERS_NONE();
     193              : 
     194            2 :     region_object = cairo_region_object_get(getThis());
     195            1 :     if (!region_object) {
     196            0 :         RETURN_THROWS();
     197              :     }
     198              : 
     199            1 :     status_case = php_enum_from_cairo_c_enum(
     200              :         ce_cairo_status,
     201            1 :         cairo_region_status(region_object->region)
     202              :     );
     203              : 
     204            1 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     205            2 :         RETURN_ZVAL(&status_case, 1, 1);
     206              :     }
     207              : }
     208              : /* }}} */
     209              : 
     210              : /* {{{ proto long \Cairo\Region::getExtents()
     211              :    Gets the bounding rectangle of a region. Returns a \Cairo\Rectangle. */
     212           27 : PHP_METHOD(Cairo_Region, getExtents)
     213              : {
     214              :     cairo_region_object *region_object;
     215              :     cairo_rectangle_object *rectangle_object;
     216              :     cairo_rectangle_int_t *int_rect;
     217              : 
     218           27 :     ZEND_PARSE_PARAMETERS_NONE();
     219              : 
     220           52 :     region_object = cairo_region_object_get(getThis());
     221           26 :     if (!region_object) {
     222            0 :         RETURN_THROWS();
     223              :     }
     224              : 
     225           26 :     cairo_region_get_extents(region_object->region, int_rect);
     226              : 
     227           26 :     object_init_ex(return_value, php_cairo_get_rectangle_ce());
     228           26 :     rectangle_object = Z_CAIRO_RECTANGLE_P(return_value);
     229           26 :     cairo_rectangle_int_to_double(int_rect, rectangle_object->rect);
     230              : }
     231              : /* }}} */
     232              : 
     233              : /* {{{ proto long \Cairo\Region::getNumRectangles()
     234              :    Returns the number of rectangles contained in region. */
     235           27 : PHP_METHOD(Cairo_Region, getNumRectangles)
     236              : {
     237              :     cairo_region_object *region_object;
     238              : 
     239           27 :     ZEND_PARSE_PARAMETERS_NONE();
     240              : 
     241           52 :     region_object = cairo_region_object_get(getThis());
     242           26 :     if (!region_object) {
     243            0 :         RETURN_THROWS();
     244              :     }
     245              : 
     246           26 :     RETVAL_LONG(cairo_region_num_rectangles(region_object->region));
     247              : }
     248              : /* }}} */
     249              : 
     250              : /* {{{ proto long \Cairo\Region::getRectangle(int number).
     251              :    Returns the nth rectangle in region or false if rectangle does not exist. */
     252            5 : PHP_METHOD(Cairo_Region, getRectangle)
     253              : {
     254              :     long rectId;
     255              :     cairo_region_object *region_object;
     256              :     cairo_rectangle_object *rectangle_object;
     257              :     cairo_rectangle_int_t int_rect;
     258              : 
     259            5 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     260           10 :         Z_PARAM_LONG(rectId)
     261            5 :     ZEND_PARSE_PARAMETERS_END();
     262              : 
     263            8 :     region_object = cairo_region_object_get(getThis());
     264            4 :     if (!region_object) {
     265            0 :         RETURN_THROWS();
     266              :     }
     267              : 
     268            4 :     if (rectId > cairo_region_num_rectangles(region_object->region) - 1) {
     269            1 :         RETURN_FALSE;
     270              :     }
     271              : 
     272            3 :     cairo_region_get_rectangle(region_object->region, rectId, &int_rect);
     273              : 
     274            3 :     object_init_ex(return_value, php_cairo_get_rectangle_ce());
     275            3 :     rectangle_object = Z_CAIRO_RECTANGLE_P(return_value);
     276            3 :     cairo_rectangle_int_to_double(&int_rect, rectangle_object->rect);
     277              : }
     278              : /* }}} */
     279              : 
     280              : /* {{{ proto bool \Cairo\Region::isEmpty()
     281              :    Checks whether region is empty. Returns TRUE if region is empty, FALSE if it isn't. */
     282            2 : PHP_METHOD(Cairo_Region, isEmpty)
     283              : {
     284              :     cairo_region_object *region_object;
     285              : 
     286            2 :     ZEND_PARSE_PARAMETERS_NONE();
     287              : 
     288            2 :     region_object = cairo_region_object_get(getThis());
     289            1 :     if (!region_object) {
     290            0 :         RETURN_THROWS();
     291              :     }
     292              : 
     293            1 :     RETVAL_BOOL(cairo_region_is_empty(region_object->region));
     294              : }
     295              : /* }}} */
     296              : 
     297              : /* {{{ proto long \Cairo\Region::containsPoint(long x, long y)
     298              :    Checks whether (x, y) is contained in region. Returns TRUE if (x, y) is contained in region, FALSE if it is not. */
     299           11 : PHP_METHOD(Cairo_Region, containsPoint)
     300              : {
     301              :     long x, y;
     302              :     cairo_region_object *region_object;
     303              : 
     304           11 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     305           18 :         Z_PARAM_LONG(x)
     306           18 :         Z_PARAM_LONG(y)
     307           11 :     ZEND_PARSE_PARAMETERS_END();
     308              : 
     309           18 :     region_object = cairo_region_object_get(getThis());
     310            9 :     if (!region_object) {
     311            0 :         RETURN_THROWS();
     312              :     }
     313              : 
     314            9 :     RETVAL_BOOL(cairo_region_contains_point(region_object->region, x, y));
     315              : }
     316              : /* }}} */
     317              : 
     318              : /* {{{ proto \Cairo\Region\Overlap \Cairo\Region::containsRectangle(Cairo\Rectangle $rect)
     319              :    Checks whether rectangle is inside, outside or partially contained in region.
     320              :    Returns OVERLAP::IN if rectangle is entirely inside region,
     321              :    OVERLAP::OUT if rectangle is entirely outside region, or
     322              :    OVERLAP::PART if rectangle is partially inside and partially outside region. */
     323            7 : PHP_METHOD(Cairo_Region, containsRectangle)
     324              : {
     325              :     cairo_rectangle_object *rectangle_object;
     326              :     cairo_region_object *region_object;
     327              :     zval *rectangle_zval;
     328              :     zval region_overlap_case;
     329              :     cairo_rectangle_int_t int_rect;
     330              : 
     331            7 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     332           10 :         Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
     333           11 :     ZEND_PARSE_PARAMETERS_END();
     334              : 
     335            8 :     region_object = cairo_region_object_get(getThis());
     336            4 :     if (!region_object) {
     337            0 :         RETURN_THROWS();
     338              :     }
     339              : 
     340            4 :     rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
     341            4 :     if (!rectangle_object) {
     342            0 :         RETURN_NULL();
     343              :     }
     344              : 
     345            4 :     int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
     346              : 
     347            4 :     region_overlap_case = php_enum_from_cairo_c_enum(
     348              :         ce_cairo_region_overlap,
     349            4 :         cairo_region_contains_rectangle(region_object->region, &int_rect)
     350              :     );
     351              : 
     352            4 :     if (Z_TYPE(region_overlap_case) == IS_OBJECT) {
     353            8 :         RETURN_ZVAL(&region_overlap_case, 1, 1);
     354              :     }
     355              : }
     356              : /* }}} */
     357              : 
     358              : /* {{{ proto long \Cairo\Region::equal(\Cairo\Region region)
     359              :    Compares whether region_a is equivalent to region_b. NULL as an argument is equal to itself, but not to any non-NULL region. */
     360            7 : PHP_METHOD(Cairo_Region, equal)
     361              : {
     362            7 :     zval *other_region = NULL;
     363              :     cairo_region_object *region_obj, *other_region_obj;
     364              : 
     365            7 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     366           12 :         Z_PARAM_OBJECT_OF_CLASS_OR_NULL(other_region, ce_cairo_region)
     367            8 :     ZEND_PARSE_PARAMETERS_END();
     368              : 
     369           10 :     region_obj = cairo_region_object_get(getThis());
     370            5 :     if (!region_obj) {
     371            0 :         RETURN_THROWS();
     372              :     }
     373              : 
     374            5 :     if (other_region == NULL) {
     375            1 :         RETURN_TRUE;
     376              :     }
     377              : 
     378            4 :     other_region_obj = Z_CAIRO_REGION_P(other_region);
     379            4 :     RETVAL_BOOL(cairo_region_equal(region_obj->region, other_region_obj->region));
     380              : }
     381              : /* }}} */
     382              : 
     383              : /* {{{ proto long \Cairo\Region::translate(long dx, long dy)
     384              :    Translates region by (dx, dy). */
     385            5 : PHP_METHOD(Cairo_Region, translate)
     386              : {
     387              :     long dx, dy;
     388              :     cairo_region_object *region_object;
     389              : 
     390            5 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     391            4 :         Z_PARAM_LONG(dx)
     392            4 :         Z_PARAM_LONG(dy)
     393            5 :     ZEND_PARSE_PARAMETERS_END();
     394              : 
     395            4 :     region_object = cairo_region_object_get(getThis());
     396            2 :     if (!region_object) {
     397            0 :         RETURN_THROWS();
     398              :     }
     399              : 
     400            2 :     cairo_region_translate(region_object->region, dx, dy);
     401            2 :     if (php_cairo_throw_exception(cairo_region_status(region_object->region))) {
     402            0 :         RETURN_THROWS();
     403              :     }
     404              : }
     405              : /* }}} */
     406              : 
     407              : /* {{{ proto \Cairo\Status \Cairo\Region::intersect(\Cairo\Region other_region)
     408              :    Computes the intersection with other_region and stores the result. */
     409            4 : PHP_METHOD(Cairo_Region, intersect)
     410              : {
     411              :     cairo_region_object *region_obj, *other_region_obj;
     412              :     zval *other_region;
     413              :     zval status_case;
     414              : 
     415            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     416            6 :         Z_PARAM_OBJECT_OF_CLASS(other_region, ce_cairo_region)
     417            6 :     ZEND_PARSE_PARAMETERS_END();
     418              : 
     419            4 :     region_obj = cairo_region_object_get(getThis());
     420            2 :     if (!region_obj) {
     421            0 :         RETURN_THROWS();
     422              :     }
     423              : 
     424            2 :     other_region_obj = Z_CAIRO_REGION_P(other_region);
     425              : 
     426            2 :     status_case = php_enum_from_cairo_c_enum(
     427              :         ce_cairo_status,
     428            2 :         cairo_region_intersect(region_obj->region, other_region_obj->region)
     429              :     );
     430              : 
     431            2 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     432            4 :         RETURN_ZVAL(&status_case, 1, 1);
     433              :     }
     434              : }
     435              : /* }}} */
     436              : 
     437              : /* {{{ proto \Cairo\Status \Cairo\Region::intersectRectangle(Cairo\Rectangle $rect)
     438              :    Computes the intersection with rectangle and stores the result. */
     439            3 : PHP_METHOD(Cairo_Region, intersectRectangle)
     440              : {
     441              :     cairo_rectangle_object *rectangle_object;
     442              :     cairo_region_object *region_object;
     443              :     zval *rectangle_zval;
     444              :     zval status_case;
     445              :     cairo_rectangle_int_t int_rect;
     446              : 
     447            3 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     448            4 :         Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
     449            4 :     ZEND_PARSE_PARAMETERS_END();
     450              : 
     451            2 :     region_object = cairo_region_object_get(getThis());
     452            1 :     if (!region_object) {
     453            0 :         RETURN_THROWS();
     454              :     }
     455              : 
     456            1 :     rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
     457            1 :     if (!rectangle_object) {
     458            0 :         RETURN_NULL();
     459              :     }
     460              : 
     461            1 :     int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
     462              : 
     463            1 :     status_case = php_enum_from_cairo_c_enum(
     464              :         ce_cairo_status,
     465            1 :         cairo_region_intersect_rectangle(region_object->region, &int_rect)
     466              :     );
     467              : 
     468            1 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     469            2 :         RETURN_ZVAL(&status_case, 1, 1);
     470              :     }
     471              : }
     472              : /* }}} */
     473              : 
     474              : /* {{{ proto \Cairo\Status \Cairo\Region::subtract(\Cairo\Region other_region)
     475              :    Subtracts other_region and stores the result. */
     476            4 : PHP_METHOD(Cairo_Region, subtract)
     477              : {
     478              :     zval *other_region;
     479              :     cairo_region_object *region_obj, *other_region_obj;
     480              :     zval status_case;
     481              : 
     482            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     483            6 :         Z_PARAM_OBJECT_OF_CLASS(other_region, ce_cairo_region)
     484            6 :     ZEND_PARSE_PARAMETERS_END();
     485              : 
     486            4 :     region_obj = cairo_region_object_get(getThis());
     487            2 :     if (!region_obj) {
     488            0 :         RETURN_THROWS();
     489              :     }
     490              : 
     491            2 :     other_region_obj = Z_CAIRO_REGION_P(other_region);
     492              : 
     493            2 :     status_case = php_enum_from_cairo_c_enum(
     494              :         ce_cairo_status,
     495            2 :         cairo_region_subtract(region_obj->region, other_region_obj->region)
     496              :     );
     497              : 
     498            2 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     499            4 :         RETURN_ZVAL(&status_case, 1, 1);
     500              :     }
     501              : }
     502              : /* }}} */
     503              : 
     504              : /* {{{ proto \Cairo\Status \Cairo\Region::subtractRectangle(Cairo\Rectangle $rect)
     505              :    Subtracts rectangle from region and stores the result. */
     506            3 : PHP_METHOD(Cairo_Region, subtractRectangle)
     507              : {
     508              :     zval *rectangle_zval;
     509              :     cairo_rectangle_object *rectangle_object;
     510              :     cairo_region_object *region_object;
     511              :     zval status_case;
     512              :     cairo_rectangle_int_t int_rect;
     513              : 
     514            3 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     515            4 :         Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
     516            4 :     ZEND_PARSE_PARAMETERS_END();
     517              : 
     518            2 :     region_object = cairo_region_object_get(getThis());
     519            1 :     if (!region_object) {
     520            0 :         RETURN_THROWS();
     521              :     }
     522              : 
     523            1 :     rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
     524            1 :     if (!rectangle_object) {
     525            0 :         RETURN_NULL();
     526              :     }
     527              : 
     528            1 :     int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
     529              : 
     530            1 :     status_case = php_enum_from_cairo_c_enum(
     531              :         ce_cairo_status,
     532            1 :         cairo_region_subtract_rectangle(region_object->region, &int_rect)
     533              :     );
     534              : 
     535            1 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     536            2 :         RETURN_ZVAL(&status_case, 1, 1);
     537              :     }
     538              : }
     539              : /* }}} */
     540              : 
     541              : /* {{{ proto \Cairo\Status \Cairo\Region::union(\Cairo\Region other_region)
     542              :    Computes the union with other_region and stores the result. */
     543            4 : PHP_METHOD(Cairo_Region, union)
     544              : {
     545              :     zval *other_region;
     546              :     cairo_region_object *region_obj, *other_region_obj;
     547              :     zval status_case;
     548              : 
     549            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     550            6 :         Z_PARAM_OBJECT_OF_CLASS(other_region, ce_cairo_region)
     551            6 :     ZEND_PARSE_PARAMETERS_END();
     552              : 
     553            4 :     region_obj = cairo_region_object_get(getThis());
     554            2 :     if (!region_obj) {
     555            0 :         RETURN_THROWS();
     556              :     }
     557              : 
     558            2 :     other_region_obj = Z_CAIRO_REGION_P(other_region);
     559              : 
     560            2 :     status_case = php_enum_from_cairo_c_enum(
     561              :         ce_cairo_status,
     562            2 :         cairo_region_union(region_obj->region, other_region_obj->region)
     563              :     );
     564              : 
     565            2 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     566            4 :         RETURN_ZVAL(&status_case, 1, 1);
     567              :     }
     568              : }
     569              : /* }}} */
     570              : 
     571              : /* {{{ proto \Cairo\Status \Cairo\Region::unionRectangle(Cairo\Rectangle $rect)
     572              :    Computes the union of region with rectangle and stores the result. */
     573            4 : PHP_METHOD(Cairo_Region, unionRectangle)
     574              : {
     575              :     zval *rectangle_zval;
     576              :     cairo_rectangle_object *rectangle_object;
     577              :     cairo_region_object *region_object;
     578              :     zval status_case;
     579              :     cairo_rectangle_int_t int_rect;
     580              : 
     581            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     582            6 :         Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
     583            6 :     ZEND_PARSE_PARAMETERS_END();
     584              : 
     585            4 :     region_object = cairo_region_object_get(getThis());
     586            2 :     if (!region_object) {
     587            0 :         RETURN_THROWS();
     588              :     }
     589              : 
     590            2 :     rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
     591            2 :     if (!rectangle_object) {
     592            0 :         RETURN_NULL();
     593              :     }
     594              : 
     595            2 :     int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
     596              : 
     597            2 :     status_case = php_enum_from_cairo_c_enum(
     598              :         ce_cairo_status,
     599            2 :         cairo_region_union_rectangle(region_object->region, &int_rect)
     600              :     );
     601              : 
     602            2 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     603            4 :         RETURN_ZVAL(&status_case, 1, 1);
     604              :     }
     605              : }
     606              : /* }}} */
     607              : 
     608              : /* {{{ proto \Cairo\Status \Cairo\Region::xor(\Cairo\Region other_region)
     609              :    Computes the exclusive difference with other_region and stores the result.
     610              :    That is, region will be set to contain all areas that are either in region or in other_region, but not in both. */
     611            4 : PHP_METHOD(Cairo_Region, xor)
     612              : {
     613              :     zval *other_region;
     614              :     cairo_region_object *region_obj, *other_region_obj;
     615              :     zval status_case;
     616              : 
     617            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     618            6 :         Z_PARAM_OBJECT_OF_CLASS(other_region, ce_cairo_region)
     619            6 :     ZEND_PARSE_PARAMETERS_END();
     620              : 
     621            4 :     region_obj = cairo_region_object_get(getThis());
     622            2 :     if (!region_obj) {
     623            0 :         RETURN_THROWS();
     624              :     }
     625              : 
     626            2 :     other_region_obj = Z_CAIRO_REGION_P(other_region);
     627              : 
     628            2 :     status_case = php_enum_from_cairo_c_enum(
     629              :         ce_cairo_status,
     630            2 :         cairo_region_xor(region_obj->region, other_region_obj->region)
     631              :     );
     632              : 
     633            2 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     634            4 :         RETURN_ZVAL(&status_case, 1, 1);
     635              :     }
     636              : }
     637              : /* }}} */
     638              : 
     639              : /* {{{ proto \Cairo\Status \Cairo\Region::xorRectangle(Cairo\Rectangle $rect)
     640              :    Computes the exclusive difference of region with rectangle and stores the result.
     641              :    That is, region will be set to contain all areas that are either in region or in rectangle, but not in both. */
     642            4 : PHP_METHOD(Cairo_Region, xorRectangle)
     643              : {
     644              :     zval *rectangle_zval;
     645              :     cairo_rectangle_object *rectangle_object;
     646              :     cairo_region_object *region_object;
     647              :     zval status_case;
     648              :     cairo_rectangle_int_t int_rect;
     649              : 
     650            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     651            6 :         Z_PARAM_OBJECT_OF_CLASS(rectangle_zval, ce_cairo_rectangle)
     652            6 :     ZEND_PARSE_PARAMETERS_END();
     653              : 
     654            4 :     region_object = cairo_region_object_get(getThis());
     655            2 :     if (!region_object) {
     656            0 :         RETURN_THROWS();
     657              :     }
     658              : 
     659            2 :     rectangle_object = Z_CAIRO_RECTANGLE_P(rectangle_zval);
     660            2 :     if (!rectangle_object) {
     661            0 :         RETURN_NULL();
     662              :     }
     663              : 
     664            2 :     int_rect = cairo_expand_to_rectangle_int(rectangle_object->rect);
     665              : 
     666            2 :     status_case = php_enum_from_cairo_c_enum(
     667              :         ce_cairo_status,
     668            2 :         cairo_region_xor_rectangle(region_object->region, &int_rect)
     669              :     );
     670              : 
     671            2 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     672            4 :         RETURN_ZVAL(&status_case, 1, 1);
     673              :     }
     674              : }
     675              : /* }}} */
     676              : 
     677              : 
     678              : /* ----------------------------------------------------------------
     679              :     \Cairo\Region Definition and registration
     680              : ------------------------------------------------------------------*/
     681              : 
     682              : 
     683              : /* {{{ PHP_MINIT_FUNCTION */
     684          424 : PHP_MINIT_FUNCTION(cairo_region)
     685              : {
     686          424 :     memcpy(
     687              :         &cairo_region_object_handlers,
     688              :         zend_get_std_object_handlers(),
     689              :         sizeof(zend_object_handlers)
     690              :     );
     691              : 
     692          424 :     cairo_region_object_handlers.offset = XtOffsetOf(cairo_region_object, std);
     693          424 :     cairo_region_object_handlers.free_obj = cairo_region_free_obj;
     694          424 :     cairo_region_object_handlers.clone_obj = cairo_region_clone_obj;
     695              : 
     696          424 :     ce_cairo_region = register_class_Cairo_Region();
     697          424 :     ce_cairo_region->create_object = cairo_region_create_object;
     698              : 
     699              :     /* Region\Overlap */
     700          424 :     ce_cairo_region_overlap = register_class_Cairo_Region_Overlap();
     701              : 
     702          424 :     return SUCCESS;
     703              : }
        

Generated by: LCOV version 2.0-1