LCOV - code coverage report
Current view: top level - src - text_cluster.c (source / functions) Coverage Total Hit
Test: PHP Cairo Extension Coverage Lines: 95.8 % 95 91
Test Date: 2025-09-10 21:28:33 Functions: 100.0 % 13 13

            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              :     long num_bytes;
     100              :     long num_glyphs;
     101              : 
     102              :     /* Now allow constructor to overwrite them if desired */
     103           10 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     104           14 :         Z_PARAM_LONG(num_bytes)
     105           12 :         Z_PARAM_LONG(num_glyphs)
     106           10 :     ZEND_PARSE_PARAMETERS_END();
     107              : 
     108           10 :     text_cluster_object = Z_CAIRO_TEXT_CLUSTER_P(getThis());
     109              : 
     110            5 :     text_cluster_object->text_cluster->num_bytes = num_bytes;
     111            5 :     text_cluster_object->text_cluster->num_glyphs = num_glyphs;
     112              : }
     113              : /* }}} */
     114              : 
     115              : /* ----------------------------------------------------------------
     116              :     \Cairo\TextCluster Object management
     117              : ------------------------------------------------------------------*/
     118              : 
     119              : /* {{{ */
     120           45 : static void cairo_text_cluster_free_obj(zend_object *zobj)
     121              : {
     122           45 :     cairo_text_cluster_object *intern = cairo_text_cluster_fetch_object(zobj);
     123              : 
     124           45 :     if (!intern) {
     125            0 :         return;
     126              :     }
     127              : 
     128           45 :     if (intern->text_cluster) {
     129           45 :         efree(intern->text_cluster);
     130           45 :         intern->text_cluster = NULL;
     131              :     }
     132              : 
     133           45 :     zend_object_std_dtor(&intern->std);
     134              : }
     135              : /* }}} */
     136              : 
     137              : /* {{{ */
     138           45 : static zend_object* cairo_text_cluster_obj_ctor(zend_class_entry *ce, cairo_text_cluster_object **intern)
     139              : {
     140           45 :     cairo_text_cluster_object *object = ecalloc(1, sizeof(cairo_text_cluster_object) + zend_object_properties_size(ce));
     141           45 :     CAIRO_ALLOC_TEXT_CLUSTER(object->text_cluster);
     142              : 
     143           45 :     zend_object_std_init(&object->std, ce);
     144              : 
     145           45 :     object->std.handlers = &cairo_text_cluster_object_handlers;
     146           45 :     *intern = object;
     147              : 
     148              :     /* We need to read in any default values and set them if applicable */
     149           45 :     if (ce->default_properties_count) {
     150           45 :         object->text_cluster->num_bytes = cairo_text_cluster_get_property_default(ce, "num_bytes");
     151           45 :         object->text_cluster->num_glyphs = cairo_text_cluster_get_property_default(ce, "num_glyphs");
     152              :     }
     153              : 
     154           45 :     return &object->std;
     155              : }
     156              : /* }}} */
     157              : 
     158              : /* {{{ */
     159           44 : static zend_object* cairo_text_cluster_create_object(zend_class_entry *ce)
     160              : {
     161           44 :     cairo_text_cluster_object *intern = NULL;
     162           44 :     zend_object *return_value = cairo_text_cluster_obj_ctor(ce, &intern);
     163              : 
     164           44 :     object_properties_init(&intern->std, ce);
     165           44 :     return return_value;
     166              : }
     167              : /* }}} */
     168              : 
     169              : /* {{{ */
     170            1 : static zend_object* cairo_text_cluster_clone_obj(zend_object *zobj)
     171              : {
     172              :     cairo_text_cluster_object *new_text_cluster;
     173            1 :     cairo_text_cluster_object *old_text_cluster = cairo_text_cluster_fetch_object(zobj);
     174            1 :     zend_object *return_value = cairo_text_cluster_obj_ctor(zobj->ce, &new_text_cluster);
     175            1 :     CAIRO_ALLOC_TEXT_CLUSTER(new_text_cluster->text_cluster);
     176              : 
     177            1 :     new_text_cluster->text_cluster->num_bytes = old_text_cluster->text_cluster->num_bytes;
     178            1 :     new_text_cluster->text_cluster->num_glyphs = old_text_cluster->text_cluster->num_glyphs;
     179              : 
     180            1 :     zend_objects_clone_members(&new_text_cluster->std, &old_text_cluster->std);
     181              : 
     182            1 :     return return_value;
     183              : }
     184              : /* }}} */
     185              : 
     186              : /* {{{ */
     187            5 : static zval *cairo_text_cluster_object_read_property(zend_object *zobj, zend_string *member, int type, void **cache_slot, zval *rv)
     188              : {
     189              :     zval *retval;
     190              :     long value;
     191            5 :     cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
     192              : 
     193            5 :     if (!text_cluster_object) {
     194            0 :         return rv;
     195              :     }
     196              : 
     197              :     do {
     198            5 :         CAIRO_VALUE_FROM_STRUCT(num_bytes);
     199            3 :         CAIRO_VALUE_FROM_STRUCT(num_glyphs);
     200              : 
     201              :         // not a struct member
     202            1 :         retval = (zend_get_std_object_handlers())->read_property(zobj, member, type, cache_slot, rv);
     203              : 
     204            1 :         return retval;
     205              :     } while(0);
     206              : 
     207            4 :     retval = rv;
     208            4 :     ZVAL_LONG(retval, value);
     209              : 
     210            4 :     return retval;
     211              : }
     212              : /* }}} */
     213              : 
     214              : /* {{{ */
     215            5 : static zval *cairo_text_cluster_object_write_property(zend_object *zobj, zend_string *member, zval *value, void **cache_slot)
     216              : {
     217            5 :     cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
     218            5 :     zval *retval = NULL;
     219              : 
     220            5 :     if (!text_cluster_object) {
     221            0 :         return retval;
     222              :     }
     223              : 
     224              :     do {
     225            7 :         CAIRO_VALUE_TO_STRUCT(num_bytes);
     226            5 :         CAIRO_VALUE_TO_STRUCT(num_glyphs);
     227              :     } while(0);
     228              : 
     229              :     // not a struct member
     230            5 :     retval = (zend_get_std_object_handlers())->write_property(zobj, member, value, cache_slot);
     231              : 
     232            5 :     return retval;
     233              : }
     234              : /* }}} */
     235              : 
     236              : /* {{{ */
     237            4 : static HashTable *cairo_text_cluster_object_get_properties(zend_object *zobj)
     238              : {
     239              :     HashTable *props;
     240              :     // used in CAIRO_ADD_STRUCT_VALUE below
     241              :     zval tmp;
     242            4 :     cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
     243              : 
     244            4 :     props = zend_std_get_properties(zobj);
     245              : 
     246            4 :     if (!text_cluster_object->text_cluster) {
     247            0 :         return props;
     248              :     }
     249              : 
     250            4 :     CAIRO_ADD_STRUCT_VALUE(num_bytes);
     251            4 :     CAIRO_ADD_STRUCT_VALUE(num_glyphs);
     252              : 
     253            4 :     return props;
     254              : }
     255              : /* }}} */
     256              : 
     257              : /* ----------------------------------------------------------------
     258              :     \Cairo\TextCluster Definition and registration
     259              : ------------------------------------------------------------------*/
     260              : 
     261              : /* {{{ PHP_MINIT_FUNCTION */
     262          424 : PHP_MINIT_FUNCTION(cairo_text_cluster)
     263              : {
     264              :     zend_class_entry ce;
     265              : 
     266          424 :     memcpy(
     267              :         &cairo_text_cluster_object_handlers,
     268              :         zend_get_std_object_handlers(),
     269              :         sizeof(zend_object_handlers)
     270              :     );
     271              : 
     272          424 :     cairo_text_cluster_object_handlers.offset = XtOffsetOf(cairo_text_cluster_object, std);
     273          424 :     cairo_text_cluster_object_handlers.free_obj = cairo_text_cluster_free_obj;
     274          424 :     cairo_text_cluster_object_handlers.clone_obj = cairo_text_cluster_clone_obj;
     275          424 :     cairo_text_cluster_object_handlers.read_property = cairo_text_cluster_object_read_property;
     276          424 :     cairo_text_cluster_object_handlers.write_property = cairo_text_cluster_object_write_property;
     277          424 :     cairo_text_cluster_object_handlers.get_property_ptr_ptr = NULL;
     278          424 :     cairo_text_cluster_object_handlers.get_properties = cairo_text_cluster_object_get_properties;
     279              : 
     280          424 :     ce_cairo_text_cluster = register_class_Cairo_TextCluster();
     281          424 :     ce_cairo_text_cluster->create_object = cairo_text_cluster_create_object;
     282              : 
     283          424 :     return SUCCESS;
     284              : }
     285              : /* }}} */
        

Generated by: LCOV version 2.0-1