1999-04-16 20:15:38 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
1999-07-16 21:13:16 +08:00
| PHP version 4.0 |
1999-04-16 20:15:38 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-01-01 09:32:05 +08:00
| Copyright ( c ) 1997 , 1998 , 1999 , 2000 The PHP Group |
1999-04-16 20:15:38 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-05-18 23:34:45 +08:00
| This source file is subject to version 2.02 of the PHP license , |
1999-07-16 21:13:16 +08:00
| that is bundled with this package in the file LICENSE , and is |
| available at through the world - wide - web at |
2000-05-18 23:34:45 +08:00
| http : //www.php.net/license/2_02.txt. |
1999-07-16 21:13:16 +08:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
1999-04-16 20:15:38 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Rasmus Lerdorf < rasmus @ lerdorf . on . ca > |
| Stig Bakken < ssb @ guardian . no > |
| Jim Winstead < jimw @ php . net > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
/* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center,
Cold Spring Harbor Labs . */
/* Note that there is no code from the gd package in this file */
1999-04-24 04:06:01 +08:00
1999-04-16 20:15:38 +08:00
# include "php.h"
1999-04-22 08:25:57 +08:00
# include "ext/standard/head.h"
1999-04-16 20:15:38 +08:00
# include <math.h>
1999-04-27 01:26:37 +08:00
# include "SAPI.h"
1999-12-05 03:19:57 +08:00
# include "php_gd.h"
2000-09-26 17:08:02 +08:00
# include "ext/standard/fsock.h"
1999-04-16 20:15:38 +08:00
# if HAVE_SYS_WAIT_H
# include <sys / wait.h>
# endif
# if HAVE_UNISTD_H
# include <unistd.h>
# endif
2000-06-16 07:45:05 +08:00
# ifdef PHP_WIN32
1999-04-16 20:15:38 +08:00
# include <io.h>
# include <fcntl.h>
# endif
# if HAVE_LIBGD
2000-04-06 06:30:19 +08:00
# include "ext/standard/info.h"
1999-04-16 20:15:38 +08:00
# include <gd.h>
# include <gdfontt.h> /* 1 Tiny font */
# include <gdfonts.h> /* 2 Small font */
# include <gdfontmb.h> /* 3 Medium bold font */
# include <gdfontl.h> /* 4 Large font */
# include <gdfontg.h> /* 5 Giant font */
1999-07-23 23:18:37 +08:00
# ifdef ENABLE_GD_TTF
1999-04-22 05:27:18 +08:00
# include "gdttf.h"
1999-04-16 20:15:38 +08:00
# endif
# ifndef M_PI
# define M_PI 3.14159265358979323846
# endif
1999-07-23 23:18:37 +08:00
# ifdef ENABLE_GD_TTF
1999-12-18 05:50:07 +08:00
static void php_imagettftext_common ( INTERNAL_FUNCTION_PARAMETERS , int ) ;
1999-04-16 20:15:38 +08:00
# endif
2000-09-26 17:08:02 +08:00
# ifdef GD2_VERS
/* it's >= 1.5, i.e. has IOCtx */
# define USE_GD_IOCTX 1
# else
# undef USE_GD_IOCTX
# endif
# ifndef USE_GD_IOCTX
# define gdImageCreateFromJpegCtx NULL
# define gdImageCreateFromPngCtx NULL
# define gdImageCreateFromWBMPCtx NULL
# endif
1999-04-16 20:15:38 +08:00
# ifdef THREAD_SAFE
DWORD GDlibTls ;
static int numthreads = 0 ;
void * gdlib_mutex = NULL ;
2000-02-29 00:52:03 +08:00
/*
1999-04-16 20:15:38 +08:00
typedef struct gdlib_global_struct {
int le_gd ;
int le_gd_font ;
2000-02-25 14:43:51 +08:00
# if HAVE_LIBT1
int le_ps_font ;
int le_ps_enc ;
# endif
1999-04-16 20:15:38 +08:00
} gdlib_global_struct ;
# define GD_GLOBAL(a) gdlib_globals->a
# define GD_TLS_VARS gdlib_global_struct *gdlib_globals = TlsGetValue(GDlibTls);
# else
# define GD_GLOBAL(a) a
# define GD_TLS_VARS
int le_gd ;
int le_gd_font ;
2000-02-25 14:43:51 +08:00
# if HAVE_LIBT1
int le_ps_font ;
int le_ps_enc ;
# endif
2000-02-29 00:52:03 +08:00
*/
1999-04-16 20:15:38 +08:00
# endif
function_entry gd_functions [ ] = {
1999-07-28 03:44:46 +08:00
PHP_FE ( imagearc , NULL )
PHP_FE ( imagechar , NULL )
PHP_FE ( imagecharup , NULL )
PHP_FE ( imagecolorallocate , NULL )
2000-06-25 10:55:31 +08:00
PHP_FE ( imagepalettecopy , NULL )
1999-07-28 03:44:46 +08:00
PHP_FE ( imagecolorat , NULL )
PHP_FE ( imagecolorclosest , NULL )
2000-06-25 10:55:31 +08:00
PHP_FE ( imagecolorclosesthwb , NULL )
1999-07-28 03:44:46 +08:00
PHP_FE ( imagecolordeallocate , NULL )
PHP_FE ( imagecolorresolve , NULL )
PHP_FE ( imagecolorexact , NULL )
PHP_FE ( imagecolorset , NULL )
PHP_FE ( imagecolortransparent , NULL )
PHP_FE ( imagecolorstotal , NULL )
PHP_FE ( imagecolorsforindex , NULL )
PHP_FE ( imagecopy , NULL )
2000-06-25 10:55:31 +08:00
PHP_FE ( imagecopymerge , NULL )
1999-07-28 03:44:46 +08:00
PHP_FE ( imagecopyresized , NULL )
PHP_FE ( imagecreate , NULL )
2000-11-04 03:53:42 +08:00
PHP_FE ( imagecreatefromstring , NULL )
1999-10-17 22:57:49 +08:00
PHP_FE ( imagecreatefrompng , NULL )
PHP_FE ( imagepng , NULL )
1999-07-28 03:44:46 +08:00
PHP_FE ( imagecreatefromgif , NULL )
1999-10-17 22:57:49 +08:00
PHP_FE ( imagegif , NULL )
2000-03-13 13:58:50 +08:00
PHP_FE ( imagecreatefromjpeg , NULL )
PHP_FE ( imagejpeg , NULL )
2000-06-25 09:44:15 +08:00
PHP_FE ( imagecreatefromwbmp , NULL )
2000-06-07 08:37:49 +08:00
PHP_FE ( imagewbmp , NULL )
PHP_FE ( imagecreatefromxbm , NULL )
PHP_FE ( imagecreatefromxpm , NULL )
1999-07-28 03:44:46 +08:00
PHP_FE ( imagedestroy , NULL )
2000-05-14 23:25:13 +08:00
PHP_FE ( imagegammacorrect , NULL )
1999-07-28 03:44:46 +08:00
PHP_FE ( imagefill , NULL )
PHP_FE ( imagefilledpolygon , NULL )
PHP_FE ( imagefilledrectangle , NULL )
PHP_FE ( imagefilltoborder , NULL )
PHP_FE ( imagefontwidth , NULL )
PHP_FE ( imagefontheight , NULL )
PHP_FE ( imageinterlace , NULL )
PHP_FE ( imageline , NULL )
PHP_FE ( imageloadfont , NULL )
PHP_FE ( imagepolygon , NULL )
PHP_FE ( imagerectangle , NULL )
PHP_FE ( imagesetpixel , NULL )
PHP_FE ( imagestring , NULL )
PHP_FE ( imagestringup , NULL )
PHP_FE ( imagesx , NULL )
PHP_FE ( imagesy , NULL )
PHP_FE ( imagedashedline , NULL )
PHP_FE ( imagettfbbox , NULL )
PHP_FE ( imagettftext , NULL )
2000-02-25 14:43:51 +08:00
PHP_FE ( imagepsloadfont , NULL )
/*
PHP_FE ( imagepscopyfont , NULL )
*/
PHP_FE ( imagepsfreefont , NULL )
PHP_FE ( imagepsencodefont , NULL )
PHP_FE ( imagepsextendfont , NULL )
PHP_FE ( imagepsslantfont , NULL )
PHP_FE ( imagepstext , NULL )
PHP_FE ( imagepsbbox , NULL )
2000-07-15 05:51:31 +08:00
PHP_FE ( imagetypes , NULL )
1999-04-16 20:15:38 +08:00
{ NULL , NULL , NULL }
} ;
1999-12-18 04:55:31 +08:00
zend_module_entry gd_module_entry = {
2000-03-04 22:21:22 +08:00
" gd " , gd_functions , PHP_MINIT ( gd ) , NULL , NULL , NULL , PHP_MINFO ( gd ) , STANDARD_MODULE_PROPERTIES
1999-04-16 20:15:38 +08:00
} ;
2000-02-29 00:52:03 +08:00
# ifdef ZTS
int gd_globals_id ;
# else
static php_gd_globals gd_globals ;
# endif
2000-05-23 17:33:51 +08:00
# ifdef COMPILE_DL_GD
2000-05-02 08:30:36 +08:00
ZEND_GET_MODULE ( gd )
1999-04-16 20:15:38 +08:00
# endif
2000-10-21 02:25:16 +08:00
static void php_free_gd_image ( zend_rsrc_list_entry * rsrc )
{
gdImageDestroy ( ( gdImagePtr ) rsrc - > ptr ) ;
}
1999-04-16 20:15:38 +08:00
2000-10-21 02:25:16 +08:00
static void php_free_gd_font ( zend_rsrc_list_entry * rsrc )
1999-12-18 05:50:07 +08:00
{
2000-10-21 02:25:16 +08:00
gdFontPtr fp = ( gdFontPtr ) rsrc - > ptr ;
1999-12-18 05:50:07 +08:00
if ( fp - > data ) {
efree ( fp - > data ) ;
}
efree ( fp ) ;
}
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
1999-07-28 03:44:46 +08:00
PHP_MINIT_FUNCTION ( gd )
1999-04-16 20:15:38 +08:00
{
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
# if defined(THREAD_SAFE)
gdlib_global_struct * gdlib_globals ;
2000-02-26 11:20:55 +08:00
PHP_MUTEX_ALLOC ( gdlib_mutex ) ;
PHP_MUTEX_LOCK ( gdlib_mutex ) ;
1999-04-16 20:15:38 +08:00
numthreads + + ;
if ( numthreads = = 1 ) {
if ( ! PHP3_TLS_PROC_STARTUP ( GDlibTls ) ) {
2000-02-26 11:20:55 +08:00
PHP_MUTEX_UNLOCK ( gdlib_mutex ) ;
PHP_MUTEX_FREE ( gdlib_mutex ) ;
1999-04-16 20:15:38 +08:00
return FAILURE ;
}
}
2000-02-26 11:20:55 +08:00
PHP_MUTEX_UNLOCK ( gdlib_mutex ) ;
1999-04-16 20:15:38 +08:00
if ( ! PHP3_TLS_THREAD_INIT ( GDlibTls , gdlib_globals , gdlib_global_struct ) ) {
2000-02-26 11:20:55 +08:00
PHP_MUTEX_FREE ( gdlib_mutex ) ;
1999-04-16 20:15:38 +08:00
return FAILURE ;
}
# endif
2000-10-26 01:44:02 +08:00
GDG ( le_gd ) = zend_register_list_destructors_ex ( php_free_gd_image , NULL , " gd " , module_number ) ;
GDG ( le_gd_font ) = zend_register_list_destructors_ex ( php_free_gd_font , NULL , " gd font " , module_number ) ;
2000-02-25 14:43:51 +08:00
# if HAVE_LIBT1
T1_SetBitmapPad ( 8 ) ;
T1_InitLib ( NO_LOGFILE | IGNORE_CONFIGFILE | IGNORE_FONTDATABASE ) ;
T1_SetLogLevel ( T1LOG_DEBUG ) ;
2000-10-26 01:44:02 +08:00
GDG ( le_ps_font ) = zend_register_list_destructors_ex ( php_free_ps_font , NULL , " gd PS font " , module_number ) ;
GDG ( le_ps_enc ) = zend_register_list_destructors_ex ( php_free_ps_enc , NULL , " gd PS encoding " , module_number ) ;
2000-02-25 14:43:51 +08:00
# endif
2000-07-15 06:07:57 +08:00
REGISTER_LONG_CONSTANT ( " IMG_GIF " , 1 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IMG_JPG " , 2 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IMG_JPEG " , 2 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IMG_PNG " , 4 , CONST_CS | CONST_PERSISTENT ) ;
REGISTER_LONG_CONSTANT ( " IMG_WBMP " , 8 , CONST_CS | CONST_PERSISTENT ) ;
1999-04-16 20:15:38 +08:00
return SUCCESS ;
}
1999-07-28 03:44:46 +08:00
PHP_MINFO_FUNCTION ( gd )
1999-05-09 21:57:09 +08:00
{
2000-04-06 06:30:19 +08:00
php_info_print_table_start ( ) ;
php_info_print_table_row ( 2 , " GD Support " , " enabled " ) ;
1999-04-16 20:15:38 +08:00
/* need to use a PHPAPI function here because it is external module in windows */
2000-04-06 06:30:19 +08:00
1999-11-30 07:21:52 +08:00
# if HAVE_GDIMAGECOLORRESOLVE
2000-04-06 06:30:19 +08:00
php_info_print_table_row ( 2 , " GD Version " , " 1.6.2 or higher " ) ;
1999-11-30 07:21:52 +08:00
# elif HAVE_LIBGD13
2000-04-06 06:30:19 +08:00
php_info_print_table_row ( 2 , " GD Version " , " between 1.3 and 1.6.1 " ) ;
1999-04-16 20:15:38 +08:00
# else
2000-04-06 06:30:19 +08:00
php_info_print_table_row ( 2 , " GD Version " , " 1.2 " ) ;
1999-04-16 20:15:38 +08:00
# endif
1999-11-30 07:21:52 +08:00
1999-07-23 23:18:37 +08:00
# ifdef ENABLE_GD_TTF
2000-04-06 06:30:19 +08:00
php_info_print_table_row ( 2 , " FreeType Support " , " enabled " ) ;
1999-11-30 07:21:52 +08:00
# if HAVE_LIBFREETYPE
2000-04-06 06:30:19 +08:00
php_info_print_table_row ( 2 , " FreeType Linkage " , " with freetype " ) ;
1999-11-30 07:21:52 +08:00
# elif HAVE_LIBTTF
2000-04-06 06:30:19 +08:00
php_info_print_table_row ( 2 , " FreeType Linkage " , " with TTF library " ) ;
1999-11-30 07:21:52 +08:00
# else
2000-04-06 06:30:19 +08:00
php_info_print_table_row ( 2 , " FreeType Linkage " , " with unknown library " ) ;
1999-11-30 07:21:52 +08:00
# endif
# endif
2000-06-07 01:12:05 +08:00
# ifdef HAVE_LIBT1
php_info_print_table_row ( 2 , " T1Lib Support " , " enabled " ) ;
# endif
2000-04-06 06:30:19 +08:00
/* this next part is stupid ... if I knew better, I'd put them all on one row (cmv) */
1999-11-30 07:21:52 +08:00
# ifdef HAVE_GD_GIF
2000-04-06 06:31:40 +08:00
php_info_print_table_row ( 2 , " GIF Support " , " enabled " ) ;
1999-11-30 07:21:52 +08:00
# endif
2000-04-08 02:50:08 +08:00
# ifdef HAVE_GD_JPG
php_info_print_table_row ( 2 , " JPG Support " , " enabled " ) ;
2000-07-15 05:51:31 +08:00
# endif
2000-11-01 12:38:28 +08:00
# ifdef HAVE_GD_PNG
php_info_print_table_row ( 2 , " PNG Support " , " enabled " ) ;
# endif
2000-07-15 05:51:31 +08:00
# ifdef HAVE_GD_WBMP
php_info_print_table_row ( 2 , " WBMP Support " , " enabled " ) ;
2000-11-01 12:38:28 +08:00
# endif
# ifdef HAVE_GD_XBM
php_info_print_table_row ( 2 , " XBM Support " , " enabled " ) ;
1999-04-16 20:15:38 +08:00
# endif
2000-04-06 06:30:19 +08:00
php_info_print_table_end ( ) ;
1999-04-16 20:15:38 +08:00
}
1999-08-06 00:25:10 +08:00
/* Need this for cpdf. See also comment in file.c php3i_get_le_fp() */
1999-12-18 05:50:07 +08:00
PHPAPI int phpi_get_le_gd ( void )
{
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
return GDG ( le_gd ) ;
1999-08-06 00:25:10 +08:00
}
1999-10-17 22:57:49 +08:00
# ifndef HAVE_GDIMAGECOLORRESOLVE
1999-04-16 20:15:38 +08:00
/********************************************************************/
/* gdImageColorResolve is a replacement for the old fragment: */
/* */
/* if ((color=gdImageColorExact(im,R,G,B)) < 0) */
/* if ((color=gdImageColorAllocate(im,R,G,B)) < 0) */
/* color=gdImageColorClosest(im,R,G,B); */
/* */
/* in a single function */
int
gdImageColorResolve ( gdImagePtr im , int r , int g , int b )
{
int c ;
int ct = - 1 ;
int op = - 1 ;
long rd , gd , bd , dist ;
long mindist = 3 * 255 * 255 ; /* init to max poss dist */
for ( c = 0 ; c < im - > colorsTotal ; c + + ) {
if ( im - > open [ c ] ) {
op = c ; /* Save open slot */
continue ; /* Color not in use */
}
rd = ( long ) ( im - > red [ c ] - r ) ;
gd = ( long ) ( im - > green [ c ] - g ) ;
bd = ( long ) ( im - > blue [ c ] - b ) ;
dist = rd * rd + gd * gd + bd * bd ;
if ( dist < mindist ) {
if ( dist = = 0 ) {
return c ; /* Return exact match color */
}
mindist = dist ;
ct = c ;
}
}
/* no exact match. We now know closest, but first try to allocate exact */
if ( op = = - 1 ) {
op = im - > colorsTotal ;
if ( op = = gdMaxColors ) { /* No room for more colors */
return ct ; /* Return closest available color */
}
im - > colorsTotal + + ;
}
im - > red [ op ] = r ;
im - > green [ op ] = g ;
im - > blue [ op ] = b ;
im - > open [ op ] = 0 ;
return op ; /* Return newly allocated color */
}
1999-10-17 22:57:49 +08:00
# endif
1999-04-16 20:15:38 +08:00
/* {{{ proto int imageloadfont(string filename)
1999-11-25 06:04:49 +08:00
Load a new font */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imageloadfont ) {
2000-02-29 00:52:03 +08:00
zval * * file ;
1999-04-16 20:15:38 +08:00
int hdr_size = sizeof ( gdFont ) - sizeof ( char * ) ;
int ind , body_size , n = 0 , b ;
gdFontPtr font ;
FILE * fp ;
int issock = 0 , socketd = 0 ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & file ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
convert_to_string_ex ( file ) ;
1999-04-16 20:15:38 +08:00
2000-03-31 06:56:34 +08:00
# ifdef PHP_WIN32
2000-04-15 22:20:01 +08:00
fp = V_FOPEN ( ( * file ) - > value . str . val , " rb " ) ;
1999-04-16 20:15:38 +08:00
# else
2000-02-29 00:52:03 +08:00
fp = php_fopen_wrapper ( ( * file ) - > value . str . val , " r " , IGNORE_PATH | IGNORE_URL_WIN , & issock , & socketd , NULL ) ;
1999-04-16 20:15:38 +08:00
# endif
if ( fp = = NULL ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " ImageFontLoad: unable to open file " ) ;
1999-04-16 20:15:38 +08:00
RETURN_FALSE ;
}
/* Only supports a architecture-dependent binary dump format
* at the moment .
* The file format is like this on machines with 32 - byte integers :
*
* byte 0 - 3 : ( int ) number of characters in the font
* byte 4 - 7 : ( int ) value of first character in the font ( often 32 , space )
* byte 8 - 11 : ( int ) pixel width of each character
* byte 12 - 15 : ( int ) pixel height of each character
* bytes 16 - : ( char ) array with character data , one byte per pixel
* in each character , for a total of
* ( nchars * width * height ) bytes .
*/
font = ( gdFontPtr ) emalloc ( sizeof ( gdFont ) ) ;
b = 0 ;
while ( b < hdr_size & & ( n = fread ( & font [ b ] , 1 , hdr_size - b , fp ) ) )
b + = n ;
if ( ! n ) {
fclose ( fp ) ;
efree ( font ) ;
if ( feof ( fp ) ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " ImageFontLoad: end of file while reading header " ) ;
1999-04-16 20:15:38 +08:00
} else {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " ImageFontLoad: error while reading header " ) ;
1999-04-16 20:15:38 +08:00
}
RETURN_FALSE ;
}
body_size = font - > w * font - > h * font - > nchars ;
font - > data = emalloc ( body_size ) ;
b = 0 ;
while ( b < body_size & & ( n = fread ( & font - > data [ b ] , 1 , body_size - b , fp ) ) )
b + = n ;
if ( ! n ) {
fclose ( fp ) ;
efree ( font - > data ) ;
efree ( font ) ;
if ( feof ( fp ) ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " ImageFontLoad: end of file while reading body " ) ;
1999-04-16 20:15:38 +08:00
} else {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " ImageFontLoad: error while reading body " ) ;
1999-04-16 20:15:38 +08:00
}
RETURN_FALSE ;
}
fclose ( fp ) ;
/* 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.
*/
2000-02-29 00:52:03 +08:00
ind = 5 + zend_list_insert ( font , GDG ( le_gd_font ) ) ;
1999-04-16 20:15:38 +08:00
RETURN_LONG ( ind ) ;
}
/* }}} */
/* {{{ proto int imagecreate(int x_size, int y_size)
1999-11-25 06:04:49 +08:00
Create a new image */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecreate )
{
2000-02-29 00:52:03 +08:00
zval * * x_size , * * y_size ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & x_size , & y_size ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( x_size ) ;
convert_to_long_ex ( y_size ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
im = gdImageCreate ( ( * x_size ) - > value . lval , ( * y_size ) - > value . lval ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
ZEND_REGISTER_RESOURCE ( return_value , im , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
2000-07-15 05:51:31 +08:00
/* {{{ proto int imagetypes(void)
Return the types of images supported in a bitfield - 1 = gif , 2 = jpeg , 4 = png , 8 = wbmp */
PHP_FUNCTION ( imagetypes )
{
int ret = 0 ;
# ifdef HAVE_GD_GIF
ret = 1 ;
# endif
# ifdef HAVE_GD_JPG
ret | = 2 ;
# endif
# ifdef HAVE_GD_PNG
ret | = 4 ;
# endif
# ifdef HAVE_GD_WBMP
ret | = 8 ;
# endif
RETURN_LONG ( ret ) ;
}
1999-10-17 22:57:49 +08:00
2000-11-04 03:53:42 +08:00
static int _php_image_type ( char data [ 8 ] )
{
/* Based on ext/standard/images.c */
if ( data = = NULL )
return - 1 ;
if ( ! memcmp ( data , php_sig_jpg , 3 ) )
return PHP_GDIMG_TYPE_JPG ;
else if ( ! memcmp ( data , php_sig_png , 3 ) ) {
if ( ! memcmp ( data , php_sig_png , 8 ) )
return PHP_GDIMG_TYPE_PNG ;
} else if ( ! memcmp ( data , php_sig_gif , 3 ) )
return PHP_GDIMG_TYPE_GIF ;
else {
gdIOCtx * io_ctx ;
io_ctx = gdNewDynamicCtx ( 8 , data ) ;
if ( io_ctx ) {
if ( getmbi ( gdGetC , io_ctx ) = = 0 & & skipheader ( gdGetC , io_ctx ) = = 0 ) {
io_ctx - > free ( io_ctx ) ;
return PHP_GDIMG_TYPE_WBM ;
} else
io_ctx - > free ( io_ctx ) ;
}
}
return - 1 ;
}
gdImagePtr _php_image_create_from_string ( zval * * Data , char * tn , gdImagePtr ( * ioctx_func_p ) ( ) ) {
gdImagePtr im ;
gdIOCtx * io_ctx ;
io_ctx = gdNewDynamicCtx ( ( * Data ) - > value . str . len ,
( * Data ) - > value . str . val ) ;
if ( ! io_ctx ) {
return NULL ;
}
im = ( * ioctx_func_p ) ( io_ctx ) ;
if ( ! im ) {
php_error ( E_WARNING , " %s: Passed data is not in '%s' format " , get_active_function_name ( ) , tn ) ;
return NULL ;
}
return im ;
}
PHP_FUNCTION ( imagecreatefromstring )
{
zval * * Data ;
gdImagePtr im ;
int imtype ;
char sig [ 8 ] ;
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & Data ) = = FAILURE )
WRONG_PARAM_COUNT ;
convert_to_string_ex ( Data ) ;
memcpy ( sig , ( * Data ) - > value . str . val , 8 ) ;
imtype = _php_image_type ( sig ) ;
switch ( imtype ) {
case PHP_GDIMG_TYPE_JPG : {
# ifdef HAVE_GD_JPG
im = _php_image_create_from_string ( Data , " JPEG " , gdImageCreateFromJpegCtx ) ;
# else
php_error ( E_WARNING , " No JPEG support in this PHP build " ) ;
# endif
break ;
}
case PHP_GDIMG_TYPE_PNG : {
# ifdef HAVE_GD_PNG
im = _php_image_create_from_string ( Data , " PNG " , gdImageCreateFromPngCtx ) ;
# else
php_error ( E_WARNING , " No PNG support in this PHP build " ) ;
# endif
break ;
}
case PHP_GDIMG_TYPE_GIF : {
# ifdef HAVE_GD_GIF
im = _php_image_create_from_string ( Data , " GIF " , gdImageCreateFromGifCtx ) ;
# else
php_error ( E_WARNING , " No GIF support in this PHP build " ) ;
# endif
break ;
}
case PHP_GDIMG_TYPE_WBM : {
# ifdef HAVE_GD_WBMP
im = _php_image_create_from_string ( Data , " WBMP " , gdImageCreateFromWBMPCtx ) ;
# else
php_error ( E_WARNING , " No WBMP support in this PHP build " ) ;
# endif
break ;
}
default :
php_error ( E_WARNING , " Data is not in a recognized format. " ) ;
RETURN_FALSE ;
}
if ( ! im ) {
php_error ( E_WARNING , " Couldn't create GD Image Stream out of Data " ) ;
RETURN_FALSE ;
}
ZEND_REGISTER_RESOURCE ( return_value , im , GDG ( le_gd ) ) ;
}
2000-09-26 17:08:02 +08:00
static void _php_image_create_from ( INTERNAL_FUNCTION_PARAMETERS , int image_type , char * tn , gdImagePtr ( * func_p ) ( ) , gdImagePtr ( * ioctx_func_p ) ( ) ) {
2000-02-29 00:52:03 +08:00
zval * * file ;
gdImagePtr im ;
2000-06-08 07:04:39 +08:00
char * fn = NULL ;
2000-02-29 00:52:03 +08:00
FILE * fp ;
int issock = 0 , socketd = 0 ;
2000-03-01 02:45:47 +08:00
GDLS_FETCH ( ) ;
2000-02-29 00:52:03 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & file ) = = FAILURE ) {
2000-02-29 00:52:03 +08:00
WRONG_PARAM_COUNT ;
}
convert_to_string_ex ( file ) ;
fn = ( * file ) - > value . str . val ;
2000-03-31 06:56:34 +08:00
# ifdef PHP_WIN32
2000-06-07 08:37:49 +08:00
fp = V_FOPEN ( Z_STRVAL_PP ( file ) , " rb " ) ;
1999-10-17 22:57:49 +08:00
# else
2000-06-07 08:37:49 +08:00
fp = php_fopen_wrapper ( Z_STRVAL_PP ( file ) , " r " , IGNORE_PATH | IGNORE_URL_WIN , & issock , & socketd , NULL ) ;
1999-10-17 22:57:49 +08:00
# endif
2000-09-26 17:08:02 +08:00
if ( ! fp & & ! socketd ) {
2000-02-29 00:52:03 +08:00
php_strip_url_passwd ( fn ) ;
2000-06-08 07:04:39 +08:00
php_error ( E_WARNING , " %s: Unable to open '%s' for reading " , get_active_function_name ( ) , fn ) ;
2000-02-29 00:52:03 +08:00
RETURN_FALSE ;
}
2000-06-08 07:04:39 +08:00
2000-09-26 17:08:02 +08:00
# ifndef USE_GD_IOCTX
ioctx_func_p = NULL ; /* don't allow sockets without IOCtx */
# endif
2000-06-08 07:04:39 +08:00
2000-09-26 17:08:02 +08:00
if ( issock & & ! ioctx_func_p ) {
php_error ( E_WARNING , " %s: Sockets are not supported for image type '%s' " , get_active_function_name ( ) , tn ) ;
RETURN_FALSE ;
}
if ( issock & & socketd ) {
# ifdef USE_GD_IOCTX
gdIOCtx * io_ctx ;
# define CHUNK_SIZE 8192
int read_len = 0 , buff_len = 0 , buff_size = 5 * CHUNK_SIZE ;
char * buff , * buff_cur ;
buff = malloc ( buff_size ) ; /* Should be malloc! GD uses free */
buff_cur = buff ;
do {
if ( buff_len > buff_size - CHUNK_SIZE ) {
buff_size + = CHUNK_SIZE ;
buff = realloc ( buff , buff_size ) ;
}
read_len = SOCK_FREAD ( buff_cur , CHUNK_SIZE , socketd ) ;
buff_len + = read_len ;
buff_cur + = read_len ;
} while ( read_len > 0 ) ;
io_ctx = gdNewDynamicCtx ( buff_len , buff ) ;
if ( ! io_ctx ) {
php_error ( E_WARNING , " %s: Cannot allocate GD IO context " , get_active_function_name ( ) ) ;
}
im = ( * ioctx_func_p ) ( io_ctx ) ;
io_ctx - > free ( io_ctx ) ;
# endif
} else {
im = ( * func_p ) ( fp ) ;
fflush ( fp ) ;
fclose ( fp ) ;
}
2000-02-29 00:52:03 +08:00
2000-04-21 10:23:16 +08:00
if ( ! im ) {
2000-06-25 09:44:15 +08:00
php_error ( E_WARNING , " %s: '%s' is not a valid %s file " , get_active_function_name ( ) , fn , tn ) ;
2000-04-21 10:23:16 +08:00
RETURN_FALSE ;
}
2000-06-07 08:37:49 +08:00
2000-02-29 00:52:03 +08:00
ZEND_REGISTER_RESOURCE ( return_value , im , GDG ( le_gd ) ) ;
2000-06-07 08:37:49 +08:00
}
/* {{{ proto int imagecreatefromgif(string filename)
Create a new image from GIF file or URL */
PHP_FUNCTION ( imagecreatefromgif )
{
# ifdef HAVE_GD_GIF
2000-09-26 17:08:02 +08:00
_php_image_create_from ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_GIF , " GIF " , gdImageCreateFromGif , NULL ) ;
2000-06-07 08:37:49 +08:00
# else /* HAVE_GD_GIF */
2000-06-08 07:04:39 +08:00
php_error ( E_WARNING , " ImageCreateFromGif: No GIF support in this PHP build " ) ;
2000-06-07 08:37:49 +08:00
RETURN_FALSE ;
# endif /* HAVE_GD_GIF */
}
/* }}} */
/* {{{ proto int imagecreatefromjpeg(string filename)
Create a new image from JPEG file or URL */
PHP_FUNCTION ( imagecreatefromjpeg )
{
# ifdef HAVE_GD_JPG
2000-09-26 17:08:02 +08:00
_php_image_create_from ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_JPG , " JPEG " , gdImageCreateFromJpeg , gdImageCreateFromJpegCtx ) ;
2000-06-07 08:37:49 +08:00
# else /* HAVE_GD_JPG */
php_error ( E_WARNING , " ImageCreateFromJpeg: No JPEG support in this PHP build " ) ;
RETURN_FALSE ;
# endif /* HAVE_GD_JPG */
}
/* }}} */
/* {{{ proto int imagecreatefrompng(string filename)
Create a new image from PNG file or URL */
PHP_FUNCTION ( imagecreatefrompng )
{
# ifdef HAVE_GD_PNG
2000-09-26 17:08:02 +08:00
_php_image_create_from ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_PNG , " PNG " , gdImageCreateFromPng , gdImageCreateFromPngCtx ) ;
2000-05-02 22:10:51 +08:00
# else /* HAVE_GD_PNG */
php_error ( E_WARNING , " ImageCreateFromPng: No PNG support in this PHP build " ) ;
RETURN_FALSE ;
# endif /* HAVE_GD_PNG */
1999-10-17 22:57:49 +08:00
}
/* }}} */
2000-06-07 08:37:49 +08:00
/* {{{ proto int imagecreatefromxbm(string filename)
Create a new image from XBM file or URL */
PHP_FUNCTION ( imagecreatefromxbm )
1999-12-18 05:50:07 +08:00
{
2000-06-07 08:37:49 +08:00
# ifdef HAVE_GD_XBM
2000-09-26 17:08:02 +08:00
_php_image_create_from ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_XBM , " XBM " , gdImageCreateFromXbm , NULL ) ;
2000-06-07 08:37:49 +08:00
# else /* HAVE_GD_XBM */
php_error ( E_WARNING , " ImageCreateFromXbm: No XBM support in this PHP build " ) ;
RETURN_FALSE ;
# endif /* HAVE_GD_XBM */
}
/* }}} */
2000-06-26 01:55:13 +08:00
/* {{{ todo int imagecreatefromxpm(string filename)
2000-06-07 08:37:49 +08:00
Create a new image from XPM file or URL */
PHP_FUNCTION ( imagecreatefromxpm )
{
/*
# ifdef HAVE_GD_XPM
2000-09-26 17:08:02 +08:00
_php_image_create_from ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_XPM , " XPM " , gdImageCreateFromXpm , NULL ) ;
2000-06-07 08:37:49 +08:00
# else
*/
php_error ( E_WARNING , " ImageCreateFromXpm: No XPM support in this PHP build " ) ;
RETURN_FALSE ;
/*
# endif
*/
}
/* }}} */
2000-06-25 09:44:15 +08:00
/* {{{ proto int imagecreatefromwbmp(string filename)
Create a new image from WBMP file or URL */
PHP_FUNCTION ( imagecreatefromwbmp )
{
# ifdef HAVE_GD_WBMP
2000-09-26 17:08:02 +08:00
_php_image_create_from ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_WBM , " WBMP " , gdImageCreateFromWBMP , gdImageCreateFromWBMPCtx ) ;
2000-06-25 09:44:15 +08:00
# else /* HAVE_GD_WBMP */
php_error ( E_WARNING , " ImageCreateFromWBMP: No WBMP support in this PHP build " ) ;
RETURN_FALSE ;
# endif /* HAVE_GD_WBMP */
}
/* }}} */
2000-06-08 07:04:39 +08:00
static void _php_image_output ( INTERNAL_FUNCTION_PARAMETERS , int image_type , char * tn , void ( * func_p ) ( ) ) {
2000-06-07 08:37:49 +08:00
zval * * imgind , * * file , * * quality ;
2000-02-29 00:52:03 +08:00
gdImagePtr im ;
2000-06-08 07:04:39 +08:00
char * fn = NULL ;
2000-02-29 00:52:03 +08:00
FILE * fp ;
int argc ;
2000-06-07 08:37:49 +08:00
int output = 1 , q = - 1 ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
2000-06-06 03:47:54 +08:00
argc = ZEND_NUM_ARGS ( ) ;
2000-06-07 08:37:49 +08:00
if ( argc < 1 | | argc > 3 | | zend_get_parameters_ex ( argc , & imgind , & file , & quality ) = = FAILURE ) {
2000-02-29 00:52:03 +08:00
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
2000-06-08 07:04:39 +08:00
if ( argc > 1 ) {
convert_to_string_ex ( file ) ;
fn = Z_STRVAL_PP ( file ) ;
if ( argc = = 3 ) {
convert_to_long_ex ( quality ) ;
q = Z_LVAL_PP ( quality ) ;
}
2000-06-07 08:37:49 +08:00
}
2000-06-08 07:04:39 +08:00
if ( ( argc = = 2 ) | | ( argc = = 3 & & Z_STRLEN_PP ( file ) ) ) {
2000-02-29 00:52:03 +08:00
if ( ! fn | | fn = = empty_string | | php_check_open_basedir ( fn ) ) {
2000-06-08 07:04:39 +08:00
php_error ( E_WARNING , " %s: invalid filename '%s' " , get_active_function_name ( ) , fn ) ;
2000-02-29 00:52:03 +08:00
RETURN_FALSE ;
}
2000-04-15 22:20:01 +08:00
fp = V_FOPEN ( fn , " wb " ) ;
2000-02-29 00:52:03 +08:00
if ( ! fp ) {
2000-06-08 07:04:39 +08:00
php_error ( E_WARNING , " %s: unable to open '%s' for writing " , get_active_function_name ( ) , fn ) ;
2000-02-29 00:52:03 +08:00
RETURN_FALSE ;
}
2000-06-07 08:37:49 +08:00
if ( image_type = = PHP_GDIMG_TYPE_JPG ) {
( * func_p ) ( im , fp , q ) ;
} else {
( * func_p ) ( im , fp ) ;
}
2000-02-29 00:52:03 +08:00
fflush ( fp ) ;
fclose ( fp ) ;
2000-06-07 08:37:49 +08:00
} else {
2000-02-29 00:52:03 +08:00
int b ;
FILE * tmp ;
char buf [ 4096 ] ;
2000-06-08 07:04:39 +08:00
2000-02-29 00:52:03 +08:00
tmp = tmpfile ( ) ;
if ( tmp = = NULL ) {
2000-06-08 07:04:39 +08:00
php_error ( E_WARNING , " %s: unable to open temporary file " , get_active_function_name ( ) ) ;
2000-02-29 00:52:03 +08:00
RETURN_FALSE ;
}
output = php_header ( ) ;
if ( output ) {
2000-06-07 08:37:49 +08:00
if ( image_type = = PHP_GDIMG_TYPE_JPG ) {
2000-06-08 07:04:39 +08:00
( * func_p ) ( im , tmp , q ) ;
2000-06-07 08:37:49 +08:00
} else {
2000-06-08 07:04:39 +08:00
( * func_p ) ( im , tmp ) ;
2000-06-07 08:37:49 +08:00
}
1999-10-17 22:57:49 +08:00
fseek ( tmp , 0 , SEEK_SET ) ;
# if APACHE && defined(CHARSET_EBCDIC)
2000-02-29 00:52:03 +08:00
SLS_FETCH ( ) ;
1999-10-17 22:57:49 +08:00
/* This is a binary file already: avoid EBCDIC->ASCII conversion */
ap_bsetflag ( php3_rqst - > connection - > client , B_EBCDIC2ASCII , 0 ) ;
# endif
while ( ( b = fread ( buf , 1 , sizeof ( buf ) , tmp ) ) > 0 ) {
1999-12-18 03:16:50 +08:00
php_write ( buf , b ) ;
1999-10-17 22:57:49 +08:00
}
}
fclose ( tmp ) ;
/* the temporary file is automatically deleted */
2000-06-07 08:37:49 +08:00
}
1999-10-17 22:57:49 +08:00
RETURN_TRUE ;
2000-06-07 08:37:49 +08:00
}
2000-06-08 07:04:39 +08:00
/* {{{ proto int imagegif(int im [, string filename])
Output GIF image to browser or file */
PHP_FUNCTION ( imagegif )
{
# ifdef HAVE_GD_GIF
_php_image_output ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_GIF , " GIF " , gdImageGif ) ;
# else /* HAVE_GD_GIF */
php_error ( E_WARNING , " ImageGif: No GIF support in this PHP build " ) ;
RETURN_FALSE ;
# endif /* HAVE_GD_GIF */
}
/* }}} */
2000-06-07 08:37:49 +08:00
/* {{{ proto int imagepng(int im [, string filename])
Output PNG image to browser or file */
PHP_FUNCTION ( imagepng )
{
# ifdef HAVE_GD_PNG
2000-06-08 07:04:39 +08:00
_php_image_output ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_PNG , " PNG " , gdImagePng ) ;
2000-05-02 22:10:51 +08:00
# else /* HAVE_GD_PNG */
php_error ( E_WARNING , " ImagePng: No PNG support in this PHP build " ) ;
RETURN_FALSE ;
# endif /* HAVE_GD_PNG */
1999-10-17 22:57:49 +08:00
}
/* }}} */
2000-06-07 08:37:49 +08:00
/* {{{ proto int imagejpeg(int im [, string filename [, int quality]])
Output JPEG image to browser or file */
PHP_FUNCTION ( imagejpeg )
2000-03-13 13:58:50 +08:00
{
2000-05-02 22:10:51 +08:00
# ifdef HAVE_GD_JPG
2000-06-08 07:04:39 +08:00
_php_image_output ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_JPG , " JPEG " , gdImageJpeg ) ;
2000-05-02 22:10:51 +08:00
# else /* HAVE_GD_JPG */
2000-06-07 08:37:49 +08:00
php_error ( E_WARNING , " ImageJpeg: No JPG support in this PHP build " ) ;
2000-05-02 22:10:51 +08:00
RETURN_FALSE ;
# endif /* HAVE_GD_JPG */
2000-03-13 13:58:50 +08:00
}
/* }}} */
2000-06-07 08:37:49 +08:00
/* {{{ proto int imagewbmp(int im [, string filename])
Output WBMP image to browser or file */
PHP_FUNCTION ( imagewbmp )
2000-03-13 13:58:50 +08:00
{
2000-06-08 07:04:39 +08:00
_php_image_output ( INTERNAL_FUNCTION_PARAM_PASSTHRU , PHP_GDIMG_TYPE_WBM , " WBMP " , _php_image_output_wbmp ) ;
2000-06-07 08:37:49 +08:00
}
/* }}} */
2000-03-13 13:58:50 +08:00
2000-06-07 08:37:49 +08:00
/* {{{ _php_image_output_wbmp(gdImagePtr im, FILE *fp)
*/
static void _php_image_output_wbmp ( gdImagePtr im , FILE * fp )
{
int x , y ;
int c , p , width , height ;
/* WBMP header, black and white, no compression */
fputc ( 0 , fp ) ; fputc ( 0 , fp ) ;
/* Width and height of image */
c = 1 ; width = im - > sx ;
while ( width & 0x7f < < 7 * c ) c + + ;
while ( c > 1 ) fputc ( 0x80 | ( ( width > > 7 * - - c ) & 0xff ) , fp ) ;
fputc ( width & 0x7f , fp ) ;
c = 1 ; height = im - > sy ;
while ( height & 0x7f < < 7 * c ) c + + ;
while ( c > 1 ) fputc ( 0x80 | ( ( height > > 7 * - - c ) & 0xff ) , fp ) ;
fputc ( height & 0x7f , fp ) ;
/* Actual image data */
for ( y = 0 ; y < im - > sy ; y + + ) {
p = c = 0 ;
for ( x = 0 ; x < im - > sx ; x + + ) {
# if HAVE_GD_ANCIENT
if ( im - > pixels [ x ] [ y ] = = 0 ) c = c | ( 1 < < ( 7 - p ) ) ;
# else
if ( im - > pixels [ y ] [ x ] = = 0 ) c = c | ( 1 < < ( 7 - p ) ) ;
# endif
if ( + + p = = 8 ) {
fputc ( c , fp ) ;
p = c = 0 ;
}
2000-03-13 13:58:50 +08:00
}
2000-06-07 08:37:49 +08:00
if ( p ) fputc ( c , fp ) ;
2000-03-13 13:58:50 +08:00
}
}
/* }}} */
1999-04-16 20:15:38 +08:00
/* {{{ proto int imagedestroy(int im)
1999-11-25 06:04:49 +08:00
Destroy an image */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagedestroy )
{
2000-02-29 00:52:03 +08:00
zval * * imgind ;
gdImagePtr im ;
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & imgind ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
zend_list_delete ( ( * imgind ) - > value . lval ) ;
1999-04-16 20:15:38 +08:00
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto int imagecolorallocate(int im, int red, int green, int blue)
1999-11-25 06:04:49 +08:00
Allocate a color for an image */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolorallocate )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * red , * * green , * * blue ;
1999-04-16 20:15:38 +08:00
int col ;
int r , g , b ;
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 4 | | zend_get_parameters_ex ( 4 , & imgind , & red ,
1999-04-16 20:15:38 +08:00
& green , & blue ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( red ) ;
convert_to_long_ex ( green ) ;
convert_to_long_ex ( blue ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
r = ( * red ) - > value . lval ;
g = ( * green ) - > value . lval ;
b = ( * blue ) - > value . lval ;
1999-04-16 20:15:38 +08:00
col = gdImageColorAllocate ( im , r , g , b ) ;
RETURN_LONG ( col ) ;
}
/* }}} */
2000-06-25 10:55:31 +08:00
/* {{{ proto int imagepalettecopy(int dst, int src)
Copy the palette from the src image onto the dst image */
PHP_FUNCTION ( imagepalettecopy )
{
2000-06-26 20:23:02 +08:00
# if HAVE_LIBGD15
2000-06-25 10:55:31 +08:00
zval * * dstim , * * srcim ;
gdImagePtr dst , src ;
if ( ZEND_NUM_ARGS ( ) ! = 2 | |
zend_get_parameters_ex ( 2 , & dstim , & srcim ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( dst , gdImagePtr , dstim , - 1 , " Image " , GDG ( le_gd ) ) ;
ZEND_FETCH_RESOURCE ( src , gdImagePtr , srcim , - 1 , " Image " , GDG ( le_gd ) ) ;
gdImagePaletteCopy ( dst , src ) ;
2000-06-25 11:26:49 +08:00
# else
php_error ( E_WARNING , " Sorry ImagePaletteCopy was introduced in GD version 1.5 " ) ;
RETURN_FALSE ;
# endif
2000-06-25 10:55:31 +08:00
}
/* }}} */
1999-04-16 20:15:38 +08:00
/* im, x, y */
/* {{{ proto int imagecolorat(int im, int x, int y)
1999-11-25 06:04:49 +08:00
Get the index of the color of a pixel */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolorat )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * x , * * y ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 3 | | zend_get_parameters_ex ( 3 , & imgind , & x , & y ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( x ) ;
convert_to_long_ex ( y ) ;
if ( gdImageBoundsSafe ( im , ( * x ) - > value . lval , ( * y ) - > value . lval ) ) {
1999-04-16 20:15:38 +08:00
# if HAVE_LIBGD13
2000-02-29 00:52:03 +08:00
RETURN_LONG ( im - > pixels [ ( * y ) - > value . lval ] [ ( * x ) - > value . lval ] ) ;
1999-04-16 20:15:38 +08:00
# else
2000-02-29 00:52:03 +08:00
RETURN_LONG ( im - > pixels [ ( * x ) - > value . lval ] [ ( * y ) - > value . lval ] ) ;
1999-04-16 20:15:38 +08:00
# endif
}
else {
RETURN_FALSE ;
}
}
/* }}} */
/* {{{ proto int imagecolorclosest(int im, int red, int green, int blue)
1999-11-25 06:04:49 +08:00
Get the index of the closest color to the specified color */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolorclosest )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * red , * * green , * * blue ;
1999-04-16 20:15:38 +08:00
int col ;
int r , g , b ;
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 4 | | zend_get_parameters_ex ( 4 , & imgind , & red ,
2000-02-29 00:52:03 +08:00
& green , & blue ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( red ) ;
convert_to_long_ex ( green ) ;
convert_to_long_ex ( blue ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
r = ( * red ) - > value . lval ;
g = ( * green ) - > value . lval ;
b = ( * blue ) - > value . lval ;
1999-04-16 20:15:38 +08:00
col = gdImageColorClosest ( im , r , g , b ) ;
RETURN_LONG ( col ) ;
}
/* }}} */
2000-06-25 10:55:31 +08:00
/* {{{ proto int imagecolorclosesthwb(int im, int red, int green, int blue)
Get the index of the color which has the hue , white and blackness nearest to the given color */
PHP_FUNCTION ( imagecolorclosesthwb )
{
2000-06-26 23:23:52 +08:00
# if HAVE_COLORCLOSESTHWB
2000-06-25 10:55:31 +08:00
zval * * imgind , * * r , * * g , * * b ;
int col ;
gdImagePtr im ;
GDLS_FETCH ( ) ;
if ( ZEND_NUM_ARGS ( ) ! = 4 | |
zend_get_parameters_ex ( 4 , & imgind , & r , & g , & b ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( r ) ;
convert_to_long_ex ( g ) ;
convert_to_long_ex ( b ) ;
col = gdImageColorClosestHWB ( im , Z_LVAL_PP ( r ) , Z_LVAL_PP ( g ) , Z_LVAL_PP ( b ) ) ;
RETURN_LONG ( col ) ;
2000-06-25 11:26:49 +08:00
# else
php_error ( E_WARNING , " ImageColorClosestHWB functionality was added in GD 1.8 " ) ;
RETURN_FALSE ;
# endif
2000-06-25 10:55:31 +08:00
}
/* }}} */
1999-04-16 20:15:38 +08:00
/* {{{ proto int imagecolordeallocate(int im, int index)
1999-11-25 06:04:49 +08:00
De - allocate a color for an image */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolordeallocate )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * index ;
int col ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & imgind , & index ) = = FAILURE ) {
2000-02-29 00:52:03 +08:00
WRONG_PARAM_COUNT ;
1999-04-16 20:15:38 +08:00
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( index ) ;
col = ( * index ) - > value . lval ;
1999-04-16 20:15:38 +08:00
if ( col > = 0 & & col < gdImageColorsTotal ( im ) ) {
gdImageColorDeallocate ( im , col ) ;
RETURN_TRUE ;
2000-02-29 00:52:03 +08:00
}
else {
php_error ( E_WARNING , " Color index out of range " ) ;
RETURN_FALSE ;
}
1999-04-16 20:15:38 +08:00
}
/* }}} */
/* {{{ proto int imagecolorresolve(int im, int red, int green, int blue)
1999-11-25 06:04:49 +08:00
Get the index of the specified color or its closest possible alternative */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolorresolve )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * red , * * green , * * blue ;
1999-04-16 20:15:38 +08:00
int col ;
int r , g , b ;
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 4 | | zend_get_parameters_ex ( 4 , & imgind , & red ,
2000-02-29 00:52:03 +08:00
& green , & blue ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( red ) ;
convert_to_long_ex ( green ) ;
convert_to_long_ex ( blue ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
r = ( * red ) - > value . lval ;
g = ( * green ) - > value . lval ;
b = ( * blue ) - > value . lval ;
1999-04-16 20:15:38 +08:00
col = gdImageColorResolve ( im , r , g , b ) ;
RETURN_LONG ( col ) ;
}
/* }}} */
/* {{{ proto int imagecolorexact(int im, int red, int green, int blue)
1999-11-25 06:04:49 +08:00
Get the index of the specified color */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolorexact )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * red , * * green , * * blue ;
1999-04-16 20:15:38 +08:00
int col ;
int r , g , b ;
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 4 | | zend_get_parameters_ex ( 4 , & imgind , & red ,
2000-02-29 00:52:03 +08:00
& green , & blue ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( red ) ;
convert_to_long_ex ( green ) ;
convert_to_long_ex ( blue ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
r = ( * red ) - > value . lval ;
g = ( * green ) - > value . lval ;
b = ( * blue ) - > value . lval ;
1999-04-16 20:15:38 +08:00
col = gdImageColorExact ( im , r , g , b ) ;
RETURN_LONG ( col ) ;
}
/* }}} */
/* {{{ proto int imagecolorset(int im, int col, int red, int green, int blue)
1999-11-25 06:04:49 +08:00
Set the color for the specified palette index */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolorset )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * color , * * red , * * green , * * blue ;
1999-04-16 20:15:38 +08:00
int col ;
int r , g , b ;
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 5 | | zend_get_parameters_ex ( 5 , & imgind , & color , & red , & green , & blue ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( color ) ;
convert_to_long_ex ( red ) ;
convert_to_long_ex ( green ) ;
convert_to_long_ex ( blue ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
col = ( * color ) - > value . lval ;
r = ( * red ) - > value . lval ;
g = ( * green ) - > value . lval ;
b = ( * blue ) - > value . lval ;
1999-04-16 20:15:38 +08:00
if ( col > = 0 & & col < gdImageColorsTotal ( im ) ) {
im - > red [ col ] = r ;
im - > green [ col ] = g ;
im - > blue [ col ] = b ;
}
else {
RETURN_FALSE ;
}
}
/* }}} */
/* {{{ proto array imagecolorsforindex(int im, int col)
1999-11-25 06:04:49 +08:00
Get the colors for an index */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolorsforindex )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * index ;
int col ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & imgind , & index ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( index ) ;
col = ( * index ) - > value . lval ;
1999-04-16 20:15:38 +08:00
if ( col > = 0 & & col < gdImageColorsTotal ( im ) ) {
if ( array_init ( return_value ) = = FAILURE ) {
RETURN_FALSE ;
}
add_assoc_long ( return_value , " red " , im - > red [ col ] ) ;
add_assoc_long ( return_value , " green " , im - > green [ col ] ) ;
add_assoc_long ( return_value , " blue " , im - > blue [ col ] ) ;
}
else {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " Color index out of range " ) ;
1999-04-16 20:15:38 +08:00
RETURN_FALSE ;
}
}
/* }}} */
2000-05-24 06:28:07 +08:00
/* {{{ proto int imagegammacorrect(int im, double inputgamma, double outputgamma)
Apply a gamma correction to a GD image */
2000-05-14 23:25:13 +08:00
PHP_FUNCTION ( imagegammacorrect )
{
zval * * IM , * * inputgamma , * * outputgamma ;
gdImagePtr im ;
int i ;
GDLS_FETCH ( ) ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 3 | |
2000-05-14 23:25:13 +08:00
zend_get_parameters_ex ( 3 , & IM , & inputgamma , & outputgamma ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
convert_to_double_ex ( inputgamma ) ;
convert_to_double_ex ( outputgamma ) ;
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
for ( i = 0 ; i < gdImageColorsTotal ( im ) ; i + + ) {
im - > red [ i ] = ( int ) ( ( pow ( ( pow ( ( im - > red [ i ] / 255.0 ) , ( * inputgamma ) - > value . dval ) ) , 1.0 / ( * outputgamma ) - > value . dval ) * 255 ) + .5 ) ;
im - > green [ i ] = ( int ) ( ( pow ( ( pow ( ( im - > green [ i ] / 255.0 ) , ( * inputgamma ) - > value . dval ) ) , 1.0 / ( * outputgamma ) - > value . dval ) * 255 ) + .5 ) ;
im - > blue [ i ] = ( int ) ( ( pow ( ( pow ( ( im - > blue [ i ] / 255.0 ) , ( * inputgamma ) - > value . dval ) ) , 1.0 / ( * outputgamma ) - > value . dval ) * 255 ) + .5 ) ;
}
RETURN_TRUE ;
}
2000-05-24 06:28:07 +08:00
/* }}} */
2000-05-14 23:25:13 +08:00
1999-04-16 20:15:38 +08:00
/* {{{ proto int imagesetpixel(int im, int x, int y, int col)
1999-11-25 06:04:49 +08:00
Set a single pixel */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagesetpixel )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * xarg , * * yarg , * * colarg ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col , y , x ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 4 | |
2000-05-14 23:25:13 +08:00
zend_get_parameters_ex ( 4 , & imgind , & xarg , & yarg , & colarg ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( xarg ) ;
convert_to_long_ex ( yarg ) ;
convert_to_long_ex ( colarg ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
col = ( * colarg ) - > value . lval ;
y = ( * yarg ) - > value . lval ;
x = ( * xarg ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageSetPixel ( im , x , y , col ) ;
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto int imageline(int im, int x1, int y1, int x2, int y2, int col)
1999-11-25 06:04:49 +08:00
Draw a line */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imageline )
{
2000-02-29 00:52:03 +08:00
zval * * IM , * * COL , * * X1 , * * Y1 , * * X2 , * * Y2 ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col , y2 , x2 , y1 , x1 ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 6 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 6 , & IM , & X1 , & Y1 , & X2 , & Y2 , & COL ) = = FAILURE )
1999-04-16 20:15:38 +08:00
{
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( X1 ) ;
convert_to_long_ex ( Y1 ) ;
convert_to_long_ex ( X2 ) ;
convert_to_long_ex ( Y2 ) ;
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
x1 = ( * X1 ) - > value . lval ;
y1 = ( * Y1 ) - > value . lval ;
x2 = ( * X2 ) - > value . lval ;
y2 = ( * Y2 ) - > value . lval ;
col = ( * COL ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageLine ( im , x1 , y1 , x2 , y2 , col ) ;
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto int imagedashedline(int im, int x1, int y1, int x2, int y2, int col)
1999-11-25 06:04:49 +08:00
Draw a dashed line */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagedashedline )
{
2000-02-29 00:52:03 +08:00
zval * * IM , * * COL , * * X1 , * * Y1 , * * X2 , * * Y2 ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col , y2 , x2 , y1 , x1 ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 6 | | zend_get_parameters_ex ( 6 , & IM , & X1 , & Y1 , & X2 , & Y2 , & COL ) = = FAILURE )
1999-04-16 20:15:38 +08:00
{
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( X1 ) ;
convert_to_long_ex ( Y1 ) ;
convert_to_long_ex ( X2 ) ;
convert_to_long_ex ( Y2 ) ;
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
x1 = ( * X1 ) - > value . lval ;
y1 = ( * Y1 ) - > value . lval ;
x2 = ( * X2 ) - > value . lval ;
y2 = ( * Y2 ) - > value . lval ;
col = ( * COL ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageDashedLine ( im , x1 , y1 , x2 , y2 , col ) ;
RETURN_TRUE ;
}
/* }}} */
/* im, x1, y1, x2, y2, col */
/* {{{ proto int imagerectangle(int im, int x1, int y1, int x2, int y2, int col)
1999-11-25 06:04:49 +08:00
Draw a rectangle */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagerectangle )
{
2000-02-29 00:52:03 +08:00
zval * * IM , * * COL , * * X1 , * * Y1 , * * X2 , * * Y2 ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col , y2 , x2 , y1 , x1 ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 6 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 6 , & IM , & X1 , & Y1 , & X2 , & Y2 , & COL ) = = FAILURE )
1999-04-16 20:15:38 +08:00
{
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( IM ) ;
convert_to_long_ex ( X1 ) ;
convert_to_long_ex ( Y1 ) ;
convert_to_long_ex ( X2 ) ;
convert_to_long_ex ( Y2 ) ;
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
x1 = ( * X1 ) - > value . lval ;
y1 = ( * Y1 ) - > value . lval ;
x2 = ( * X2 ) - > value . lval ;
y2 = ( * Y2 ) - > value . lval ;
col = ( * COL ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageRectangle ( im , x1 , y1 , x2 , y2 , col ) ;
RETURN_TRUE ;
}
/* }}} */
/* im, x1, y1, x2, y2, col */
/* {{{ proto int imagefilledrectangle(int im, int x1, int y1, int x2, int y2, int col)
1999-11-25 06:04:49 +08:00
Draw a filled rectangle */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagefilledrectangle )
{
2000-02-29 00:52:03 +08:00
zval * * IM , * * COL , * * X1 , * * Y1 , * * X2 , * * Y2 ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col , y2 , x2 , y1 , x1 ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 6 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 6 , & IM , & X1 , & Y1 , & X2 , & Y2 , & COL ) = = FAILURE )
1999-04-16 20:15:38 +08:00
{
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( X1 ) ;
convert_to_long_ex ( Y1 ) ;
convert_to_long_ex ( X2 ) ;
convert_to_long_ex ( Y2 ) ;
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
x1 = ( * X1 ) - > value . lval ;
y1 = ( * Y1 ) - > value . lval ;
x2 = ( * X2 ) - > value . lval ;
y2 = ( * Y2 ) - > value . lval ;
col = ( * COL ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageFilledRectangle ( im , x1 , y1 , x2 , y2 , col ) ;
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto int imagearc(int im, int cx, int cy, int w, int h, int s, int e, int col)
1999-11-25 06:04:49 +08:00
Draw a partial ellipse */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagearc )
{
2000-02-29 00:52:03 +08:00
zval * * COL , * * E , * * ST , * * H , * * W , * * CY , * * CX , * * IM ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col , e , st , h , w , cy , cx ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 8 | |
2000-03-03 22:15:05 +08:00
zend_get_parameters_ex ( 8 , & IM , & CX , & CY , & W , & H , & ST , & E , & COL ) = = FAILURE )
1999-04-16 20:15:38 +08:00
{
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( CX ) ;
convert_to_long_ex ( CY ) ;
convert_to_long_ex ( W ) ;
convert_to_long_ex ( H ) ;
convert_to_long_ex ( ST ) ;
convert_to_long_ex ( E ) ;
convert_to_long_ex ( COL ) ;
col = ( * COL ) - > value . lval ;
e = ( * E ) - > value . lval ;
st = ( * ST ) - > value . lval ;
h = ( * H ) - > value . lval ;
w = ( * W ) - > value . lval ;
cy = ( * CY ) - > value . lval ;
cx = ( * CX ) - > value . lval ;
1999-04-16 20:15:38 +08:00
if ( e < 0 ) {
e % = 360 ;
}
if ( st < 0 ) {
st % = 360 ;
}
gdImageArc ( im , cx , cy , w , h , st , e , col ) ;
RETURN_TRUE ;
}
/* }}} */
/* im, x, y, border, col */
/* {{{ proto int imagefilltoborder(int im, int x, int y, int border, int col)
1999-11-25 06:04:49 +08:00
Flood fill to specific color */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagefilltoborder )
{
2000-02-29 00:52:03 +08:00
zval * * IM , * * X , * * Y , * * BORDER , * * COL ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col , border , y , x ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 5 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 5 , & IM , & X , & Y , & BORDER , & COL ) = = FAILURE )
1999-04-16 20:15:38 +08:00
{
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( X ) ;
convert_to_long_ex ( Y ) ;
convert_to_long_ex ( BORDER ) ;
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
col = ( * COL ) - > value . lval ;
border = ( * BORDER ) - > value . lval ;
y = ( * Y ) - > value . lval ;
x = ( * X ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageFillToBorder ( im , x , y , border , col ) ;
RETURN_TRUE ;
}
/* }}} */
/* im, x, y, col */
/* {{{ proto int imagefill(int im, int x, int y, int col)
1999-11-25 06:04:49 +08:00
Flood fill */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagefill )
{
2000-02-29 00:52:03 +08:00
zval * * IM , * * X , * * Y , * * COL ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col , y , x ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 4 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 4 , & IM , & X , & Y , & COL ) = = FAILURE )
1999-04-16 20:15:38 +08:00
{
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( X ) ;
convert_to_long_ex ( Y ) ;
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
col = ( * COL ) - > value . lval ;
y = ( * Y ) - > value . lval ;
x = ( * X ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageFill ( im , x , y , col ) ;
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto int imagecolorstotal(int im)
1999-11-25 06:04:49 +08:00
Find out the number of colors in an image ' s palette */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolorstotal )
{
2000-02-29 00:52:03 +08:00
zval * * IM ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & IM ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
RETURN_LONG ( gdImageColorsTotal ( im ) ) ;
}
/* }}} */
/* im, col */
/* {{{ proto int imagecolortransparent(int im [, int col])
1999-11-25 06:04:49 +08:00
Define a color as transparent */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecolortransparent )
{
2000-08-22 12:11:57 +08:00
zval * * IM , * * COL ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int col ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-16 20:15:38 +08:00
case 1 :
2000-02-29 00:52:03 +08:00
if ( zend_get_parameters_ex ( 1 , & IM ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
break ;
case 2 :
2000-02-29 00:52:03 +08:00
if ( zend_get_parameters_ex ( 2 , & IM , & COL ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
break ;
default :
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-08-22 12:11:57 +08:00
if ( ZEND_NUM_ARGS ( ) > 1 ) {
gdImageColorTransparent ( im , Z_LVAL_PP ( COL ) ) ;
1999-04-16 20:15:38 +08:00
}
col = gdImageGetTransparent ( im ) ;
RETURN_LONG ( col ) ;
}
/* }}} */
/* im, interlace */
/* {{{ proto int imageinterlace(int im [, int interlace])
1999-11-25 06:04:49 +08:00
Enable or disable interlace */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imageinterlace )
{
2000-02-29 00:52:03 +08:00
zval * * IM , * * INT = NULL ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int interlace ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
1999-04-16 20:15:38 +08:00
case 1 :
2000-02-29 00:52:03 +08:00
if ( zend_get_parameters_ex ( 1 , & IM ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
break ;
case 2 :
2000-02-29 00:52:03 +08:00
if ( zend_get_parameters_ex ( 2 , & IM , & INT ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( INT ) ;
1999-04-16 20:15:38 +08:00
break ;
default :
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
if ( ( * INT ) ! = NULL ) {
interlace = ( * INT ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageInterlace ( im , interlace ) ;
}
interlace = gdImageGetInterlaced ( im ) ;
RETURN_LONG ( interlace ) ;
}
/* }}} */
/* arg = 0 normal polygon
arg = 1 filled polygon */
/* im, points, num_points, col */
1999-12-18 05:50:07 +08:00
static void php_imagepolygon ( INTERNAL_FUNCTION_PARAMETERS , int filled ) {
2000-02-29 00:52:03 +08:00
zval * * IM , * * POINTS , * * NPOINTS , * * COL ;
pval * * var = NULL ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
2000-05-02 02:56:58 +08:00
gdPointPtr points ;
1999-04-16 20:15:38 +08:00
int npoints , col , nelem , i ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 4 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 4 , & IM , & POINTS , & NPOINTS , & COL ) = = FAILURE )
1999-04-16 20:15:38 +08:00
{
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( NPOINTS ) ;
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
npoints = ( * NPOINTS ) - > value . lval ;
col = ( * COL ) - > value . lval ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
if ( ( * POINTS ) - > type ! = IS_ARRAY ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " 2nd argument to imagepolygon not an array " ) ;
1999-04-16 20:15:38 +08:00
RETURN_FALSE ;
}
/*
* * we shouldn ' t need this check , should we ? * *
if ( ! ParameterPassedByReference ( ht , 2 ) ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " 2nd argument to imagepolygon not passed by reference " ) ;
1999-04-16 20:15:38 +08:00
RETURN_FALSE ;
}
*/
2000-02-29 00:52:03 +08:00
nelem = zend_hash_num_elements ( ( * POINTS ) - > value . ht ) ;
1999-04-16 20:15:38 +08:00
if ( nelem < 6 ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING ,
1999-04-16 20:15:38 +08:00
" you must have at least 3 points in your array " ) ;
RETURN_FALSE ;
}
if ( nelem < npoints * 2 ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING ,
1999-04-16 20:15:38 +08:00
" trying to use %d points in array with only %d points " ,
npoints , nelem / 2 ) ;
RETURN_FALSE ;
}
2000-05-02 02:56:58 +08:00
points = ( gdPointPtr ) emalloc ( npoints * sizeof ( gdPoint ) ) ;
1999-04-16 20:15:38 +08:00
for ( i = 0 ; i < npoints ; i + + ) {
2000-02-29 00:52:03 +08:00
if ( zend_hash_index_find ( ( * POINTS ) - > value . ht , ( i * 2 ) , ( void * * ) & var ) = = SUCCESS ) {
SEPARATE_ZVAL ( ( var ) ) ;
1999-07-24 00:03:18 +08:00
convert_to_long ( * var ) ;
points [ i ] . x = ( * var ) - > value . lval ;
1999-04-16 20:15:38 +08:00
}
2000-02-29 00:52:03 +08:00
if ( zend_hash_index_find ( ( * POINTS ) - > value . ht , ( i * 2 ) + 1 , ( void * * ) & var ) = = SUCCESS ) {
1999-07-24 00:03:18 +08:00
SEPARATE_ZVAL ( var ) ;
convert_to_long ( * var ) ;
points [ i ] . y = ( * var ) - > value . lval ;
1999-04-16 20:15:38 +08:00
}
}
if ( filled ) {
gdImageFilledPolygon ( im , points , npoints , col ) ;
}
else {
gdImagePolygon ( im , points , npoints , col ) ;
}
2000-05-02 02:56:58 +08:00
efree ( points ) ;
1999-04-16 20:15:38 +08:00
RETURN_TRUE ;
}
/* {{{ proto int imagepolygon(int im, array point, int num_points, int col)
1999-11-25 06:04:49 +08:00
Draw a polygon */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagepolygon )
1999-04-16 20:15:38 +08:00
{
1999-12-18 05:50:07 +08:00
php_imagepolygon ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
/* {{{ proto int imagefilledpolygon(int im, array point, int num_points, int col)
1999-11-25 06:04:49 +08:00
Draw a filled polygon */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagefilledpolygon )
1999-04-16 20:15:38 +08:00
{
1999-12-18 05:50:07 +08:00
php_imagepolygon ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
1999-12-18 05:50:07 +08:00
static gdFontPtr php_find_gd_font ( int size )
1999-04-16 20:15:38 +08:00
{
gdFontPtr font ;
int ind_type ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
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 :
1999-12-18 03:51:39 +08:00
font = zend_list_find ( size - 5 , & ind_type ) ;
2000-02-29 00:52:03 +08:00
if ( ! font | | ind_type ! = GDG ( le_gd_font ) ) {
1999-04-16 20:15:38 +08:00
if ( size < 1 ) {
font = gdFontTiny ;
} else {
font = gdFontGiant ;
}
}
break ;
}
return font ;
}
/*
* arg = 0 ImageFontWidth
* arg = 1 ImageFontHeight
*/
1999-12-18 05:50:07 +08:00
static void php_imagefontsize ( INTERNAL_FUNCTION_PARAMETERS , int arg )
1999-04-16 20:15:38 +08:00
{
pval * SIZE ;
gdFontPtr font ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters ( ht , 1 , & SIZE ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
convert_to_long ( SIZE ) ;
1999-12-18 05:50:07 +08:00
font = php_find_gd_font ( SIZE - > value . lval ) ;
1999-04-16 20:15:38 +08:00
RETURN_LONG ( arg ? font - > h : font - > w ) ;
}
/* {{{ proto int imagefontwidth(int font)
1999-11-25 06:04:49 +08:00
Get font width */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagefontwidth )
1999-04-16 20:15:38 +08:00
{
1999-12-18 05:50:07 +08:00
php_imagefontsize ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
/* {{{ proto int imagefontheight(int font)
2000-01-25 04:25:57 +08:00
Get font height */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagefontheight )
1999-04-16 20:15:38 +08:00
{
1999-12-18 05:50:07 +08:00
php_imagefontsize ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
/* workaround for a bug in gd 1.2 */
1999-12-18 05:50:07 +08:00
void php_gdimagecharup ( gdImagePtr im , gdFontPtr f , int x , int y , int c ,
1999-04-16 20:15:38 +08:00
int color )
{
int cx , cy , px , py , fline ;
cx = 0 ;
cy = 0 ;
if ( ( c < f - > offset ) | | ( c > = ( f - > offset + f - > nchars ) ) ) {
return ;
}
fline = ( c - f - > offset ) * f - > h * f - > w ;
for ( py = y ; ( py > ( y - f - > w ) ) ; py - - ) {
for ( px = x ; ( px < ( x + f - > h ) ) ; px + + ) {
if ( f - > data [ fline + cy * f - > w + cx ] ) {
gdImageSetPixel ( im , px , py , color ) ;
}
cy + + ;
}
cy = 0 ;
cx + + ;
}
}
/*
* arg = 0 ImageChar
* arg = 1 ImageCharUp
* arg = 2 ImageString
* arg = 3 ImageStringUp
*/
1999-12-18 05:50:07 +08:00
static void php_imagechar ( INTERNAL_FUNCTION_PARAMETERS , int mode ) {
2000-02-29 00:52:03 +08:00
zval * * IM , * * SIZE , * * X , * * Y , * * C , * * COL ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
int ch = 0 , col , x , y , size , i , l = 0 ;
2000-02-09 06:21:43 +08:00
unsigned char * str = NULL ;
1999-04-16 20:15:38 +08:00
gdFontPtr font ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 6 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 6 , & IM , & SIZE , & X , & Y , & C , & COL ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( SIZE ) ;
convert_to_long_ex ( X ) ;
convert_to_long_ex ( Y ) ;
convert_to_string_ex ( C ) ;
convert_to_long_ex ( COL ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
col = ( * COL ) - > value . lval ;
1999-04-16 20:15:38 +08:00
if ( mode < 2 ) {
2000-02-29 00:52:03 +08:00
ch = ( int ) ( ( unsigned char ) * ( ( * C ) - > value . str . val ) ) ;
1999-04-16 20:15:38 +08:00
} else {
2000-02-29 00:52:03 +08:00
str = ( unsigned char * ) estrndup ( ( * C ) - > value . str . val , ( * C ) - > value . str . len ) ;
2000-02-09 06:21:43 +08:00
l = strlen ( str ) ;
1999-04-16 20:15:38 +08:00
}
2000-02-29 00:52:03 +08:00
y = ( * Y ) - > value . lval ;
x = ( * X ) - > value . lval ;
size = ( * SIZE ) - > value . lval ;
1999-04-16 20:15:38 +08:00
1999-12-18 05:50:07 +08:00
font = php_find_gd_font ( size ) ;
1999-04-16 20:15:38 +08:00
switch ( mode ) {
case 0 :
gdImageChar ( im , font , x , y , ch , col ) ;
break ;
case 1 :
1999-12-18 05:50:07 +08:00
php_gdimagecharup ( im , font , x , y , ch , col ) ;
1999-04-16 20:15:38 +08:00
break ;
case 2 :
for ( i = 0 ; ( i < l ) ; i + + ) {
2000-02-09 06:21:43 +08:00
gdImageChar ( im , font , x , y , ( int ) ( ( unsigned char ) str [ i ] ) ,
1999-04-16 20:15:38 +08:00
col ) ;
x + = font - > w ;
}
break ;
case 3 : {
for ( i = 0 ; ( i < l ) ; i + + ) {
2000-02-09 06:21:43 +08:00
/* php_gdimagecharup(im, font, x, y, (int)str[i], col); */
gdImageCharUp ( im , font , x , y , ( int ) str [ i ] , col ) ;
1999-04-16 20:15:38 +08:00
y - = font - > w ;
}
break ;
}
}
2000-02-09 06:21:43 +08:00
if ( str ) {
efree ( str ) ;
1999-04-16 20:15:38 +08:00
}
RETURN_TRUE ;
}
/* {{{ proto int imagechar(int im, int font, int x, int y, string c, int col)
1999-11-25 06:04:49 +08:00
Draw a character */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagechar ) {
1999-12-18 05:50:07 +08:00
php_imagechar ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
/* {{{ proto int imagecharup(int im, int font, int x, int y, string c, int col)
1999-11-25 06:04:49 +08:00
Draw a character rotated 90 degrees counter - clockwise */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagecharup ) {
1999-12-18 05:50:07 +08:00
php_imagechar ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
/* {{{ proto int imagestring(int im, int font, int x, int y, string str, int col)
1999-11-25 06:04:49 +08:00
Draw a string horizontally */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagestring ) {
1999-12-18 05:50:07 +08:00
php_imagechar ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 2 ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
/* {{{ proto int imagestringup(int im, int font, int x, int y, string str, int col)
1999-11-25 06:04:49 +08:00
Draw a string vertically - rotated 90 degrees counter - clockwise */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagestringup ) {
1999-12-18 05:50:07 +08:00
php_imagechar ( INTERNAL_FUNCTION_PARAM_PASSTHRU , 3 ) ;
1999-04-16 20:15:38 +08:00
}
/* }}} */
2000-03-14 04:36:59 +08:00
/* {{{ proto int imagecopy(int dst_im, int src_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h)
1999-11-25 06:04:49 +08:00
Copy part of an image */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagecopy )
1999-04-16 20:15:38 +08:00
{
2000-02-29 00:52:03 +08:00
zval * * SIM , * * DIM , * * SX , * * SY , * * SW , * * SH , * * DX , * * DY ;
1999-04-16 20:15:38 +08:00
gdImagePtr im_dst ;
gdImagePtr im_src ;
int srcH , srcW , srcY , srcX , dstY , dstX ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 8 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 8 , & DIM , & SIM , & DX , & DY , & SX , & SY , & SW , & SH )
1999-04-16 20:15:38 +08:00
= = FAILURE ) {
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im_src , gdImagePtr , SIM , - 1 , " Image " , GDG ( le_gd ) ) ;
ZEND_FETCH_RESOURCE ( im_dst , gdImagePtr , DIM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( SX ) ;
convert_to_long_ex ( SY ) ;
convert_to_long_ex ( SW ) ;
convert_to_long_ex ( SH ) ;
convert_to_long_ex ( DX ) ;
convert_to_long_ex ( DY ) ;
srcX = ( * SX ) - > value . lval ;
srcY = ( * SY ) - > value . lval ;
srcH = ( * SH ) - > value . lval ;
srcW = ( * SW ) - > value . lval ;
dstX = ( * DX ) - > value . lval ;
dstY = ( * DY ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageCopy ( im_dst , im_src , dstX , dstY , srcX , srcY , srcW , srcH ) ;
RETURN_TRUE ;
}
/* }}} */
2000-06-25 11:06:38 +08:00
/* {{{ proto int imagecopymerge(int src_im, int dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct)
2000-06-25 18:59:42 +08:00
Merge one part of an image with another */
2000-06-25 10:55:31 +08:00
PHP_FUNCTION ( imagecopymerge )
{
2000-06-26 20:23:02 +08:00
# if HAVE_LIBGD15
2000-06-25 10:55:31 +08:00
zval * * SIM , * * DIM , * * SX , * * SY , * * SW , * * SH , * * DX , * * DY , * * PCT ;
gdImagePtr im_dst ;
gdImagePtr im_src ;
int srcH , srcW , srcY , srcX , dstY , dstX , pct ;
GDLS_FETCH ( ) ;
if ( ZEND_NUM_ARGS ( ) ! = 9 | |
zend_get_parameters_ex ( 9 , & DIM , & SIM , & DX , & DY , & SX , & SY , & SW , & SH , & PCT ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( im_src , gdImagePtr , SIM , - 1 , " Image " , GDG ( le_gd ) ) ;
ZEND_FETCH_RESOURCE ( im_dst , gdImagePtr , DIM , - 1 , " Image " , GDG ( le_gd ) ) ;
convert_to_long_ex ( SX ) ;
convert_to_long_ex ( SY ) ;
convert_to_long_ex ( SW ) ;
convert_to_long_ex ( SH ) ;
convert_to_long_ex ( DX ) ;
convert_to_long_ex ( DY ) ;
convert_to_long_ex ( PCT ) ;
srcX = Z_LVAL_PP ( SX ) ;
srcY = Z_LVAL_PP ( SY ) ;
srcH = Z_LVAL_PP ( SH ) ;
srcW = Z_LVAL_PP ( SW ) ;
2000-06-25 11:12:38 +08:00
dstX = Z_LVAL_PP ( DX ) ;
2000-06-25 10:55:31 +08:00
dstY = Z_LVAL_PP ( DY ) ;
pct = Z_LVAL_PP ( PCT ) ;
gdImageCopyMerge ( im_dst , im_src , dstX , dstY , srcX , srcY , srcW , srcH , pct ) ;
RETURN_TRUE ;
2000-06-25 11:26:49 +08:00
# else
php_error ( E_WARNING , " ImageCopyMerge was introduced in GD version 1.5 " ) ;
RETURN_FALSE ;
# endif
2000-06-25 10:55:31 +08:00
}
2000-06-25 11:06:38 +08:00
/* }}} */
2000-06-25 10:55:31 +08:00
2000-06-19 00:31:52 +08:00
/* {{{ proto int imagecopyresized(int dst_im, int src_im, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h)
1999-11-25 06:04:49 +08:00
Copy and resize part of an image */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagecopyresized )
1999-04-16 20:15:38 +08:00
{
2000-02-29 00:52:03 +08:00
zval * * SIM , * * DIM , * * SX , * * SY , * * SW , * * SH , * * DX , * * DY , * * DW , * * DH ;
1999-04-16 20:15:38 +08:00
gdImagePtr im_dst ;
gdImagePtr im_src ;
int srcH , srcW , dstH , dstW , srcY , srcX , dstY , dstX ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 10 | |
2000-02-29 00:52:03 +08:00
zend_get_parameters_ex ( 10 , & DIM , & SIM , & DX , & DY , & SX , & SY , & DW , & DH ,
& SW , & SH ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im_dst , gdImagePtr , DIM , - 1 , " Image " , GDG ( le_gd ) ) ;
ZEND_FETCH_RESOURCE ( im_src , gdImagePtr , SIM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( SX ) ;
convert_to_long_ex ( SY ) ;
convert_to_long_ex ( SW ) ;
convert_to_long_ex ( SH ) ;
convert_to_long_ex ( DX ) ;
convert_to_long_ex ( DY ) ;
convert_to_long_ex ( DW ) ;
convert_to_long_ex ( DH ) ;
srcX = ( * SX ) - > value . lval ;
srcY = ( * SY ) - > value . lval ;
srcH = ( * SH ) - > value . lval ;
srcW = ( * SW ) - > value . lval ;
dstX = ( * DX ) - > value . lval ;
dstY = ( * DY ) - > value . lval ;
dstH = ( * DH ) - > value . lval ;
dstW = ( * DW ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageCopyResized ( im_dst , im_src , dstX , dstY , srcX , srcY , dstW , dstH ,
srcW , srcH ) ;
RETURN_TRUE ;
}
/* }}} */
/* {{{ proto int imagesx(int im)
1999-11-25 06:04:49 +08:00
Get image width */
1999-07-28 03:44:46 +08:00
PHP_FUNCTION ( imagesx )
1999-04-16 20:15:38 +08:00
{
2000-02-29 00:52:03 +08:00
zval * * IM ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & IM ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
RETURN_LONG ( gdImageSX ( im ) ) ;
}
/* }}} */
/* {{{ proto int imagesy(int im)
2000-01-25 04:25:57 +08:00
Get image height */
1999-07-28 03:44:46 +08:00
PHP_FUNCTION ( imagesy )
1999-04-16 20:15:38 +08:00
{
2000-02-29 00:52:03 +08:00
zval * * IM ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & IM ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
RETURN_LONG ( gdImageSY ( im ) ) ;
}
/* }}} */
1999-07-23 23:18:37 +08:00
# ifdef ENABLE_GD_TTF
1999-04-16 20:15:38 +08:00
# define TTFTEXT_DRAW 0
# define TTFTEXT_BBOX 1
2000-05-02 22:10:51 +08:00
# endif
1999-04-16 20:15:38 +08:00
/* {{{ proto array imagettfbbox(int size, int angle, string font_file, string text)
1999-11-25 06:04:49 +08:00
Give the bounding box of a text using TrueType fonts */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagettfbbox )
1999-04-16 20:15:38 +08:00
{
2000-05-02 22:10:51 +08:00
# ifdef ENABLE_GD_TTF
1999-12-18 05:50:07 +08:00
php_imagettftext_common ( INTERNAL_FUNCTION_PARAM_PASSTHRU , TTFTEXT_BBOX ) ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImageTtfBBox: No TTF support in this PHP build " ) ;
RETURN_FALSE ;
# endif
1999-04-16 20:15:38 +08:00
}
/* }}} */
/* {{{ proto array imagettftext(int im, int size, int angle, int x, int y, int col, string font_file, string text)
1999-11-25 06:04:49 +08:00
Write text to the image using a TrueType font */
1999-05-21 18:06:25 +08:00
PHP_FUNCTION ( imagettftext )
1999-04-16 20:15:38 +08:00
{
2000-05-02 22:10:51 +08:00
# ifdef ENABLE_GD_TTF
1999-12-18 05:50:07 +08:00
php_imagettftext_common ( INTERNAL_FUNCTION_PARAM_PASSTHRU , TTFTEXT_DRAW ) ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImageTtfText: No TTF support in this PHP build " ) ;
RETURN_FALSE ;
# endif
1999-04-16 20:15:38 +08:00
}
/* }}} */
2000-05-02 22:10:51 +08:00
# ifdef ENABLE_GD_TTF
1999-04-16 20:15:38 +08:00
static
1999-12-18 05:50:07 +08:00
void php_imagettftext_common ( INTERNAL_FUNCTION_PARAMETERS , int mode )
1999-04-16 20:15:38 +08:00
{
2000-02-29 00:52:03 +08:00
zval * * IM , * * PTSIZE , * * ANGLE , * * X , * * Y , * * C , * * FONTNAME , * * COL ;
2000-05-24 16:58:40 +08:00
gdImagePtr im = NULL ;
2000-02-29 00:52:03 +08:00
int col , x , y , l = 0 , i ;
1999-04-16 20:15:38 +08:00
int brect [ 8 ] ;
double ptsize , angle ;
2000-02-09 06:21:43 +08:00
unsigned char * str = NULL , * fontname = NULL ;
2000-02-29 00:52:03 +08:00
char * error ;
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
if ( mode = = TTFTEXT_BBOX ) {
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 4 | | zend_get_parameters_ex ( 4 , & PTSIZE , & ANGLE , & FONTNAME , & C ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
} else {
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 8 | | zend_get_parameters_ex ( 8 , & IM , & PTSIZE , & ANGLE , & X , & Y , & COL , & FONTNAME , & C ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( im , gdImagePtr , IM , - 1 , " Image " , GDG ( le_gd ) ) ;
1999-04-16 20:15:38 +08:00
}
2000-02-29 00:52:03 +08:00
convert_to_double_ex ( PTSIZE ) ;
convert_to_double_ex ( ANGLE ) ;
convert_to_string_ex ( FONTNAME ) ;
convert_to_string_ex ( C ) ;
1999-04-16 20:15:38 +08:00
if ( mode = = TTFTEXT_BBOX ) {
im = NULL ;
col = x = y = - 1 ;
} else {
2000-02-29 00:52:03 +08:00
convert_to_long_ex ( X ) ;
convert_to_long_ex ( Y ) ;
convert_to_long_ex ( COL ) ;
col = ( * COL ) - > value . lval ;
y = ( * Y ) - > value . lval ;
x = ( * X ) - > value . lval ;
}
ptsize = ( * PTSIZE ) - > value . dval ;
angle = ( * ANGLE ) - > value . dval * ( M_PI / 180 ) ; /* convert to radians */
str = ( unsigned char * ) ( * C ) - > value . str . val ;
2000-02-09 06:21:43 +08:00
l = strlen ( str ) ;
2000-02-29 00:52:03 +08:00
fontname = ( unsigned char * ) ( * FONTNAME ) - > value . str . val ;
1999-04-16 20:15:38 +08:00
2000-10-16 21:50:30 +08:00
# ifdef USE_GD_IMGSTRTTF
error = gdImageStringTTF ( im , brect , col , fontname , ptsize , angle , x , y , str ) ;
# else
2000-02-09 06:21:43 +08:00
error = gdttf ( im , brect , col , fontname , ptsize , angle , x , y , str ) ;
2000-10-16 21:50:30 +08:00
# endif
1999-04-16 20:15:38 +08:00
if ( error ) {
2000-10-21 07:39:16 +08:00
php_error ( E_WARNING , " %s " , error ) ;
1999-04-16 20:15:38 +08:00
RETURN_FALSE ;
}
if ( array_init ( return_value ) = = FAILURE ) {
RETURN_FALSE ;
}
/* return array with the text's bounding box */
for ( i = 0 ; i < 8 ; i + + ) {
add_next_index_long ( return_value , brect [ i ] ) ;
}
}
2000-02-25 14:43:51 +08:00
# endif /* ENABLE_GD_TTF */
# if HAVE_LIBT1
2000-10-21 02:25:16 +08:00
void php_free_ps_font ( zend_rsrc_list_entry * rsrc )
2000-02-25 14:43:51 +08:00
{
2000-10-21 02:25:16 +08:00
int * font = ( int * ) rsrc - > ptr ;
2000-02-25 14:43:51 +08:00
T1_DeleteFont ( * font ) ;
efree ( font ) ;
}
2000-10-21 02:25:16 +08:00
void php_free_ps_enc ( zend_rsrc_list_entry * rsrc )
2000-02-25 14:43:51 +08:00
{
2000-10-21 02:25:16 +08:00
char * * enc = ( char * * ) rsrc - > ptr ;
2000-02-25 14:43:51 +08:00
T1_DeleteEncoding ( enc ) ;
}
2000-05-02 22:10:51 +08:00
# endif
2000-02-25 14:43:51 +08:00
/* {{{ proto int imagepsloadfont(string pathname)
Load a new font from specified file */
PHP_FUNCTION ( imagepsloadfont )
{
2000-05-02 22:10:51 +08:00
# if HAVE_LIBT1
2000-02-25 14:43:51 +08:00
zval * * file ;
2000-02-29 00:52:03 +08:00
int f_ind ;
2000-02-25 14:43:51 +08:00
int * font ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & file ) = = FAILURE ) {
2000-02-25 14:43:51 +08:00
WRONG_PARAM_COUNT ;
}
convert_to_string_ex ( file ) ;
f_ind = T1_AddFont ( ( * file ) - > value . str . val ) ;
if ( f_ind < 0 ) {
switch ( f_ind ) {
case - 1 :
php_error ( E_WARNING , " Couldn't find the font file " ) ;
RETURN_FALSE ;
break ;
case - 2 :
case - 3 :
php_error ( E_WARNING , " Memory allocation fault in t1lib " ) ;
RETURN_FALSE ;
break ;
default :
php_error ( E_WARNING , " An unknown error occurred in t1lib " ) ;
RETURN_FALSE ;
break ;
}
}
2000-06-16 18:09:12 +08:00
if ( T1_LoadFont ( f_ind ) ) {
php_error ( E_WARNING , " Couldn't load the font " ) ;
RETURN_FALSE ;
}
2000-02-25 14:43:51 +08:00
font = ( int * ) emalloc ( sizeof ( int ) ) ;
* font = f_ind ;
2000-02-29 00:52:03 +08:00
ZEND_REGISTER_RESOURCE ( return_value , font , GDG ( le_ps_font ) ) ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImagePsLoadFont: No T1lib support in this PHP build " ) ;
RETURN_FALSE ;
# endif
2000-02-25 14:43:51 +08:00
}
/* }}} */
/* {{{ The function in t1lib which this function uses seem to be buggy...
proto int imagepscopyfont ( int font_index )
Make a copy of a font for purposes like extending or reenconding */
/*
PHP_FUNCTION ( imagepscopyfont )
{
2000-05-02 22:10:51 +08:00
# if HAVE_LIBT1
2000-02-25 14:43:51 +08:00
pval * fnt ;
int l_ind , type ;
gd_ps_font * nf_ind , * of_ind ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters ( ht , 1 , & fnt ) = = FAILURE ) {
2000-02-25 14:43:51 +08:00
WRONG_PARAM_COUNT ;
}
convert_to_long ( fnt ) ;
of_ind = zend_list_find ( fnt - > value . lval , & type ) ;
2000-02-29 00:52:03 +08:00
if ( type ! = GDG ( le_ps_font ) ) {
2000-02-25 14:43:51 +08:00
php_error ( E_WARNING , " %d is not a Type 1 font index " , fnt - > value . lval ) ;
RETURN_FALSE ;
}
nf_ind = emalloc ( sizeof ( gd_ps_font ) ) ;
nf_ind - > font_id = T1_CopyFont ( of_ind - > font_id ) ;
if ( nf_ind - > font_id < 0 ) {
l_ind = nf_ind - > font_id ;
efree ( nf_ind ) ;
switch ( l_ind ) {
case - 1 :
php_error ( E_WARNING , " FontID %d is not loaded in memory " , l_ind ) ;
RETURN_FALSE ;
break ;
case - 2 :
php_error ( E_WARNING , " Tried to copy a logical font " ) ;
RETURN_FALSE ;
break ;
case - 3 :
php_error ( E_WARNING , " Memory allocation fault in t1lib " ) ;
RETURN_FALSE ;
break ;
default :
php_error ( E_WARNING , " An unknown error occurred in t1lib " ) ;
RETURN_FALSE ;
break ;
}
}
nf_ind - > extend = 1 ;
2000-02-29 00:52:03 +08:00
l_ind = zend_list_insert ( nf_ind , GDG ( le_ps_font ) ) ;
2000-02-25 14:43:51 +08:00
RETURN_LONG ( l_ind ) ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImagePsCopyFont: No T1lib support in this PHP build " ) ;
RETURN_FALSE ;
# endif
2000-02-25 14:43:51 +08:00
}
*/
/* }}} */
/* {{{ proto bool imagepsfreefont(int font_index)
Free memory used by a font */
PHP_FUNCTION ( imagepsfreefont )
{
2000-05-02 22:10:51 +08:00
# if HAVE_LIBT1
2000-02-25 14:43:51 +08:00
zval * * fnt ;
int * f_ind ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_get_parameters_ex ( 1 , & fnt ) = = FAILURE ) {
2000-02-25 14:43:51 +08:00
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( f_ind , int * , fnt , - 1 , " Type 1 font " , GDG ( le_ps_font ) ) ;
2000-02-25 14:43:51 +08:00
zend_list_delete ( ( * fnt ) - > value . lval ) ;
RETURN_TRUE ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImagePsFreeFont: No T1lib support in this PHP build " ) ;
RETURN_FALSE ;
# endif
2000-02-25 14:43:51 +08:00
}
/* }}} */
/* {{{ proto bool imagepsencodefont(int font_index, string filename)
To change a fonts character encoding vector */
PHP_FUNCTION ( imagepsencodefont )
{
2000-05-02 22:10:51 +08:00
# if HAVE_LIBT1
2000-02-25 14:43:51 +08:00
zval * * fnt , * * enc ;
char * * enc_vector ;
int * f_ind ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & fnt , & enc ) = = FAILURE ) {
2000-02-25 14:43:51 +08:00
WRONG_PARAM_COUNT ;
}
convert_to_string_ex ( enc ) ;
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( f_ind , int * , fnt , - 1 , " Type 1 font " , GDG ( le_ps_font ) ) ;
2000-02-25 14:43:51 +08:00
if ( ( enc_vector = T1_LoadEncoding ( ( * enc ) - > value . str . val ) ) = = NULL ) {
php_error ( E_WARNING , " Couldn't load encoding vector from %s " , ( * enc ) - > value . str . val ) ;
RETURN_FALSE ;
}
T1_DeleteAllSizes ( * f_ind ) ;
if ( T1_ReencodeFont ( * f_ind , enc_vector ) ) {
T1_DeleteEncoding ( enc_vector ) ;
php_error ( E_WARNING , " Couldn't reencode font " ) ;
RETURN_FALSE ;
}
2000-02-29 00:52:03 +08:00
zend_list_insert ( enc_vector , GDG ( le_ps_enc ) ) ;
2000-02-25 14:43:51 +08:00
RETURN_TRUE ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImagePsEncodeFont: No T1lib support in this PHP build " ) ;
RETURN_FALSE ;
# endif
2000-02-25 14:43:51 +08:00
}
/* }}} */
/* {{{ proto bool imagepsextendfont(int font_index, double extend)
Extend or or condense ( if extend < 1 ) a font */
PHP_FUNCTION ( imagepsextendfont )
{
2000-05-02 22:10:51 +08:00
# if HAVE_LIBT1
2000-02-25 14:43:51 +08:00
zval * * fnt , * * ext ;
int * f_ind ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & fnt , & ext ) = = FAILURE ) {
2000-02-25 14:43:51 +08:00
WRONG_PARAM_COUNT ;
}
convert_to_double_ex ( ext ) ;
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( f_ind , int * , fnt , - 1 , " Type 1 font " , GDG ( le_ps_font ) ) ;
2000-02-25 14:43:51 +08:00
if ( T1_ExtendFont ( * f_ind , ( * ext ) - > value . dval ) ! = 0 ) RETURN_FALSE ;
RETURN_TRUE ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImagePsExtendFont: No T1lib support in this PHP build " ) ;
RETURN_FALSE ;
# endif
2000-02-25 14:43:51 +08:00
}
/* }}} */
/* {{{ proto bool imagepsslantfont(int font_index, double slant)
Slant a font */
PHP_FUNCTION ( imagepsslantfont )
{
2000-05-02 22:10:51 +08:00
# if HAVE_LIBT1
2000-02-25 14:43:51 +08:00
zval * * fnt , * * slt ;
int * f_ind ;
2000-06-06 03:47:54 +08:00
if ( ZEND_NUM_ARGS ( ) ! = 2 | | zend_get_parameters_ex ( 2 , & fnt , & slt ) = = FAILURE ) {
2000-02-25 14:43:51 +08:00
WRONG_PARAM_COUNT ;
}
convert_to_double_ex ( slt ) ;
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( f_ind , int * , fnt , - 1 , " Type 1 font " , GDG ( le_ps_font ) ) ;
2000-02-25 14:43:51 +08:00
if ( T1_SlantFont ( * f_ind , ( * slt ) - > value . dval ) ! = 0 ) RETURN_FALSE ;
RETURN_TRUE ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImagePsSlantFont: No T1lib support in this PHP build " ) ;
RETURN_FALSE ;
# endif
2000-02-25 14:43:51 +08:00
}
/* }}} */
/* {{{ proto array imagepstext(int image, string text, int font, int size, int xcoord, int ycoord [, int space, int tightness, double angle, int antialias])
Rasterize a string over an image */
PHP_FUNCTION ( imagepstext )
{
2000-05-02 22:10:51 +08:00
# if HAVE_LIBT1
2000-02-25 14:43:51 +08:00
zval * * img , * * str , * * fnt , * * sz , * * fg , * * bg , * * sp , * * px , * * py , * * aas , * * wd , * * ang ;
int i , j , x , y ;
2000-02-29 00:52:03 +08:00
int space ;
2000-02-25 14:43:51 +08:00
int * f_ind ;
int h_lines , v_lines , c_ind ;
int rd , gr , bl , fg_rd , fg_gr , fg_bl , bg_rd , bg_gr , bg_bl ;
int aa [ 16 ] , aa_steps ;
int width , amount_kern , add_width ;
double angle , extend ;
unsigned long aa_greys [ ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 } ;
gdImagePtr bg_img ;
GLYPH * str_img ;
T1_OUTLINE * char_path , * str_path ;
T1_TMATRIX * transform = NULL ;
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2000-02-25 14:43:51 +08:00
case 8 :
if ( zend_get_parameters_ex ( 8 , & img , & str , & fnt , & sz , & fg , & bg , & px , & py ) = = FAILURE ) {
RETURN_FALSE ;
}
convert_to_string_ex ( str ) ;
convert_to_long_ex ( sz ) ;
convert_to_long_ex ( fg ) ;
convert_to_long_ex ( bg ) ;
convert_to_long_ex ( px ) ;
convert_to_long_ex ( py ) ;
x = ( * px ) - > value . lval ;
y = ( * py ) - > value . lval ;
space = 0 ;
aa_steps = 4 ;
width = 0 ;
angle = 0 ;
break ;
case 12 :
if ( zend_get_parameters_ex ( 12 , & img , & str , & fnt , & sz , & fg , & bg , & px , & py , & sp , & wd , & ang , & aas ) = = FAILURE ) {
RETURN_FALSE ;
}
convert_to_string_ex ( str ) ;
convert_to_long_ex ( sz ) ;
convert_to_long_ex ( sp ) ;
convert_to_long_ex ( fg ) ;
convert_to_long_ex ( bg ) ;
convert_to_long_ex ( px ) ;
convert_to_long_ex ( py ) ;
x = ( * px ) - > value . lval ;
y = ( * py ) - > value . lval ;
convert_to_long_ex ( sp ) ;
space = ( * sp ) - > value . lval ;
convert_to_long_ex ( aas ) ;
aa_steps = ( * aas ) - > value . lval ;
convert_to_long_ex ( wd ) ;
width = ( * wd ) - > value . lval ;
convert_to_double_ex ( ang ) ;
angle = ( * ang ) - > value . dval ;
break ;
default :
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( bg_img , gdImagePtr , img , - 1 , " Image " , GDG ( le_gd ) ) ;
ZEND_FETCH_RESOURCE ( f_ind , int * , fnt , - 1 , " Type 1 font " , GDG ( le_ps_font ) ) ;
2000-02-25 14:43:51 +08:00
fg_rd = gdImageRed ( bg_img , ( * fg ) - > value . lval ) ;
fg_gr = gdImageGreen ( bg_img , ( * fg ) - > value . lval ) ;
fg_bl = gdImageBlue ( bg_img , ( * fg ) - > value . lval ) ;
bg_rd = gdImageRed ( bg_img , ( * bg ) - > value . lval ) ;
bg_gr = gdImageGreen ( bg_img , ( * bg ) - > value . lval ) ;
bg_bl = gdImageBlue ( bg_img , ( * bg ) - > value . lval ) ;
for ( i = 0 ; i < aa_steps ; i + + ) {
rd = bg_rd + ( double ) ( fg_rd - bg_rd ) / aa_steps * ( i + 1 ) ;
gr = bg_gr + ( double ) ( fg_gr - bg_gr ) / aa_steps * ( i + 1 ) ;
bl = bg_bl + ( double ) ( fg_bl - bg_bl ) / aa_steps * ( i + 1 ) ;
aa [ i ] = gdImageColorResolve ( bg_img , rd , gr , bl ) ;
}
T1_AASetBitsPerPixel ( 8 ) ;
switch ( aa_steps ) {
case 4 :
T1_AASetGrayValues ( 0 , 1 , 2 , 3 , 4 ) ;
T1_AASetLevel ( T1_AA_LOW ) ;
break ;
case 16 :
T1_AAHSetGrayValues ( aa_greys ) ;
T1_AASetLevel ( T1_AA_HIGH ) ;
break ;
default :
php_error ( E_WARNING , " Invalid value %d as number of steps for antialiasing " , aa_steps ) ;
RETURN_FALSE ;
}
if ( angle ) {
transform = T1_RotateMatrix ( NULL , angle ) ;
}
if ( width ) {
extend = T1_GetExtend ( * f_ind ) ;
str_path = T1_GetCharOutline ( * f_ind , ( * str ) - > value . str . val [ 0 ] , ( * sz ) - > value . lval , transform ) ;
for ( i = 1 ; i < ( * str ) - > value . str . len ; i + + ) {
amount_kern = ( int ) T1_GetKerning ( * f_ind , ( * str ) - > value . str . val [ i - 1 ] , ( * str ) - > value . str . val [ i ] ) ;
amount_kern + = ( * str ) - > value . str . val [ i - 1 ] = = ' ' ? space : 0 ;
add_width = ( int ) ( amount_kern + width ) / extend ;
char_path = T1_GetMoveOutline ( * f_ind , add_width , 0 , 0 , ( * sz ) - > value . lval , transform ) ;
str_path = T1_ConcatOutlines ( str_path , char_path ) ;
char_path = T1_GetCharOutline ( * f_ind , ( * str ) - > value . str . val [ i ] , ( * sz ) - > value . lval , transform ) ;
str_path = T1_ConcatOutlines ( str_path , char_path ) ;
}
str_img = T1_AAFillOutline ( str_path , 0 ) ;
} else {
str_img = T1_AASetString ( * f_ind , ( * str ) - > value . str . val , ( * str ) - > value . str . len ,
space , T1_KERNING , ( * sz ) - > value . lval , transform ) ;
}
2000-06-16 18:09:12 +08:00
if ( T1_errno ) {
php_error ( E_WARNING , " libt1 returned error %d " , T1_errno ) ;
RETURN_FALSE ;
}
2000-02-25 14:43:51 +08:00
h_lines = str_img - > metrics . ascent - str_img - > metrics . descent ;
v_lines = str_img - > metrics . rightSideBearing - str_img - > metrics . leftSideBearing ;
for ( i = 0 ; i < v_lines ; i + + ) {
for ( j = 0 ; j < h_lines ; j + + ) {
switch ( str_img - > bits [ j * v_lines + i ] ) {
case 0 :
break ;
default :
c_ind = aa [ str_img - > bits [ j * v_lines + i ] - 1 ] ;
gdImageSetPixel ( bg_img , x + str_img - > metrics . leftSideBearing + i , y - str_img - > metrics . ascent + j , c_ind ) ;
}
}
}
if ( array_init ( return_value ) = = FAILURE ) {
2000-06-16 18:09:12 +08:00
php_error ( E_WARNING , " Couldn't initialize array for returning bounding box " ) ;
2000-02-25 14:43:51 +08:00
RETURN_FALSE ;
}
add_next_index_long ( return_value , str_img - > metrics . leftSideBearing ) ;
add_next_index_long ( return_value , str_img - > metrics . descent ) ;
add_next_index_long ( return_value , str_img - > metrics . rightSideBearing ) ;
add_next_index_long ( return_value , str_img - > metrics . ascent ) ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImagePsText: No T1lib support in this PHP build " ) ;
RETURN_FALSE ;
# endif
2000-02-25 14:43:51 +08:00
}
/* }}} */
/* {{{ proto array imagepsbbox(string text, int font, int size [, int space, int tightness, int angle])
Return the bounding box needed by a string if rasterized */
PHP_FUNCTION ( imagepsbbox )
{
2000-05-02 22:10:51 +08:00
# if HAVE_LIBT1
2000-02-25 14:43:51 +08:00
zval * * str , * * fnt , * * sz , * * sp , * * wd , * * ang ;
2000-02-29 00:52:03 +08:00
int i , space , add_width , char_width , amount_kern ;
2000-02-25 14:43:51 +08:00
int cur_x , cur_y , dx , dy ;
int x1 , y1 , x2 , y2 , x3 , y3 , x4 , y4 ;
int * f_ind ;
int per_char = 0 ;
2000-02-29 00:52:03 +08:00
double angle , sin_a = 0 , cos_a = 0 ;
2000-02-25 14:43:51 +08:00
BBox char_bbox , str_bbox = { 0 , 0 , 0 , 0 } ;
2000-06-06 03:47:54 +08:00
switch ( ZEND_NUM_ARGS ( ) ) {
2000-02-25 14:43:51 +08:00
case 3 :
if ( zend_get_parameters_ex ( 3 , & str , & fnt , & sz ) = = FAILURE ) {
RETURN_FALSE ;
}
convert_to_string_ex ( str ) ;
convert_to_long_ex ( sz ) ;
space = 0 ;
break ;
case 6 :
if ( zend_get_parameters_ex ( 6 , & str , & fnt , & sz , & sp , & wd , & ang ) = = FAILURE ) {
RETURN_FALSE ;
}
convert_to_string_ex ( str ) ;
convert_to_long_ex ( sz ) ;
convert_to_long_ex ( sp ) ;
space = ( * sp ) - > value . lval ;
convert_to_long_ex ( wd ) ;
add_width = ( * wd ) - > value . lval ;
convert_to_double_ex ( ang ) ;
angle = ( * ang ) - > value . dval * M_PI / 180 ;
sin_a = sin ( angle ) ;
cos_a = cos ( angle ) ;
per_char = add_width | | angle ? 1 : 0 ;
break ;
default :
WRONG_PARAM_COUNT ;
}
2000-02-29 00:52:03 +08:00
ZEND_FETCH_RESOURCE ( f_ind , int * , fnt , - 1 , " Type 1 font " , GDG ( le_ps_font ) ) ;
2000-02-25 14:43:51 +08:00
# define max(a, b) (a > b ? a : b)
# define min(a, b) (a < b ? a : b)
# define new_x(a, b) (int) ((a) * cos_a - (b) * sin_a)
# define new_y(a, b) (int) ((a) * sin_a + (b) * cos_a)
if ( per_char ) {
space + = T1_GetCharWidth ( * f_ind , ' ' ) ;
cur_x = cur_y = 0 ;
for ( i = 0 ; i < ( * str ) - > value . str . len ; i + + ) {
if ( ( * str ) - > value . str . val [ i ] = = ' ' ) {
char_bbox . llx = char_bbox . lly = char_bbox . ury = 0 ;
char_bbox . urx = char_width = space ;
} else {
char_bbox = T1_GetCharBBox ( * f_ind , ( * str ) - > value . str . val [ i ] ) ;
char_width = T1_GetCharWidth ( * f_ind , ( * str ) - > value . str . val [ i ] ) ;
}
amount_kern = i ? T1_GetKerning ( * f_ind , ( * str ) - > value . str . val [ i - 1 ] , ( * str ) - > value . str . val [ i ] ) : 0 ;
/* Transfer character bounding box to right place */
x1 = new_x ( char_bbox . llx , char_bbox . lly ) + cur_x ;
y1 = new_y ( char_bbox . llx , char_bbox . lly ) + cur_y ;
x2 = new_x ( char_bbox . llx , char_bbox . ury ) + cur_x ;
y2 = new_y ( char_bbox . llx , char_bbox . ury ) + cur_y ;
x3 = new_x ( char_bbox . urx , char_bbox . ury ) + cur_x ;
y3 = new_y ( char_bbox . urx , char_bbox . ury ) + cur_y ;
x4 = new_x ( char_bbox . urx , char_bbox . lly ) + cur_x ;
y4 = new_y ( char_bbox . urx , char_bbox . lly ) + cur_y ;
/* Find min & max values and compare them with current bounding box */
str_bbox . llx = min ( str_bbox . llx , min ( x1 , min ( x2 , min ( x3 , x4 ) ) ) ) ;
str_bbox . lly = min ( str_bbox . lly , min ( y1 , min ( y2 , min ( y3 , y4 ) ) ) ) ;
str_bbox . urx = max ( str_bbox . urx , max ( x1 , max ( x2 , max ( x3 , x4 ) ) ) ) ;
str_bbox . ury = max ( str_bbox . ury , max ( y1 , max ( y2 , max ( y3 , y4 ) ) ) ) ;
/* Move to the next base point */
dx = new_x ( char_width + add_width + amount_kern , 0 ) ;
dy = new_y ( char_width + add_width + amount_kern , 0 ) ;
cur_x + = dx ;
cur_y + = dy ;
/*
printf ( " %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \t %d \n " , x1 , y1 , x2 , y2 , x3 , y3 , x4 , y4 , char_bbox . llx , char_bbox . lly , char_bbox . urx , char_bbox . ury , char_width , amount_kern , cur_x , cur_y , dx , dy ) ;
*/
}
} else {
str_bbox = T1_GetStringBBox ( * f_ind , ( * str ) - > value . str . val , ( * str ) - > value . str . len , space , T1_KERNING ) ;
}
if ( T1_errno ) RETURN_FALSE ;
if ( array_init ( return_value ) = = FAILURE ) {
RETURN_FALSE ;
}
/*
printf ( " %d %d %d %d \n " , str_bbox . llx , str_bbox . lly , str_bbox . urx , str_bbox . ury ) ;
*/
add_next_index_long ( return_value , ( int ) ceil ( ( ( double ) str_bbox . llx ) * ( * sz ) - > value . lval / 1000 ) ) ;
add_next_index_long ( return_value , ( int ) ceil ( ( ( double ) str_bbox . lly ) * ( * sz ) - > value . lval / 1000 ) ) ;
add_next_index_long ( return_value , ( int ) ceil ( ( ( double ) str_bbox . urx ) * ( * sz ) - > value . lval / 1000 ) ) ;
add_next_index_long ( return_value , ( int ) ceil ( ( ( double ) str_bbox . ury ) * ( * sz ) - > value . lval / 1000 ) ) ;
2000-05-02 22:10:51 +08:00
# else
php_error ( E_WARNING , " ImagePsBBox: No T1lib support in this PHP build " ) ;
RETURN_FALSE ;
# endif
2000-02-25 14:43:51 +08:00
}
/* }}} */
# endif /* HAVE_LIBGD */
1999-04-16 20:15:38 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
*/