]> granicus.if.org Git - php/commitdiff
Convert gdFont from resource to object
authorSara Golemon <pollita@php.net>
Wed, 21 Oct 2020 23:21:25 +0000 (23:21 +0000)
committerSara Golemon <pollita@php.net>
Wed, 21 Oct 2020 23:41:41 +0000 (23:41 +0000)
ext/gd/gd.c
ext/gd/gd.stub.php
ext/gd/gd_arginfo.h

index 6ade5c7931d1af5281d16ed80f3e755911744e42..6889802a13a74314b67a42ce5b10fb89d91c6c3b 100644 (file)
@@ -57,8 +57,6 @@
 
 #include "gd_compat.h"
 
-static int le_gd_font;
-
 #include <gd.h>
 #include <gd_errors.h>
 #include <gdfontt.h>  /* 1 Tiny font */
@@ -235,6 +233,75 @@ static void php_gd_object_minit_helper()
        php_gd_image_object_handlers.offset = XtOffsetOf(php_gd_image_object, std);
 }
 
+static zend_class_entry *gd_font_ce = NULL;
+static zend_object_handlers php_gd_font_object_handlers;
+
+typedef struct _php_gd_font_object {
+       gdFontPtr font;
+       zend_object std;
+} php_gd_font_object;
+
+static php_gd_font_object *php_gd_font_object_from_zend_object(zend_object *zobj)
+{
+       return ((php_gd_font_object*)(zobj + 1)) - 1;
+}
+
+static zend_object *php_gd_font_object_to_zend_object(php_gd_font_object *obj)
+{
+       return ((zend_object*)(obj + 1)) - 1;
+}
+
+static zend_object *php_gd_font_object_create(zend_class_entry *ce)
+{
+       php_gd_font_object *obj = zend_object_alloc(sizeof(php_gd_font_object), ce);
+       zend_object *zobj = php_gd_font_object_to_zend_object(obj);
+
+       obj->font = NULL;
+       zend_object_std_init(zobj, ce);
+       object_properties_init(zobj, ce);
+       zobj->handlers = &php_gd_font_object_handlers;
+
+       return zobj;
+}
+
+static void php_gd_font_object_free(zend_object *zobj)
+{
+       php_gd_font_object *obj = php_gd_font_object_from_zend_object(zobj);
+
+       if (obj->font) {
+               if (obj->font->data) {
+                       efree(obj->font->data);
+               }
+               efree(obj->font);
+               obj->font = NULL;
+       }
+
+       zend_object_std_dtor(zobj);
+}
+
+static zend_function *php_gd_font_object_get_constructor(zend_object *object)
+{
+       zend_throw_error(NULL, "You cannot initialize a GdImage object except through helper functions");
+       return NULL;
+}
+
+static void php_gd_font_minit_helper()
+{
+       zend_class_entry ce;
+       INIT_CLASS_ENTRY(ce, "GdFont", class_GdFont_methods);
+       gd_font_ce = zend_register_internal_class(&ce);
+       gd_font_ce->ce_flags |= ZEND_ACC_FINAL;
+       gd_font_ce->create_object = php_gd_font_object_create;
+       gd_font_ce->serialize = zend_class_serialize_deny;
+       gd_font_ce->unserialize = zend_class_unserialize_deny;
+
+       /* setting up the object handlers for the GdFont class */
+       memcpy(&php_gd_font_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
+       php_gd_font_object_handlers.clone_obj = NULL;
+       php_gd_font_object_handlers.free_obj = php_gd_font_object_free;
+       php_gd_font_object_handlers.get_constructor = php_gd_font_object_get_constructor;
+       php_gd_font_object_handlers.offset = XtOffsetOf(php_gd_font_object, std);
+}
 
 /*********************************************************
  *
@@ -265,19 +332,6 @@ PHP_INI_BEGIN()
 PHP_INI_END()
 /* }}} */
 
-/* {{{ php_free_gd_font */
-static void php_free_gd_font(zend_resource *rsrc)
-{
-       gdFontPtr fp = (gdFontPtr) rsrc->ptr;
-
-       if (fp->data) {
-               efree(fp->data);
-       }
-
-       efree(fp);
-}
-/* }}} */
-
 /* {{{ php_gd_error_method */
 void php_gd_error_method(int type, const char *format, va_list args)
 {
@@ -302,8 +356,8 @@ void php_gd_error_method(int type, const char *format, va_list args)
 /* {{{ PHP_MINIT_FUNCTION */
 PHP_MINIT_FUNCTION(gd)
 {
-       le_gd_font = zend_register_list_destructors_ex(php_free_gd_font, NULL, "gd font", module_number);
        php_gd_object_minit_helper();
+       php_gd_font_minit_helper();
 
 #if defined(HAVE_GD_FREETYPE) && defined(HAVE_GD_BUNDLED)
        gdFontCacheMutexSetup();
@@ -614,7 +668,6 @@ PHP_FUNCTION(gd_info)
 /* {{{ Load a new font */
 PHP_FUNCTION(imageloadfont)
 {
-       zval *ind;
        zend_string *file;
        int hdr_size = sizeof(gdFont) - sizeof(char *);
        int body_size, n = 0, b, i, body_size_check;
@@ -704,13 +757,8 @@ PHP_FUNCTION(imageloadfont)
        }
        php_stream_close(stream);
 
-       ind = zend_list_insert(font, le_gd_font);
-
-       /* Adding 5 to the font index so we will never have font indices
-        * that overlap with the old fonts (with indices 1-5).  The first
-        * list index given out is always 1.
-        */
-       RETURN_LONG(Z_RES_HANDLE_P(ind) + 5);
+       object_init_ex(return_value, gd_font_ce);
+       php_gd_font_object_from_zend_object(Z_OBJ_P(return_value))->font = font;
 }
 /* }}} */
 
@@ -2695,42 +2743,26 @@ PHP_FUNCTION(imagefilledpolygon)
 /* }}} */
 
 /* {{{ php_find_gd_font */
-static gdFontPtr php_find_gd_font(int size)
+static gdFontPtr php_find_gd_font(zval *zfont)
 {
-       gdFontPtr font;
+       if ((Z_TYPE_P(zfont) == IS_OBJECT) && instanceof_function(Z_OBJCE_P(zfont), gd_font_ce)) {
+               return php_gd_font_object_from_zend_object(Z_OBJ_P(zfont))->font;
+       }
 
-       switch (size) {
-               case 1:
-                       font = gdFontTiny;
-                       break;
-               case 2:
-                       font = gdFontSmall;
-                       break;
-               case 3:
-                       font = gdFontMediumBold;
-                       break;
-               case 4:
-                       font = gdFontLarge;
-                       break;
-               case 5:
-                       font = gdFontGiant;
-                       break;
-               default: {
-                        zval *zv = zend_hash_index_find(&EG(regular_list), size - 5);
-                        if (!zv || (Z_RES_P(zv))->type != le_gd_font) {
-                                if (size < 1) {
-                                        font = gdFontTiny;
-                                } else {
-                                        font = gdFontGiant;
-                                }
-                        } else {
-                                font = (gdFontPtr)Z_RES_P(zv)->ptr;
-                        }
-                }
-                break;
-       }
-
-       return font;
+       if (Z_TYPE_P(zfont) != IS_LONG) {
+               /* In practice, type checks should prevent us from reaching here. */
+               return gdFontTiny;
+       }
+
+       switch (Z_LVAL_P(zfont)) {
+               case 1: return gdFontTiny;
+               case 2: return gdFontSmall;
+               case 3: return gdFontMediumBold;
+               case 4: return gdFontLarge;
+               case 5: return gdFontGiant;
+       }
+
+       return (Z_LVAL_P(zfont) < 1) ? gdFontTiny : gdFontGiant;
 }
 /* }}} */
 
@@ -2740,14 +2772,14 @@ static gdFontPtr php_find_gd_font(int size)
  */
 static void php_imagefontsize(INTERNAL_FUNCTION_PARAMETERS, int arg)
 {
-       zend_long SIZE;
+       zval *zfont;
        gdFontPtr font;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &SIZE) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &zfont) == FAILURE) {
                RETURN_THROWS();
        }
 
-       font = php_find_gd_font(SIZE);
+       font = php_find_gd_font(zfont);
        RETURN_LONG(arg ? font->h : font->w);
 }
 /* }}} */
@@ -2801,15 +2833,16 @@ static void php_gdimagecharup(gdImagePtr im, gdFontPtr f, int x, int y, int c, i
 static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode)
 {
        zval *IM;
-       zend_long SIZE, X, Y, COL;
+       zend_long X, Y, COL;
        char *C;
        size_t C_len;
        gdImagePtr im;
-       int ch = 0, col, x, y, size, i, l = 0;
+       int ch = 0, col, x, y, i, l = 0;
        unsigned char *str = NULL;
+       zval *zfont;
        gdFontPtr font;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olllsl", &IM, gd_image_ce, &SIZE, &X, &Y, &C, &C_len, &COL) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "Ozllsl", &IM, gd_image_ce, &zfont, &X, &Y, &C, &C_len, &COL) == FAILURE) {
                RETURN_THROWS();
        }
 
@@ -2826,9 +2859,8 @@ static void php_imagechar(INTERNAL_FUNCTION_PARAMETERS, int mode)
 
        y = Y;
        x = X;
-       size = SIZE;
 
-       font = php_find_gd_font(size);
+       font = php_find_gd_font(zfont);
 
        switch (mode) {
                case 0:
index fe0d5658eef70998d4fbd41d902f754609cf7508..0ef410fc1e9565b98cd5ede5074ac2de6acde92b 100644 (file)
@@ -2,13 +2,12 @@
 
 /** @generate-function-entries */
 
-final class GdImage
-{
-}
+final class GdImage {}
+final class GdFont {}
 
 function gd_info(): array {}
 
-function imageloadfont(string $filename): int|false {}
+function imageloadfont(string $filename): GdFont|false {}
 
 function imagesetstyle(GdImage $image, array $style): bool {}
 
@@ -187,17 +186,17 @@ function imageopenpolygon(GdImage $image, array $points, int $num_points_or_colo
 
 function imagefilledpolygon(GdImage $image, array $points, int $num_points_or_color, ?int $color = null): bool {}
 
-function imagefontwidth(int $font): int {}
+function imagefontwidth(GdFont|int $font): int {}
 
-function imagefontheight(int $font): int {}
+function imagefontheight(GdFont|int $font): int {}
 
-function imagechar(GdImage $image, int $font, int $x, int $y, string $char, int $color): bool {}
+function imagechar(GdImage $image, GdFont|int $font, int $x, int $y, string $char, int $color): bool {}
 
-function imagecharup(GdImage $image, int $font, int $x, int $y, string $char, int $color): bool {}
+function imagecharup(GdImage $image, GdFont|int $font, int $x, int $y, string $char, int $color): bool {}
 
-function imagestring(GdImage $image, int $font, int $x, int $y, string $string, int $color): bool {}
+function imagestring(GdImage $image, GdFont|int $font, int $x, int $y, string $string, int $color): bool {}
 
-function imagestringup(GdImage $image, int $font, int $x, int $y, string $string, int $color): bool {}
+function imagestringup(GdImage $image, GdFont|int $font, int $x, int $y, string $string, int $color): bool {}
 
 function imagecopy(GdImage $dst_image, GdImage $src_image, int $dst_x, int $dst_y, int $src_x, int $src_y, int $src_width, int $src_height): bool {}
 
index 4d59767b4eb93cfa803b993f9915aaa971fc56a1..ea61b0837410a331a857a01c0d0ac16ba71339a8 100644 (file)
@@ -1,10 +1,10 @@
 /* This is a generated file, edit the .stub.php file instead.
- * Stub hash: 59256d0de105f1a2f5d5fc1e20f8090031b42a76 */
+ * Stub hash: 23b7c8395c628239fb10d746ca6bba72871ee9f3 */
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gd_info, 0, 0, IS_ARRAY, 0)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imageloadfont, 0, 1, MAY_BE_LONG|MAY_BE_FALSE)
+ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imageloadfont, 0, 1, GdFont, MAY_BE_FALSE)
        ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
 ZEND_END_ARG_INFO()
 
@@ -380,14 +380,14 @@ ZEND_END_ARG_INFO()
 #define arginfo_imagefilledpolygon arginfo_imagepolygon
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagefontwidth, 0, 1, IS_LONG, 0)
-       ZEND_ARG_TYPE_INFO(0, font, IS_LONG, 0)
+       ZEND_ARG_OBJ_TYPE_MASK(0, font, GdFont, MAY_BE_LONG, NULL)
 ZEND_END_ARG_INFO()
 
 #define arginfo_imagefontheight arginfo_imagefontwidth
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagechar, 0, 6, _IS_BOOL, 0)
        ZEND_ARG_OBJ_INFO(0, image, GdImage, 0)
-       ZEND_ARG_TYPE_INFO(0, font, IS_LONG, 0)
+       ZEND_ARG_OBJ_TYPE_MASK(0, font, GdFont, MAY_BE_LONG, NULL)
        ZEND_ARG_TYPE_INFO(0, x, IS_LONG, 0)
        ZEND_ARG_TYPE_INFO(0, y, IS_LONG, 0)
        ZEND_ARG_TYPE_INFO(0, char, IS_STRING, 0)
@@ -398,7 +398,7 @@ ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagestring, 0, 6, _IS_BOOL, 0)
        ZEND_ARG_OBJ_INFO(0, image, GdImage, 0)
-       ZEND_ARG_TYPE_INFO(0, font, IS_LONG, 0)
+       ZEND_ARG_OBJ_TYPE_MASK(0, font, GdFont, MAY_BE_LONG, NULL)
        ZEND_ARG_TYPE_INFO(0, x, IS_LONG, 0)
        ZEND_ARG_TYPE_INFO(0, y, IS_LONG, 0)
        ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0)
@@ -831,3 +831,8 @@ static const zend_function_entry ext_functions[] = {
 static const zend_function_entry class_GdImage_methods[] = {
        ZEND_FE_END
 };
+
+
+static const zend_function_entry class_GdFont_methods[] = {
+       ZEND_FE_END
+};