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-02-20 07:21:46 +08:00
| This source file is subject to version 2.01 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-02-20 07:21:46 +08:00
| http : //www.php.net/license/2_01.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"
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
# if WIN32|WINNT
# include <io.h>
# include <fcntl.h>
# endif
# if HAVE_LIBGD
# 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
# 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 )
PHP_FE ( imagecolorat , NULL )
PHP_FE ( imagecolorclosest , NULL )
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 )
PHP_FE ( imagecopyresized , NULL )
PHP_FE ( imagecreate , NULL )
1999-10-17 22:57:49 +08:00
# ifdef HAVE_GD_PNG
PHP_FE ( imagecreatefrompng , NULL )
PHP_FE ( imagepng , NULL )
1999-11-25 05:43:54 +08:00
# endif
# ifdef HAVE_GD_GIF
1999-07-28 03:44:46 +08:00
PHP_FE ( imagecreatefromgif , NULL )
1999-10-17 22:57:49 +08:00
PHP_FE ( imagegif , NULL )
# endif
1999-07-28 03:44:46 +08:00
PHP_FE ( imagedestroy , NULL )
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 )
1999-07-23 23:18:37 +08:00
# ifdef ENABLE_GD_TTF
1999-07-28 03:44:46 +08:00
PHP_FE ( imagettfbbox , NULL )
PHP_FE ( imagettftext , NULL )
2000-02-25 14:43:51 +08:00
# endif
# if HAVE_LIBT1
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 )
1999-04-16 20:15:38 +08:00
# endif
{ NULL , NULL , NULL }
} ;
1999-12-18 04:55:31 +08:00
zend_module_entry gd_module_entry = {
1999-07-28 03:44:46 +08:00
" gd " , gd_functions , PHP_MINIT ( gd ) , PHP_MSHUTDOWN ( gd ) , 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
1999-12-04 22:45:38 +08:00
# ifdef COMPILE_DL_GD
1999-12-02 06:59:45 +08:00
# include "dl / phpdl.h"
1999-12-18 04:55:31 +08:00
DLEXPORT zend_module_entry * get_module ( void ) { return & gd_module_entry ; }
1999-04-16 20:15:38 +08:00
# endif
# define PolyMaxPoints 256
1999-12-18 05:50:07 +08:00
static void php_free_gd_font ( gdFontPtr fp )
{
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-02-29 00:52:03 +08:00
GDG ( le_gd ) = register_list_destructors ( gdImageDestroy , NULL ) ;
GDG ( le_gd_font ) = register_list_destructors ( php_free_gd_font , NULL ) ;
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-02-29 00:52:03 +08:00
GDG ( le_ps_font ) = register_list_destructors ( php_free_ps_font , NULL ) ;
GDG ( le_ps_enc ) = register_list_destructors ( php_free_ps_enc , NULL ) ;
2000-02-25 14:43:51 +08:00
# endif
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
{
1999-04-16 20:15:38 +08:00
/* need to use a PHPAPI function here because it is external module in windows */
1999-11-30 07:21:52 +08:00
# if HAVE_GDIMAGECOLORRESOLVE
php_printf ( " Version 1.6.2 or higher " ) ;
# elif HAVE_LIBGD13
php_printf ( " Version between 1.3 and 1.6.1 " ) ;
1999-04-16 20:15:38 +08:00
# else
1999-08-03 03:17:14 +08:00
php_printf ( " 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
1999-08-03 03:17:14 +08:00
php_printf ( " with FreeType support " ) ;
1999-11-30 07:21:52 +08:00
# if HAVE_LIBFREETYPE
php_printf ( " (linked with freetype) " ) ;
# elif HAVE_LIBTTF
php_printf ( " (linked with ttf library) " ) ;
# else
php_printf ( " (linked with unknown library) " ) ;
# endif
# endif
php_printf ( " which supports: " ) ;
# ifdef HAVE_GD_GIF
php_printf ( " GIF " ) ;
# endif
# ifdef HAVE_GD_PNG
php_printf ( " PNG " ) ;
1999-04-16 20:15:38 +08:00
# endif
}
1999-07-28 03:44:46 +08:00
PHP_MSHUTDOWN_FUNCTION ( gd )
1999-04-27 01:26:37 +08:00
{
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
# ifdef THREAD_SAFE
PHP3_TLS_THREAD_FREE ( gdlib_globals ) ;
2000-02-26 11:20:55 +08:00
PHP_MUTEX_LOCK ( gdlib_mutex ) ;
1999-04-16 20:15:38 +08:00
numthreads - - ;
if ( numthreads < 1 ) {
PHP3_TLS_PROC_SHUTDOWN ( 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 SUCCESS ;
}
2000-02-26 11:20:55 +08:00
PHP_MUTEX_UNLOCK ( gdlib_mutex ) ;
1999-04-16 20:15:38 +08:00
# endif
return SUCCESS ;
}
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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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
# if WIN32|WINNT
2000-02-29 00:52:03 +08:00
fp = 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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
}
/* }}} */
1999-10-17 22:57:49 +08:00
# ifdef HAVE_GD_PNG
/* {{{ proto int imagecreatefrompng(string filename)
1999-11-25 06:04:49 +08:00
Create a new image from file or URL */
1999-12-18 05:50:07 +08:00
PHP_FUNCTION ( imagecreatefrompng )
{
2000-02-29 00:52:03 +08:00
zval * * file ;
gdImagePtr im ;
char * fn = NULL ;
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
if ( ARG_COUNT ( ht ) ! = 1 | | zend_get_parameters_ex ( 1 , & file ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
convert_to_string_ex ( file ) ;
fn = ( * file ) - > value . str . val ;
1999-10-17 22:57:49 +08:00
# if WIN32|WINNT
2000-02-29 00:52:03 +08:00
fp = fopen ( ( * file ) - > value . str . val , " rb " ) ;
1999-10-17 22:57:49 +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-10-17 22:57:49 +08:00
# endif
2000-02-29 00:52:03 +08:00
if ( ! fp ) {
php_strip_url_passwd ( fn ) ;
php_error ( E_WARNING ,
" ImageCreateFromPng: Unable to open %s for reading " , fn ) ;
RETURN_FALSE ;
}
im = gdImageCreateFromPng ( fp ) ;
fflush ( fp ) ;
fclose ( fp ) ;
ZEND_REGISTER_RESOURCE ( return_value , im , GDG ( le_gd ) ) ;
1999-10-17 22:57:49 +08:00
}
/* }}} */
1999-11-11 02:57:19 +08:00
/* {{{ proto int imagepng(int im [, string filename])
1999-11-25 06:04:49 +08:00
Output image to browser or file */
1999-12-18 05:50:07 +08:00
PHP_FUNCTION ( imagepng )
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * file ;
gdImagePtr im ;
char * fn = NULL ;
FILE * fp ;
int argc ;
int output = 1 ;
GDLS_FETCH ( ) ;
argc = ARG_COUNT ( ht ) ;
if ( argc < 1 | | argc > 2 | | zend_get_parameters_ex ( argc , & imgind , & file ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
ZEND_FETCH_RESOURCE ( im , gdImagePtr , imgind , - 1 , " Image " , GDG ( le_gd ) ) ;
if ( argc = = 2 ) {
convert_to_string_ex ( file ) ;
fn = ( * file ) - > value . str . val ;
if ( ! fn | | fn = = empty_string | | php_check_open_basedir ( fn ) ) {
php_error ( E_WARNING , " ImagePng: Invalid filename " ) ;
RETURN_FALSE ;
}
}
if ( argc = = 2 ) {
fp = fopen ( fn , " wb " ) ;
if ( ! fp ) {
php_error ( E_WARNING , " ImagePng: unable to open %s for writing " , fn ) ;
RETURN_FALSE ;
}
gdImagePng ( im , fp ) ;
fflush ( fp ) ;
fclose ( fp ) ;
}
else {
int b ;
FILE * tmp ;
char buf [ 4096 ] ;
tmp = tmpfile ( ) ;
if ( tmp = = NULL ) {
php_error ( E_WARNING , " Unable to open temporary file " ) ;
RETURN_FALSE ;
}
output = php_header ( ) ;
if ( output ) {
gdImagePng ( im , tmp ) ;
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 */
}
RETURN_TRUE ;
}
/* }}} */
1999-11-25 05:43:54 +08:00
# endif /* HAVE_GD_PNG */
# ifdef HAVE_GD_GIF
1999-10-17 22:57:49 +08:00
1999-04-16 20:15:38 +08:00
/* {{{ proto int imagecreatefromgif(string filename)
1999-11-25 06:04:49 +08:00
Create a new image from file or URL */
1999-07-24 00:03:18 +08:00
PHP_FUNCTION ( imagecreatefromgif )
{
2000-02-29 00:52:03 +08:00
zval * * file ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
char * fn = NULL ;
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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
fn = ( * file ) - > value . str . val ;
1999-04-16 20:15:38 +08:00
# if WIN32|WINNT
2000-02-29 00:52:03 +08:00
fp = 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 ) {
1999-12-18 03:16:50 +08:00
php_strip_url_passwd ( fn ) ;
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING ,
2000-02-29 00:52:03 +08:00
" ImageCreateFromGif: Unable to open %s for reading " , fn ) ;
1999-04-16 20:15:38 +08:00
RETURN_FALSE ;
}
2000-02-29 00:52:03 +08:00
im = gdImageCreateFromGif ( fp ) ;
1999-04-16 20:15:38 +08:00
fflush ( fp ) ;
fclose ( fp ) ;
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
}
/* }}} */
1999-11-11 02:57:19 +08:00
/* {{{ proto int imagegif(int im [, string filename])
1999-11-25 06:04:49 +08:00
Output image to browser or file */
2000-02-29 00:52:03 +08:00
PHP_FUNCTION ( imagegif )
1999-10-17 22:57:49 +08:00
{
2000-02-29 00:52:03 +08:00
zval * * imgind , * * file ;
1999-10-17 22:57:49 +08:00
gdImagePtr im ;
char * fn = NULL ;
FILE * fp ;
int argc ;
int output = 1 ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-10-17 22:57:49 +08:00
argc = ARG_COUNT ( ht ) ;
2000-02-29 00:52:03 +08:00
if ( argc < 1 | | argc > 2 | | zend_get_parameters_ex ( argc , & imgind , & file ) = = FAILURE ) {
1999-10-17 22:57:49 +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-10-17 22:57:49 +08:00
if ( argc = = 2 ) {
2000-02-29 00:52:03 +08:00
convert_to_string_ex ( file ) ;
fn = ( * file ) - > value . str . val ;
1999-12-18 03:16:50 +08:00
if ( ! fn | | fn = = empty_string | | php_check_open_basedir ( fn ) ) {
1999-10-17 22:57:49 +08:00
php_error ( E_WARNING , " ImageGif: Invalid filename " ) ;
RETURN_FALSE ;
}
}
if ( argc = = 2 ) {
fp = fopen ( fn , " wb " ) ;
if ( ! fp ) {
php_error ( E_WARNING , " ImageGif: unable to open %s for writing " , fn ) ;
RETURN_FALSE ;
}
2000-02-29 00:52:03 +08:00
gdImageGif ( im , fp ) ;
1999-10-17 22:57:49 +08:00
fflush ( fp ) ;
fclose ( fp ) ;
}
else {
int b ;
FILE * tmp ;
char buf [ 4096 ] ;
tmp = tmpfile ( ) ;
if ( tmp = = NULL ) {
php_error ( E_WARNING , " Unable to open temporary file " ) ;
RETURN_FALSE ;
}
1999-12-18 03:51:39 +08:00
output = php_header ( ) ;
1999-10-17 22:57:49 +08:00
if ( output ) {
2000-02-29 00:52:03 +08:00
gdImageGif ( im , tmp ) ;
1999-10-17 22:57:49 +08:00
fseek ( tmp , 0 , SEEK_SET ) ;
# if APACHE && defined(CHARSET_EBCDIC)
1999-12-12 18:53:45 +08:00
{
SLS_FETCH ( ) ;
/* This is a binary file already: avoid EBCDIC->ASCII conversion */
ap_bsetflag ( ( ( request_rec * ) SG ( server_context ) ) - > connection - > client , B_EBCDIC2ASCII , 0 ) ;
}
1999-10-17 22:57:49 +08:00
# 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 */
}
RETURN_TRUE ;
}
/* }}} */
1999-11-25 05:43:54 +08:00
# endif /* HAVE_GD_GIF */
1999-10-17 22:57:49 +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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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 ) ;
}
/* }}} */
/* 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 4 | | zend_get_parameters_ex ( 4 , & imgind , & 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 ( 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 ) ;
}
/* }}} */
/* {{{ 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 2 | | zend_get_parameters_ex ( 2 , & imgind , & index ) = = FAILURE ) {
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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 4 | | zend_get_parameters_ex ( 4 , & imgind , & 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 ( 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 4 | | zend_get_parameters_ex ( 4 , & imgind , & 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 ( 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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 ;
}
}
/* }}} */
/* {{{ 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
if ( ARG_COUNT ( ht ) ! = 4 | |
2000-02-29 00:52:03 +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 ;
}
/* }}} */
/* im, x1, y1, x2, y2, col */
/* {{{ 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
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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
if ( ARG_COUNT ( ht ) ! = 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
if ( ARG_COUNT ( ht ) ! = 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
if ( ARG_COUNT ( ht ) ! = 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
if ( ARG_COUNT ( ht ) ! = 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
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
zval * * IM , * * COL = NULL ;
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
switch ( ARG_COUNT ( ht ) ) {
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-02-29 00:52:03 +08:00
if ( ( * COL ) ! = NULL ) {
col = ( * COL ) - > value . lval ;
1999-04-16 20:15:38 +08:00
gdImageColorTransparent ( im , col ) ;
}
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
switch ( ARG_COUNT ( ht ) ) {
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 ;
gdPoint points [ PolyMaxPoints ] ;
int npoints , col , nelem , i ;
2000-02-29 00:52:03 +08:00
GDLS_FETCH ( ) ;
1999-04-16 20:15:38 +08:00
if ( ARG_COUNT ( ht ) ! = 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 ;
}
if ( npoints > PolyMaxPoints ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , " maximum %d points " , PolyMaxPoints ) ;
1999-04-16 20:15:38 +08:00
RETURN_FALSE ;
}
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 ) ;
}
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 ;
1999-12-20 23:23:38 +08:00
if ( ARG_COUNT ( ht ) ! = 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
if ( ARG_COUNT ( ht ) ! = 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
}
/* }}} */
/* {{{ proto int imagecopy(int dst_im, int src_im, int dstX, int dstY, int srcX, int srcY, int srcW, int srcH)
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
if ( ARG_COUNT ( ht ) ! = 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 ;
}
/* }}} */
/* {{{ proto int imagecopyresized(int dst_im, int src_im, int dstX, int dstY, int srcX, int srcY, int dstW, int dstH, int srcW, int srcH);
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
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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
/* {{{ 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
{
1999-12-18 05:50:07 +08:00
php_imagettftext_common ( INTERNAL_FUNCTION_PARAM_PASSTHRU , TTFTEXT_BBOX ) ;
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
{
1999-12-18 05:50:07 +08:00
php_imagettftext_common ( INTERNAL_FUNCTION_PARAM_PASSTHRU , TTFTEXT_DRAW ) ;
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 ;
1999-04-16 20:15:38 +08:00
gdImagePtr im ;
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-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 4 | | zend_get_parameters_ex ( 4 , & PTSIZE , & ANGLE , & FONTNAME , & C ) = = FAILURE ) {
1999-04-16 20:15:38 +08:00
WRONG_PARAM_COUNT ;
}
} else {
2000-02-29 00:52:03 +08:00
if ( ARG_COUNT ( ht ) ! = 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-02-09 06:21:43 +08:00
error = gdttf ( im , brect , col , fontname , ptsize , angle , x , y , str ) ;
1999-04-16 20:15:38 +08:00
if ( error ) {
1999-08-03 03:17:14 +08:00
php_error ( E_WARNING , 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
void php_free_ps_font ( int * font )
{
T1_DeleteFont ( * font ) ;
efree ( font ) ;
}
void php_free_ps_enc ( char * * enc )
{
T1_DeleteEncoding ( enc ) ;
}
/* {{{ proto int imagepsloadfont(string pathname)
Load a new font from specified file */
PHP_FUNCTION ( imagepsloadfont )
{
zval * * file ;
2000-02-29 00:52:03 +08:00
int f_ind ;
2000-02-25 14:43:51 +08:00
int * font ;
if ( ARG_COUNT ( ht ) ! = 1 | | zend_get_parameters_ex ( 1 , & file ) = = FAILURE ) {
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 ;
}
}
T1_LoadFont ( f_ind ) ;
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-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 )
{
pval * fnt ;
int l_ind , type ;
gd_ps_font * nf_ind , * of_ind ;
if ( ARG_COUNT ( ht ) ! = 1 | | zend_get_parameters ( ht , 1 , & fnt ) = = FAILURE ) {
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 ) ;
}
*/
/* }}} */
/* {{{ proto bool imagepsfreefont(int font_index)
Free memory used by a font */
PHP_FUNCTION ( imagepsfreefont )
{
zval * * fnt ;
int * f_ind ;
if ( ARG_COUNT ( ht ) ! = 1 | | zend_get_parameters_ex ( 1 , & fnt ) = = FAILURE ) {
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 ;
}
/* }}} */
/* {{{ proto bool imagepsencodefont(int font_index, string filename)
To change a fonts character encoding vector */
PHP_FUNCTION ( imagepsencodefont )
{
zval * * fnt , * * enc ;
char * * enc_vector ;
int * f_ind ;
if ( ARG_COUNT ( ht ) ! = 2 | | zend_get_parameters_ex ( 2 , & fnt , & enc ) = = FAILURE ) {
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 ;
}
/* }}} */
/* {{{ proto bool imagepsextendfont(int font_index, double extend)
Extend or or condense ( if extend < 1 ) a font */
PHP_FUNCTION ( imagepsextendfont )
{
zval * * fnt , * * ext ;
int * f_ind ;
if ( ARG_COUNT ( ht ) ! = 2 | | zend_get_parameters_ex ( 2 , & fnt , & ext ) = = FAILURE ) {
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 ;
}
/* }}} */
/* {{{ proto bool imagepsslantfont(int font_index, double slant)
Slant a font */
PHP_FUNCTION ( imagepsslantfont )
{
zval * * fnt , * * slt ;
int * f_ind ;
if ( ARG_COUNT ( ht ) ! = 2 | | zend_get_parameters_ex ( 2 , & fnt , & slt ) = = FAILURE ) {
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 ;
}
/* }}} */
/* {{{ 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 )
{
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 ;
switch ( ARG_COUNT ( ht ) ) {
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 ) ;
}
if ( T1_errno ) RETURN_FALSE ;
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 ) {
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 ) ;
}
/* }}} */
/* {{{ 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 )
{
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 } ;
switch ( ARG_COUNT ( ht ) ) {
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 ) ) ;
}
/* }}} */
# endif /* HAVE_LIBT1 */
# endif /* HAVE_LIBGD */
1999-04-16 20:15:38 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
*/