|             Line data    Source code 
       1              : /*
       2              :   +----------------------------------------------------------------------+
       3              :   | For PHP Version 8                                                    |
       4              :   +----------------------------------------------------------------------+
       5              :   | Copyright (c) 2022 Swen Zanon                                        |
       6              :   +----------------------------------------------------------------------+
       7              :   | http://www.opensource.org/licenses/mit-license.php  MIT License      |
       8              :   | Also available in LICENSE                                            |
       9              :   +----------------------------------------------------------------------+
      10              :   | Authors: Swen Zanon <swen.zanon@geoglis.de>                          |
      11              :   +----------------------------------------------------------------------+
      12              : */
      13              : 
      14              : #ifdef HAVE_CONFIG_H
      15              : #include "config.h"
      16              : #endif
      17              : 
      18              : #include <cairo.h>
      19              : #include <php.h>
      20              : #include <zend_exceptions.h>
      21              : 
      22              : #include "php_cairo.h"
      23              : #include "php_cairo_internal.h"
      24              : #include "text_cluster_arginfo.h"
      25              : 
      26              : zend_class_entry *ce_cairo_text_cluster;
      27              : 
      28              : static zend_object_handlers cairo_text_cluster_object_handlers;
      29              : 
      30          105 : cairo_text_cluster_object *cairo_text_cluster_fetch_object(zend_object *object)
      31              : {
      32          105 :     return (cairo_text_cluster_object *) ((char*)(object) - XtOffsetOf(cairo_text_cluster_object, std));
      33              : }
      34              : 
      35           90 : static inline long cairo_text_cluster_get_property_default(zend_class_entry *ce, char * name) {
      36              :     zend_property_info *property_info;
      37           90 :     long value = 0;
      38           90 :     zend_string *key = zend_string_init(name, strlen(name), 0);
      39              : 
      40           90 :     property_info = zend_get_property_info(ce, key, 1);
      41           90 :     if (property_info) {
      42           90 :         zval *val = (zval*)((char*)ce->default_properties_table + property_info->offset - OBJ_PROP_TO_OFFSET(0));
      43           90 :         if (val) {
      44           90 :             value = zval_get_long(val);
      45              :         }
      46              :     }
      47              :     zend_string_release(key);
      48           90 :     return value;
      49              : }
      50              : 
      51              : #define CAIRO_ALLOC_TEXT_CLUSTER(text_cluster_value) if (!text_cluster_value) \
      52              :     { text_cluster_value = ecalloc(1, sizeof(cairo_text_cluster_t)); }
      53              : 
      54              : #define CAIRO_VALUE_FROM_STRUCT(n) \
      55              :     if (strcmp(member->val, #n) == 0) { \
      56              :         value = text_cluster_object->text_cluster->n; \
      57              :         break; \
      58              :     }
      59              : 
      60              : #define CAIRO_VALUE_TO_STRUCT(n) \
      61              :     if (strcmp(member->val, #n) == 0) { \
      62              :         text_cluster_object->text_cluster->n = zval_get_long(value); \
      63              :         break; \
      64              :     }
      65              : 
      66              : #define CAIRO_ADD_STRUCT_VALUE(n) \
      67              :     ZVAL_LONG(&tmp, text_cluster_object->text_cluster->n); \
      68              :     zend_hash_str_update(props, #n, sizeof(#n)-1, &tmp);
      69              : 
      70              : /* ----------------------------------------------------------------
      71              :     \Cairo\TextCluster C API
      72              : ------------------------------------------------------------------*/
      73              : 
      74              : /* {{{ */
      75            6 : cairo_text_cluster_t *cairo_text_cluster_object_get_text_cluster(zval *zv)
      76              : {
      77            6 :     cairo_text_cluster_object *text_cluster_object = Z_CAIRO_TEXT_CLUSTER_P(zv);
      78              : 
      79            6 :     return text_cluster_object->text_cluster;
      80              : }
      81              : /* }}} */
      82              : 
      83           34 : zend_class_entry* php_cairo_get_text_cluster_ce()
      84              : {
      85           34 :     return ce_cairo_text_cluster;
      86              : }
      87              : 
      88              : /* ----------------------------------------------------------------
      89              :     \Cairo\TextCluster Class API
      90              : ------------------------------------------------------------------*/
      91              : 
      92              : /* {{{ proto void __construct(int num_bytes, int num_glyphs)
      93              :     Creates a new text_cluster with the properties populated */
      94           10 : PHP_METHOD(Cairo_TextCluster, __construct)
      95              : {
      96              :     cairo_text_cluster_object *text_cluster_object;
      97              : 
      98              :     /* read defaults from object */
      99              :     zend_long num_bytes, num_glyphs;
     100              : 
     101              :     /* Now allow constructor to overwrite them if desired */
     102           10 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     103           14 :         Z_PARAM_LONG(num_bytes)
     104           12 :         Z_PARAM_LONG(num_glyphs)
     105           10 :     ZEND_PARSE_PARAMETERS_END();
     106              : 
     107           10 :     text_cluster_object = Z_CAIRO_TEXT_CLUSTER_P(getThis());
     108              : 
     109            5 :     text_cluster_object->text_cluster->num_bytes = (int) num_bytes;
     110            5 :     text_cluster_object->text_cluster->num_glyphs = (int) num_glyphs;
     111              : }
     112              : /* }}} */
     113              : 
     114              : /* ----------------------------------------------------------------
     115              :     \Cairo\TextCluster Object management
     116              : ------------------------------------------------------------------*/
     117              : 
     118              : /* {{{ */
     119           45 : static void cairo_text_cluster_free_obj(zend_object *zobj)
     120              : {
     121           45 :     cairo_text_cluster_object *intern = cairo_text_cluster_fetch_object(zobj);
     122              : 
     123           45 :     if (!intern) {
     124            0 :         return;
     125              :     }
     126              : 
     127           45 :     if (intern->text_cluster) {
     128           45 :         efree(intern->text_cluster);
     129           45 :         intern->text_cluster = NULL;
     130              :     }
     131              : 
     132           45 :     zend_object_std_dtor(&intern->std);
     133              : }
     134              : /* }}} */
     135              : 
     136              : /* {{{ */
     137           45 : static zend_object* cairo_text_cluster_obj_ctor(zend_class_entry *ce, cairo_text_cluster_object **intern)
     138              : {
     139           45 :     cairo_text_cluster_object *object = ecalloc(1, sizeof(cairo_text_cluster_object) + zend_object_properties_size(ce));
     140           45 :     CAIRO_ALLOC_TEXT_CLUSTER(object->text_cluster);
     141              : 
     142           45 :     zend_object_std_init(&object->std, ce);
     143              : 
     144           45 :     object->std.handlers = &cairo_text_cluster_object_handlers;
     145           45 :     *intern = object;
     146              : 
     147              :     /* We need to read in any default values and set them if applicable */
     148           45 :     if (ce->default_properties_count) {
     149           45 :         object->text_cluster->num_bytes = cairo_text_cluster_get_property_default(ce, "num_bytes");
     150           45 :         object->text_cluster->num_glyphs = cairo_text_cluster_get_property_default(ce, "num_glyphs");
     151              :     }
     152              : 
     153           45 :     return &object->std;
     154              : }
     155              : /* }}} */
     156              : 
     157              : /* {{{ */
     158           44 : static zend_object* cairo_text_cluster_create_object(zend_class_entry *ce)
     159              : {
     160           44 :     cairo_text_cluster_object *intern = NULL;
     161           44 :     zend_object *return_value = cairo_text_cluster_obj_ctor(ce, &intern);
     162              : 
     163           44 :     object_properties_init(&intern->std, ce);
     164           44 :     return return_value;
     165              : }
     166              : /* }}} */
     167              : 
     168              : /* {{{ */
     169            1 : static zend_object* cairo_text_cluster_clone_obj(zend_object *zobj)
     170              : {
     171              :     cairo_text_cluster_object *new_text_cluster;
     172            1 :     cairo_text_cluster_object *old_text_cluster = cairo_text_cluster_fetch_object(zobj);
     173            1 :     zend_object *return_value = cairo_text_cluster_obj_ctor(zobj->ce, &new_text_cluster);
     174            1 :     CAIRO_ALLOC_TEXT_CLUSTER(new_text_cluster->text_cluster);
     175              : 
     176            1 :     new_text_cluster->text_cluster->num_bytes = old_text_cluster->text_cluster->num_bytes;
     177            1 :     new_text_cluster->text_cluster->num_glyphs = old_text_cluster->text_cluster->num_glyphs;
     178              : 
     179            1 :     zend_objects_clone_members(&new_text_cluster->std, &old_text_cluster->std);
     180              : 
     181            1 :     return return_value;
     182              : }
     183              : /* }}} */
     184              : 
     185              : /* {{{ */
     186            5 : static zval *cairo_text_cluster_object_read_property(zend_object *zobj, zend_string *member, int type, void **cache_slot, zval *rv)
     187              : {
     188              :     zval *retval;
     189              :     long value;
     190            5 :     cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
     191              : 
     192            5 :     if (!text_cluster_object) {
     193            0 :         return rv;
     194              :     }
     195              : 
     196              :     do {
     197            5 :         CAIRO_VALUE_FROM_STRUCT(num_bytes);
     198            3 :         CAIRO_VALUE_FROM_STRUCT(num_glyphs);
     199              : 
     200              :         // not a struct member
     201            1 :         retval = (zend_get_std_object_handlers())->read_property(zobj, member, type, cache_slot, rv);
     202              : 
     203            1 :         return retval;
     204              :     } while(0);
     205              : 
     206            4 :     retval = rv;
     207            4 :     ZVAL_LONG(retval, value);
     208              : 
     209            4 :     return retval;
     210              : }
     211              : /* }}} */
     212              : 
     213              : /* {{{ */
     214            5 : static zval *cairo_text_cluster_object_write_property(zend_object *zobj, zend_string *member, zval *value, void **cache_slot)
     215              : {
     216            5 :     cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
     217            5 :     zval *retval = NULL;
     218              : 
     219            5 :     if (!text_cluster_object) {
     220            0 :         return retval;
     221              :     }
     222              : 
     223              :     do {
     224            7 :         CAIRO_VALUE_TO_STRUCT(num_bytes);
     225            5 :         CAIRO_VALUE_TO_STRUCT(num_glyphs);
     226              :     } while(0);
     227              : 
     228              :     // not a struct member
     229            5 :     retval = (zend_get_std_object_handlers())->write_property(zobj, member, value, cache_slot);
     230              : 
     231            5 :     return retval;
     232              : }
     233              : /* }}} */
     234              : 
     235              : /* {{{ */
     236            4 : static HashTable *cairo_text_cluster_object_get_properties(zend_object *zobj)
     237              : {
     238              :     HashTable *props;
     239              :     // used in CAIRO_ADD_STRUCT_VALUE below
     240              :     zval tmp;
     241            4 :     cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
     242              : 
     243            4 :     props = zend_std_get_properties(zobj);
     244              : 
     245            4 :     if (!text_cluster_object->text_cluster) {
     246            0 :         return props;
     247              :     }
     248              : 
     249            4 :     CAIRO_ADD_STRUCT_VALUE(num_bytes);
     250            4 :     CAIRO_ADD_STRUCT_VALUE(num_glyphs);
     251              : 
     252            4 :     return props;
     253              : }
     254              : /* }}} */
     255              : 
     256              : /* ----------------------------------------------------------------
     257              :     \Cairo\TextCluster Definition and registration
     258              : ------------------------------------------------------------------*/
     259              : 
     260              : /* {{{ PHP_MINIT_FUNCTION */
     261          433 : PHP_MINIT_FUNCTION(cairo_text_cluster)
     262              : {
     263              :     zend_class_entry ce;
     264              : 
     265          433 :     memcpy(
     266              :         &cairo_text_cluster_object_handlers,
     267              :         zend_get_std_object_handlers(),
     268              :         sizeof(zend_object_handlers)
     269              :     );
     270              : 
     271          433 :     cairo_text_cluster_object_handlers.offset = XtOffsetOf(cairo_text_cluster_object, std);
     272          433 :     cairo_text_cluster_object_handlers.free_obj = cairo_text_cluster_free_obj;
     273          433 :     cairo_text_cluster_object_handlers.clone_obj = cairo_text_cluster_clone_obj;
     274          433 :     cairo_text_cluster_object_handlers.read_property = cairo_text_cluster_object_read_property;
     275          433 :     cairo_text_cluster_object_handlers.write_property = cairo_text_cluster_object_write_property;
     276          433 :     cairo_text_cluster_object_handlers.get_property_ptr_ptr = NULL;
     277          433 :     cairo_text_cluster_object_handlers.get_properties = cairo_text_cluster_object_get_properties;
     278              : 
     279          433 :     ce_cairo_text_cluster = register_class_Cairo_TextCluster();
     280          433 :     ce_cairo_text_cluster->create_object = cairo_text_cluster_create_object;
     281              : 
     282          433 :     return SUCCESS;
     283              : }
     284              : /* }}} */
         |