LCOV - code coverage report
Current view: top level - src - context.c (source / functions) Coverage Total Hit
Test: PHP Pango Extension Coverage Lines: 99.4 % 162 161
Test Date: 2025-10-26 00:52:08 Functions: 100.0 % 24 24

            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              :   | Authors: Michael Maclean <mgdm@php.net>                              |
      16              :   |          Marcel Bolten <github@marcelbolten.de>                      |
      17              :   +----------------------------------------------------------------------+
      18              : */
      19              : 
      20              : #ifdef HAVE_CONFIG_H
      21              : #include "config.h"
      22              : #endif
      23              : 
      24              : #include "php.h"
      25              : #include "php_pango.h"
      26              : #include "context_arginfo.h"
      27              : 
      28              : zend_class_entry *pango_ce_pango_context;
      29              : zend_class_entry *pango_ce_pango_direction;
      30              : zend_class_entry *pango_ce_pango_gravity;
      31              : zend_class_entry *pango_ce_pango_gravity_hint;
      32              : 
      33          255 : PHP_PANGO_API zend_class_entry* php_pango_get_context_ce() {
      34          255 :     return pango_ce_pango_context;
      35              : }
      36              : 
      37            4 : PHP_PANGO_API zend_class_entry* php_pango_get_direction_ce() {
      38            4 :     return pango_ce_pango_direction;
      39              : }
      40              : 
      41            2 : PHP_PANGO_API zend_class_entry* php_pango_get_gravity_ce() {
      42            2 :     return pango_ce_pango_gravity;
      43              : }
      44              : 
      45              : static zend_object_handlers pango_context_object_handlers;
      46              : 
      47          270 : pango_context_object *pango_context_fetch_object(zend_object *object)
      48              : {
      49          270 :     return (pango_context_object *) ((char*)(object) - XtOffsetOf(pango_context_object, std));
      50              : }
      51              : 
      52              : /* {{{ Creates a new PangoContext initialized to default values. */
      53           76 : PHP_METHOD(Pango_Context, __construct)
      54              : {
      55              :     pango_context_object *context_object;
      56           76 :     zval *font_map_zv = NULL;
      57              :     pango_font_map_object *font_map_object;
      58              : 
      59           76 :     ZEND_PARSE_PARAMETERS_START(0, 1)
      60           75 :         Z_PARAM_OPTIONAL
      61          137 :         Z_PARAM_OBJECT_OF_CLASS_OR_NULL(font_map_zv, php_pango_get_font_map_ce())
      62          137 :     ZEND_PARSE_PARAMETERS_END();
      63              : 
      64          148 :     context_object = Z_PANGO_CONTEXT_P(getThis());
      65              : 
      66          135 :     if (font_map_zv && Z_TYPE_P(font_map_zv) != IS_NULL) {
      67           61 :         font_map_object = Z_PANGO_FONT_MAP_P(font_map_zv);
      68           61 :         context_object->context = pango_font_map_create_context(font_map_object->font_map);
      69              : 
      70              :         // keep a reference of the font map zval in the pango context object
      71           61 :         ZVAL_COPY(&context_object->font_map_zv, font_map_zv);
      72           61 :         return;
      73              :     }
      74              : 
      75           13 :     context_object->context = pango_context_new();
      76              : }
      77              : 
      78              : /* {{{ */
      79            5 : PHP_METHOD(Pango_Context, getFontDescription)
      80              : {
      81              :     pango_context_object *context_object;
      82              : 
      83            5 :     ZEND_PARSE_PARAMETERS_NONE();
      84              : 
      85            8 :     context_object = Z_PANGO_CONTEXT_P(getThis());
      86              : 
      87            8 :     if (Z_TYPE(context_object->font_description_zv) != IS_UNDEF) {
      88            3 :         RETURN_COPY(&context_object->font_description_zv);
      89              :     }
      90              : 
      91            2 :     RETURN_NULL();
      92              : }
      93              : /* }}} */
      94              : 
      95              : /* {{{ */
      96            5 : PHP_METHOD(Pango_Context, setFontDescription)
      97              : {
      98              :     zval *font_desc_zv;
      99              :     pango_context_object *context_object;
     100            5 :     PangoFontDescription *font_description = NULL;
     101              : 
     102            5 :     ZEND_PARSE_PARAMETERS_START(1, 1);
     103            6 :         Z_PARAM_OBJECT_OF_CLASS_OR_NULL(font_desc_zv, php_pango_get_font_description_ce())
     104            5 :     ZEND_PARSE_PARAMETERS_END();
     105              : 
     106            4 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     107            2 :     zval_ptr_dtor(&context_object->font_description_zv);
     108              : 
     109            3 :     if (font_desc_zv && Z_TYPE_P(font_desc_zv) != IS_NULL) {
     110            1 :         ZVAL_COPY(&context_object->font_description_zv, font_desc_zv);
     111            1 :         font_description = Z_PANGO_FONT_DESC_P(font_desc_zv)->font_description;
     112              :     } else {
     113            1 :         ZVAL_NULL(&context_object->font_description_zv);
     114              :     }
     115              : 
     116            2 :     pango_context_set_font_description(context_object->context, font_description);
     117              : }
     118              : /* }}} */
     119              : 
     120              : /* {{{ */
     121            4 : PHP_METHOD(Pango_Context, getFontMap)
     122              : {
     123              :     pango_context_object *context_object;
     124              : 
     125            4 :     ZEND_PARSE_PARAMETERS_NONE();
     126              : 
     127            4 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     128              : 
     129            4 :     if (Z_TYPE(context_object->font_map_zv) != IS_UNDEF) {
     130            2 :         RETURN_COPY(&context_object->font_map_zv);
     131              :     }
     132              : 
     133            1 :     RETURN_NULL();
     134              : }
     135              : /* }}} */
     136              : 
     137              : // /* {{{ Sets the font map to be searched when fonts are looked-up in this context.
     138              : //        This is only for internal use by Pango backends, a PangoContext obtained
     139              : //        via one of the recommended methods should already have a suitable font map. */
     140              : // PHP_METHOD(Pango_Context, setFontMap)
     141              : // {
     142              : //     zval *font_map_zv = NULL;
     143              : 
     144              : //     ZEND_PARSE_PARAMETERS_START(0, 1);
     145              : //         Z_PARAM_OPTIONAL
     146              : //         Z_PARAM_OBJECT_OF_CLASS_OR_NULL(font_map_zv, php_pango_get_font_map_ce())
     147              : //     ZEND_PARSE_PARAMETERS_END();
     148              : // }
     149              : // /* }}} */
     150              : 
     151              : /* {{{ */
     152            2 : PHP_METHOD(Pango_Context, listFamilies)
     153              : {
     154              :     pango_context_object *context_object;
     155              :     PangoFontFamily** families;
     156              :     int num_families;
     157              :     zval family_zv;
     158              :     pango_font_family_object *font_family_object;
     159              : 
     160            2 :     ZEND_PARSE_PARAMETERS_NONE();
     161              : 
     162            2 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     163              : 
     164            1 :     pango_context_list_families(context_object->context, &families, &num_families);
     165              : 
     166            1 :     array_init(return_value);
     167           29 :     for (int i = 0; i < num_families; i++) {
     168           28 :         object_init_ex(&family_zv, php_pango_get_font_family_ce());
     169           28 :         font_family_object = Z_PANGO_FONT_FAMILY_P(&family_zv);
     170           28 :         font_family_object->font_family = g_object_ref(families[i]);
     171              :         add_next_index_zval(return_value, &family_zv);
     172              :     }
     173              : 
     174            1 :     g_free(families);
     175              : }
     176              : /* }}} */
     177              : 
     178              : 
     179              : /* {{{ Retrieves the base direction for the context. */
     180            4 : PHP_METHOD(Pango_Context, getBaseDir)
     181              : {
     182              :     pango_context_object *context_object;
     183              :     zend_object *base_dir_case;
     184              : 
     185            4 :     ZEND_PARSE_PARAMETERS_NONE();
     186              : 
     187            6 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     188              : 
     189            3 :     zend_enum_get_case_by_value(
     190              :         &base_dir_case, pango_ce_pango_direction,
     191            3 :         pango_context_get_base_dir(context_object->context),
     192              :         NULL, false
     193              :     );
     194              : 
     195            6 :     RETURN_OBJ_COPY(base_dir_case);
     196              : }
     197              : /* }}} */
     198              : 
     199              : /* {{{ Gets the base gravity to be used to lay out the text. */
     200            4 : PHP_METHOD(Pango_Context, getBaseGravity)
     201              : {
     202              :     pango_context_object *context_object;
     203              :     zend_object *base_gravity_case;
     204              : 
     205            4 :     ZEND_PARSE_PARAMETERS_NONE();
     206              : 
     207            6 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     208              : 
     209            3 :     zend_enum_get_case_by_value(
     210              :         &base_gravity_case, pango_ce_pango_gravity,
     211            3 :         pango_context_get_base_gravity(context_object->context),
     212              :         NULL, false
     213              :     );
     214              : 
     215            6 :     RETURN_OBJ_COPY(base_gravity_case);
     216              : }
     217              : /* }}} */
     218              : 
     219              : /* {{{ Gets the gravity to be used to lay out the text */
     220            2 : PHP_METHOD(Pango_Context, getGravity)
     221              : {
     222              :     pango_context_object *context_object;
     223              :     zend_object *gravity_case;
     224              : 
     225            2 :     ZEND_PARSE_PARAMETERS_NONE();
     226              : 
     227            2 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     228              : 
     229            1 :     zend_enum_get_case_by_value(
     230              :         &gravity_case, pango_ce_pango_gravity,
     231            1 :         pango_context_get_gravity(context_object->context),
     232              :         NULL, false
     233              :     );
     234              : 
     235            2 :     RETURN_OBJ_COPY(gravity_case);
     236              : }
     237              : /* }}} */
     238              : 
     239              : /* {{{ Gets the gravity hint to be used to lay out the text */
     240            4 : PHP_METHOD(Pango_Context, getGravityHint)
     241              : {
     242              :     pango_context_object *context_object;
     243              :     zend_object *gravity_hint_case;
     244              : 
     245            4 :     ZEND_PARSE_PARAMETERS_NONE();
     246              : 
     247            6 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     248              : 
     249            3 :     zend_enum_get_case_by_value(
     250              :         &gravity_hint_case, pango_ce_pango_gravity_hint,
     251            3 :         pango_context_get_gravity_hint(context_object->context),
     252              :         NULL, false
     253              :     );
     254              : 
     255            6 :     RETURN_OBJ_COPY(gravity_hint_case);
     256              : }
     257              : /* }}} */
     258              : 
     259              : /* {{{ */
     260            5 : PHP_METHOD(Pango_Context, getMatrix)
     261              : {
     262              :     pango_context_object *context_object;
     263              :     const PangoMatrix *matrix_pango;
     264              :     PangoMatrix *matrix_php;
     265              : 
     266            5 :     ZEND_PARSE_PARAMETERS_NONE();
     267              : 
     268            8 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     269            4 :     matrix_pango = pango_context_get_matrix(context_object->context);
     270              : 
     271              :     // start with a new identity matrix
     272            4 :     object_init_ex(return_value, php_pango_get_matrix_ce());
     273              : 
     274              :     // if the context has a matrix set, copy its values to the php matrix object
     275            4 :     if (matrix_pango != NULL) {
     276              :         // TODO: check if a copy is wanted here, perhaps just assign the pointer?
     277              :         // but the returned matrix is const so probably a copy is better
     278            2 :         matrix_php = pango_matrix_object_get_matrix(return_value);
     279            2 :         *matrix_php = *matrix_pango;
     280              :     }
     281              : }
     282              : /* }}} */
     283              : 
     284              : /* {{{ Returns whether font rendering with this context should round glyph positions and widths. */
     285            4 : PHP_METHOD(Pango_Context, getRoundGlyphPositions)
     286              : {
     287              :     pango_context_object *context_object;
     288              : 
     289            4 :     ZEND_PARSE_PARAMETERS_NONE();
     290              : 
     291            6 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     292              : 
     293            3 :     RETURN_BOOL(pango_context_get_round_glyph_positions(context_object->context));
     294              : }
     295              : /* }}} */
     296              : 
     297              : /* {{{ Sets the base direction for the context. */
     298            4 : PHP_METHOD(Pango_Context, setBaseDir)
     299              : {
     300              :     pango_context_object *context_object;
     301              :     zend_object *base_dir;
     302              : 
     303            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     304            4 :         Z_PARAM_OBJ_OF_CLASS(base_dir, pango_ce_pango_direction)
     305            4 :     ZEND_PARSE_PARAMETERS_END();
     306              : 
     307            2 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     308            1 :     pango_context_set_base_dir(
     309              :         context_object->context,
     310            2 :         Z_LVAL_P(zend_enum_fetch_case_value(base_dir))
     311              :     );
     312              : }
     313              : /* }}} */
     314              : 
     315              : /* {{{ Sets the base gravity to be used to lay out the text */
     316            4 : PHP_METHOD(Pango_Context, setBaseGravity)
     317              : {
     318              :     pango_context_object *context_object;
     319              :     zend_object *base_gravity;
     320              : 
     321            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     322            4 :         Z_PARAM_OBJ_OF_CLASS(base_gravity, pango_ce_pango_gravity)
     323            4 :     ZEND_PARSE_PARAMETERS_END();
     324              : 
     325            2 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     326            1 :     pango_context_set_base_gravity(
     327              :         context_object->context,
     328            2 :         Z_LVAL_P(zend_enum_fetch_case_value(base_gravity))
     329              :     );
     330              : }
     331              : /* }}} */
     332              : 
     333              : /* {{{ Sets the gravity hint to be used to lay out the text */
     334            4 : PHP_METHOD(Pango_Context, setGravityHint)
     335              : {
     336              :     pango_context_object *context_object;
     337              :     zend_object *gravity_hint;
     338              : 
     339            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     340            4 :         Z_PARAM_OBJ_OF_CLASS(gravity_hint, pango_ce_pango_gravity_hint)
     341            4 :     ZEND_PARSE_PARAMETERS_END();
     342              : 
     343            2 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     344            1 :     pango_context_set_gravity_hint(
     345              :         context_object->context,
     346            2 :         Z_LVAL_P(zend_enum_fetch_case_value(gravity_hint))
     347              :     );
     348              : }
     349              : /* }}} */
     350              : 
     351              : /* {{{ */
     352            4 : PHP_METHOD(Pango_Context, setMatrix)
     353              : {
     354              :     pango_context_object *context_object;
     355              :     zval *matrix_zval;
     356              :     PangoMatrix *matrix;
     357              : 
     358            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     359            4 :         Z_PARAM_OBJECT_OF_CLASS_OR_NULL(matrix_zval, php_pango_get_matrix_ce())
     360            4 :     ZEND_PARSE_PARAMETERS_END();
     361              : 
     362            2 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     363            1 :     matrix = pango_matrix_object_get_matrix(matrix_zval);
     364              : 
     365            1 :     pango_context_set_matrix(context_object->context, matrix);
     366              : }
     367              : /* }}} */
     368              : 
     369              : /* {{{ Sets the round glyph positions for the context. */
     370            4 : PHP_METHOD(Pango_Context, setRoundGlyphPositions)
     371              : {
     372              :     pango_context_object *context_object;
     373              :     bool round;
     374              : 
     375            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     376            4 :         Z_PARAM_BOOL(round)
     377            4 :     ZEND_PARSE_PARAMETERS_END();
     378              : 
     379            2 :     context_object = Z_PANGO_CONTEXT_P(getThis());
     380            1 :     pango_context_set_round_glyph_positions(context_object->context, round);
     381              : }
     382              : /* }}} */
     383              : 
     384              : 
     385              : /* ----------------------------------------------------------------
     386              :     \Pango\Context Object management
     387              : ------------------------------------------------------------------*/
     388              : 
     389              : /* {{{ */
     390           77 : static void pango_context_free_obj(zend_object *zobj)
     391              : {
     392           77 :     pango_context_object *intern = pango_context_fetch_object(zobj);
     393              : 
     394           77 :     if (!intern) {
     395            0 :         return;
     396              :     }
     397              : 
     398           77 :     zval_ptr_dtor(&intern->font_map_zv);
     399           77 :     zval_ptr_dtor(&intern->font_options_zv);
     400           77 :     zval_ptr_dtor(&intern->font_description_zv);
     401           77 :     zval_ptr_dtor(&intern->cairo_context_zv);
     402              : 
     403           77 :     if (intern->context) {
     404           75 :         g_object_unref(intern->context);
     405              :     }
     406              : 
     407           77 :     zend_object_std_dtor(&intern->std);
     408              : }
     409              : 
     410              : /* {{{ */
     411           77 : static zend_object* pango_context_obj_ctor(zend_class_entry *ce, pango_context_object **intern)
     412              : {
     413           77 :     pango_context_object *object = ecalloc(1, sizeof(pango_context_object) + zend_object_properties_size(ce));
     414              : 
     415           77 :     object->context = NULL;
     416              : 
     417           77 :     ZVAL_UNDEF(&object->cairo_context_zv);
     418           77 :     ZVAL_UNDEF(&object->font_map_zv);
     419           77 :     ZVAL_UNDEF(&object->font_options_zv);
     420           77 :     ZVAL_UNDEF(&object->font_description_zv);
     421              : 
     422           77 :     zend_object_std_init(&object->std, ce);
     423              : 
     424           77 :     object->std.handlers = &pango_context_object_handlers;
     425           77 :     *intern = object;
     426              : 
     427           77 :     return &object->std;
     428              : }
     429              : /* }}} */
     430              : 
     431              : /* {{{ */
     432           77 : static zend_object* pango_context_create_object(zend_class_entry *ce)
     433              : {
     434           77 :     pango_context_object *intern = NULL;
     435           77 :     zend_object *return_value = pango_context_obj_ctor(ce, &intern);
     436              : 
     437           77 :     object_properties_init(&intern->std, ce);
     438           77 :     return return_value;
     439              : }
     440              : /* }}} */
     441              : 
     442              : /* {{{ PHP_MINIT_FUNCTION */
     443          194 : PHP_MINIT_FUNCTION(pango_context)
     444              : {
     445          194 :     memcpy(
     446              :         &pango_context_object_handlers,
     447              :         zend_get_std_object_handlers(),
     448              :         sizeof(zend_object_handlers)
     449              :     );
     450              : 
     451          194 :     pango_context_object_handlers.offset = XtOffsetOf(pango_context_object, std);
     452          194 :     pango_context_object_handlers.free_obj = pango_context_free_obj;
     453              : 
     454          194 :     pango_ce_pango_context = register_class_Pango_Context();
     455          194 :     pango_ce_pango_context->create_object = pango_context_create_object;
     456              : 
     457          194 :     pango_ce_pango_gravity = register_class_Pango_Gravity();
     458          194 :     pango_ce_pango_gravity_hint = register_class_Pango_GravityHint();
     459          194 :     pango_ce_pango_direction = register_class_Pango_Direction();
     460              : 
     461          194 :     return SUCCESS;
     462              : }
     463              : /* }}} */
        

Generated by: LCOV version 2.0-1