LCOV - code coverage report
Current view: top level - src - item.c (source / functions) Coverage Total Hit
Test: PHP Pango Extension Coverage Lines: 95.3 % 85 81
Test Date: 2025-10-26 00:52:08 Functions: 100.0 % 8 8

            Line data    Source code
       1              : /*
       2              :   +----------------------------------------------------------------------+
       3              :   | For PHP Version 8.2+                                                 |
       4              :   +----------------------------------------------------------------------+
       5              :   | Copyright (c) The PHP Group                                          |
       6              :   +----------------------------------------------------------------------+
       7              :   | This source file is subject to version 3.01 of the PHP license,      |
       8              :   | that is bundled with this package in the file LICENSE, and is        |
       9              :   | available through the world-wide-web at the following url:           |
      10              :   | http://www.php.net/license/3_01.txt                                  |
      11              :   | If you did not receive a copy of the PHP license and are unable to   |
      12              :   | obtain it through the world-wide-web, please send a note to          |
      13              :   | license@php.net so we can mail you a copy immediately.               |
      14              :   +----------------------------------------------------------------------+
      15              :   | Author: Marcel Bolten <github@marcelbolten.de>                       |
      16              :   +----------------------------------------------------------------------+
      17              : */
      18              : 
      19              : #ifdef HAVE_CONFIG_H
      20              : #include "config.h"
      21              : #endif
      22              : 
      23              : #include "php.h"
      24              : #include "php_pango.h"
      25              : #include "item_arginfo.h"
      26              : 
      27              : #include <string.h>
      28              : #include <glib.h>
      29              : #include "zend_exceptions.h"
      30              : 
      31              : zend_class_entry *pango_ce_pango_item;
      32              : 
      33              : static zend_object_handlers pango_item_object_handlers;
      34              : 
      35           13 : pango_item_object *pango_item_fetch_object(zend_object *object)
      36              : {
      37           13 :     return (pango_item_object *) ((char*)(object) - XtOffsetOf(pango_item_object, std));
      38              : }
      39              : 
      40              : #define PANGO_VALUE_FROM_STRUCT(php_name, c_name) \
      41              :     if (strcmp(ZSTR_VAL(member), #php_name) == 0) { \
      42              :         zend_long value = 0; \
      43              :         value = item_object->item->c_name; \
      44              :         ZVAL_LONG(rv, value); \
      45              :         return rv; \
      46              :     }
      47              : 
      48              : #define PANGO_ADD_STRUCT_VALUE(php_name, c_name) \
      49              :     ZVAL_LONG(&tmp, item_object->item->c_name); \
      50              :     zend_hash_str_update(props, #php_name, sizeof(#php_name)-1, &tmp);
      51              : 
      52              : 
      53            4 : PHP_PANGO_API zend_class_entry* php_pango_get_item_ce()
      54              : {
      55            4 :     return pango_ce_pango_item;
      56              : }
      57              : 
      58              : /* ----------------------------------------------------------------
      59              :     \Pango\Item Object management
      60              : ------------------------------------------------------------------*/
      61              : 
      62              : /* {{{ */
      63            4 : static void pango_item_free_obj(zend_object *zobj)
      64              : {
      65            4 :     pango_item_object *intern = pango_item_fetch_object(zobj);
      66              : 
      67            4 :     if (!intern) {
      68            0 :         return;
      69              :     }
      70              : 
      71            4 :     if (intern->item != NULL) {
      72            4 :         pango_item_free(intern->item);
      73            4 :         intern->item = NULL;
      74              :     }
      75              : 
      76            4 :     zval_ptr_dtor(&intern->glyph_item_zv);
      77              : 
      78            4 :     zend_object_std_dtor(&intern->std);
      79              : }
      80              : /* }}} */
      81              : 
      82              : /* {{{ */
      83            4 : static zend_object* pango_item_obj_ctor(zend_class_entry *ce, pango_item_object **intern)
      84              : {
      85            4 :     pango_item_object *object = ecalloc(1, sizeof(pango_item_object) + zend_object_properties_size(ce));
      86              : 
      87            4 :     ZVAL_UNDEF(&object->glyph_item_zv);
      88              : 
      89            4 :     zend_object_std_init(&object->std, ce);
      90              : 
      91            4 :     object->std.handlers = &pango_item_object_handlers;
      92            4 :     *intern = object;
      93              : 
      94            4 :     return &object->std;
      95              : }
      96              : /* }}} */
      97              : 
      98              : /* {{{ */
      99            4 : static zend_object* pango_item_create_object(zend_class_entry *ce)
     100              : {
     101            4 :     pango_item_object *intern = NULL;
     102            4 :     zend_object *return_value = pango_item_obj_ctor(ce, &intern);
     103              : 
     104            4 :     object_properties_init(&intern->std, ce);
     105            4 :     return return_value;
     106              : }
     107              : /* }}} */
     108              : 
     109              : /* {{{ */
     110            4 : static zval *pango_item_read_property(zend_object *zobj, zend_string *member, int type, void **cache_slot, zval *rv)
     111              : {
     112            4 :     pango_item_object *item_object = pango_item_fetch_object(zobj);
     113              : 
     114            4 :     if (!item_object) {
     115            0 :         return rv;
     116              :     }
     117              : 
     118            4 :     if (strcmp(ZSTR_VAL(member), "analysis") == 0) {
     119            1 :         array_init(rv);
     120            1 :         add_assoc_long(rv, "bidiLevel", item_object->item->analysis.level);
     121              : 
     122              :         zend_object *gravity_case;
     123            1 :         zend_enum_get_case_by_value(
     124              :             &gravity_case, php_pango_get_gravity_ce(),
     125            1 :             item_object->item->analysis.gravity,
     126              :             NULL, false
     127              :         );
     128            1 :         GC_ADDREF(gravity_case);
     129            1 :         add_assoc_object(rv, "gravity", gravity_case);
     130              : 
     131              :         // add_assoc_long(rv, "flags", item_object->item->analysis.flags);
     132            1 :         add_assoc_bool(rv, "centeredBaseline", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE) != 0);
     133            1 :         add_assoc_bool(rv, "isEllipsis", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_IS_ELLIPSIS) != 0);
     134            1 :         add_assoc_bool(rv, "needsHyphen", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_NEED_HYPHEN) != 0);
     135              : 
     136            1 :         guint32 script_code = GUINT32_TO_BE(g_unicode_script_to_iso15924((GUnicodeScript)item_object->item->analysis.script));
     137            1 :         char script_str[5] = {0};
     138            1 :         memcpy(script_str, &script_code, 4);
     139            1 :         script_str[4] = '\0';
     140              :         add_assoc_string(rv, "script", script_str);
     141              : 
     142            1 :         if (item_object->item->analysis.language != NULL) {
     143            1 :             const char* lang_str = pango_language_to_string(item_object->item->analysis.language);
     144              :             add_assoc_string(rv, "language", lang_str);
     145              :         } else {
     146              :             add_assoc_null(rv, "language");
     147              :         }
     148            1 :         return rv;
     149              :     }
     150              : 
     151            3 :     PANGO_VALUE_FROM_STRUCT(offset, offset);
     152            2 :     PANGO_VALUE_FROM_STRUCT(length, length);
     153            1 :     PANGO_VALUE_FROM_STRUCT(numChars, num_chars);
     154            0 : }
     155              : /* }}} */
     156              : 
     157              : /* {{{ */
     158            1 : static HashTable *pango_item_get_properties(zend_object *object)
     159              : {
     160              :     HashTable *props;
     161              :     // used in PANGO_ADD_STRUCT_VALUE below
     162              :     zval tmp;
     163            1 :     pango_item_object *item_object = pango_item_fetch_object(object);
     164              : 
     165            1 :     props = zend_std_get_properties(object);
     166              : 
     167            1 :     if (!item_object->item) {
     168            0 :         return props;
     169              :     }
     170              : 
     171            1 :     array_init(&tmp);
     172            1 :     add_assoc_long(&tmp, "bidiLevel", item_object->item->analysis.level);
     173              : 
     174              :     zend_object *gravity_case;
     175            1 :     zend_enum_get_case_by_value(
     176              :         &gravity_case, php_pango_get_gravity_ce(),
     177            1 :         item_object->item->analysis.gravity,
     178              :         NULL, false
     179              :     );
     180            1 :     GC_ADDREF(gravity_case);
     181            1 :     add_assoc_object(&tmp, "gravity", gravity_case);
     182              : 
     183              :     // add_assoc_long(&tmp, "flags", item_object->item->analysis.flags);
     184            1 :     add_assoc_bool(&tmp, "centeredBaseline", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE) != 0);
     185            1 :     add_assoc_bool(&tmp, "isEllipsis", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_IS_ELLIPSIS) != 0);
     186            1 :     add_assoc_bool(&tmp, "needsHyphen", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_NEED_HYPHEN) != 0);
     187              : 
     188            1 :     guint32 script_code = GUINT32_TO_BE(g_unicode_script_to_iso15924((GUnicodeScript)item_object->item->analysis.script));
     189            1 :     char script_str[5] = {0};
     190            1 :     memcpy(script_str, &script_code, 4);
     191            1 :     script_str[4] = '\0';
     192              :     add_assoc_string(&tmp, "script", script_str);
     193              : 
     194            1 :     if (item_object->item->analysis.language != NULL) {
     195            1 :         const char* lang_str = pango_language_to_string(item_object->item->analysis.language);
     196              :         add_assoc_string(&tmp, "language", lang_str);
     197              :     } else {
     198              :         add_assoc_null(&tmp, "language");
     199              :     }
     200            1 :     zend_hash_str_update(props, "analysis", sizeof("analysis")-1, &tmp);
     201              : 
     202            1 :     PANGO_ADD_STRUCT_VALUE(offset, offset);
     203            1 :     PANGO_ADD_STRUCT_VALUE(length, length);
     204            1 :     PANGO_ADD_STRUCT_VALUE(numChars, num_chars);
     205              : 
     206            1 :     return props;
     207              : }
     208              : /* }}} */
     209              : 
     210              : /* {{{ PHP_MINIT_FUNCTION */
     211          194 : PHP_MINIT_FUNCTION(pango_item)
     212              : {
     213          194 :     memcpy(
     214              :         &pango_item_object_handlers,
     215              :         zend_get_std_object_handlers(),
     216              :         sizeof(zend_object_handlers)
     217              :     );
     218              : 
     219          194 :     pango_item_object_handlers.offset = XtOffsetOf(pango_item_object, std);
     220          194 :     pango_item_object_handlers.free_obj = pango_item_free_obj;
     221          194 :     pango_item_object_handlers.read_property = pango_item_read_property;
     222          194 :     pango_item_object_handlers.get_property_ptr_ptr = NULL;
     223          194 :     pango_item_object_handlers.get_properties = pango_item_get_properties;
     224              : 
     225          194 :     pango_ce_pango_item = register_class_Pango_Item();
     226          194 :     pango_ce_pango_item->create_object = pango_item_create_object;
     227              : 
     228          194 :     return SUCCESS;
     229              : }
     230              : /* }}} */
        

Generated by: LCOV version 2.0-1