5757
5858#include "gd_compat.h"
5959
60- static int le_gd_font ;
61-
6260#include <gd.h>
6361#include <gd_errors.h>
6462#include <gdfontt.h> /* 1 Tiny font */
@@ -235,6 +233,75 @@ static void php_gd_object_minit_helper()
235233 php_gd_image_object_handlers .offset = XtOffsetOf (php_gd_image_object , std );
236234}
237235
236+ static zend_class_entry * gd_font_ce = NULL ;
237+ static zend_object_handlers php_gd_font_object_handlers ;
238+
239+ typedef struct _php_gd_font_object {
240+ gdFontPtr font ;
241+ zend_object std ;
242+ } php_gd_font_object ;
243+
244+ static php_gd_font_object * php_gd_font_object_from_zend_object (zend_object * zobj )
245+ {
246+ return ((php_gd_font_object * )(zobj + 1 )) - 1 ;
247+ }
248+
249+ static zend_object * php_gd_font_object_to_zend_object (php_gd_font_object * obj )
250+ {
251+ return ((zend_object * )(obj + 1 )) - 1 ;
252+ }
253+
254+ static zend_object * php_gd_font_object_create (zend_class_entry * ce )
255+ {
256+ php_gd_font_object * obj = zend_object_alloc (sizeof (php_gd_font_object ), ce );
257+ zend_object * zobj = php_gd_font_object_to_zend_object (obj );
258+
259+ obj -> font = NULL ;
260+ zend_object_std_init (zobj , ce );
261+ object_properties_init (zobj , ce );
262+ zobj -> handlers = & php_gd_font_object_handlers ;
263+
264+ return zobj ;
265+ }
266+
267+ static void php_gd_font_object_free (zend_object * zobj )
268+ {
269+ php_gd_font_object * obj = php_gd_font_object_from_zend_object (zobj );
270+
271+ if (obj -> font ) {
272+ if (obj -> font -> data ) {
273+ efree (obj -> font -> data );
274+ }
275+ efree (obj -> font );
276+ obj -> font = NULL ;
277+ }
278+
279+ zend_object_std_dtor (zobj );
280+ }
281+
282+ static zend_function * php_gd_font_object_get_constructor (zend_object * object )
283+ {
284+ zend_throw_error (NULL , "You cannot initialize a GdImage object except through helper functions" );
285+ return NULL ;
286+ }
287+
288+ static void php_gd_font_minit_helper ()
289+ {
290+ zend_class_entry ce ;
291+ INIT_CLASS_ENTRY (ce , "GdFont" , class_GdFont_methods );
292+ gd_font_ce = zend_register_internal_class (& ce );
293+ gd_font_ce -> ce_flags |= ZEND_ACC_FINAL ;
294+ gd_font_ce -> create_object = php_gd_font_object_create ;
295+ gd_font_ce -> serialize = zend_class_serialize_deny ;
296+ gd_font_ce -> unserialize = zend_class_unserialize_deny ;
297+
298+ /* setting up the object handlers for the GdFont class */
299+ memcpy (& php_gd_font_object_handlers , & std_object_handlers , sizeof (zend_object_handlers ));
300+ php_gd_font_object_handlers .clone_obj = NULL ;
301+ php_gd_font_object_handlers .free_obj = php_gd_font_object_free ;
302+ php_gd_font_object_handlers .get_constructor = php_gd_font_object_get_constructor ;
303+ php_gd_font_object_handlers .offset = XtOffsetOf (php_gd_font_object , std );
304+ }
238305
239306/*********************************************************
240307 *
@@ -265,19 +332,6 @@ PHP_INI_BEGIN()
265332PHP_INI_END ()
266333/* }}} */
267334
268- /* {{{ php_free_gd_font */
269- static void php_free_gd_font (zend_resource * rsrc )
270- {
271- gdFontPtr fp = (gdFontPtr ) rsrc -> ptr ;
272-
273- if (fp -> data ) {
274- efree (fp -> data );
275- }
276-
277- efree (fp );
278- }
279- /* }}} */
280-
281335/* {{{ php_gd_error_method */
282336void php_gd_error_method (int type , const char * format , va_list args )
283337{
@@ -302,8 +356,8 @@ void php_gd_error_method(int type, const char *format, va_list args)
302356/* {{{ PHP_MINIT_FUNCTION */
303357PHP_MINIT_FUNCTION (gd )
304358{
305- le_gd_font = zend_register_list_destructors_ex (php_free_gd_font , NULL , "gd font" , module_number );
306359 php_gd_object_minit_helper ();
360+ php_gd_font_minit_helper ();
307361
308362#if defined(HAVE_GD_FREETYPE ) && defined(HAVE_GD_BUNDLED )
309363 gdFontCacheMutexSetup ();
@@ -614,7 +668,6 @@ PHP_FUNCTION(gd_info)
614668/* {{{ Load a new font */
615669PHP_FUNCTION (imageloadfont )
616670{
617- zval * ind ;
618671 zend_string * file ;
619672 int hdr_size = sizeof (gdFont ) - sizeof (char * );
620673 int body_size , n = 0 , b , i , body_size_check ;
@@ -704,13 +757,8 @@ PHP_FUNCTION(imageloadfont)
704757 }
705758 php_stream_close (stream );
706759
707- ind = zend_list_insert (font , le_gd_font );
708-
709- /* Adding 5 to the font index so we will never have font indices
710- * that overlap with the old fonts (with indices 1-5). The first
711- * list index given out is always 1.
712- */
713- RETURN_LONG (Z_RES_HANDLE_P (ind ) + 5 );
760+ object_init_ex (return_value , gd_font_ce );
761+ php_gd_font_object_from_zend_object (Z_OBJ_P (return_value ))-> font = font ;
714762}
715763/* }}} */
716764
@@ -2695,42 +2743,26 @@ PHP_FUNCTION(imagefilledpolygon)
26952743/* }}} */
26962744
26972745/* {{{ php_find_gd_font */
2698- static gdFontPtr php_find_gd_font (int size )
2746+ static gdFontPtr php_find_gd_font (zval * zfont )
26992747{
2700- gdFontPtr font ;
2748+ if ((Z_TYPE_P (zfont ) == IS_OBJECT ) && instanceof_function (Z_OBJCE_P (zfont ), gd_font_ce )) {
2749+ return php_gd_font_object_from_zend_object (Z_OBJ_P (zfont ))-> font ;
2750+ }
27012751
2702- switch (size ) {
2703- case 1 :
2704- font = gdFontTiny ;
2705- break ;
2706- case 2 :
2707- font = gdFontSmall ;
2708- break ;
2709- case 3 :
2710- font = gdFontMediumBold ;
2711- break ;
2712- case 4 :
2713- font = gdFontLarge ;
2714- break ;
2715- case 5 :
2716- font = gdFontGiant ;
2717- break ;
2718- default : {
2719- zval * zv = zend_hash_index_find (& EG (regular_list ), size - 5 );
2720- if (!zv || (Z_RES_P (zv ))-> type != le_gd_font ) {
2721- if (size < 1 ) {
2722- font = gdFontTiny ;
2723- } else {
2724- font = gdFontGiant ;
2725- }
2726- } else {
2727- font = (gdFontPtr )Z_RES_P (zv )-> ptr ;
2728- }
2729- }
2730- break ;
2731- }
2732-
2733- return font ;
2752+ if (Z_TYPE_P (zfont ) != IS_LONG ) {
2753+ /* In practice, type checks should prevent us from reaching here. */
2754+ return gdFontTiny ;
2755+ }
2756+
2757+ switch (Z_LVAL_P (zfont )) {
2758+ case 1 : return gdFontTiny ;
2759+ case 2 : return gdFontSmall ;
2760+ case 3 : return gdFontMediumBold ;
2761+ case 4 : return gdFontLarge ;
2762+ case 5 : return gdFontGiant ;
2763+ }
2764+
2765+ return (Z_LVAL_P (zfont ) < 1 ) ? gdFontTiny : gdFontGiant ;
27342766}
27352767/* }}} */
27362768
@@ -2740,14 +2772,14 @@ static gdFontPtr php_find_gd_font(int size)
27402772 */
27412773static void php_imagefontsize (INTERNAL_FUNCTION_PARAMETERS , int arg )
27422774{
2743- zend_long SIZE ;
2775+ zval * zfont ;
27442776 gdFontPtr font ;
27452777
2746- if (zend_parse_parameters (ZEND_NUM_ARGS (), "l " , & SIZE ) == FAILURE ) {
2778+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "z " , & zfont ) == FAILURE ) {
27472779 RETURN_THROWS ();
27482780 }
27492781
2750- font = php_find_gd_font (SIZE );
2782+ font = php_find_gd_font (zfont );
27512783 RETURN_LONG (arg ? font -> h : font -> w );
27522784}
27532785/* }}} */
@@ -2801,15 +2833,16 @@ static void php_gdimagecharup(gdImagePtr im, gdFontPtr f, int x, int y, int c, i
28012833static void php_imagechar (INTERNAL_FUNCTION_PARAMETERS , int mode )
28022834{
28032835 zval * IM ;
2804- zend_long SIZE , X , Y , COL ;
2836+ zend_long X , Y , COL ;
28052837 char * C ;
28062838 size_t C_len ;
28072839 gdImagePtr im ;
2808- int ch = 0 , col , x , y , size , i , l = 0 ;
2840+ int ch = 0 , col , x , y , i , l = 0 ;
28092841 unsigned char * str = NULL ;
2842+ zval * zfont ;
28102843 gdFontPtr font ;
28112844
2812- if (zend_parse_parameters (ZEND_NUM_ARGS (), "Olllsl " , & IM , gd_image_ce , & SIZE , & X , & Y , & C , & C_len , & COL ) == FAILURE ) {
2845+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "Ozllsl " , & IM , gd_image_ce , & zfont , & X , & Y , & C , & C_len , & COL ) == FAILURE ) {
28132846 RETURN_THROWS ();
28142847 }
28152848
@@ -2826,9 +2859,8 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode)
28262859
28272860 y = Y ;
28282861 x = X ;
2829- size = SIZE ;
28302862
2831- font = php_find_gd_font (size );
2863+ font = php_find_gd_font (zfont );
28322864
28332865 switch (mode ) {
28342866 case 0 :
0 commit comments