LCOV - code coverage report
Current view: top level - src - matrix.c (source / functions) Coverage Total Hit
Test: PHP Cairo Extension Coverage Lines: 92.9 % 254 236
Test Date: 2025-09-10 21:28:33 Functions: 100.0 % 26 26

            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              : #include <zend_gc.h>
      23              : 
      24              : #include "php_cairo.h"
      25              : #include "php_cairo_internal.h"
      26              : #include "matrix_arginfo.h"
      27              : 
      28              : zend_class_entry *ce_cairo_matrix;
      29              : static zend_object_handlers cairo_matrix_object_handlers;
      30              : 
      31          647 : cairo_matrix_object *cairo_matrix_fetch_object(zend_object *object)
      32              : {
      33          647 :     return (cairo_matrix_object *) ((char*)(object) - XtOffsetOf(cairo_matrix_object, std));
      34              : }
      35              : 
      36          468 : static inline double cairo_matrix_get_property_default(zend_class_entry *ce, char * name) {
      37              :     zend_property_info *property_info;
      38          468 :     double value = 0.0;
      39          468 :     zend_string *key = zend_string_init(name, strlen(name), 0);
      40              : 
      41          468 :     property_info = zend_get_property_info(ce, key, 1);
      42          468 :     if (property_info) {
      43          468 :         zval *val = (zval*)((char*)ce->default_properties_table + property_info->offset - OBJ_PROP_TO_OFFSET(0));
      44          468 :         if (val) {
      45          468 :             value = zval_get_double(val);
      46              :         }
      47              :     }
      48              :     zend_string_release(key);
      49          468 :     return value;
      50              : }
      51              : 
      52          396 : static inline double cairo_matrix_get_property_value(zend_object *object, char *name) {
      53              :     zval *prop, rv;
      54              : 
      55          396 :     prop = zend_read_property(object->ce, object, name, strlen(name), 1, &rv);
      56          396 :     return zval_get_double(prop);
      57              : }
      58              : 
      59           47 : cairo_matrix_object *cairo_matrix_object_get(zval *zv)
      60              : {
      61           47 :     cairo_matrix_object *object = Z_CAIRO_MATRIX_P(zv);
      62              : 
      63           47 :     if (object->matrix == NULL) {
      64            0 :         zend_throw_exception_ex(ce_cairo_exception, 0,
      65              :             "Internal matrix object missing in %s, you must call parent::__construct in extended classes.",
      66            0 :             ZSTR_VAL(Z_OBJCE_P(zv)->name));
      67            0 :         return NULL;
      68              :     }
      69              : 
      70           47 :     return object;
      71              : }
      72              : 
      73              : #define CAIRO_ALLOC_MATRIX(matrix_value) \
      74              :     if (!matrix_value) { \
      75              :         matrix_value = ecalloc(1, sizeof(cairo_matrix_t)); \
      76              :     }
      77              : 
      78              : #define CAIRO_VALUE_FROM_STRUCT(n) \
      79              :     if (strcmp(member->val, #n) == 0) { \
      80              :         value = matrix_object->matrix->n; \
      81              :         break; \
      82              :     }
      83              : 
      84              : #define CAIRO_VALUE_TO_STRUCT(n) \
      85              :     if (strcmp(member->val, #n) == 0) { \
      86              :         matrix_object->matrix->n = zval_get_double(value); \
      87              :         break; \
      88              :     }
      89              : 
      90              : #define CAIRO_ADD_STRUCT_VALUE(n) \
      91              :     ZVAL_DOUBLE(&tmp, matrix_object->matrix->n); \
      92              :     zend_hash_str_update(props, #n, sizeof(#n)-1, &tmp);
      93              : 
      94              : /* ----------------------------------------------------------------
      95              :     Cairo\Matrix C API
      96              : ------------------------------------------------------------------*/
      97              : 
      98              : /* {{{ */
      99           34 : cairo_matrix_t *cairo_matrix_object_get_matrix(zval *zv)
     100              : {
     101           34 :     cairo_matrix_object *matrix_object = cairo_matrix_object_get(zv);
     102              : 
     103           34 :     return matrix_object->matrix;
     104              : }
     105              : /* }}} */
     106              : 
     107            4 : zend_class_entry* php_cairo_get_matrix_ce()
     108              : {
     109            4 :     return ce_cairo_matrix;
     110              : }
     111              : 
     112              : /* ----------------------------------------------------------------
     113              :     Cairo\Matrix Class API
     114              : ------------------------------------------------------------------*/
     115              : 
     116              : /* {{{ proto void __construct([float xx, float yx, float xy, float yy, float x0, float y0])
     117              :     CairoMatrix is used throughout cairo to convert between different coordinate
     118              :     spaces. A CairoMatrix holds an affine transformation, such as a scale, rotation,
     119              :     shear, or a combination of these */
     120           66 : PHP_METHOD(Cairo_Matrix, __construct)
     121              : {
     122              :     cairo_matrix_object *matrix_object;
     123          132 :     zend_object *object = Z_OBJ_P(getThis());
     124              : 
     125              :     /* read defaults from object */
     126           66 :     double xx = cairo_matrix_get_property_value(object, "xx");
     127           66 :     double yx = cairo_matrix_get_property_value(object, "yx");
     128           66 :     double xy = cairo_matrix_get_property_value(object, "xy");
     129           66 :     double yy = cairo_matrix_get_property_value(object, "yy");
     130           66 :     double x0 = cairo_matrix_get_property_value(object, "x0");
     131           66 :     double y0 = cairo_matrix_get_property_value(object, "y0");
     132              : 
     133           66 :     ZEND_PARSE_PARAMETERS_START(0, 6)
     134           65 :         Z_PARAM_OPTIONAL
     135          123 :         Z_PARAM_DOUBLE(xx)
     136          111 :         Z_PARAM_DOUBLE(yx)
     137          102 :         Z_PARAM_DOUBLE(xy)
     138           96 :         Z_PARAM_DOUBLE(yy)
     139           56 :         Z_PARAM_DOUBLE(x0)
     140           15 :         Z_PARAM_DOUBLE(y0)
     141           66 :     ZEND_PARSE_PARAMETERS_END();
     142              : 
     143           59 :     matrix_object = cairo_matrix_fetch_object(object);
     144              : 
     145           59 :     cairo_matrix_init(matrix_object->matrix, xx, yx, xy, yy, x0, y0);
     146              : }
     147              : /* }}} */
     148              : 
     149              : /* {{{ proto object \Cairo\Matrix::initIdentity()
     150              :        Create initialized matrix to be an identity transformation. */
     151            2 : PHP_METHOD(Cairo_Matrix, initIdentity)
     152              : {
     153              :     cairo_matrix_object *matrix_object;
     154              : 
     155            2 :     ZEND_PARSE_PARAMETERS_NONE();
     156              : 
     157            1 :     object_init_ex(return_value, ce_cairo_matrix);
     158            1 :     matrix_object = cairo_matrix_object_get(return_value);
     159            1 :     if (!matrix_object) {
     160            0 :         RETURN_THROWS();
     161              :     }
     162              : 
     163            1 :     cairo_matrix_init_identity(matrix_object->matrix);
     164              : }
     165              : /* }}} */
     166              : 
     167              : /* {{{ proto object \Cairo\Matrix::initTranslate(float tx, float ty)
     168              :        Create initialized matrix to a transformation that translates by
     169              :        tx and ty in the X and Y dimensions, respectively. */
     170            6 : PHP_METHOD(Cairo_Matrix, initTranslate)
     171              : {
     172            6 :     double tx = 0.0, ty = 0.0;
     173              :     cairo_matrix_object *matrix_object;
     174              : 
     175            6 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     176            6 :         Z_PARAM_DOUBLE(tx)
     177            4 :         Z_PARAM_DOUBLE(ty)
     178            6 :     ZEND_PARSE_PARAMETERS_END();
     179              : 
     180            1 :     object_init_ex(return_value, ce_cairo_matrix);
     181            1 :     matrix_object = cairo_matrix_object_get(return_value);
     182            1 :     if (!matrix_object) {
     183            0 :         RETURN_THROWS();
     184              :     }
     185              : 
     186            1 :     cairo_matrix_init_translate(matrix_object->matrix, tx, ty);
     187              : }
     188              : /* }}} */
     189              : 
     190              : /* {{{ proto object \Cairo\Matrix::initScale(float sx, float sy)
     191              :        Create initialized matrix to a transformation that scales
     192              :        by sx and sy in the X and Y dimensions, respectively. */
     193            6 : PHP_METHOD(Cairo_Matrix, initScale)
     194              : {
     195            6 :     double sx = 0.0, sy = 0.0;
     196              :     cairo_matrix_object *matrix_object;
     197              : 
     198            6 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     199            6 :         Z_PARAM_DOUBLE(sx)
     200            4 :         Z_PARAM_DOUBLE(sy)
     201            6 :     ZEND_PARSE_PARAMETERS_END();
     202              : 
     203            1 :     object_init_ex(return_value, ce_cairo_matrix);
     204            1 :     matrix_object = cairo_matrix_object_get(return_value);
     205            1 :     if (!matrix_object) {
     206            0 :         RETURN_THROWS();
     207              :     }
     208              : 
     209            1 :     cairo_matrix_init_scale(matrix_object->matrix, sx, sy);
     210              : }
     211              : /* }}} */
     212              : 
     213              : /* {{{ proto object \Cairo\Matrix::initRotate(float radians)
     214              :        Create initialized matrix to a transformation that rotates by radians. */
     215            4 : PHP_METHOD(Cairo_Matrix, initRotate)
     216              : {
     217            4 :     double radians = 0.0;
     218              :     cairo_matrix_object *matrix_object;
     219              : 
     220            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     221            4 :         Z_PARAM_DOUBLE(radians)
     222            4 :     ZEND_PARSE_PARAMETERS_END();
     223              : 
     224            1 :     object_init_ex(return_value, ce_cairo_matrix);
     225            1 :     matrix_object = cairo_matrix_object_get(return_value);
     226            1 :     if (!matrix_object) {
     227            0 :         RETURN_THROWS();
     228              :     }
     229              : 
     230            1 :     cairo_matrix_init_rotate(matrix_object->matrix, radians);
     231              : }
     232              : /* }}} */
     233              : 
     234              : /* {{{ proto void CairoMatrix->translate(float tx, float ty)
     235              :     Applies a translation to the transformation. The effect of the new transformation
     236              :     is to first translate the coordinates by tx and ty, then apply the original
     237              :     transformation to the coordinates. */
     238            6 : PHP_METHOD(Cairo_Matrix, translate)
     239              : {
     240            6 :     double tx = 0.0, ty = 0.0;
     241              :     cairo_matrix_object *matrix_object;
     242              : 
     243            6 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     244            6 :         Z_PARAM_DOUBLE(tx)
     245            4 :         Z_PARAM_DOUBLE(ty)
     246            6 :     ZEND_PARSE_PARAMETERS_END();
     247              : 
     248            2 :     matrix_object = cairo_matrix_object_get(getThis());
     249            1 :     if (!matrix_object) {
     250            0 :         RETURN_THROWS();
     251              :     }
     252              : 
     253            1 :     cairo_matrix_translate(matrix_object->matrix, tx, ty);
     254              : }
     255              : /* }}} */
     256              : 
     257              : /* {{{ proto void CairoMatrix->scale(float sx, float sy)
     258              :        Applies scaling by sx, sy to the transformation in matrix. The effect of
     259              :        the new transformation is to first scale the coordinates by sx and sy, then apply
     260              :        the original transformation to the coordinates. */
     261            6 : PHP_METHOD(Cairo_Matrix, scale)
     262              : {
     263            6 :     double sx = 0.0, sy = 0.0;
     264              :     cairo_matrix_object *matrix_object;
     265              : 
     266            6 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     267            6 :         Z_PARAM_DOUBLE(sx)
     268            4 :         Z_PARAM_DOUBLE(sy)
     269            6 :     ZEND_PARSE_PARAMETERS_END();
     270              : 
     271            2 :     matrix_object = cairo_matrix_object_get(getThis());
     272            1 :     if (!matrix_object) {
     273            0 :         RETURN_THROWS();
     274              :     }
     275              : 
     276            1 :     cairo_matrix_scale(matrix_object->matrix, sx, sy);
     277              : }
     278              : /* }}} */
     279              : 
     280              : /* {{{ proto void CairoMatrix->rotate(float radians)
     281              :        Applies rotation by radians to the transformation in matrix. The effect of the new
     282              :        transformation is to first rotate the coordinates by radians, then
     283              :        apply the original transformation to the coordinates. */
     284            4 : PHP_METHOD(Cairo_Matrix, rotate)
     285              : {
     286            4 :     double radians = 0.0;
     287              :     cairo_matrix_object *matrix_object;
     288              : 
     289            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     290            4 :         Z_PARAM_DOUBLE(radians)
     291            4 :     ZEND_PARSE_PARAMETERS_END();
     292              : 
     293            2 :     matrix_object = cairo_matrix_object_get(getThis());
     294            1 :     if (!matrix_object) {
     295            0 :         RETURN_THROWS();
     296              :     }
     297              : 
     298            1 :     cairo_matrix_rotate(matrix_object->matrix, radians);
     299              : }
     300              : /* }}} */
     301              : 
     302              : /* {{{ proto void CairoMatrix->invert()
     303              :        Changes matrix to be the inverse of it's original value. Not all transformation
     304              :        matrices have inverses; if the matrix collapses points together (it is degenerate),
     305              :        then it has no inverse and this function will fail. */
     306            3 : PHP_METHOD(Cairo_Matrix, invert)
     307              : {
     308              :     cairo_matrix_object *matrix_object;
     309              : 
     310            3 :     ZEND_PARSE_PARAMETERS_NONE();
     311              : 
     312            4 :     matrix_object = cairo_matrix_object_get(getThis());
     313            2 :     if (!matrix_object) {
     314            0 :         RETURN_THROWS();
     315              :     }
     316              : 
     317            2 :     if (php_cairo_throw_exception(cairo_matrix_invert(matrix_object->matrix))) {
     318            1 :         RETURN_THROWS();
     319              :     }
     320              : }
     321              : /* }}} */
     322              : 
     323              : /* {{{ proto CairoMatrix \Cairo\Matrix::multiply(Cairo\Matrix matrix1, Cairo\Matrix matrix2)
     324              :        Multiplies the affine transformations in two matrices together and returns the result */
     325            6 : PHP_METHOD(Cairo_Matrix, multiply)
     326              : {
     327            6 :     zval *matrix1 = NULL, *matrix2 = NULL;
     328              :     cairo_matrix_object *matrix_object, *matrix_object1, *matrix_object2;
     329              : 
     330            6 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     331            6 :         Z_PARAM_OBJECT_OF_CLASS(matrix1, ce_cairo_matrix)
     332            4 :         Z_PARAM_OBJECT_OF_CLASS(matrix2, ce_cairo_matrix)
     333            6 :     ZEND_PARSE_PARAMETERS_END();
     334              : 
     335            1 :     object_init_ex(return_value, ce_cairo_matrix);
     336            1 :     matrix_object = Z_CAIRO_MATRIX_P(return_value);
     337            1 :     CAIRO_ALLOC_MATRIX(matrix_object->matrix);
     338              : 
     339            1 :     matrix_object1 = cairo_matrix_object_get(matrix1);
     340            1 :     matrix_object2 = cairo_matrix_object_get(matrix2);
     341            1 :     if (!matrix_object1 || !matrix_object2) {
     342            0 :         RETURN_THROWS();
     343              :     }
     344              : 
     345            1 :     cairo_matrix_multiply(matrix_object->matrix, matrix_object1->matrix, matrix_object2->matrix);
     346              : }
     347              : /* }}} */
     348              : 
     349              : /* {{{ proto array CairoMatrix->transformDistance(float dx, float dy)
     350              :        Transforms the distance vector (dx, dy) by matrix. This is similar to transform point
     351              :        except that the translation components of the transformation are ignored */
     352            6 : PHP_METHOD(Cairo_Matrix, transformDistance)
     353              : {
     354            6 :     double dx = 0.0, dy = 0.0;
     355              :     cairo_matrix_object *matrix_object;
     356              : 
     357            6 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     358            6 :         Z_PARAM_DOUBLE(dx)
     359            4 :         Z_PARAM_DOUBLE(dy)
     360            6 :     ZEND_PARSE_PARAMETERS_END();
     361              : 
     362            2 :     matrix_object = cairo_matrix_object_get(getThis());
     363            1 :     if (!matrix_object) {
     364            0 :         RETURN_THROWS();
     365              :     }
     366              : 
     367            1 :     cairo_matrix_transform_distance(matrix_object->matrix, &dx, &dy);
     368              : 
     369            1 :     array_init(return_value);
     370            1 :     add_assoc_double(return_value, "x", dx);
     371            1 :     add_assoc_double(return_value, "y", dy);
     372              : }
     373              : /* }}} */
     374              : 
     375              : /* {{{ proto array CairoMatrix->transformPoint(float x, float y)
     376              :        Transforms the point (x, y) by matrix. */
     377            6 : PHP_METHOD(Cairo_Matrix, transformPoint)
     378              : {
     379            6 :     double x = 0.0, y = 0.0;
     380              :     cairo_matrix_object *matrix_object;
     381              : 
     382            6 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     383            6 :         Z_PARAM_DOUBLE(x)
     384            4 :         Z_PARAM_DOUBLE(y)
     385            6 :     ZEND_PARSE_PARAMETERS_END();
     386              : 
     387            2 :     matrix_object = cairo_matrix_object_get(getThis());
     388            1 :     if (!matrix_object) {
     389            0 :         RETURN_THROWS();
     390              :     }
     391              : 
     392            1 :     cairo_matrix_transform_point(matrix_object->matrix, &x, &y);
     393              : 
     394            1 :     array_init(return_value);
     395            1 :     add_assoc_double(return_value, "x", x);
     396            1 :     add_assoc_double(return_value, "y", y);
     397              : }
     398              : /* }}} */
     399              : 
     400              : /* ----------------------------------------------------------------
     401              :     Cairo\Matrix Object management
     402              : ------------------------------------------------------------------*/
     403              : 
     404              : /* {{{ */
     405           78 : static void cairo_matrix_free_obj(zend_object *object)
     406              : {
     407           78 :     cairo_matrix_object *intern = cairo_matrix_fetch_object(object);
     408              : 
     409           78 :     if (!intern) {
     410            0 :         return;
     411              :     }
     412              : 
     413           78 :     if (intern->matrix) {
     414           78 :         efree(intern->matrix);
     415           78 :         intern->matrix = NULL;
     416              :     }
     417              : 
     418           78 :     zend_object_std_dtor(&intern->std);
     419              : }
     420              : /* }}} */
     421              : 
     422              : /* {{{ */
     423           78 : static zend_object* cairo_matrix_obj_ctor(zend_class_entry *ce, cairo_matrix_object **intern)
     424              : {
     425           78 :     cairo_matrix_object *object = ecalloc(1, sizeof(cairo_matrix_object) + zend_object_properties_size(ce));
     426           78 :     CAIRO_ALLOC_MATRIX(object->matrix);
     427              : 
     428           78 :     zend_object_std_init(&object->std, ce);
     429           78 :     object->std.handlers = &cairo_matrix_object_handlers;
     430           78 :     *intern = object;
     431              : 
     432              :     /* We need to read in any default values and set them if applicable
     433              :        xx, yx, xy, yy, x0, y0
     434              :      */
     435           78 :     if (ce->default_properties_count) {
     436           78 :         object->matrix->xx = cairo_matrix_get_property_default(ce, "xx");
     437           78 :         object->matrix->yx = cairo_matrix_get_property_default(ce, "yx");
     438           78 :         object->matrix->xy = cairo_matrix_get_property_default(ce, "xy");
     439           78 :         object->matrix->yy = cairo_matrix_get_property_default(ce, "yy");
     440           78 :         object->matrix->x0 = cairo_matrix_get_property_default(ce, "x0");
     441           78 :         object->matrix->y0 = cairo_matrix_get_property_default(ce, "y0");
     442              :     }
     443              : 
     444           78 :     return &object->std;
     445              : }
     446              : /* }}} */
     447              : 
     448              : /* {{{ */
     449           76 : static zend_object* cairo_matrix_create_object(zend_class_entry *ce)
     450              : {
     451           76 :     cairo_matrix_object *intern = NULL;
     452           76 :     zend_object *return_value = cairo_matrix_obj_ctor(ce, &intern);
     453              : 
     454           76 :     object_properties_init(&intern->std, ce);
     455           76 :     return return_value;
     456              : }
     457              : /* }}} */
     458              : 
     459              : /* {{{ */
     460            2 : static zend_object* cairo_matrix_clone_obj(zend_object *zobj)
     461              : {
     462              :     cairo_matrix_object *new_matrix;
     463            2 :     cairo_matrix_object *old_matrix = cairo_matrix_fetch_object(zobj);
     464            2 :     zend_object *return_value = cairo_matrix_obj_ctor(zobj->ce, &new_matrix);
     465            2 :     CAIRO_ALLOC_MATRIX(new_matrix->matrix);
     466              : 
     467            2 :     cairo_matrix_init(
     468            2 :         new_matrix->matrix,
     469            2 :         old_matrix->matrix->xx,
     470            2 :         old_matrix->matrix->yx,
     471            2 :         old_matrix->matrix->xy,
     472            2 :         old_matrix->matrix->yy,
     473            2 :         old_matrix->matrix->x0,
     474            2 :         old_matrix->matrix->y0
     475              :     );
     476              : 
     477            2 :     zend_objects_clone_members(&new_matrix->std, &old_matrix->std);
     478              : 
     479            2 :     return return_value;
     480              : }
     481              : /* }}} */
     482              : 
     483              : /* {{{ */
     484          412 : static zval *cairo_matrix_object_read_property(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv)
     485              : {
     486              :     zval *retval;
     487              :     double value;
     488          412 :     cairo_matrix_object *matrix_object = cairo_matrix_fetch_object(object);
     489              : 
     490          412 :     if (!matrix_object) {
     491            0 :         return rv;
     492              :     }
     493              : 
     494              :     do {
     495          412 :         CAIRO_VALUE_FROM_STRUCT(xx);
     496          341 :         CAIRO_VALUE_FROM_STRUCT(yx);
     497          273 :         CAIRO_VALUE_FROM_STRUCT(xy);
     498          205 :         CAIRO_VALUE_FROM_STRUCT(yy);
     499          137 :         CAIRO_VALUE_FROM_STRUCT(x0);
     500           69 :         CAIRO_VALUE_FROM_STRUCT(y0);
     501              : 
     502              :         /* not a struct member */
     503            1 :         retval = (zend_get_std_object_handlers())->read_property(object, member, type, cache_slot, rv);
     504              : 
     505            1 :         return retval;
     506              :     } while(0);
     507              : 
     508          411 :     retval = rv;
     509          411 :     ZVAL_DOUBLE(retval, value);
     510              : 
     511          411 :     return retval;
     512              : }
     513              : /* }}} */
     514              : 
     515              : /* {{{ */
     516            8 : static zval *cairo_matrix_object_write_property(zend_object *object, zend_string *member, zval *value, void **cache_slot)
     517              : {
     518            8 :     cairo_matrix_object *matrix_object = cairo_matrix_fetch_object(object);
     519            8 :     zval *retval = NULL;
     520              : 
     521            8 :     if (!matrix_object) {
     522            0 :         return retval;
     523              :     }
     524              : 
     525              :     do {
     526           10 :         CAIRO_VALUE_TO_STRUCT(xx);
     527            7 :         CAIRO_VALUE_TO_STRUCT(yx);
     528            6 :         CAIRO_VALUE_TO_STRUCT(xy);
     529            5 :         CAIRO_VALUE_TO_STRUCT(yy);
     530            4 :         CAIRO_VALUE_TO_STRUCT(x0);
     531            3 :         CAIRO_VALUE_TO_STRUCT(y0);
     532              : 
     533              :         /* not a struct member */
     534            1 :         retval = (zend_get_std_object_handlers())->write_property(object, member, value, cache_slot);
     535              :     } while(0);
     536              : 
     537            8 :     return retval;
     538              : }
     539              : /* }}} */
     540              : 
     541              : /* {{{ */
     542           28 : static HashTable *cairo_matrix_object_get_properties(zend_object *object)
     543              : {
     544              :     HashTable *props;
     545              :     // used in CAIRO_ADD_STRUCT_VALUE below
     546              :     zval tmp;
     547           28 :     cairo_matrix_object *matrix_object = cairo_matrix_fetch_object(object);
     548              : 
     549           28 :     props = zend_std_get_properties(object);
     550              : 
     551           28 :     if (!matrix_object->matrix) {
     552            0 :         return props;
     553              :     }
     554              : 
     555              :     /* Don't add struct values when destructor calls get_properties handler */
     556           56 :     if (props && GC_REFCOUNT(props) > 0) {
     557           28 :         CAIRO_ADD_STRUCT_VALUE(xx);
     558           28 :         CAIRO_ADD_STRUCT_VALUE(yx);
     559           28 :         CAIRO_ADD_STRUCT_VALUE(xy);
     560           28 :         CAIRO_ADD_STRUCT_VALUE(yy);
     561           28 :         CAIRO_ADD_STRUCT_VALUE(x0);
     562           28 :         CAIRO_ADD_STRUCT_VALUE(y0);
     563              :     }
     564              : 
     565           28 :     return props;
     566              : }
     567              : /* }}} */
     568              : 
     569              : /* ----------------------------------------------------------------
     570              :     Cairo\Matrix Definition and registration
     571              : ------------------------------------------------------------------*/
     572              : 
     573              : /* {{{ PHP_MINIT_FUNCTION */
     574          424 : PHP_MINIT_FUNCTION(cairo_matrix)
     575              : {
     576          424 :     memcpy(
     577              :         &cairo_matrix_object_handlers,
     578              :         zend_get_std_object_handlers(),
     579              :         sizeof(zend_object_handlers)
     580              :     );
     581              : 
     582          424 :     cairo_matrix_object_handlers.offset = XtOffsetOf(cairo_matrix_object, std);
     583          424 :     cairo_matrix_object_handlers.free_obj = cairo_matrix_free_obj;
     584          424 :     cairo_matrix_object_handlers.clone_obj = cairo_matrix_clone_obj;
     585          424 :     cairo_matrix_object_handlers.read_property = cairo_matrix_object_read_property;
     586          424 :     cairo_matrix_object_handlers.write_property = cairo_matrix_object_write_property;
     587          424 :     cairo_matrix_object_handlers.get_property_ptr_ptr = NULL;
     588          424 :     cairo_matrix_object_handlers.get_properties = cairo_matrix_object_get_properties;
     589              : 
     590          424 :     ce_cairo_matrix = register_class_Cairo_Matrix();
     591          424 :     ce_cairo_matrix->create_object = cairo_matrix_create_object;
     592              : 
     593          424 :     return SUCCESS;
     594              : }
     595              : /* }}} */
        

Generated by: LCOV version 2.0-1