LCOV - code coverage report
Current view: top level - src - scaled_font.c (source / functions) Coverage Total Hit
Test: PHP Cairo Extension Coverage Lines: 84.8 % 237 201
Test Date: 2025-09-10 21:28:33 Functions: 100.0 % 19 19

            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              : 
      23              : #include "php_cairo.h"
      24              : #include "php_cairo_internal.h"
      25              : #include "scaled_font_arginfo.h"
      26              : 
      27              : 
      28              : zend_class_entry *ce_cairo_scaled_font;
      29              : 
      30              : static zend_object_handlers cairo_scaled_font_object_handlers;
      31              : 
      32           70 : cairo_scaled_font_object *cairo_scaled_font_fetch_object(zend_object *object)
      33              : {
      34           70 :     return (cairo_scaled_font_object *) ((char*)(object) - XtOffsetOf(cairo_scaled_font_object, std));
      35              : }
      36              : 
      37           18 : static inline cairo_scaled_font_object *cairo_scaled_font_object_get(zval *zv)
      38              : {
      39           18 :     cairo_scaled_font_object *object = Z_CAIRO_SCALED_FONT_P(zv);
      40           18 :     if (object->scaled_font == NULL) {
      41            0 :         zend_throw_exception_ex(ce_cairo_exception, 0,
      42              :             "Internal scaled_font object missing in %s, you must call parent::__construct in extended classes.",
      43            0 :             ZSTR_VAL(Z_OBJCE_P(zv)->name));
      44            0 :         return NULL;
      45              :     }
      46           18 :     return object;
      47              : }
      48              : 
      49              : 
      50              : /* ----------------------------------------------------------------
      51              :     Cairo\FontOptions Object management
      52              : ------------------------------------------------------------------*/
      53              : 
      54              : /* {{{ */
      55           29 : static void cairo_scaled_font_free_obj(zend_object *object)
      56              : {
      57           29 :     cairo_scaled_font_object *intern = cairo_scaled_font_fetch_object(object);
      58              : 
      59           29 :     if (!intern) {
      60            0 :         return;
      61              :     }
      62              : 
      63           29 :     zval_ptr_dtor(&intern->font_face);
      64           29 :     zval_ptr_dtor(&intern->matrix);
      65           29 :     zval_ptr_dtor(&intern->ctm);
      66           29 :     zval_ptr_dtor(&intern->font_options);
      67              : 
      68           29 :     if (intern->scaled_font) {
      69           20 :         cairo_scaled_font_destroy(intern->scaled_font);
      70           20 :         intern->scaled_font = NULL;
      71              :     }
      72              : 
      73           29 :     zend_object_std_dtor(&intern->std);
      74              : }
      75              : 
      76              : /* {{{ */
      77           29 : static zend_object* cairo_scaled_font_obj_ctor(zend_class_entry *ce, cairo_scaled_font_object **intern)
      78              : {
      79           29 :     cairo_scaled_font_object *object = ecalloc(1, sizeof(cairo_scaled_font_object) + zend_object_properties_size(ce));
      80              : 
      81           29 :     ZVAL_UNDEF(&object->font_face);
      82           29 :     ZVAL_UNDEF(&object->matrix);
      83           29 :     ZVAL_UNDEF(&object->ctm);
      84           29 :     ZVAL_UNDEF(&object->font_options);
      85           29 :     object->scaled_font = NULL;
      86              : 
      87           29 :     zend_object_std_init(&object->std, ce);
      88           29 :     object->std.handlers = &cairo_scaled_font_object_handlers;
      89           29 :     *intern = object;
      90              : 
      91           29 :     return &object->std;
      92              : }
      93              : /* }}} */
      94              : 
      95              : /* {{{ */
      96           29 : static zend_object* cairo_scaled_font_create_object(zend_class_entry *ce)
      97              : {
      98           29 :     cairo_scaled_font_object *scaled_font_obj = NULL;
      99           29 :     zend_object *return_value = cairo_scaled_font_obj_ctor(ce, &scaled_font_obj);
     100              : 
     101           29 :     object_properties_init(&scaled_font_obj->std, ce);
     102           29 :     return return_value;
     103              : }
     104              : /* }}} */
     105              : 
     106              : 
     107              : /* ----------------------------------------------------------------
     108              :     Cairo\FontOptions C API
     109              : ------------------------------------------------------------------*/
     110              : 
     111            5 : zend_class_entry * php_cairo_get_scaled_font_ce()
     112              : {
     113            5 :     return ce_cairo_scaled_font;
     114              : }
     115              : 
     116              : 
     117              : /* ----------------------------------------------------------------
     118              :     Cairo\FontOptions Class API
     119              : ------------------------------------------------------------------*/
     120              : 
     121              : /* {{{ proto void __construct(\Cairo\FontFace font_face, \Cairo\Matrix matrix, \Cairo\Matrix ctm, \Cairo\FontOptions options)
     122              :        Creates a \Cairo\ScaledFont object from a font face and matrices that describe the size of the font and the environment in which it will be used */
     123           24 : PHP_METHOD(Cairo_ScaledFont, __construct)
     124              : {
     125              :     zval *font_face_zval, *matrix_zval, *ctm_zval, *font_options_zval;
     126              :     cairo_scaled_font_object *scaled_font_object;
     127              : 
     128           24 :     ZEND_PARSE_PARAMETERS_START(4, 4)
     129           38 :         Z_PARAM_OBJECT_OF_CLASS(font_face_zval, ce_cairo_fontface)
     130           36 :         Z_PARAM_OBJECT_OF_CLASS(matrix_zval, ce_cairo_matrix)
     131           34 :         Z_PARAM_OBJECT_OF_CLASS(ctm_zval, ce_cairo_matrix)
     132           32 :         Z_PARAM_OBJECT_OF_CLASS(font_options_zval, ce_cairo_fontoptions)
     133           24 :     ZEND_PARSE_PARAMETERS_END();
     134              : 
     135           30 :     scaled_font_object = Z_CAIRO_SCALED_FONT_P(getThis());
     136           15 :     if (!scaled_font_object) {
     137            0 :         RETURN_NULL();
     138              :     }
     139              : 
     140           15 :     scaled_font_object->scaled_font = cairo_scaled_font_create(
     141              :         cairo_font_face_object_get_font_face(font_face_zval),
     142           15 :         cairo_matrix_object_get_matrix(matrix_zval),
     143           15 :         cairo_matrix_object_get_matrix(ctm_zval),
     144           15 :         cairo_font_options_object_get_font_options(font_options_zval)
     145              :     );
     146           15 :     if (php_cairo_throw_exception(cairo_scaled_font_status(scaled_font_object->scaled_font))) {
     147            0 :         RETURN_THROWS();
     148              :     }
     149              : 
     150              :     /* we need to be able to get these zvals out later, so store them */
     151           15 :     ZVAL_COPY(&scaled_font_object->font_face, font_face_zval);
     152           15 :     ZVAL_COPY(&scaled_font_object->matrix, matrix_zval);
     153           15 :     ZVAL_COPY(&scaled_font_object->ctm, ctm_zval);
     154           15 :     ZVAL_COPY(&scaled_font_object->font_options, font_options_zval);
     155              : }
     156              : /* }}} */
     157              : 
     158              : /* {{{ proto \Cairo\Status \Cairo\ScaledFont::getStatus()
     159              :        Returns the current integer status of the CairoScaledFont */
     160            2 : PHP_METHOD(Cairo_ScaledFont, getStatus)
     161              : {
     162              :     cairo_scaled_font_object *scaled_font_object;
     163              :     zval status_case;
     164              : 
     165            3 :     ZEND_PARSE_PARAMETERS_NONE();
     166              : 
     167            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     168            1 :     if (!scaled_font_object) {
     169            0 :         RETURN_THROWS();
     170              :     }
     171              : 
     172            1 :     status_case = php_enum_from_cairo_c_enum(
     173              :         ce_cairo_status,
     174            1 :         cairo_scaled_font_status(scaled_font_object->scaled_font)
     175              :     );
     176              : 
     177            1 :     if (Z_TYPE(status_case) == IS_OBJECT) {
     178            2 :         RETURN_ZVAL(&status_case, 1, 1);
     179              :     }
     180              : }
     181              : /* }}} */
     182              : 
     183              : /* {{{ proto array \Cairo\ScaledFont::getExtents()
     184              :        Gets the metrics for a scaled font in an assoc array
     185              : */
     186            2 : PHP_METHOD(Cairo_ScaledFont, getExtents)
     187              : {
     188              :     cairo_scaled_font_object *scaled_font_object;
     189              :     cairo_font_extents_t extents;
     190              : 
     191            2 :     ZEND_PARSE_PARAMETERS_NONE();
     192              : 
     193            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     194            1 :     if (!scaled_font_object) {
     195            0 :         RETURN_THROWS();
     196              :     }
     197              : 
     198            1 :     cairo_scaled_font_extents(scaled_font_object->scaled_font, &extents);
     199              : 
     200            1 :     array_init(return_value);
     201            1 :     add_assoc_double(return_value, "ascent", extents.ascent);
     202            1 :     add_assoc_double(return_value, "descent", extents.descent);
     203            1 :     add_assoc_double(return_value, "height", extents.height);
     204            1 :     add_assoc_double(return_value, "max_x_advance", extents.max_x_advance);
     205            1 :     add_assoc_double(return_value, "max_y_advance", extents.max_y_advance);
     206              : }
     207              : /* }}} */
     208              : 
     209              : /* {{{ proto array \Cairo\ScaledFont::getTextExtents(string text)
     210              :        previous method-name was textExtents()
     211              :        Gets the extents for a string of UTF8 text.
     212              : */
     213            4 : PHP_METHOD(Cairo_ScaledFont, getTextExtents)
     214              : {
     215              :     cairo_scaled_font_object *scaled_font_object;
     216              :     char *text, *cairo_text;
     217              :     size_t text_len;
     218              :     cairo_text_extents_t extents;
     219              : 
     220            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     221            4 :         Z_PARAM_STRING(text, text_len)
     222            4 :     ZEND_PARSE_PARAMETERS_END();
     223              : 
     224            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     225            1 :     if (!scaled_font_object) {
     226            0 :         RETURN_THROWS();
     227              :     }
     228              : 
     229            1 :     cairo_text = estrdup(text);
     230            1 :     cairo_scaled_font_text_extents(scaled_font_object->scaled_font, cairo_text, &extents);
     231            1 :     efree(cairo_text);
     232              : 
     233            1 :     array_init(return_value);
     234            1 :     add_assoc_double(return_value, "x_bearing", extents.x_bearing);
     235            1 :     add_assoc_double(return_value, "y_bearing", extents.y_bearing);
     236            1 :     add_assoc_double(return_value, "width", extents.width);
     237            1 :     add_assoc_double(return_value, "height", extents.height);
     238            1 :     add_assoc_double(return_value, "x_advance", extents.x_advance);
     239            1 :     add_assoc_double(return_value, "y_advance", extents.y_advance);
     240              : }
     241              : /* }}} */
     242              : 
     243              : /* {{{ proto array \Cairo\ScaledFont::getGlyphExtents(array glyphs)
     244              :     previous method-name was "glyphExtents".
     245              :     Gets the extents for an array of glyphs. The extents describe a user-space
     246              :     rectangle that encloses the "inked" portion of the glyphs. */
     247            2 : PHP_METHOD(Cairo_ScaledFont, getGlyphExtents)
     248              : {
     249              :     cairo_scaled_font_object *scaled_font_object;
     250              :     cairo_glyph_t *glyphs_array;
     251            2 :     int num_glyphs = 0;
     252              :     cairo_text_extents_t extents;
     253            2 :     int i = 0;
     254              : 
     255            2 :     zval *php_glyphs = NULL;
     256              :     zval *pzval;
     257            2 :     HashTable *glyphs_hash = NULL;
     258              : 
     259            2 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     260            4 :         Z_PARAM_ARRAY(php_glyphs);
     261            3 :     ZEND_PARSE_PARAMETERS_END();
     262              : 
     263            4 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     264            2 :     if (!scaled_font_object) {
     265            0 :         RETURN_THROWS();
     266              :     }
     267              : 
     268              :     /* Grab the zend hash and see how big our array will be */
     269            2 :     glyphs_hash = Z_ARRVAL_P(php_glyphs);
     270            2 :     num_glyphs = zend_hash_num_elements(glyphs_hash);
     271            2 :     glyphs_array = ecalloc(num_glyphs, sizeof(cairo_glyph_t));
     272              : 
     273              :     /* iterate over the array, each value inside MUST be an instance of CairoGlyph */
     274            5 :     ZEND_HASH_FOREACH_VAL(glyphs_hash, pzval) {
     275            2 :         if (Z_TYPE_P(pzval) != IS_OBJECT || Z_OBJCE_P(pzval) != ce_cairo_glyph) {
     276            1 :             zend_throw_exception(zend_ce_type_error, "Cairo\\ScaledFont::getGlyphExtents(): Argument #1 ($glyphs) must be an array of Cairo\\Glyph objects.", 0);
     277            1 :             efree(glyphs_array);
     278            1 :             RETURN_THROWS();
     279              :         }
     280            1 :         glyphs_array[i++] = *(cairo_glyph_object_get_glyph(pzval));
     281              :     } ZEND_HASH_FOREACH_END();
     282              : 
     283            1 :     cairo_scaled_font_glyph_extents(scaled_font_object->scaled_font, glyphs_array, num_glyphs, &extents);
     284            1 :     efree(glyphs_array);
     285              : 
     286            1 :     array_init(return_value);
     287            1 :     add_assoc_double(return_value, "x_bearing", extents.x_bearing);
     288            1 :     add_assoc_double(return_value, "y_bearing", extents.y_bearing);
     289            1 :     add_assoc_double(return_value, "width", extents.width);
     290            1 :     add_assoc_double(return_value, "height", extents.height);
     291            1 :     add_assoc_double(return_value, "x_advance", extents.x_advance);
     292            1 :     add_assoc_double(return_value, "y_advance", extents.y_advance);
     293              : }
     294              : /* }}} */
     295              : 
     296              : /* {{{ proto \Cairo\FontFace object \Cairo\ScaledFont::getFontFace()
     297              :        Retrieves the font face used to create the scaled font. */
     298            2 : PHP_METHOD(Cairo_ScaledFont, getFontFace)
     299              : {
     300              :     cairo_scaled_font_object *scaled_font_object;
     301              :     cairo_font_face_object *font_face_object;
     302              :     cairo_font_face_t *font_face;
     303              : 
     304            2 :     ZEND_PARSE_PARAMETERS_NONE();
     305              : 
     306            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     307            1 :     if (!scaled_font_object) {
     308            0 :         RETURN_THROWS();
     309              :     }
     310              : 
     311              :     /* Grab the font face properly */
     312            1 :     font_face = cairo_scaled_font_get_font_face(scaled_font_object->scaled_font);
     313            1 :     if (php_cairo_throw_exception(cairo_scaled_font_status(scaled_font_object->scaled_font))) {
     314            0 :         RETURN_THROWS();
     315              :     }
     316              : 
     317              :     /* If we have a font face object stored, grab that zval to use */
     318            5 :     CAIRO_RETURN_IF_REF(scaled_font_object->font_face);
     319              : 
     320              :     /* Otherwise we spawn a new object */
     321            0 :     object_init_ex(return_value, php_cairo_get_toyfontface_ce());
     322            0 :     font_face_object = Z_CAIRO_FONT_FACE_P(return_value);
     323            0 :     font_face_object->font_face = font_face;
     324              : }
     325              : /* }}} */
     326              : 
     327              : /* {{{ proto \Cairo\FontOptions object \Cairo\ScaledFont::getFontOptions()
     328              :        Retrieves the font options used to create the scaled font. */
     329            2 : PHP_METHOD(Cairo_ScaledFont, getFontOptions)
     330              : {
     331              :     cairo_scaled_font_object *scaled_font_object;
     332              :     cairo_font_options_object *font_options_object;
     333            2 :     cairo_font_options_t *font_options = NULL;
     334              : 
     335            2 :     ZEND_PARSE_PARAMETERS_NONE();
     336              : 
     337            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     338            1 :     if (!scaled_font_object) {
     339            0 :         RETURN_THROWS();
     340              :     }
     341              : 
     342              :     /* Grab the font options properly */
     343            1 :     cairo_scaled_font_get_font_options(scaled_font_object->scaled_font, font_options);
     344            1 :     if (php_cairo_throw_exception(cairo_scaled_font_status(scaled_font_object->scaled_font))) {
     345            0 :         RETURN_THROWS();
     346              :     }
     347              : 
     348              :     /* If we have a font options object stored, grab that zval to use */
     349            5 :     CAIRO_RETURN_IF_REF(scaled_font_object->font_options);
     350              : 
     351              :     /* Otherwise we spawn a new object */
     352            0 :     object_init_ex(return_value, php_cairo_get_fontoptions_ce());
     353            0 :     font_options_object = Z_CAIRO_FONT_OPTIONS_P(return_value);
     354            0 :     font_options_object->font_options = font_options;
     355              : }
     356              : /* }}} */
     357              : 
     358              : /* {{{ proto \Cairo\Matrix object \Cairo\ScaledFont::getFontMatrix()
     359              :        Returns the font matrix used when creating the scaled font */
     360            2 : PHP_METHOD(Cairo_ScaledFont, getFontMatrix)
     361              : {
     362              :     cairo_scaled_font_object *scaled_font_object;
     363              :     cairo_matrix_object *matrix_object;
     364              : 
     365            2 :     ZEND_PARSE_PARAMETERS_NONE();
     366              : 
     367            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     368            1 :     if (!scaled_font_object) {
     369            0 :         RETURN_THROWS();
     370              :     }
     371              : 
     372              :     /* If we have a matrix object stored, grab that zval to use */
     373            5 :     CAIRO_RETURN_IF_REF(scaled_font_object->matrix);
     374              : 
     375              :     /* Otherwise we spawn a new object */
     376            0 :     object_init_ex(return_value, php_cairo_get_matrix_ce());
     377            0 :     matrix_object = Z_CAIRO_MATRIX_P(return_value);
     378            0 :     cairo_scaled_font_get_font_matrix(scaled_font_object->scaled_font, matrix_object->matrix);
     379              : }
     380              : /* }}} */
     381              : 
     382              : /* {{{ proto \Cairo\Matrix object \Cairo\ScaledFont::getCtm()
     383              :         Returns the ctm matrix used when creating the scaled font */
     384            2 : PHP_METHOD(Cairo_ScaledFont, getCtm)
     385              : {
     386              :     cairo_scaled_font_object *scaled_font_object;
     387              :     cairo_matrix_object *matrix_object;
     388              : 
     389            2 :     ZEND_PARSE_PARAMETERS_NONE();
     390              : 
     391            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     392            1 :     if (!scaled_font_object) {
     393            0 :         RETURN_THROWS();
     394              :     }
     395              : 
     396              :     /* If we have a matrix object stored, grab that zval to use */
     397            5 :     CAIRO_RETURN_IF_REF(scaled_font_object->ctm);
     398              : 
     399              :     /* Otherwise we spawn a new object */
     400            0 :     object_init_ex(return_value, php_cairo_get_matrix_ce());
     401            0 :     matrix_object = Z_CAIRO_MATRIX_P(return_value);
     402            0 :     cairo_scaled_font_get_ctm(scaled_font_object->scaled_font, matrix_object->matrix);
     403              : }
     404              : /* }}} */
     405              : 
     406              : /* {{{ proto \Cairo\Matrix object \Cairo\ScaledFont::getScaleMatrix()
     407              :        The scale matrix is product of the font matrix and the ctm associated with the scaled font,
     408              :        and hence is the matrix mapping from font space to device space */
     409            2 : PHP_METHOD(Cairo_ScaledFont, getScaleMatrix)
     410              : {
     411              :     cairo_scaled_font_object *scaled_font_object;
     412              :     cairo_matrix_object *matrix_object;
     413              : 
     414            2 :     ZEND_PARSE_PARAMETERS_NONE();
     415              : 
     416            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     417            1 :     if (!scaled_font_object) {
     418            0 :         RETURN_THROWS();
     419              :     }
     420              : 
     421              :     /* This is never stored in the object, but created every time */
     422            1 :     object_init_ex(return_value, php_cairo_get_matrix_ce());
     423              : 
     424            1 :     matrix_object = Z_CAIRO_MATRIX_P(return_value);
     425            1 :     cairo_scaled_font_get_scale_matrix(scaled_font_object->scaled_font, matrix_object->matrix);
     426              : }
     427              : /* }}} */
     428              : 
     429              : /* {{{ proto long \Cairo\ScaledFont::getType()
     430              :        Returns the current integer type of the CairoScaledFont backend */
     431            2 : PHP_METHOD(Cairo_ScaledFont, getType)
     432              : {
     433              :     cairo_scaled_font_object *scaled_font_object;
     434              :     zval font_type_case;
     435              : 
     436            3 :     ZEND_PARSE_PARAMETERS_NONE();
     437              : 
     438            2 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     439            1 :     if (!scaled_font_object) {
     440            0 :         RETURN_THROWS();
     441              :     }
     442              : 
     443            1 :     font_type_case = php_enum_from_cairo_c_enum(
     444              :         ce_cairo_fonttype,
     445            1 :         cairo_scaled_font_get_type(scaled_font_object->scaled_font)
     446              :     );
     447              : 
     448            1 :     if (Z_TYPE(font_type_case) == IS_OBJECT) {
     449            2 :         RETURN_ZVAL(&font_type_case, 1, 1);
     450              :     }
     451              : }
     452              : /* }}} */
     453              : 
     454              : /* {{{ proto void \Cairo\ScaledFont->textToGlyphs()
     455              :        Converts UTF-8 text to an array of glyphs,
     456              :        optionally with cluster mapping,
     457              :        that can be used to render later using scaled_font . */
     458           15 : PHP_METHOD(Cairo_ScaledFont, textToGlyphs)
     459              : {
     460              :     cairo_scaled_font_object *scaled_font_object;
     461              : 
     462              :     double x, y;
     463              :     char *utf8Str;
     464           15 :     size_t utf8Str_len = 0;
     465           15 :     bool return_clusters = false;
     466              : 
     467              :     int num_glyphs, num_clusters;
     468           15 :     cairo_glyph_t *glyphs = NULL;
     469           15 :     cairo_text_cluster_t *clusters = NULL;
     470              :     cairo_text_cluster_flags_t cluster_flags;
     471              : 
     472              :     cairo_status_t status;
     473              :     zval glyphs_zv;
     474              :     zval clusters_zv;
     475              :     zval cluster_flags_zv;
     476              : 
     477           15 :     ZEND_PARSE_PARAMETERS_START(3, 4)
     478           22 :         Z_PARAM_DOUBLE(x)
     479           20 :         Z_PARAM_DOUBLE(y)
     480           18 :         Z_PARAM_STRING(utf8Str, utf8Str_len)
     481            8 :         Z_PARAM_OPTIONAL
     482           15 :         Z_PARAM_BOOL(return_clusters)
     483           15 :     ZEND_PARSE_PARAMETERS_END();
     484              : 
     485           14 :     scaled_font_object = cairo_scaled_font_object_get(getThis());
     486            7 :     if (!scaled_font_object) {
     487            0 :         RETURN_THROWS();
     488              :     }
     489              : 
     490           21 :     status = cairo_scaled_font_text_to_glyphs(
     491              :         scaled_font_object->scaled_font,
     492              :         x, y,
     493              :         utf8Str, utf8Str_len,
     494              :         &glyphs, &num_glyphs,
     495            7 :         return_clusters ? &clusters : NULL,
     496            7 :         return_clusters ? &num_clusters : NULL,
     497            7 :         return_clusters ? &cluster_flags : NULL
     498              :     );
     499              : 
     500            7 :     if (php_cairo_throw_exception(status)) {
     501            0 :         cairo_glyph_free(glyphs);
     502            0 :         if (return_clusters) {
     503            0 :             cairo_text_cluster_free(clusters);
     504              :         }
     505            0 :         RETURN_THROWS();
     506              :     }
     507              : 
     508            7 :     array_init_size(&glyphs_zv, num_glyphs);
     509           49 :     for (int i = 0; i < num_glyphs; i++) {
     510              :         zval glyph;
     511           42 :         object_init_ex(&glyph, php_cairo_get_glyph_ce());
     512           42 :         cairo_glyph_object *glyph_obj = Z_CAIRO_GLYPH_P(&glyph);
     513           42 :         *glyph_obj->glyph = glyphs[i];
     514              :         add_next_index_zval(&glyphs_zv, &glyph);
     515              :     }
     516              : 
     517            7 :     ZVAL_NULL(&clusters_zv);
     518            7 :     ZVAL_LONG(&cluster_flags_zv, 0);
     519            7 :     if (return_clusters) {
     520            4 :         if (num_clusters) {
     521            4 :             array_init(&clusters_zv);
     522           38 :             for (int i = 0; i < num_clusters; i++) {
     523              :                 zval cluster_zv;
     524           34 :                 object_init_ex(&cluster_zv, php_cairo_get_text_cluster_ce());
     525           34 :                 cairo_text_cluster_object *cluster_obj = Z_CAIRO_TEXT_CLUSTER_P(&cluster_zv);
     526           34 :                 *cluster_obj->text_cluster = clusters[i];
     527              :                 add_next_index_zval(&clusters_zv, &cluster_zv);
     528              :             }
     529              :         }
     530              : 
     531            4 :         if (cluster_flags) {
     532            0 :             ZVAL_LONG(&cluster_flags_zv, cluster_flags);
     533              :         }
     534              :     }
     535              : 
     536              :     // TODO: perhaps returning an object would be better
     537            7 :     array_init_size(return_value, 3);
     538              :     add_assoc_zval(return_value, "glyphs", &glyphs_zv);
     539              :     add_assoc_zval(return_value, "clusters", &clusters_zv);
     540              :     add_assoc_zval(return_value, "cluster_flags", &cluster_flags_zv);
     541              : 
     542            7 :     cairo_glyph_free(glyphs);
     543            7 :     if (return_clusters) {
     544            4 :         cairo_text_cluster_free(clusters);
     545              :     }
     546              : }
     547              : /* }}} */
     548              : 
     549              : 
     550              : /* ----------------------------------------------------------------
     551              :     Cairo\FontOptions Definition and registration
     552              : ------------------------------------------------------------------*/
     553              : 
     554              : /* {{{ PHP_MINIT_FUNCTION */
     555          424 : PHP_MINIT_FUNCTION(cairo_scaled_font)
     556              : {
     557          424 :     memcpy(
     558              :         &cairo_scaled_font_object_handlers,
     559              :         zend_get_std_object_handlers(),
     560              :         sizeof(zend_object_handlers)
     561              :     );
     562              : 
     563              :     /* ScaledFont */
     564          424 :     cairo_scaled_font_object_handlers.offset = XtOffsetOf(cairo_scaled_font_object, std);
     565          424 :     cairo_scaled_font_object_handlers.free_obj = cairo_scaled_font_free_obj;
     566              : 
     567          424 :     ce_cairo_scaled_font = register_class_Cairo_ScaledFont();
     568          424 :     ce_cairo_scaled_font->create_object = cairo_scaled_font_create_object;
     569              : 
     570          424 :     return SUCCESS;
     571              : }
     572              : /* }}} */
        

Generated by: LCOV version 2.0-1