#ifdef PERL_CAPI
#define WIN32IO_IS_STDIO
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <gd.h>
#include <gdfontg.h>
#include <gdfontl.h>
#include <gdfontmb.h>
#include <gdfonts.h>
#include <gdfontt.h>
#include <errno.h>
#ifdef FCGI
#include <fcgi_stdio.h>
#else
#ifdef USE_SFIO
#include <config.h>
#else
#include <stdio.h>
#endif
#include <perlio.h>
#endif
/* Copyright 1995 - 1998, Lincoln D. Stein. See accompanying README file for
usage restrictions */
#ifndef PERL_REVISION
# ifndef __PATCHLEVEL_H_INCLUDED__
# include "patchlevel.h"
# endif
# ifndef PERL_REVISION
# define PERL_REVISION (5)
/* Replace: 1 */
# define PERL_VERSION PATCHLEVEL
# define PERL_SUBVERSION SUBVERSION
/* Replace PERL_PATCHLEVEL with PERL_VERSION */
/* Replace: 0 */
# endif
#endif
#if (PERL_VERSION == 5) && (PERL_SUBVERSION==3)
#ifndef PL_na
# define PL_na na
#endif
#ifndef SvPV_nolen
# define SvPV_nolen(sv) SvPV(sv, PL_na)
#endif
#endif /* 5.00503 */
#ifdef WIN32
#define snprintf _snprintf
#endif
#ifndef START_MY_CXT
static truecolor_default = 0;
#endif
static int
not_here(char *s)
{
croak("%s not implemented on this architecture", s);
return -1;
}
static double
constant(char *name)
{
errno = 0;
switch (*name) {
case 'A':
break;
case 'B':
break;
case 'C':
break;
case 'D':
break;
case 'E':
break;
case 'F':
break;
case 'G':
if (strEQ(name, "GD_CMP_IMAGE"))
#ifdef GD_CMP_IMAGE
return GD_CMP_IMAGE;
#else
goto not_there;
#endif
if (strEQ(name, "GD_CMP_NUM_COLORS"))
#ifdef GD_CMP_NUM_COLORS
return GD_CMP_NUM_COLORS;
#else
goto not_there;
#endif
if (strEQ(name, "GD_CMP_COLOR"))
#ifdef GD_CMP_COLOR
return GD_CMP_COLOR;
#else
goto not_there;
#endif
if (strEQ(name, "GD_CMP_SIZE_X"))
#ifdef GD_CMP_SIZE_X
return GD_CMP_SIZE_X;
#else
goto not_there;
#endif
if (strEQ(name, "GD_CMP_SIZE_Y"))
#ifdef GD_CMP_SIZE_Y
return GD_CMP_SIZE_Y;
#else
goto not_there;
#endif
if (strEQ(name, "GD_CMP_TRANSPARENT"))
#ifdef GD_CMP_TRANSPARENT
return GD_CMP_TRANSPARENT;
#else
goto not_there;
#endif
if (strEQ(name, "GD_CMP_BACKGROUND"))
#ifdef GD_CMP_BACKGROUND
return GD_CMP_BACKGROUND;
#else
goto not_there;
#endif
if (strEQ(name, "GD_CMP_INTERLACE"))
#ifdef GD_CMP_INTERLACE
return GD_CMP_INTERLACE;
#else
goto not_there;
#endif
if (strEQ(name, "GD_CMP_TRUECOLOR"))
#ifdef GD_CMP_TRUECOLOR
return GD_CMP_TRUECOLOR;
#else
goto not_there;
#endif
break;
case 'H':
break;
case 'I':
break;
case 'J':
break;
case 'K':
break;
case 'L':
break;
case 'M':
break;
case 'N':
break;
case 'O':
break;
case 'P':
break;
case 'Q':
break;
case 'R':
break;
case 'S':
break;
case 'T':
break;
case 'U':
break;
case 'V':
break;
case 'W':
break;
case 'X':
break;
case 'Y':
break;
case 'Z':
break;
case 'a':
break;
case 'b':
break;
case 'c':
break;
case 'd':
break;
case 'e':
break;
case 'f':
break;
case 'g':
if (strEQ(name, "gdBrushed"))
#ifdef gdBrushed
return gdBrushed;
#else
goto not_there;
#endif
if (strEQ(name, "gdDashSize"))
#ifdef gdDashSize
return gdDashSize;
#else
goto not_there;
#endif
if (strEQ(name, "gdMaxColors"))
#ifdef gdMaxColors
return gdMaxColors;
#else
goto not_there;
#endif
if (strEQ(name, "gdStyled"))
#ifdef gdStyled
return gdStyled;
#else
goto not_there;
#endif
if (strEQ(name, "gdStyledBrushed"))
#ifdef gdStyledBrushed
return gdStyledBrushed;
#else
goto not_there;
#endif
if (strEQ(name, "gdTiled"))
#ifdef gdTiled
return gdTiled;
#else
goto not_there;
#endif
if (strEQ(name, "gdTransparent"))
#ifdef gdTransparent
return gdTransparent;
#else
goto not_there;
#endif
if (strEQ(name,"gdAntiAliased"))
#ifdef gdAntiAliased
return gdAntiAliased;
#else
goto not_there;
#endif
if (strEQ(name,"gdAntiAliased"))
#ifdef gdAntiAliased
return gdAntiAliased;
#else
goto not_there;
#endif
if (strEQ(name,"gdArc"))
#ifdef gdArc
return gdArc;
#else
goto not_there;
#endif
if (strEQ(name,"gdPie"))
#ifdef gdPie
return gdPie;
#else
goto not_there;
#endif
if (strEQ(name,"gdChord"))
#ifdef gdChord
return gdChord;
#else
goto not_there;
#endif
if (strEQ(name,"gdNoFill"))
#ifdef gdNoFill
return gdNoFill;
#else
goto not_there;
#endif
if (strEQ(name,"gdEdged"))
#ifdef gdEdged
return gdEdged;
#else
goto not_there;
#endif
if (strEQ(name,"gdAlphaMax"))
#ifdef gdAlphaMax
return gdAlphaMax;
#else
goto not_there;
#endif
if (strEQ(name,"gdAlphaOpaque"))
#ifdef gdAlphaOpaque
return gdAlphaOpaque;
#else
goto not_there;
#endif
if (strEQ(name,"gdAlphaTransparent"))
#ifdef gdAlphaTransparent
return gdAlphaTransparent;
#else
goto not_there;
#endif
break;
case 'h':
break;
case 'i':
break;
case 'j':
break;
case 'k':
break;
case 'l':
break;
case 'm':
break;
case 'n':
break;
case 'o':
break;
case 'p':
break;
case 'q':
break;
case 'r':
break;
case 's':
break;
case 't':
break;
case 'u':
break;
case 'v':
break;
case 'w':
break;
case 'x':
break;
case 'y':
break;
case 'z':
break;
}
errno = EINVAL;
return 0;
not_there:
errno = ENOENT;
return 0;
}
typedef gdImagePtr GD__Image;
typedef gdFontPtr GD__Font;
typedef PerlIO * InputStream;
#ifdef PERL_OBJECT
# ifdef WIN32
#define GDIMAGECREATEFROMPNG(x) gdImageCreateFromPng((FILE*)x)
#define GDIMAGECREATEFROMXBM(x) gdImageCreateFromXbm((FILE*)x)
#define GDIMAGECREATEFROMJPEG(x) gdImageCreateFromJpeg((FILE*)x)
#define GDIMAGECREATEFROMGIF(x) gdImageCreateFromGif((FILE*)x)
#define GDIMAGECREATEFROMWBMP(x) gdImageCreateFromWBMP((FILE*)x)
#define GDIMAGECREATEFROMGD(x) gdImageCreateFromGd((FILE*)x)
#define GDIMAGECREATEFROMGD2(x) gdImageCreateFromGd2((FILE*)x)
#define GDIMAGECREATEFROMGD2PART(x,a,b,c,d) gdImageCreateFromGd2Part((FILE*)x,a,b,c,d)
# endif
#else
# ifdef USE_PERLIO
#define GDIMAGECREATEFROMPNG(x) gdImageCreateFromPng(PerlIO_findFILE(x))
#define GDIMAGECREATEFROMXBM(x) gdImageCreateFromXbm(PerlIO_findFILE(x))
#define GDIMAGECREATEFROMJPEG(x) gdImageCreateFromJpeg(PerlIO_findFILE(x))
#define GDIMAGECREATEFROMGIF(x) gdImageCreateFromGif(PerlIO_findFILE(x))
#define GDIMAGECREATEFROMWBMP(x) gdImageCreateFromWBMP(PerlIO_findFILE(x))
#define GDIMAGECREATEFROMGD(x) gdImageCreateFromGd(PerlIO_findFILE(x))
#define GDIMAGECREATEFROMGD2(x) gdImageCreateFromGd2(PerlIO_findFILE(x))
#define GDIMAGECREATEFROMGD2PART(x,a,b,c,d) gdImageCreateFromGd2Part(PerlIO_findFILE(x),a,b,c,d)
# else
#define GDIMAGECREATEFROMPNG(x) gdImageCreateFromPng(x)
#define GDIMAGECREATEFROMXBM(x) gdImageCreateFromXbm(x)
#define GDIMAGECREATEFROMJPEG(x) gdImageCreateFromJpeg(x)
#define GDIMAGECREATEFROMGIF(x) gdImageCreateFromGif(x)
#define GDIMAGECREATEFROMWBMP(x) gdImageCreateFromWBMP(x)
#define GDIMAGECREATEFROMGD(x) gdImageCreateFromGd(x)
#define GDIMAGECREATEFROMGD2(x) gdImageCreateFromGd2(x)
#define GDIMAGECREATEFROMGD2PART(x,a,b,c,d) gdImageCreateFromGd2Part(x,a,b,c,d)
# endif
#endif
#define littleendian(a) \
(a[3]<<24)+(a[2]<<16)+(a[1]<<8)+a[0]
/* definitions required to create images from in-memory buffers */
typedef struct bufIOCtx {
gdIOCtx ctx;
char* data;
int length;
int pos;
} bufIOCtx;
typedef struct bufIOCtx *bufIOCtxPtr;
static int bufGetC (gdIOCtxPtr ctx) {
bufIOCtxPtr bctx = (bufIOCtxPtr) ctx;
if (bctx->pos >= bctx->length) return EOF;
return bctx->data[bctx->pos];
}
static int bufGetBuf (gdIOCtxPtr ctx, void* buf, int len) {
bufIOCtxPtr bctx = (bufIOCtxPtr) ctx;
int remain,rlen;
remain = bctx->length - bctx->pos;
if (remain >= len) {
rlen = len;
} else {
if (remain <= 0) return EOF;
rlen = remain;
}
memcpy(buf,(void*)(bctx->data + bctx->pos),rlen);
bctx->pos += rlen;
return rlen;
}
static int bufSeek (gdIOCtxPtr ctx, const int pos) {
bufIOCtxPtr bctx = (bufIOCtxPtr) ctx;
bctx->pos = pos;
if (bctx->pos > bctx->length)
bctx->pos = bctx->length;
return TRUE;
}
static long bufTell (gdIOCtxPtr ctx) {
bufIOCtxPtr bctx = (bufIOCtxPtr) ctx;
return bctx->pos;
}
static void bufFree(gdIOCtxPtr ctx) {
Safefree(ctx);
}
static gdIOCtx* newDynamicCtx (char* data, int length) {
bufIOCtxPtr ctx;
#ifdef Newz
Newz(0,ctx,1,bufIOCtx);
#else
Newxz(ctx,1,bufIOCtx);
#endif
if (ctx == NULL) return NULL;
ctx->data = data;
ctx->pos = 0;
ctx->length = length;
ctx->ctx.getC = bufGetC;
ctx->ctx.getBuf = bufGetBuf;
ctx->ctx.seek = bufSeek;
ctx->ctx.tell = bufTell;
ctx->ctx.gd_free = bufFree;
ctx->ctx.putC = NULL;
ctx->ctx.putBuf = NULL;
return (gdIOCtx*)ctx;
}
/* helper routines for image transformation */
static GD__Image
gd_cloneDim(GD__Image src, int x, int y) {
GD__Image dst;
if (gdImageTrueColor(src)) {
dst = (GD__Image) gdImageCreateTrueColor(x,y);
} else {
int i;
dst = (GD__Image) gdImageCreatePalette(x,y);
/* copy across the palette information */
for (i = 0; i < gdMaxColors; i++) {
dst->red[i] = src->red[i];
dst->green[i] = src->green[i];
dst->blue[i] = src->blue[i];
dst->alpha[i] = src->alpha[i];
dst->open[i] = src->open[i];
}
dst->colorsTotal = src->colorsTotal;
dst->transparent = src->transparent;
dst->interlace = src->interlace;
dst->thick = src->thick;
}
return(dst);
}
void
get_xformbounds(GD__Image src, int *x, int *y,
int *x1, int *y1, int *x2, int *y2)
{
*x = gdImageSX(src);
*y = gdImageSY(src);
*x1 = *x - 1;
*y1 = *y - 1;
*x2 = *x / 2;
*y2 = *y / 2;
}
/* helper macros for image transformations */
#define GDGetImagePixel(im,x,y) \
gdImageTrueColor(im) ? \
gdImageTrueColorPixel(im,x,y) : \
gdImagePalettePixel(im,x,y)
#define GDSetImagePixel(im,x,y,p) \
gdImageTrueColor(im) ? \
(gdImageTrueColorPixel(im,x,y) = p) : \
(gdImagePalettePixel(im,x,y) = p)
#define GDCopyImagePixel(dst,dx,dy,src,sx,sy) \
gdImageTrueColor(src) ? \
(gdImageTrueColorPixel(dst,dx,dy)=gdImageTrueColorPixel(src,sx,sy)) : \
(gdImagePalettePixel(dst,dx,dy)=gdImagePalettePixel(src,sx,sy))
/* Check the image format being returned */
void
gd_chkimagefmt(GD__Image image, int truecolor) {
if ((image != NULL)
&& !truecolor) { /* return a palette image */
if (gdImageTrueColor(image)) {
gdImageTrueColorToPalette(image,1,gdMaxColors);
}
}
}
/* GLOBAL THREAD-SAFE DATA */
#ifdef START_MY_CXT
#define MY_CXT_KEY "GD::_guts" XS_VERSION
typedef struct {
/* Current image true color default
* 0 - create palette based images by default
* 1 - create true color images by default
*/
int truecolor_default;
} my_cxt_t;
START_MY_CXT
#endif
MODULE = GD PACKAGE = GD
double
constant(name)
char * name
BOOT:
{
#ifdef START_MY_CXT
MY_CXT_INIT;
MY_CXT.truecolor_default = 0;
#endif
}
MODULE = GD PACKAGE = GD::Image PREFIX=gd
# Set the new image true color default
# 0 - create palette based images by default
# 1 - create true color images by default
int
gdtrueColor(packname="GD::Image", ...)
char * packname
PROTOTYPE: $$
PREINIT:
#ifdef START_MY_CXT
dMY_CXT;
int previous_value = MY_CXT.truecolor_default;
#else
int previous_value = truecolor_default;
#endif
CODE:
{
if (items > 1)
#ifdef START_MY_CXT
MY_CXT.truecolor_default = (int)SvIV(ST(1));
#else
truecolor_default = (int)SvIV(ST(1));
#endif
RETVAL = previous_value;
}
OUTPUT:
RETVAL
GD::Image
gd_new(packname="GD::Image", x=64, y=64, ...)
char * packname
int x
int y
PROTOTYPE: $;$$$
PREINIT:
#ifdef START_MY_CXT
dMY_CXT;
int truecolor = MY_CXT.truecolor_default;
#else
int truecolor = truecolor_default;
#endif
CODE:
{
gdImagePtr theImage;
if (items > 3)
truecolor = (int)SvIV(ST(3));
if (truecolor) {
theImage = (GD__Image) gdImageCreateTrueColor(x,y);
} else {
theImage = (GD__Image) gdImageCreate(x,y);
}
RETVAL = theImage;
}
OUTPUT:
RETVAL
#ifdef HAVE_PNG
GD::Image
gd_newFromPng(packname="GD::Image", filehandle, ...)
char * packname
InputStream filehandle
PROTOTYPE: $$;$
PREINIT:
#ifdef START_MY_CXT
dMY_CXT;
int truecolor = MY_CXT.truecolor_default;
#else
int truecolor = truecolor_default;
#endif
CODE:
RETVAL = (GD__Image) GDIMAGECREATEFROMPNG(filehandle);
if (items > 2) truecolor = (int)SvIV(ST(2));
gd_chkimagefmt(RETVAL, truecolor);
OUTPUT:
RETVAL
GD::Image
gdnewFromPngData(packname="GD::Image", imageData, ...)
char * packname
SV * imageData
PROTOTYPE: $$;$
PREINIT:
gdIOCtx* ctx;
char* data;
STRLEN len;
#ifdef START_MY_CXT
dMY_CXT;
int truecolor = MY_CXT.truecolor_default;
#else
int truecolor = truecolor_default;
#endif
CODE:
data = SvPV(imageData,len);
ctx = newDynamicCtx(data,len);
RETVAL = (GD__Image) gdImageCreateFromPngCtx(ctx);
(ctx->gd_free)(ctx);
if (items > 2) truecolor = (int)SvIV(ST(2));
gd_chkimagefmt(RETVAL, truecolor);
OUTPUT:
RETVAL
#endif
GD::Image
gdnewFromGdData(packname="GD::Image", imageData)
char * packname
SV * imageData
PROTOTYPE: $$
PREINIT:
char* data;
STRLEN len;
CODE:
data = SvPV(imageData,len);
RETVAL = (GD__Image) gdImageCreateFromGdPtr(len,(void*) data);
OUTPUT:
RETVAL
GD::Image
gdnewFromGd2Data(packname="GD::Image", imageData)
char * packname
SV * imageData
PROTOTYPE: $$
PREINIT:
char* data;
STRLEN len;
CODE:
data = SvPV(imageData,len);
RETVAL = (GD__Image) gdImageCreateFromGd2Ptr(len,(void*) data);
OUTPUT:
RETVAL
#ifdef HAVE_JPEG
GD::Image
gdnewFromJpegData(packname="GD::Image", imageData, ...)
char * packname
SV * imageData
PROTOTYPE: $$;$
PREINIT:
gdIOCtx* ctx;
char* data;
STRLEN len;
#ifdef START_MY_CXT
dMY_CXT;
int truecolor = MY_CXT.truecolor_default;
#else
int truecolor = truecolor_default;
#endif
CODE:
data = SvPV(imageData,len);
ctx = newDynamicCtx(data,len);
RETVAL = (GD__Image) gdImageCreateFromJpegCtx(ctx);
(ctx->gd_free)(ctx);
if (items > 2) truecolor = (int)SvIV(ST(2));
gd_chkimagefmt(RETVAL, truecolor);
OUTPUT:
RETVAL
#endif
GD::Image
gdnewFromWBMPData(packname="GD::Image", imageData, ...)
char * packname
SV * imageData
PROTOTYPE: $$;$
PREINIT:
gdIOCtx* ctx;
char* data;
STRLEN len;
#ifdef START_MY_CXT
dMY_CXT;
int truecolor = MY_CXT.truecolor_default;
#else
int truecolor = truecolor_default;
#endif
CODE:
data = SvPV(imageData,len);
ctx = newDynamicCtx(data,len);
RETVAL = (GD__Image) gdImageCreateFromWBMPCtx(ctx);
(ctx->gd_free)(ctx);
if (items > 2) truecolor = (int)SvIV(ST(2));
gd_chkimagefmt(RETVAL, truecolor);
OUTPUT:
RETVAL
GD::Image
gd_newFromXbm(packname="GD::Image", filehandle)
char * packname
InputStream filehandle
PROTOTYPE: $$
CODE:
RETVAL = GDIMAGECREATEFROMXBM(filehandle);
OUTPUT:
RETVAL
GD::Image
gd_newFromGd(packname="GD::Image", filehandle)
char * packname
InputStream filehandle
PROTOTYPE: $$
CODE:
RETVAL = GDIMAGECREATEFROMGD(filehandle);
OUTPUT:
RETVAL
GD::Image
gd_newFromGd2(packname="GD::Image", filehandle)
char * packname
InputStream filehandle
PROTOTYPE: $$
CODE:
RETVAL = GDIMAGECREATEFROMGD2(filehandle);
OUTPUT:
RETVAL
#ifdef HAVE_JPEG
GD::Image
gd_newFromJpeg(packname="GD::Image", filehandle, ...)
char * packname
InputStream filehandle
PROTOTYPE: $$;$
PREINIT:
#ifdef START_MY_CXT
dMY_CXT;
int truecolor = MY_CXT.truecolor_default;
#else
int truecolor = truecolor_default;
#endif
CODE:
RETVAL = GDIMAGECREATEFROMJPEG(filehandle);
if (items > 2) truecolor = (int)SvIV(ST(2));
gd_chkimagefmt(RETVAL, truecolor);
OUTPUT:
RETVAL
#endif
GD::Image
gd_newFromWBMP(packname="GD::Image", filehandle)
char * packname
InputStream filehandle
PROTOTYPE: $$
PREINIT:
gdImagePtr img;
SV* errormsg;
CODE:
img = GDIMAGECREATEFROMWBMP(filehandle);
if (img == NULL) {
errormsg = perl_get_sv("@",0);
if (errormsg != NULL)
sv_setpv(errormsg,"libgd was not built with WBMP support\n");
XSRETURN_EMPTY;
}
RETVAL = img;
OUTPUT:
RETVAL
GD::Image
gdnewFromXpm(packname="GD::Image", filename)
char * packname
char * filename
PROTOTYPE: $$
PREINIT:
gdImagePtr img;
SV* errormsg;
CODE:
#ifdef HAVE_XPM
img = (GD__Image) gdImageCreateFromXpm(filename);
if (img == NULL) {
errormsg = perl_get_sv("@",0);
if (errormsg != NULL)
sv_setpv(errormsg,"libgd was not built with xpm support\n");
XSRETURN_EMPTY;
}
RETVAL = img;
#else
errormsg = perl_get_sv("@",0);
sv_setpv(errormsg,"libgd was not built with xpm support\n");
XSRETURN_EMPTY;
#endif
OUTPUT:
RETVAL
GD::Image
gd_newFromGd2Part(packname="GD::Image", filehandle,srcX,srcY,width,height)
char * packname
InputStream filehandle
int srcX
int srcY
int width
int height
PROTOTYPE: $$$$$$
CODE:
RETVAL = GDIMAGECREATEFROMGD2PART(filehandle,srcX,srcY,width,height);
OUTPUT:
RETVAL
#ifdef HAVE_GIF
GD::Image
gd_newFromGif(packname="GD::Image", filehandle)
char * packname
InputStream filehandle
PROTOTYPE: $$;$
PREINIT:
#ifdef START_MY_CXT
dMY_CXT;
int truecolor = MY_CXT.truecolor_default;
#else
int truecolor = truecolor_default;
#endif
CODE:
RETVAL = GDIMAGECREATEFROMGIF(filehandle);
OUTPUT:
RETVAL
GD::Image
gdnewFromGifData(packname="GD::Image", imageData)
char * packname
SV * imageData
PROTOTYPE: $$;$
PREINIT:
gdIOCtx* ctx;
char* data;
STRLEN len;
#ifdef START_MY_CXT
dMY_CXT;
int truecolor = MY_CXT.truecolor_default;
#else
int truecolor = truecolor_default;
#endif
CODE:
data = SvPV(imageData,len);
ctx = newDynamicCtx(data,len);
RETVAL = (GD__Image) gdImageCreateFromGifCtx(ctx);
(ctx->gd_free)(ctx);
OUTPUT:
RETVAL
#endif
void
gdDESTROY(image)
GD::Image image
PROTOTYPE: $
CODE:
{
gdImageDestroy(image);
}
SV* gdSTORABLE_freeze(image,cloning)
GD::Image image
int cloning
PROTOTYPE: $$
CODE:
{
void* data;
int size;
if (cloning) XSRETURN_UNDEF;
data = gdImageGd2Ptr(image,0,GD2_FMT_COMPRESSED,&size);
RETVAL=newSVpvn((char*)data,size);
gdFree(data);
}
OUTPUT:
RETVAL
void gdSTORABLE_thaw(object,cloning,serialized)
SV* object
int cloning
SV* serialized
PREINIT:
STRLEN length;
void* data;
GD__Image image;
CODE:
{
if (cloning) XSRETURN_UNDEF;
data = (void*) SvPV(serialized,length);
image = gdImageCreateFromGd2Ptr(length,data);
/* sv_setiv(SvRV(object),(int)image); */
sv_setiv(SvRV(object),(long int)image);
}
#ifdef HAVE_PNG
SV*
gdpng(image, ...)
GD::Image image
PROTOTYPE: $;$
PREINIT:
CODE:
{
void* data;
int size;
int level;
if (items > 1) {
level = (int)SvIV(ST(1));
data = (void *) gdImagePngPtrEx(image,&size,level);
} else {
data = (void *) gdImagePngPtr(image,&size);
}
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
}
OUTPUT:
RETVAL
#endif
#ifdef HAVE_JPEG
SV*
gdjpeg(image,quality=-1)
GD::Image image
int quality
PROTOTYPE: $
PREINIT:
SV* errormsg;
CODE:
{
void* data;
int size;
data = (void *) gdImageJpegPtr(image,&size,quality);
if (data == NULL) {
errormsg = perl_get_sv("@",0);
if (errormsg != NULL)
sv_setpv(errormsg,"libgd was not built with jpeg support\n");
XSRETURN_EMPTY;
}
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
}
OUTPUT:
RETVAL
#endif
SV*
gdgifanimbegin(image,globalcm=-1,loops=-1)
GD::Image image
int globalcm
int loops
PROTOTYPE: $$$
PREINIT:
CODE:
{
void* data;
int size;
#ifdef HAVE_ANIMGIF
data = (void *) gdImageGifAnimBeginPtr(image,&size,globalcm,loops);
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
#else
die("libgd 2.0.33 or higher required for animated GIF support");
#endif
}
OUTPUT:
RETVAL
SV*
gdgifanimadd(image,localcm=-1,leftofs=-1,topofs=-1,delay=-1,disposal=-1,previm=0)
GD::Image image
int localcm
int leftofs
int topofs
int delay
int disposal
GD::Image previm
PROTOTYPE: $$$$$$$
CODE:
{
void* data;
int size;
#ifdef HAVE_ANIMGIF
data = (void *) gdImageGifAnimAddPtr(image,&size,localcm,leftofs,topofs,delay,disposal,previm);
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
#else
die("libgd 2.0.33 or higher required for animated GIF support");
#endif
}
OUTPUT:
RETVAL
SV*
gdgifanimend(image)
GD::Image image
PROTOTYPE: $
CODE:
{
void* data;
int size;
#ifdef HAVE_ANIMGIF
data = (void *) gdImageGifAnimEndPtr(&size);
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
#else
die("libgd 2.0.33 or higher required for animated GIF support");
#endif
}
OUTPUT:
RETVAL
SV*
gdwbmp(image,fg)
GD::Image image
int fg
PROTOTYPE: $
PREINIT:
SV* errormsg;
CODE:
{
void* data;
int size;
data = (void *) gdImageWBMPPtr(image,&size,fg);
if (data == NULL) {
errormsg = perl_get_sv("@",0);
if (errormsg != NULL)
sv_setpv(errormsg,"libgd was not built with WBMP support\n");
XSRETURN_EMPTY;
}
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
}
OUTPUT:
RETVAL
#ifdef HAVE_GIF
SV*
gdgif(image)
GD::Image image
PROTOTYPE: $
PREINIT:
SV* errormsg;
CODE:
{
void* data;
int size;
data = (void *) gdImageGifPtr(image,&size);
if (data == NULL) {
errormsg = perl_get_sv("@",0);
if (errormsg != NULL)
sv_setpv(errormsg,"libgd was not built with gif support\n");
XSRETURN_EMPTY;
}
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
}
OUTPUT:
RETVAL
#endif
SV*
gdgd(image)
GD::Image image
PROTOTYPE: $
CODE:
{
void* data;
int size;
data = gdImageGdPtr(image,&size);
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
}
OUTPUT:
RETVAL
SV*
gdgd2(image)
GD::Image image
PROTOTYPE: $
CODE:
{
void* data;
int size;
data = gdImageGd2Ptr(image,0,GD2_FMT_COMPRESSED,&size);
RETVAL = newSVpvn((char*) data,size);
gdFree(data);
}
OUTPUT:
RETVAL
int
gdtransparent(image, ...)
GD::Image image
PROTOTYPE: $;$
CODE:
{
int color;
if (items > 1) {
color=(int)SvIV(ST(1));
gdImageColorTransparent(image,color);
}
RETVAL = gdImageGetTransparent(image);
}
OUTPUT:
RETVAL
void
gdgetBounds(image)
GD::Image image
PROTOTYPE: $
PPCODE:
{
int sx,sy;
sx = gdImageSX(image);
sy = gdImageSY(image);
EXTEND(sp,2);
PUSHs(sv_2mortal(newSViv(sx)));
PUSHs(sv_2mortal(newSViv(sy)));
}
int
gdisTrueColor(image)
GD::Image image
PROTOTYPE: $
CODE:
{
RETVAL=gdImageTrueColor(image);
}
OUTPUT:
RETVAL
void
gdtrueColorToPalette(image, dither=0, colors=gdMaxColors)
GD::Image image
int dither
int colors
PROTOTYPE: $;$$
CODE:
{
gdImageTrueColorToPalette(image,dither,colors);
}
void
gdrgb(image,color)
GD::Image image
int color
PROTOTYPE: $$
PPCODE:
{
int r,g,b;
r = gdImageRed(image,color);
g = gdImageGreen(image,color);
b = gdImageBlue(image,color);
EXTEND(sp,3);
PUSHs(sv_2mortal(newSViv(r)));
PUSHs(sv_2mortal(newSViv(g)));
PUSHs(sv_2mortal(newSViv(b)));
}
int
gdboundsSafe(image,x,y)
GD::Image image
int x
int y
PROTOTYPE: $$$
CODE:
{
RETVAL=gdImageBoundsSafe(image,x,y);
if (RETVAL == 0)
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
int
gdgetPixel(image,x,y)
GD::Image image
int x
int y
PROTOTYPE: $$$
CODE:
{
RETVAL=gdImageGetPixel(image,x,y);
}
OUTPUT:
RETVAL
void
gdsetPixel(image,x,y,color)
GD::Image image
int x
int y
int color
PROTOTYPE: $$$$
CODE:
{
gdImageSetPixel(image,x,y,color);
}
GD::Image
gdcopyRotate90(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j;
GD__Image dst;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
dst = (GD__Image) gd_cloneDim(src, y, x);
for (j=0;j<y;j++) {
for (i=0;i<x;i++) {
GDCopyImagePixel(dst,y1-j,i,src,i,j);
}
}
RETVAL = dst;
}
OUTPUT:
RETVAL
GD::Image
gdcopyRotate180(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j;
GD__Image dst;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
dst = (GD__Image) gd_cloneDim(src, x, y);
for (j=0;j<y;j++) {
for (i=0;i<x;i++) {
GDCopyImagePixel(dst,x1-i,y1-j,src,i,j);
}
}
RETVAL = dst;
}
OUTPUT:
RETVAL
GD::Image
gdcopyRotate270(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j;
GD__Image dst;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
dst = (GD__Image) gd_cloneDim(src, y, x);
for (i=0;i<x;i++) {
for (j=0;j<y;j++) {
GDCopyImagePixel(dst,j,x1-i,src,i,j);
}
}
RETVAL = dst;
}
OUTPUT:
RETVAL
GD::Image
gdcopyFlipHorizontal(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j;
GD__Image dst;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
dst = (GD__Image) gd_cloneDim(src, x, y);
for (j=0;j<y;j++) {
for (i=0;i<x;i++) {
GDCopyImagePixel(dst,x1-i,j,src,i,j);
}
}
RETVAL = dst;
}
OUTPUT:
RETVAL
GD::Image
gdcopyFlipVertical(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j;
GD__Image dst;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
dst = (GD__Image) gd_cloneDim(src, x, y);
for (j=0;j<y;j++) {
for (i=0;i<x;i++) {
GDCopyImagePixel(dst,i,y1-j,src,i,j);
}
}
RETVAL = dst;
}
OUTPUT:
RETVAL
GD::Image
gdcopyTranspose(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j;
GD__Image dst;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
dst = (GD__Image) gd_cloneDim(src, y, x);
for (j=0;j<y;j++) {
for (i=0;i<x;i++) {
GDCopyImagePixel(dst,j,i,src,i,j);
}
}
RETVAL = dst;
}
OUTPUT:
RETVAL
GD::Image
gdcopyReverseTranspose(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j;
GD__Image dst;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
dst = (GD__Image) gd_cloneDim(src, y, x);
for (j=0;j<y;j++) {
for (i=0;i<x;i++) {
GDCopyImagePixel(dst,y1-j,x1-i,src,i,j);
}
}
RETVAL = dst;
}
OUTPUT:
RETVAL
void
gdrotate180(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j, tmp;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
for (j=0;j<y2;j++) {
for (i=0;i<x;i++) {
tmp = GDGetImagePixel(src,x1-i,y1-j);
GDCopyImagePixel(src,x1-i,y1-j,src,i,j);
GDSetImagePixel(src,i,j,tmp);
}
}
}
void
gdcopyRotated(dst,src,dstX,dstY,srcX,srcY,srcW,srcH,angle)
GD::Image dst
GD::Image src
double dstX
double dstY
int srcX
int srcY
int srcW
int srcH
int angle
PROTOTYPE: $$$$$$$$$
CODE:
{
#ifdef VERSION_33
gdImageCopyRotated(dst,src,dstX,dstY,srcX,srcY,srcW,srcH,angle);
#else
die("libgd 2.0.33 or higher required for copyRotated support");
#endif
}
void
gdflipHorizontal(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j, tmp;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
for (j=0;j<y;j++) {
for (i=0;i<x2;i++) {
tmp = GDGetImagePixel(src,x1-i,j);
GDCopyImagePixel(src,x1-i,j,src,i,j);
GDSetImagePixel(src,i,j,tmp);
}
}
}
void
gdflipVertical(src)
GD::Image src
PROTOTYPE: $
CODE:
{
int x, y, x1, y1, x2, y2, i, j, tmp;
get_xformbounds(src, &x, &y, &x1, &y1, &x2, &y2);
for (j=0;j<y2;j++) {
for (i=0;i<x;i++) {
tmp = GDGetImagePixel(src,i,y1-j);
GDCopyImagePixel(src,i,y1-j,src,i,j);
GDSetImagePixel(src,i,j,tmp);
}
}
}
void
gdline(image,x1,y1,x2,y2,color)
GD::Image image
int x1
int y1
int x2
int y2
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageLine(image,x1,y1,x2,y2,color);
}
void
gddashedLine(image,x1,y1,x2,y2,color)
GD::Image image
int x1
int y1
int x2
int y2
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageDashedLine(image,x1,y1,x2,y2,color);
}
void
gdopenPolygon(image,poly,color)
GD::Image image
SV * poly
int color
PROTOTYPE: $$$
CODE:
{
dSP ;
int length,count ;
int x,y,i ;
gdPointPtr polyptr;
ENTER ;
SAVETMPS ;
PUSHMARK(sp) ;
XPUSHs(poly) ;
PUTBACK ;
count = perl_call_method("length",G_SCALAR) ;
SPAGAIN ;
if (count != 1)
croak("Didn't get a single result from GD::Poly::length() call.\n");
length = POPi ;
PUTBACK ;
FREETMPS ;
LEAVE ;
polyptr = (gdPointPtr)safemalloc(sizeof(gdPoint)*length);
if (polyptr == NULL)
croak("safemalloc() returned NULL in GD::Image::poly().\n");
for (i=0;i<length;i++) {
ENTER ;
SAVETMPS ;
PUSHMARK(sp) ;
XPUSHs(poly) ;
XPUSHs(sv_2mortal(newSViv(i))) ;
PUTBACK ;
count = perl_call_method("getPt",G_ARRAY) ;
SPAGAIN ;
if (count != 2)
croak("Didn't get a single result from GD::Poly::length() call.\n");
y = POPi ;
x = POPi ;
PUTBACK ;
FREETMPS ;
LEAVE ;
polyptr[i].x = x;
polyptr[i].y = y;
}
gdImagePolygon(image,polyptr,length,color);
safefree((char*) polyptr);
}
void
gdunclosedPolygon(image,poly,color)
GD::Image image
SV * poly
int color
PROTOTYPE: $$$
CODE:
{
dSP ;
int length,count ;
int x,y,i ;
gdPointPtr polyptr;
#ifdef HAVE_UNCLOSEDPOLY
ENTER ;
SAVETMPS ;
PUSHMARK(sp) ;
XPUSHs(poly) ;
PUTBACK ;
count = perl_call_method("length",G_SCALAR) ;
SPAGAIN ;
if (count != 1)
croak("Didn't get a single result from GD::Poly::length() call.\n");
length = POPi ;
PUTBACK ;
FREETMPS ;
LEAVE ;
polyptr = (gdPointPtr)safemalloc(sizeof(gdPoint)*length);
if (polyptr == NULL)
croak("safemalloc() returned NULL in GD::Image::poly().\n");
for (i=0;i<length;i++) {
ENTER ;
SAVETMPS ;
PUSHMARK(sp) ;
XPUSHs(poly) ;
XPUSHs(sv_2mortal(newSViv(i))) ;
PUTBACK ;
count = perl_call_method("getPt",G_ARRAY) ;
SPAGAIN ;
if (count != 2)
croak("Didn't get a single result from GD::Poly::length() call.\n");
y = POPi ;
x = POPi ;
PUTBACK ;
FREETMPS ;
LEAVE ;
polyptr[i].x = x;
polyptr[i].y = y;
}
gdImageOpenPolygon(image,polyptr,length,color);
safefree((char*) polyptr);
#else
die("libgd 2.0.33 or higher required for unclosed polygon support");
#endif
}
void
gdfilledPolygon(image,poly,color)
GD::Image image
SV * poly
int color
PROTOTYPE: $$$
CODE:
{
dSP ;
int length,count ;
int x,y,i ;
gdPointPtr polyptr;
ENTER ;
SAVETMPS ;
PUSHMARK(sp) ;
XPUSHs(poly) ;
PUTBACK ;
count = perl_call_method("length",G_SCALAR) ;
SPAGAIN ;
if (count != 1)
croak("Didn't get a single result from GD::Poly::length() call.\n");
length = POPi ;
PUTBACK ;
FREETMPS ;
LEAVE ;
polyptr = (gdPointPtr)safemalloc(sizeof(gdPoint)*length);
if (polyptr == NULL)
croak("safemalloc() returned NULL in GD::Image::poly().\n");
for (i=0;i<length;i++) {
ENTER ;
SAVETMPS ;
PUSHMARK(sp) ;
XPUSHs(poly) ;
XPUSHs(sv_2mortal(newSViv(i))) ;
PUTBACK ;
count = perl_call_method("getPt",G_ARRAY) ;
SPAGAIN ;
if (count != 2)
croak("Didn't get a single result from GD::Poly::length() call.\n");
y = POPi ;
x = POPi ;
PUTBACK ;
FREETMPS ;
LEAVE ;
polyptr[i].x = x;
polyptr[i].y = y;
}
gdImageFilledPolygon(image,polyptr,length,color);
safefree((char*) polyptr);
}
void
gdrectangle(image,x1,y1,x2,y2,color)
GD::Image image
int x1
int y1
int x2
int y2
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageRectangle(image,x1,y1,x2,y2,color);
}
void
gdfilledRectangle(image,x1,y1,x2,y2,color)
GD::Image image
int x1
int y1
int x2
int y2
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageFilledRectangle(image,x1,y1,x2,y2,color);
}
void
gdfilledEllipse(image,cx,cy,w,h,color)
GD::Image image
int cx
int cy
int w
int h
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageFilledEllipse(image,cx,cy,w,h,color);
}
void
gdarc(image,cx,cy,w,h,s,e,color)
GD::Image image
int cx
int cy
int w
int h
int s
int e
int color
PROTOTYPE: $$$$$$$$
CODE:
{
gdImageArc(image,cx,cy,w,h,s,e,color);
}
void
gdfilledArc(image,cx,cy,w,h,s,e,color,arc_style=0)
GD::Image image
int cx
int cy
int w
int h
int s
int e
int color
int arc_style
PROTOTYPE: $$$$$$$$$
CODE:
{
gdImageFilledArc(image,cx,cy,w,h,s,e,color,arc_style);
}
void
fillToBorder(image,x,y,border,color)
GD::Image image
int x
int y
int border
int color
PROTOTYPE: $$$$$
CODE:
{
gdImageFillToBorder(image,x,y,border,color);
}
void
fill(image,x,y,color)
GD::Image image
int x
int y
int color
PROTOTYPE: $$$$
CODE:
{
gdImageFill(image,x,y,color);
}
void
setBrush(image,brush)
GD::Image image
GD::Image brush
PROTOTYPE: $$
CODE:
{
gdImageSetBrush(image,brush);
}
void
setTile(image,tile)
GD::Image image
GD::Image tile
PROTOTYPE: $$
CODE:
{
gdImageSetTile(image,tile);
}
void
setThickness(image,thickness)
GD::Image image
int thickness
PROTOTYPE: $$
CODE:
{
gdImageSetThickness(image,thickness);
}
void
setStyle(image, ...)
GD::Image image
PROTOTYPE: $;$
CODE:
{
int *style;
int i;
if (items < 2)
return;
style = (int*) safemalloc(sizeof(int)*(items-1));
if (style == NULL)
croak("malloc returned NULL at setStyle().\n");
for(i=1;i<items;i++) {
style[i-1]=(int)SvIV(ST(i));
}
gdImageSetStyle(image,style,items-1);
safefree((char*) style);
}
int
colorAllocate(image,r,g,b)
GD::Image image
int r
int g
int b
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorAllocate(image,r,g,b);
}
OUTPUT:
RETVAL
int
colorAllocateAlpha(image,r,g,b,a)
GD::Image image
int r
int g
int b
int a
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorAllocateAlpha(image,r,g,b,a);
}
OUTPUT:
RETVAL
int
colorClosest(image,r,g,b)
GD::Image image
int r
int g
int b
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorClosest(image,r,g,b);
}
OUTPUT:
RETVAL
int
colorClosestAlpha(image,r,g,b,a)
GD::Image image
int r
int g
int b
int a
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorClosest(image,r,g,b);
}
OUTPUT:
RETVAL
int
colorClosestHWB(image,r,g,b)
GD::Image image
int r
int g
int b
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorClosestHWB(image,r,g,b);
}
OUTPUT:
RETVAL
int
colorExact(image,r,g,b)
GD::Image image
int r
int g
int b
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorExact(image,r,g,b);
}
OUTPUT:
RETVAL
int
colorExactAlpha(image,r,g,b,a)
GD::Image image
int r
int g
int b
int a
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorExactAlpha(image,r,g,b,a);
}
OUTPUT:
RETVAL
int
colorResolve(image,r,g,b)
GD::Image image
int r
int g
int b
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorResolve(image,r,g,b);
}
OUTPUT:
RETVAL
int
colorResolveAlpha(image,r,g,b,a)
GD::Image image
int r
int g
int b
int a
PROTOTYPE: $$$$
CODE:
{
RETVAL = gdImageColorResolveAlpha(image,r,g,b,a);
}
OUTPUT:
RETVAL
int
colorsTotal(image)
GD::Image image
PROTOTYPE: $
CODE:
{
if (gdImageTrueColor(image))
XSRETURN_UNDEF;
RETVAL = gdImageColorsTotal(image);
}
OUTPUT:
RETVAL
int
interlaced(image, ...)
GD::Image image
PROTOTYPE: $;$
CODE:
{
if (items > 1) {
if (SvOK(ST(1)))
gdImageInterlace(image,1);
else
gdImageInterlace(image,0);
}
RETVAL = gdImageGetInterlaced(image);
}
OUTPUT:
RETVAL
int
compare(image1,image2)
GD::Image image1
GD::Image image2
PROTOTYPE: $$
CODE:
{
RETVAL = gdImageCompare(image1,image2);
}
OUTPUT:
RETVAL
void
colorDeallocate(image,color)
GD::Image image
int color
PROTOTYPE: $$
CODE:
{
gdImageColorDeallocate(image,color);
}
void
copy(destination,source,dstX,dstY,srcX,srcY,w,h)
GD::Image destination
GD::Image source
int dstX
int dstY
int srcX
int srcY
int w
int h
PROTOTYPE: $$$$$$$$
CODE:
{
gdImageCopy(destination,source,dstX,dstY,srcX,srcY,w,h);
}
void
copyResized(destination,source,dstX,dstY,srcX,srcY,destW,destH,srcW,srcH)
GD::Image destination
GD::Image source
int dstX
int dstY
int srcX
int srcY
int destW
int destH
int srcW
int srcH
PROTOTYPE: $$$$$$$$$$
CODE:
{
gdImageCopyResized(destination,source,dstX,dstY,srcX,srcY,destW,destH,srcW,srcH);
}
void
copyResampled(destination,source,dstX,dstY,srcX,srcY,destW,destH,srcW,srcH)
GD::Image destination
GD::Image source
int dstX
int dstY
int srcX
int srcY
int destW
int destH
int srcW
int srcH
PROTOTYPE: $$$$$$$$$$
CODE:
{
gdImageCopyResampled(destination,source,dstX,dstY,srcX,srcY,destW,destH,srcW,srcH);
}
void
copyMerge(destination,source,dstX,dstY,srcX,srcY,w,h,pct)
GD::Image destination
GD::Image source
int dstX
int dstY
int srcX
int srcY
int w
int h
int pct
PROTOTYPE: $$$$$$$$$
CODE:
{
gdImageCopyMerge(destination,source,dstX,dstY,srcX,srcY,w,h,pct);
}
void
copyMergeGray(destination,source,dstX,dstY,srcX,srcY,w,h,pct)
GD::Image destination
GD::Image source
int dstX
int dstY
int srcX
int srcY
int w
int h
int pct
PROTOTYPE: $$$$$$$$$
CODE:
{
gdImageCopyMergeGray(destination,source,dstX,dstY,srcX,srcY,w,h,pct);
}
void
paletteCopy(destination,source)
GD::Image destination
GD::Image source
PROTOTYPE: $$
CODE:
{
gdImagePaletteCopy(destination,source);
}
void
gdchar(image,font,x,y,c,color)
GD::Image image
GD::Font font
int x
int y
char * c
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageChar(image,font,x,y,*c,color);
}
void
gdcharUp(image,font,x,y,c,color)
GD::Image image
GD::Font font
int x
int y
char * c
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageCharUp(image,font,x,y,*c,color);
}
void
gdstring(image,font,x,y,s,color)
GD::Image image
GD::Font font
int x
int y
char * s
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageString(image,font,x,y,(unsigned char*)s,color);
}
void
gdstringUp(image,font,x,y,s,color)
GD::Image image
GD::Font font
int x
int y
char * s
int color
PROTOTYPE: $$$$$$
CODE:
{
gdImageStringUp(image,font,x,y,(unsigned char*)s,color);
}
void
gdstringFT(image,fgcolor,fontname,ptsize,angle,x,y,string,...)
SV * image
int fgcolor
char * fontname
double ptsize
double angle
int x
int y
char * string
PROTOTYPE: $$$$$$$$;$
PREINIT:
gdImagePtr img;
int brect[8];
char *err;
char *a;
SV* errormsg;
HV* hash;
SV** value;
int i;
int hdpi;
int vdpi;
gdFTStringExtra strex;
PPCODE:
{
#ifndef HAVE_FT
errormsg = perl_get_sv("@",0);
sv_setpv(errormsg,"libgd was not built with FreeType font support\n");
XSRETURN_EMPTY;
#endif
if (sv_isobject(image) && sv_derived_from(image, "GD::Image")) {
IV tmp = SvIV((SV*)SvRV(image));
img = (gdImagePtr) tmp;
} else {
img = NULL;
}
if (items == 9) { /* hashref options at end */
if (SvTYPE(SvRV(ST(8))) != SVt_PVHV)
croak ("Usage: $gd->stringFT(image,fgcolor,fontname,ptsize,angle,x,y,string,[{options}])");
hash = (HV*)SvRV(ST(8));
strex.flags = 0;
strex.linespacing = 0;
strex.charmap = 0;
if (value = hv_fetch(hash,"linespacing",strlen("linespacing"),0)) {
strex.flags |= gdFTEX_LINESPACE;
strex.linespacing = SvNV(*value);
}
if (value = hv_fetch(hash,"charmap",strlen("charmap"),0)) {
strex.flags |= gdFTEX_CHARMAP;
if (strEQ(SvPV_nolen(*value),"Unicode"))
strex.charmap = gdFTEX_Unicode;
else if (strEQ(SvPV_nolen(*value),"Shift_JIS"))
strex.charmap = gdFTEX_Shift_JIS;
else if (strEQ(SvPV_nolen(*value),"Big5"))
strex.charmap = gdFTEX_Big5;
else
croak("Unknown charmap %s",SvPV_nolen(*value));
}
#ifdef VERSION_33
if (value = hv_fetch(hash,"resolution",strlen("resolution"),0)) {
strex.flags |= gdFTEX_RESOLUTION;
a = SvPV_nolen(*value);
if (sscanf(a,"%d,%d",&hdpi,&vdpi) == 2) {
strex.hdpi = hdpi;
strex.vdpi = vdpi;
}
}
if (value = hv_fetch(hash,"kerning",strlen("kerning"),0)) {
if (!SvTRUE(*value)) {
strex.flags |= gdFTEX_DISABLE_KERNING;
}
else
strex.flags &= gdFTEX_DISABLE_KERNING;
}
#endif
err = gdImageStringFTEx(img,brect,fgcolor,fontname,ptsize,angle,x,y,string,&strex);
}
else {
err = gdImageStringFT(img,brect,fgcolor,fontname,ptsize,angle,x,y,string);
}
if (err) {
errormsg = perl_get_sv("@",0);
if (errormsg != NULL)
sv_setpv(errormsg,err);
XSRETURN_EMPTY;
} else {
EXTEND(sp,8);
for (i=0;i<8;i++) {
PUSHs(sv_2mortal(newSViv(brect[i])));
}
}
}
int
gdstringFTCircle(image,cx,cy,radius,textRadius,fillPortion,fontname,points,top,bottom,fgcolor)
GD::Image image
int cx
int cy
double radius
double textRadius
double fillPortion
char * fontname
double points
char * top
char * bottom
int fgcolor
PROTOTYPE: $$$$$$$$$$$
PREINIT:
char* err;
SV* errormsg;
CODE:
{
#ifdef HAVE_FT
#ifdef HAVE_FTCIRCLE
fprintf(stderr,"cx=%d,cy=%d,radius=%f,textRadius=%f,fillPortion=%f,fontname=%s,points=%f,top=%s,bottom=%s,fgcolor=%d",
cx,cy,radius,textRadius,
fillPortion,fontname,points,top,bottom,fgcolor);
err = gdImageStringFTCircle(image,cx,cy,radius,textRadius,
fillPortion,fontname,points,top,bottom,fgcolor);
if (err) {
errormsg = perl_get_sv("@",0);
if (errormsg != NULL)
sv_setpv(errormsg,err);
XSRETURN_EMPTY;
} else {
RETVAL = 1;
}
#else
errormsg = perl_get_sv("@",0);
sv_setpv(errormsg,"libgd must be version 2.0.33 or higher to use this function\n");
XSRETURN_EMPTY;
#endif
#else
errormsg = perl_get_sv("@",0);
sv_setpv(errormsg,"libgd was not built with FreeType support\n");
XSRETURN_EMPTY;
#endif
}
OUTPUT:
RETVAL
int
gduseFontConfig(image,flag)
SV* image
int flag
PROTOTYPE: $$
PREINIT:
SV* errormsg;
CODE:
{
#ifdef HAVE_FONTCONFIG
RETVAL = gdFTUseFontConfig(flag);
#else
errormsg = perl_get_sv("@",0);
sv_setpv(errormsg,"libgd was not built with fontconfig support\n");
XSRETURN_EMPTY;
#endif
}
OUTPUT:
RETVAL
void
gdalphaBlending(image,blending)
GD::Image image
int blending
PROTOTYPE: $$
CODE:
{
gdImageAlphaBlending(image,blending);
}
void
gdsaveAlpha(image,saveAlphaArg)
GD::Image image
int saveAlphaArg
PROTOTYPE: $$
CODE:
{
gdImageSaveAlpha(image,saveAlphaArg) ;
}
void
gdclip(image,...)
GD::Image image
PROTOTYPE: $;$$$$
PREINIT:
int coords[4];
int i;
PPCODE:
{
if (items == 5) {
for (i=0;i<4;i++)
coords[i] = (int)SvIV(ST(i+1));
gdImageSetClip(image,coords[0],coords[1],coords[2],coords[3]);
}
else if (items > 1) /* something weird */
croak("Usage: $gd->clip() or $gd->clip(x1,x2,y1,y2)");
gdImageGetClip(image,&coords[0],&coords[1],&coords[2],&coords[3]);
EXTEND(sp,4);
for (i=0;i<4;i++)
PUSHs(sv_2mortal(newSViv(coords[i])));
}
void
gdsetAntiAliased(image,color)
GD::Image image
int color
PROTOTYPE: $$
CODE:
{
gdImageSetAntiAliased(image,color);
}
void
gdsetAntiAliasedDontBlend(image,color,flag=1)
GD::Image image
int color
int flag
PROTOTYPE: $$$
CODE:
{
gdImageSetAntiAliasedDontBlend(image,color,flag);
}
MODULE = GD PACKAGE = GD::Font PREFIX=gd
GD::Font
gdload(packname="GD::Font",fontpath)
char * packname
char * fontpath
PROTOTYPE: $$
PREINIT:
int fontfile;
int datasize;
SV* errormsg;
char errstr[256];
gdFontPtr font;
unsigned char word[4];
char* fontdata;
CODE:
{
fontfile = open(fontpath,O_RDONLY);
if (fontfile < 0) {
errormsg = perl_get_sv("@",0);
snprintf(errstr,256,"could not open font file %s: %s",fontpath,strerror(errno));
sv_setpv(errormsg,errstr);
XSRETURN_EMPTY;
}
font = (gdFontPtr)safemalloc(sizeof(gdFont));
if (font == NULL)
croak("safemalloc() returned NULL while trying to allocate font struct.\n");
/* read header from font - note that the file is assumed to be littleendian*/
if (read(fontfile,word,4) < 4)
croak("error while reading font file: %s",strerror(errno));
font->nchars = littleendian(word);
if (read(fontfile,word,4) < 4)
croak("error while reading font file: %s",strerror(errno));
font->offset = littleendian(word);
if (read(fontfile,word,4) < 4)
croak("error while reading font file: %s",strerror(errno));
font->w = littleendian(word);
if (read(fontfile,word,4) < 4)
croak("error while reading font file: %s",strerror(errno));
font->h = littleendian(word);
datasize = font->nchars * font->w * font->h;
fontdata = (char*)safemalloc(datasize);
if (fontdata == NULL)
croak("safemalloc() returned NULL while trying to allocate font bitmap.\n");
if (read(fontfile,fontdata,datasize) < datasize)
croak("error while reading font file: %s",strerror(errno));
font->data = fontdata;
close(fontfile); /* please don't leak file descriptors! */
RETVAL = font;
}
OUTPUT:
RETVAL
void
gdDESTROY(self)
GD::Font self
PROTOTYPE: $
CODE:
{
if (self == gdFontGetSmall() ||
self == gdFontGetLarge() ||
self == gdFontGetGiant() ||
self == gdFontGetMediumBold() ||
self == gdFontGetTiny() )
XSRETURN_EMPTY;
safefree(self->data);
safefree(self);
}
GD::Font
gdSmall(packname="GD::Font")
char * packname
PROTOTYPE: $
CODE:
{
RETVAL = gdFontGetSmall();
}
OUTPUT:
RETVAL
GD::Font
gdLarge(packname="GD::Font")
char * packname
PROTOTYPE: $
CODE:
{
RETVAL = gdFontGetLarge();
}
OUTPUT:
RETVAL
GD::Font
gdGiant(packname="GD::Font")
char * packname
PROTOTYPE: $
CODE:
{
RETVAL = gdFontGetGiant();
}
OUTPUT:
RETVAL
GD::Font
gdMediumBold(packname="GD::Font")
char * packname
PROTOTYPE: $
CODE:
{
RETVAL = gdFontGetMediumBold();
}
OUTPUT:
RETVAL
GD::Font
gdTiny(packname="GD::Font")
char * packname
PROTOTYPE: $
CODE:
{
RETVAL = gdFontGetTiny();
}
OUTPUT:
RETVAL
int
gdnchars(font)
GD::Font font
PROTOTYPE: $
CODE:
{
RETVAL = font->nchars;
}
OUTPUT:
RETVAL
int
gdoffset(font)
GD::Font font
PROTOTYPE: $
CODE:
{
RETVAL = font->offset;
}
OUTPUT:
RETVAL
int
gdwidth(font)
GD::Font font
PROTOTYPE: $
CODE:
{
RETVAL = font->w;
}
OUTPUT:
RETVAL
int
gdheight(font)
GD::Font font
PROTOTYPE: $
CODE:
{
RETVAL = font->h;
}
OUTPUT:
RETVAL