|             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              :   +----------------------------------------------------------------------+
      12              : */
      13              : 
      14              : #ifdef HAVE_CONFIG_H
      15              : #    include "config.h"
      16              : #endif
      17              : 
      18              : #include <php.h>
      19              : #include <zend_exceptions.h>
      20              : #include <ext/standard/info.h>
      21              : #include <cairo.h>
      22              : 
      23              : #include "php_cairo.h"
      24              : #include "php_cairo_internal.h"
      25              : #include "cairo_arginfo.h"
      26              : 
      27              : /* ----------------------------------------------------------------
      28              :     Cairo Namespace
      29              : ------------------------------------------------------------------ */
      30              : 
      31              : #if defined(CAIRO_HAS_FT_FONT) && defined(HAVE_FREETYPE)
      32            1 : const char* php_cairo_get_ft_error(int error) {
      33              : 
      34            1 :     php_cairo_ft_error *current_error = php_cairo_ft_errors;
      35              : 
      36            2 :     while (current_error->err_msg != NULL) {
      37            2 :         if (current_error->err_code == error) {
      38            1 :             return current_error->err_msg;
      39              :         }
      40            1 :         current_error++;
      41              :     }
      42            0 :     return NULL;
      43              : }
      44              : #endif
      45              : 
      46           74 : zval php_enum_from_cairo_c_enum(
      47              :     zend_class_entry *enum_ce,
      48              :     long c_enum_value
      49              : ) {
      50              :     zval php_enum;
      51              :     zval backing_value;
      52              :     zval retval;
      53              : 
      54           74 :     ZVAL_LONG(&backing_value, c_enum_value);
      55              : 
      56              :     zend_call_method_with_1_params(NULL, enum_ce, NULL, "from", &retval, &backing_value);
      57              : 
      58           74 :     if (Z_TYPE(retval) == IS_OBJECT) {
      59           74 :         ZVAL_COPY(&php_enum, &retval);
      60              :     } else {
      61            0 :         ZVAL_NULL(&php_enum);
      62            0 :         zend_throw_exception_ex(ce_cairo_exception, 0,
      63              :             "Failed to create %s enum from value: %ld",
      64            0 :             ZSTR_VAL(enum_ce->name),
      65              :             c_enum_value
      66              :         );
      67              :     }
      68              : 
      69           74 :     zval_ptr_dtor(&retval);
      70           74 :     return php_enum;
      71              : }
      72              : 
      73              : 
      74              : /* {{{ proto int \Cairo\version(void)
      75              :        Returns an integer version number of the cairo library being used */
      76            5 : PHP_FUNCTION(Cairo_version)
      77              : {
      78            5 :     ZEND_PARSE_PARAMETERS_NONE();
      79              : 
      80            3 :     RETURN_LONG(cairo_version());
      81              : }
      82              : /* }}} */
      83              : 
      84              : /* {{{ proto string \Cairo\version_string(void)
      85              :        Returns a string version of the cairo library being used */
      86            4 : PHP_FUNCTION(Cairo_version_string)
      87              : {
      88            4 :     ZEND_PARSE_PARAMETERS_NONE();
      89              : 
      90            4 :     RETURN_STRING(cairo_version_string());
      91              : }
      92              : /* }}} */
      93              : 
      94              : /* {{{ proto int \Cairo::version(void)
      95              :        Returns an integer version number of the cairo library being used */
      96            2 : PHP_METHOD(Cairo_Cairo, version)
      97              : {
      98            2 :     ZEND_PARSE_PARAMETERS_NONE();
      99              : 
     100            1 :     RETURN_LONG(cairo_version());
     101              : }
     102              : /* }}} */
     103              : 
     104              : /* {{{ proto string \Cairo::versionString(void)
     105              :        Returns a string version of the cairo library being used */
     106            2 : PHP_METHOD(Cairo_Cairo, versionString)
     107              : {
     108            2 :     ZEND_PARSE_PARAMETERS_NONE();
     109              : 
     110            2 :     RETURN_STRING(cairo_version_string());
     111              : }
     112              : /* }}} */
     113              : 
     114              : /* {{{ proto array \Cairo::availableSurfaces(void)
     115              :        Returns an array of available Cairo backend surfaces */
     116           18 : PHP_METHOD(Cairo_Cairo, availableSurfaces)
     117              : {
     118           18 :     ZEND_PARSE_PARAMETERS_NONE();
     119              : 
     120           17 :     array_init(return_value);
     121           17 :     add_next_index_string(return_value, "IMAGE");
     122              : 
     123              : #ifdef CAIRO_HAS_PNG_FUNCTIONS
     124           17 :     add_next_index_string(return_value, "PNG");
     125              : #endif
     126              : 
     127              : #ifdef CAIRO_HAS_JPEG_FUNCTIONS
     128           17 :     add_next_index_string(return_value, "JPEG");
     129              : #endif
     130              : 
     131              : #ifdef CAIRO_HAS_PDF_SURFACE
     132           17 :     add_next_index_string(return_value, "PDF");
     133              : #endif
     134              : 
     135              : #ifdef CAIRO_HAS_PS_SURFACE
     136           17 :     add_next_index_string(return_value, "PS");
     137              : #endif
     138              : 
     139              : #ifdef CAIRO_HAS_SVG_SURFACE
     140           17 :     add_next_index_string(return_value, "SVG");
     141              : #endif
     142              : 
     143              : #ifdef CAIRO_HAS_XLIB_SURFACE
     144           17 :     add_next_index_string(return_value, "XLIB");
     145              : #endif
     146              : 
     147              : #ifdef CAIRO_HAS_RECORDING_SURFACE
     148           17 :     add_next_index_string(return_value, "RECORDING");
     149              : #endif
     150              : 
     151              : #ifdef CAIRO_HAS_QUARTZ_SURFACE
     152              :     add_next_index_string(return_value, "QUARTZ");
     153              : #endif
     154              : 
     155              : #ifdef CAIRO_HAS_WIN32_SURFACE
     156              :     add_next_index_string(return_value, "WIN32");
     157              : #endif
     158              : }
     159              : /* }}} */
     160              : 
     161              : /* {{{ proto array \Cairo::availableFonts(void)
     162              :        Returns an array of available Cairo font backends */
     163            2 : PHP_METHOD(Cairo_Cairo, availableFonts)
     164              : {
     165            2 :     ZEND_PARSE_PARAMETERS_NONE();
     166              : 
     167            1 :     array_init(return_value);
     168              : 
     169              : #if defined(CAIRO_HAS_FT_FONT) && defined(HAVE_FREETYPE)
     170            1 :     add_next_index_string(return_value, "FREETYPE");
     171              : #endif
     172              : #ifdef CAIRO_HAS_QUARTZ_FONT
     173              :     add_next_index_string(return_value, "QUARTZ");
     174              : #endif
     175              : #ifdef CAIRO_HAS_WIN32_FONT
     176              :     add_next_index_string(return_value, "WIN32");
     177              : #endif
     178              : #ifdef CAIRO_HAS_USER_FONT
     179            1 :     add_next_index_string(return_value, "USER");
     180              : #endif
     181              : }
     182              : /* }}} */
     183              : 
     184              : 
     185              : /* {{{ PHP_MINIT_FUNCTION */
     186          433 : PHP_MINIT_FUNCTION(cairo)
     187              : {
     188              :     zend_class_entry ce;
     189              :     zend_class_entry *cairo_ce_cairo;
     190              : 
     191          433 :     cairo_ce_cairo = register_class_Cairo_Cairo();
     192              : 
     193              :     /* Namespaced version constants */
     194          433 :     register_cairo_symbols(module_number);
     195              : 
     196          433 :     PHP_MINIT(cairo_pattern)(INIT_FUNC_ARGS_PASSTHRU);
     197          433 :     PHP_MINIT(cairo_rectangle)(INIT_FUNC_ARGS_PASSTHRU);
     198          433 :     PHP_MINIT(cairo_matrix)(INIT_FUNC_ARGS_PASSTHRU);
     199          433 :     PHP_MINIT(cairo_exception)(INIT_FUNC_ARGS_PASSTHRU);
     200          433 :     PHP_MINIT(cairo_region)(INIT_FUNC_ARGS_PASSTHRU);
     201          433 :     PHP_MINIT(cairo_font_face)(INIT_FUNC_ARGS_PASSTHRU);
     202          433 :     PHP_MINIT(cairo_font)(INIT_FUNC_ARGS_PASSTHRU);
     203          433 :     PHP_MINIT(cairo_font_options)(INIT_FUNC_ARGS_PASSTHRU);
     204          433 :     PHP_MINIT(cairo_scaled_font)(INIT_FUNC_ARGS_PASSTHRU);
     205              : #if defined(CAIRO_HAS_FT_FONT) && defined(HAVE_FREETYPE)
     206          433 :     PHP_MINIT(cairo_ft_font)(INIT_FUNC_ARGS_PASSTHRU);
     207              : #endif
     208              : #if defined(CAIRO_HAS_QUARTZ_FONT)
     209              :     PHP_MINIT(cairo_quartz_font)(INIT_FUNC_ARGS_PASSTHRU);
     210              : #endif
     211              : #if defined(CAIRO_HAS_WIN32_FONT) && defined(HAVE_WIN32_FONT)
     212              :     PHP_MINIT(cairo_win32_font)(INIT_FUNC_ARGS_PASSTHRU);
     213              : #endif
     214          433 :     PHP_MINIT(cairo_surface)(INIT_FUNC_ARGS_PASSTHRU);
     215          433 :     PHP_MINIT(cairo_image_surface)(INIT_FUNC_ARGS_PASSTHRU);
     216          433 :     PHP_MINIT(cairo_sub_surface)(INIT_FUNC_ARGS_PASSTHRU);
     217          433 :     PHP_MINIT(cairo_recording_surface)(INIT_FUNC_ARGS_PASSTHRU);
     218          433 :     PHP_MINIT(cairo_pdf_surface)(INIT_FUNC_ARGS_PASSTHRU);
     219          433 :     PHP_MINIT(cairo_svg_surface)(INIT_FUNC_ARGS_PASSTHRU);
     220          433 :     PHP_MINIT(cairo_ps_surface)(INIT_FUNC_ARGS_PASSTHRU);
     221          433 :     PHP_MINIT(cairo_path)(INIT_FUNC_ARGS_PASSTHRU);
     222          433 :     PHP_MINIT(cairo_context)(INIT_FUNC_ARGS_PASSTHRU);
     223          433 :     PHP_MINIT(cairo_glyph)(INIT_FUNC_ARGS_PASSTHRU);
     224          433 :     PHP_MINIT(cairo_text_cluster)(INIT_FUNC_ARGS_PASSTHRU);
     225              : 
     226          433 :     return SUCCESS;
     227              : }
     228              : /* }}} */
     229              : 
     230              : /* {{{ PHP_MSHUTDOWN_FUNCTION */
     231          433 : PHP_MSHUTDOWN_FUNCTION(cairo)
     232              : {
     233              : #if 0 && defined(ZEND_DEBUG) && ZEND_DEBUG == 1
     234              :      cairo_debug_reset_static_data();
     235              :     // ^^^ when running some tests with pango, this causes a crash
     236              :     // This is what happens:
     237              :     // Assertion failed: hash_table->live_entries == 0 (../src/cairo-hash.c: _cairo_hash_table_destroy: 217)
     238              :     // bt
     239              :     // #0  __restore_sigs (set=set@entry=0x7ffe66bfa860) at ./arch/x86_64/syscall_arch.h:40
     240              :     // #1  0x00007688c4091e1b in raise (sig=sig@entry=6) at src/signal/raise.c:11
     241              :     // #2  0x00007688c40759ad in abort () at src/exit/abort.c:11
     242              :     // #3  0x00007688c4075a59 in __assert_fail (expr=<optimized out>, file=<optimized out>, line=<optimized out>, func=<optimized out>) at src/exit/assert.c:7
     243              :     // #4  0x00007688c2c2cb50 in _cairo_hash_table_destroy (hash_table=<optimized out>) at ../src/cairo-hash.c:214
     244              :     // #5  _cairo_hash_table_destroy (hash_table=<optimized out>) at ../src/cairo-hash.c:214
     245              :     // #6  0x00007688c2c26a19 in _cairo_scaled_font_map_destroy () at ../src/cairo-scaled-font.c:451
     246              :     // #7  cairo_debug_reset_static_data () at ../src/cairo-debug.c:67
     247              :     // #8  0x00007688c2d24bbf in zm_shutdown_cairo (type=1, module_number=36) at /src/php-cairo/src/cairo.c:210
     248              :     // cairo-scaled-font.c:451 _cairo_hash_table_destroy (font_map->hash_table);
     249              :     // cairo-hash.c:217 assert (hash_table->live_entries == 0);
     250              :     // So this means there are still references to scaled fonts somewhere.
     251              :     // But where? I have no idea.
     252              : #endif
     253              : 
     254          433 :     return SUCCESS;
     255              : }
     256              : 
     257              : /* {{{ PHP_MINFO_FUNCTION */
     258            1 : PHP_MINFO_FUNCTION(cairo)
     259              : {
     260            1 :     php_info_print_table_start();
     261            1 :     php_info_print_table_header(2, "Cairo Graphics Library Bindings", "enabled");
     262            1 :     php_info_print_table_header(1,
     263              : #ifdef COMPILE_DL_CAIRO
     264              :         "compiled as dynamic module"
     265              : #else
     266              :         "compiled as static module"
     267              : #endif
     268              :     );
     269            1 :     php_info_print_table_row(2, "Cairo Library Version", CAIRO_VERSION_STRING);
     270            1 :     php_info_print_table_row(2, "Extension Version", PHP_CAIRO_VERSION);
     271            1 :     php_info_print_table_row(1, "Surface Backends Available");
     272            1 :     php_info_print_table_row(2, "Image Surface", "enabled");
     273            1 :     php_info_print_table_row(2, "PNG Support",
     274              : #ifdef CAIRO_HAS_PNG_FUNCTIONS
     275              :         "enabled"
     276              : #else
     277              :         "disabled"
     278              : #endif
     279              :     );
     280            1 :     php_info_print_table_row(2, "JPEG Support",
     281              : #ifdef CAIRO_HAS_JPEG_FUNCTIONS
     282              :         "enabled"
     283              : #else
     284              :         "disabled"
     285              : #endif
     286              :         );
     287            1 :     php_info_print_table_row(2, "PDF Surface",
     288              : #ifdef CAIRO_HAS_PDF_SURFACE
     289              :         "enabled"
     290              : #else
     291              :         "disabled"
     292              : #endif
     293              :     );
     294            1 :     php_info_print_table_row(2, "PS Surface",
     295              : #ifdef CAIRO_HAS_PS_SURFACE
     296              :         "enabled"
     297              : #else
     298              :         "disabled"
     299              : #endif
     300              :     );
     301            1 :     php_info_print_table_row(2, "Xlib (X11, X.org) Surface",
     302              : #ifdef CAIRO_HAS_XLIB_SURFACE
     303              :         "enabled"
     304              : #else
     305              :         "disabled"
     306              : #endif
     307              :     );
     308            1 :     php_info_print_table_row(2, "Quartz (MacOSX) Surface",
     309              : #ifdef CAIRO_HAS_QUARTZ_SURFACE
     310              :         "enabled"
     311              : #else
     312              :         "disabled"
     313              : #endif
     314              :     );
     315            1 :     php_info_print_table_row(2, "SVG Surface",
     316              : #ifdef CAIRO_HAS_SVG_SURFACE
     317              :         "enabled"
     318              : #else
     319              :         "disabled"
     320              : #endif
     321              :     );
     322            1 :     php_info_print_table_row(2, "Win32 Surface",
     323              : #ifdef CAIRO_HAS_WIN32_SURFACE
     324              :         "enabled"
     325              : #else
     326              :         "disabled"
     327              : #endif
     328              :     );
     329            1 :     php_info_print_table_row(2, "Recording Surface",
     330              : #ifdef CAIRO_HAS_RECORDING_SURFACE
     331              :         "enabled"
     332              : #else
     333              :         "disabled"
     334              : #endif
     335              :     );
     336            1 :     php_info_print_table_row(1, "Font Backends Available");
     337            1 :     php_info_print_table_row(2, "Freetype Fonts",
     338              : #if defined(CAIRO_HAS_FT_FONT) && defined(HAVE_FREETYPE)
     339              :         "enabled"
     340              : #else
     341              :         "disabled"
     342              : #endif
     343              :     );
     344            1 :     php_info_print_table_row(2, "Quartz Fonts",
     345              : #ifdef CAIRO_HAS_QUARTZ_FONT
     346              :         "enabled"
     347              : #else
     348              :         "disabled"
     349              : #endif
     350              :     );
     351            1 :     php_info_print_table_row(2, "Win32 Fonts",
     352              : #ifdef CAIRO_HAS_WIN32_FONT
     353              :         "enabled"
     354              : #else
     355              :         "disabled"
     356              : #endif
     357              :     );
     358            1 :     php_info_print_table_row(2, "User Fonts",
     359              : #ifdef CAIRO_HAS_USER_FONT
     360              :         "enabled"
     361              : #else
     362              :         "disabled"
     363              : #endif
     364              :     );
     365            1 :     php_info_print_table_end();
     366            1 : }
     367              : /* }}} */
     368              : 
     369              : /* {{{ cairo_module_entry */
     370              : zend_module_entry cairo_module_entry = {
     371              :     STANDARD_MODULE_HEADER_EX,
     372              :     NULL,
     373              :     NULL,
     374              :     "cairo",
     375              :     ext_functions,
     376              :     PHP_MINIT(cairo),
     377              :     PHP_MSHUTDOWN(cairo),
     378              :     NULL,
     379              :     NULL,
     380              :     PHP_MINFO(cairo),
     381              :     PHP_CAIRO_VERSION,
     382              :     STANDARD_MODULE_PROPERTIES
     383              : };
     384              : /* }}} */
     385              : 
     386              : #ifdef COMPILE_DL_CAIRO
     387          433 :     ZEND_GET_MODULE(cairo)
     388              : #endif
         |