LCOV - code coverage report
Current view: top level - src - ps_surface.c (source / functions) Coverage Total Hit
Test: PHP Cairo Extension Coverage Lines: 88.1 % 109 96
Test Date: 2025-09-10 21:28:33 Functions: 100.0 % 11 11

            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              : 
      26              : #if CAIRO_HAS_PS_SURFACE
      27              : #include <cairo-ps.h>
      28              : #include "ps_surface_arginfo.h"
      29              : 
      30              : zend_class_entry *ce_cairo_pssurface;
      31              : zend_class_entry *ce_cairo_pslevel;
      32              : 
      33              : /* ----------------------------------------------------------------
      34              :     Cairo\Surface\Ps Class API
      35              : ------------------------------------------------------------------*/
      36              : 
      37              : /* {{{ proto void CairoPsSurface->__construct(string|resource file, int|float width, int|float height)
      38              :        Creates a PS surface of the specified size in points to be written to filename. */
      39           17 : PHP_METHOD(Cairo_Surface_Ps, __construct)
      40              : {
      41           17 :     zval *stream_zval = NULL;
      42              :     stream_closure *closure;
      43           17 :     php_stream *stream = NULL;
      44              :     double width, height;
      45           17 :     bool owned_stream = false;
      46              :     cairo_surface_object *surface_object;
      47              : 
      48           17 :     ZEND_PARSE_PARAMETERS_START(3, 3)
      49           13 :         Z_PARAM_ZVAL(stream_zval)
      50           26 :         Z_PARAM_DOUBLE(width)
      51           24 :         Z_PARAM_DOUBLE(height)
      52           17 :     ZEND_PARSE_PARAMETERS_END();
      53              : 
      54           22 :     surface_object = Z_CAIRO_SURFACE_P(getThis());
      55           11 :     if (!surface_object) {
      56            0 :         RETURN_NULL();
      57              :     }
      58              : 
      59              :     /* special case - a NULL file is like an "in memory" surface
      60              :        notice it uses the regular create cairo method, not create for stream */
      61           22 :     if (Z_TYPE_P(stream_zval) == IS_NULL) {
      62            8 :         surface_object->surface = cairo_ps_surface_create(NULL, width, height);
      63              :     }
      64              :     /* Otherwise it can be a filename or a PHP stream */
      65              :     else {
      66            6 :         if (Z_TYPE_P(stream_zval) == IS_STRING) {
      67            1 :             stream = php_stream_open_wrapper(Z_STRVAL_P(stream_zval), "w+b", REPORT_ERRORS, NULL);
      68            1 :             owned_stream = 1;
      69            4 :         } else if (Z_TYPE_P(stream_zval) == IS_RESOURCE) {
      70            1 :             php_stream_from_zval(stream, stream_zval);
      71              :         } else {
      72            1 :             zend_throw_exception(zend_ce_type_error, "Cairo\\Surface\\Ps::__construct() expects parameter 1 to be null, a string, or a stream resource", 0);
      73            1 :             RETURN_THROWS();
      74              :         }
      75              : 
      76              :         /* Pack stream into struct */
      77            2 :         closure = ecalloc(1, sizeof(stream_closure));
      78            2 :         closure->stream = stream;
      79            2 :         closure->owned_stream = owned_stream;
      80              : 
      81            2 :         surface_object->closure = closure;
      82            2 :         surface_object->surface = cairo_ps_surface_create_for_stream(php_cairo_write_func, (void *)closure, width, height);
      83              :     }
      84              : 
      85           10 :     if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
      86            0 :         RETURN_THROWS();
      87              :     }
      88              : }
      89              : /* }}} */
      90              : 
      91              : /* {{{ proto void CairoPsSurface->setSize(double width, double height)
      92              :        Changes the size of a PS surface for the current (and subsequent) pages.
      93              :        This should be called before any drawing takes place on the surface */
      94            6 : PHP_METHOD(Cairo_Surface_Ps, setSize)
      95              : {
      96            6 :     double width = 0.0, height = 0.0;
      97              :     cairo_surface_object *surface_object;
      98              : 
      99            6 :     ZEND_PARSE_PARAMETERS_START(2, 2)
     100            6 :         Z_PARAM_DOUBLE(width)
     101            4 :         Z_PARAM_DOUBLE(height)
     102            6 :     ZEND_PARSE_PARAMETERS_END();
     103              : 
     104            2 :     surface_object = cairo_surface_object_get(getThis());
     105            1 :     if (!surface_object) {
     106            0 :         RETURN_THROWS();
     107              :     }
     108              : 
     109            1 :     cairo_ps_surface_set_size(surface_object->surface, width, height);
     110              : 
     111            1 :     if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
     112            0 :         RETURN_THROWS();
     113              :     }
     114              : }
     115              : /* }}} */
     116              : 
     117              : /* {{{ proto void CairoPsSurface->restrictToLevel(int level)
     118              :        Restricts the generated PostScript file to level. */
     119            4 : PHP_METHOD(Cairo_Surface_Ps, restrictToLevel)
     120              : {
     121              :     cairo_surface_object *surface_object;
     122            4 :     zval *level = NULL;
     123              : 
     124            4 :     ZEND_PARSE_PARAMETERS_START(0, 1)
     125            3 :         Z_PARAM_OPTIONAL
     126            5 :         Z_PARAM_OBJECT_OF_CLASS(level, ce_cairo_pslevel)
     127            4 :     ZEND_PARSE_PARAMETERS_END();
     128              : 
     129            4 :     surface_object = cairo_surface_object_get(getThis());
     130            2 :     if (!surface_object) {
     131            0 :         RETURN_THROWS();
     132              :     }
     133              : 
     134            2 :     cairo_ps_surface_restrict_to_level(
     135              :         surface_object->surface,
     136              :         level
     137            3 :             ? Z_LVAL_P(zend_enum_fetch_case_value(Z_OBJ_P(level)))
     138              :             : CAIRO_PS_LEVEL_2
     139              :     );
     140              : 
     141            2 :     if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
     142            0 :         RETURN_THROWS();
     143              :     }
     144              : }
     145              : /* }}} */
     146              : 
     147              : /* {{{ proto void CairoPsSurface->setEps(boolean eps)
     148              :        If eps is TRUE, the PostScript surface will output Encapsulated PostScript. */
     149            4 : PHP_METHOD(Cairo_Surface_Ps, setEps)
     150              : {
     151            4 :     bool eps = false;
     152              :     cairo_surface_object *surface_object;
     153              : 
     154            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     155            4 :         Z_PARAM_BOOL(eps)
     156            4 :     ZEND_PARSE_PARAMETERS_END();
     157              : 
     158            2 :     surface_object = cairo_surface_object_get(getThis());
     159            1 :     if (!surface_object) {
     160            0 :         RETURN_THROWS();
     161              :     }
     162              : 
     163            1 :     cairo_ps_surface_set_eps(surface_object->surface, eps);
     164              : 
     165            1 :     if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
     166            0 :         RETURN_THROWS();
     167              :     }
     168              : }
     169              : /* }}} */
     170              : 
     171              : /* {{{ proto boolean CairoPsSurface->getEps(void)
     172              :        Check whether the PostScript surface will output Encapsulated PostScript. */
     173            2 : PHP_METHOD(Cairo_Surface_Ps, getEps)
     174              : {
     175              :     cairo_surface_object *surface_object;
     176              : 
     177            2 :     ZEND_PARSE_PARAMETERS_NONE();
     178              : 
     179            2 :     surface_object = cairo_surface_object_get(getThis());
     180            1 :     if (!surface_object) {
     181            0 :         RETURN_THROWS();
     182              :     }
     183              : 
     184            1 :     RETURN_BOOL(cairo_ps_surface_get_eps(surface_object->surface));
     185              : }
     186              : /* }}} */
     187              : 
     188              : /* {{{ proto void CairoPsSurface->dscBeginSetup(void)
     189              :        This function indicates that subsequent calls to cairo_ps_surface_dsc_comment() should
     190              :        direct comments to the Setup section of the PostScript output. */
     191            2 : PHP_METHOD(Cairo_Surface_Ps, dscBeginSetup)
     192              : {
     193              :     cairo_surface_object *surface_object;
     194              : 
     195            2 :     ZEND_PARSE_PARAMETERS_NONE();
     196              : 
     197            2 :     surface_object = cairo_surface_object_get(getThis());
     198            1 :     if (!surface_object) {
     199            0 :         RETURN_THROWS();
     200              :     }
     201              : 
     202            1 :     cairo_ps_surface_dsc_begin_setup(surface_object->surface);
     203              : }
     204              : /* }}} */
     205              : 
     206              : /* {{{ proto void CairoPsSurface->dscBeginPageSetup(void)
     207              :        This indicates that subsequent calls to cairo_ps_surface_dsc_comment()
     208              :        should direct comments to the PageSetup section of the PostScript output.
     209              : 
     210              :        This function call is only needed for the first page of a surface.
     211              :        It should be called after any call to cairo_ps_surface_dsc_begin_setup()
     212              :        and before any drawing is performed to the surface. */
     213            2 : PHP_METHOD(Cairo_Surface_Ps, dscBeginPageSetup)
     214              : {
     215              :     cairo_surface_object *surface_object;
     216              : 
     217            2 :     ZEND_PARSE_PARAMETERS_NONE();
     218              : 
     219            2 :     surface_object = cairo_surface_object_get(getThis());
     220            1 :     if (!surface_object) {
     221            0 :         RETURN_THROWS();
     222              :     }
     223              : 
     224            1 :     cairo_ps_surface_dsc_begin_page_setup(surface_object->surface);
     225              : }
     226              : /* }}} */
     227              : 
     228              : /* {{{ proto void CairoPsSurface->dscComment(string comment)
     229              :        Emit a comment into the PostScript output for the given surface. */
     230            4 : PHP_METHOD(Cairo_Surface_Ps, dscComment)
     231              : {
     232              :     cairo_surface_object *surface_object;
     233              :     char *comment, *cairo_comment;
     234              :     size_t comment_len;
     235              : 
     236            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     237            4 :         Z_PARAM_STRING(comment, comment_len)
     238            4 :     ZEND_PARSE_PARAMETERS_END();
     239              : 
     240            2 :     surface_object = cairo_surface_object_get(getThis());
     241            1 :     if (!surface_object) {
     242            0 :         RETURN_THROWS();
     243              :     }
     244              : 
     245            1 :     cairo_comment = estrdup(comment);
     246            1 :     cairo_ps_surface_dsc_comment(surface_object->surface, cairo_comment);
     247            1 :     efree(cairo_comment);
     248              : 
     249            1 :     if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
     250            0 :         RETURN_THROWS();
     251              :     }
     252              : }
     253              : /* }}} */
     254              : 
     255              : /* {{{ proto array CairoPsSurface::getLevels(void)
     256              :        Used to retrieve the list of supported levels. See cairo_ps_surface_restrict_to_level(). */
     257            2 : PHP_METHOD(Cairo_Surface_Ps, getLevels)
     258              : {
     259              :     const cairo_ps_level_t *levels;
     260              :     int num_levels, i;
     261              :     zval ps_level_case;
     262              : 
     263            2 :     ZEND_PARSE_PARAMETERS_NONE();
     264              : 
     265            1 :     cairo_ps_get_levels(&levels, &num_levels);
     266              : 
     267            1 :     array_init(return_value);
     268            3 :     for (i = 0; i < num_levels; i++) {
     269            2 :         ps_level_case = php_enum_from_cairo_c_enum(ce_cairo_pslevel, levels[i]);
     270              :         add_next_index_zval(return_value, &ps_level_case);
     271              :     }
     272              : }
     273              : /* }}} */
     274              : 
     275              : /* {{{ proto string \Cairo\Surface\Ps::levelToString(Cairo\Surface\Ps\Level level)
     276              :        Get the string representation of the given level id. */
     277            4 : PHP_METHOD(Cairo_Surface_Ps, levelToString)
     278              : {
     279              :     zval *level;
     280              : 
     281            4 :     ZEND_PARSE_PARAMETERS_START(1, 1)
     282            4 :         Z_PARAM_OBJECT_OF_CLASS(level, ce_cairo_pslevel)
     283            4 :     ZEND_PARSE_PARAMETERS_END();
     284              : 
     285            3 :     RETURN_STRING(cairo_ps_level_to_string(Z_LVAL_P(zend_enum_fetch_case_value(Z_OBJ_P(level)))));
     286              : }
     287              : /* }}} */
     288              : 
     289              : /* ----------------------------------------------------------------
     290              :     Cairo\Surface\ps Definition and registration
     291              : ------------------------------------------------------------------*/
     292              : 
     293              : /* {{{ PHP_MINIT_FUNCTION */
     294          424 : PHP_MINIT_FUNCTION(cairo_ps_surface)
     295              : {
     296              :     zend_class_entry pssurface_ce;
     297              : 
     298          424 :     ce_cairo_pssurface = register_class_Cairo_Surface_Ps(ce_cairo_surface);
     299              : 
     300              :     /* Ps Level */
     301          424 :     ce_cairo_pslevel = register_class_Cairo_Surface_Ps_Level();
     302              : 
     303          424 :     return SUCCESS;
     304              : }
     305              : 
     306              : #endif
        

Generated by: LCOV version 2.0-1