rasmus Tue Oct 29 18:08:02 2002 EDT Modified files: /php4/ext/gd gd.c gd_ctx.c /php4/ext/gd/libgd gd.c gd.h gd2topng.c gd_gd.c gd_gd2.c gd_gif_in.c gd_io.h gd_io_dp.c gd_io_file.c gd_io_ss.c gd_jpeg.c gd_png.c gd_ss.c gd_wbmp.c gdcache.h gdft.c gdhelpers.h gdkanji.c gdparttopng.c gdtest.c Log: Update bundled gd library with relevant changes from gd-2.0.4 I still need to add a configure check for the gdIOCtx struct changes so building against older external gd libs will work again.
Index: php4/ext/gd/gd.c diff -u php4/ext/gd/gd.c:1.217 php4/ext/gd/gd.c:1.218 --- php4/ext/gd/gd.c:1.217 Mon Oct 28 20:15:43 2002 +++ php4/ext/gd/gd.c Tue Oct 29 18:08:01 2002 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gd.c,v 1.217 2002/10/29 01:15:43 iliaa Exp $ */ +/* $Id: gd.c,v 1.218 2002/10/29 23:08:01 rasmus Exp $ */ /* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center, Cold Spring Harbor Labs. */ @@ -1073,10 +1073,10 @@ io_ctx = gdNewDynamicCtx (8, data); if (io_ctx) { if (getmbi((int(*)(void*))gdGetC, io_ctx) == 0 && skipheader((int(*)(void*))gdGetC, io_ctx) == 0 ) { - io_ctx->free(io_ctx); + io_ctx->gd_free(io_ctx); return PHP_GDIMG_TYPE_WBM; } else - io_ctx->free(io_ctx); + io_ctx->gd_free(io_ctx); } } #endif @@ -1253,7 +1253,7 @@ } else { im = (*ioctx_func_p)(io_ctx); } - io_ctx->free(io_ctx); + io_ctx->gd_free(io_ctx); #endif } else { Index: php4/ext/gd/gd_ctx.c diff -u php4/ext/gd/gd_ctx.c:1.13 php4/ext/gd/gd_ctx.c:1.14 --- php4/ext/gd/gd_ctx.c:1.13 Thu Aug 22 14:38:44 2002 +++ php4/ext/gd/gd_ctx.c Tue Oct 29 18:08:01 2002 @@ -67,7 +67,7 @@ ctx = emalloc(sizeof(gdIOCtx)); ctx->putC = _php_image_output_putc; ctx->putBuf = _php_image_output_putbuf; - ctx->free = _php_image_output_ctxfree; + ctx->gd_free = _php_image_output_ctxfree; #if APACHE && defined(CHARSET_EBCDIC) /* XXX this is unlikely to work any more [EMAIL PROTECTED] */ @@ -95,7 +95,7 @@ break; } - ctx->free(ctx); + ctx->gd_free(ctx); if(fp) { fflush(fp); Index: php4/ext/gd/libgd/gd.c diff -u php4/ext/gd/libgd/gd.c:1.22 php4/ext/gd/libgd/gd.c:1.23 --- php4/ext/gd/libgd/gd.c:1.22 Tue Oct 29 15:19:38 2002 +++ php4/ext/gd/libgd/gd.c Tue Oct 29 18:08:01 2002 @@ -90,6 +90,7 @@ static int gdLayerOverlay(int dst, int src); static int gdAlphaBlendColor(int b1, int b2, int a1, int a2); static int gdAlphaOverlayColor(int src, int dst, int max); +static int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y); gdImagePtr gdImageCreate (int sx, int sy) @@ -152,8 +153,13 @@ im->transparent = (-1); im->interlace = 0; im->trueColor = 1; - im->saveAlphaFlag = 1; - im->alphaBlendingFlag = 0; + /* 2.0.2: alpha blending is now on by default, and saving of alpha is + off by default. This allows font antialiasing to work as expected + on the first try in JPEGs -- quite important -- and also allows + for smaller PNGs when saving of alpha channel is not really + desired, which it usually isn't! */ + im->saveAlphaFlag = 0; + im->alphaBlendingFlag = 1; im->thick = 1; return im; } @@ -217,7 +223,8 @@ rd = (im->red[i] - r); gd = (im->green[i] - g); bd = (im->blue[i] - b); - ad = (im->blue[i] - b); + /* gd 2.02: whoops, was - b (thanks to David Marwood) */ + ad = (im->blue[i] - a); dist = rd * rd + gd * gd + bd * bd + ad * ad; if (first || (dist < mindist)) { @@ -509,6 +516,12 @@ op = c; /* Save open slot */ continue; /* Color not in use */ } + if (c == im->transparent) + { + /* don't ever resolve to the color that has + * been designated as the transparent color */ + continue; + } rd = (long) (im->red[c] - r); gd = (long) (im->green[c] - g); bd = (long) (im->blue[c] - b); @@ -1336,7 +1349,7 @@ gdPoint pts[3]; int i; int lx = 0, ly = 0; - int fx, fy; + int fx = 0, fy = 0; int w2, h2; w2 = w / 2; h2 = h / 2; @@ -1975,7 +1988,7 @@ tox = dstX; for (x = srcX; (x < (srcX + srcW)); x++) { - int nc; + int nc = 0; int mapTo; if (!stx[x - srcX]) { @@ -2073,7 +2086,6 @@ { for (x = dstX; (x < dstX + dstW); x++) { - /*int pd = gdImageGetPixel (dst, x, y);*/ float sy1, sy2, sx1, sx2; float sx, sy; float spixels = 0.0f; Index: php4/ext/gd/libgd/gd.h diff -u php4/ext/gd/libgd/gd.h:1.6 php4/ext/gd/libgd/gd.h:1.7 --- php4/ext/gd/libgd/gd.h:1.6 Mon Oct 28 20:15:44 2002 +++ php4/ext/gd/libgd/gd.h Tue Oct 29 18:08:01 2002 @@ -7,7 +7,7 @@ #ifndef WIN32 /* default fontpath for unix systems */ -#define DEFAULT_FONTPATH "/usr/share/fonts/truetype" +#define DEFAULT_FONTPATH +"/usr/X11R6/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/truetype:/usr/X11R6/lib/X11/fonts/TTF:/usr/share/fonts/TrueType:/usr/share/fonts/truetype:/usr/openwin/lib/X11/fonts/TrueType:/usr/X11R6/lib/X11/fonts/Type1" #define PATHSEPARATOR ":" #else /* default fontpath for windows systems */ @@ -254,6 +254,9 @@ void gdImageString16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); void gdImageStringUp16(gdImagePtr im, gdFontPtr f, int x, int y, unsigned short *s, int color); +/* clean up after using fonts in gdImageStringFT() */ +void gdFreeFontCache(); + /* Calls gdImageStringFT. Provided for backwards compatibility only. */ char *gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string); @@ -370,6 +373,8 @@ /* Best to free this memory with gdFree(), not free() */ void *gdImageWBMPPtr(gdImagePtr im, int *size, int fg); +/* 100 is highest quality (there is always a little loss with JPEG). + 0 is lowest. 10 is about the lowest useful setting. */ void gdImageJpeg(gdImagePtr im, FILE *out, int quality); void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality); Index: php4/ext/gd/libgd/gd2topng.c diff -u php4/ext/gd/libgd/gd2topng.c:1.1 php4/ext/gd/libgd/gd2topng.c:1.2 --- php4/ext/gd/libgd/gd2topng.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd2topng.c Tue Oct 29 18:08:01 2002 @@ -37,7 +37,11 @@ gdImageDestroy (im); exit (1); } +#ifdef HAVE_LIBPNG gdImagePng (im, out); +#else + fprintf(stderr, "No PNG library support available.\n"); +#endif fclose (out); gdImageDestroy (im); Index: php4/ext/gd/libgd/gd_gd.c diff -u php4/ext/gd/libgd/gd_gd.c:1.3 php4/ext/gd/libgd/gd_gd.c:1.4 --- php4/ext/gd/libgd/gd_gd.c:1.3 Sun Aug 11 15:19:35 2002 +++ php4/ext/gd/libgd/gd_gd.c Tue Oct 29 18:08:01 2002 @@ -147,7 +147,7 @@ in = gdNewFileCtx (inFile); im = gdImageCreateFromGdCtx (in); - in->free (in); + in->gd_free (in); return im; } @@ -196,7 +196,7 @@ { int i; - gdPutC ((unsigned char)im->trueColor, out); + gdPutC (im->trueColor, out); if (!im->trueColor) { gdPutWord (im->colorsTotal, out); @@ -256,7 +256,7 @@ { gdIOCtx *out = gdNewFileCtx (outFile); _gdImageGd (im, out); - out->free (out); + out->gd_free (out); } void * @@ -266,6 +266,6 @@ gdIOCtx *out = gdNewDynamicCtx (2048, NULL); _gdImageGd (im, out); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } Index: php4/ext/gd/libgd/gd_gd2.c diff -u php4/ext/gd/libgd/gd_gd2.c:1.2 php4/ext/gd/libgd/gd_gd2.c:1.3 --- php4/ext/gd/libgd/gd_gd2.c:1.2 Sun Aug 11 09:50:27 2002 +++ php4/ext/gd/libgd/gd_gd2.c Tue Oct 29 18:08:01 2002 @@ -15,10 +15,11 @@ #include <math.h> #include <string.h> #include <stdlib.h> -#include <zlib.h> #include "gd.h" #include "gdhelpers.h" +#include <zlib.h> + #define TRUE 1 #define FALSE 0 @@ -250,7 +251,7 @@ im = gdImageCreateFromGd2Ctx (in); - in->free (in); + in->gd_free (in); return im; } @@ -266,10 +267,10 @@ t_chunk_info *chunkIdx = NULL; /* So we can gdFree it with impunity. */ unsigned char *chunkBuf = NULL; /* So we can gdFree it with impunity. */ int chunkNum = 0; - int chunkMax; + int chunkMax = 0; uLongf chunkLen; - int chunkPos; - int compMax; + int chunkPos = 0; + int compMax = 0; int bytesPerPixel; char *compBuf = NULL; /* So we can gdFree it with impunity. */ @@ -433,7 +434,7 @@ im = gdImageCreateFromGd2PartCtx (in, srcx, srcy, w, h); - in->free (in); + in->gd_free (in); return im; } @@ -450,9 +451,9 @@ t_chunk_info *chunkIdx = NULL; char *chunkBuf = NULL; int chunkNum; - int chunkMax; + int chunkMax = 0; uLongf chunkLen; - int chunkPos; + int chunkPos = 0; int compMax; char *compBuf = NULL; @@ -635,10 +636,10 @@ { if (im->trueColor) { - ch = (chunkBuf[chunkPos++] << 24) - + (chunkBuf[chunkPos++] << 16) - + (chunkBuf[chunkPos++] << 8) - + (chunkBuf[chunkPos++]); + ch = chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; + ch = (ch << 8) + chunkBuf[chunkPos++]; } else { @@ -710,12 +711,12 @@ char *chunkData = NULL; /* So we can gdFree it with impunity. */ char *compData = NULL; /* So we can gdFree it with impunity. */ uLongf compLen; - int idxPos; + int idxPos = 0; int idxSize; t_chunk_info *chunkIdx = NULL; int posSave; int bytesPerPixel = im->trueColor ? 4 : 1; - int compMax; + int compMax = 0; /*printf("Trying to write GD2 file\n"); */ @@ -762,7 +763,7 @@ /* The zlib notes say output buffer size should be (input size) * 1.01 * 12 */ /* - we'll use 1.02 to be paranoid. */ /* */ - compMax = (int)(cs * bytesPerPixel * cs * 1.02f + 12); + compMax = cs * bytesPerPixel * cs * 1.02 + 12; /* */ /* Allocate the buffers. */ @@ -908,7 +909,7 @@ { gdIOCtx *out = gdNewFileCtx (outFile); _gdImageGd2 (im, out, cs, fmt); - out->free (out); + out->gd_free (out); } void * @@ -918,6 +919,6 @@ gdIOCtx *out = gdNewDynamicCtx (2048, NULL); _gdImageGd2 (im, out, cs, fmt); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } Index: php4/ext/gd/libgd/gd_gif_in.c diff -u php4/ext/gd/libgd/gd_gif_in.c:1.1 php4/ext/gd/libgd/gd_gif_in.c:1.2 --- php4/ext/gd/libgd/gd_gif_in.c:1.1 Sun Oct 6 02:03:17 2002 +++ php4/ext/gd/libgd/gd_gif_in.c Tue Oct 29 18:08:01 2002 @@ -83,7 +83,7 @@ im = gdImageCreateFromGifCtx(in); - in->free(in); + in->gd_free(in); return im; } @@ -96,7 +96,7 @@ im = gdImageCreateFromGifCtx(fd); - fd->free(fd); + fd->gd_free(fd); return im; } Index: php4/ext/gd/libgd/gd_io.h diff -u php4/ext/gd/libgd/gd_io.h:1.1 php4/ext/gd/libgd/gd_io.h:1.2 --- php4/ext/gd/libgd/gd_io.h:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd_io.h Tue Oct 29 18:08:01 2002 @@ -13,7 +13,7 @@ int (*seek)(struct gdIOCtx*, const int); long (*tell)(struct gdIOCtx*); - void (*free)(struct gdIOCtx*); + void (*gd_free)(struct gdIOCtx*); } gdIOCtx; Index: php4/ext/gd/libgd/gd_io_dp.c diff -u php4/ext/gd/libgd/gd_io_dp.c:1.1 php4/ext/gd/libgd/gd_io_dp.c:1.2 --- php4/ext/gd/libgd/gd_io_dp.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd_io_dp.c Tue Oct 29 18:08:01 2002 @@ -1,4 +1,3 @@ - /* * io_dp.c * @@ -95,7 +94,7 @@ ctx->ctx.seek = dynamicSeek; ctx->ctx.tell = dynamicTell; - ctx->ctx.free = gdFreeDynamicCtx; + ctx->ctx.gd_free = gdFreeDynamicCtx; return (gdIOCtx *) ctx; } Index: php4/ext/gd/libgd/gd_io_file.c diff -u php4/ext/gd/libgd/gd_io_file.c:1.1 php4/ext/gd/libgd/gd_io_file.c:1.2 --- php4/ext/gd/libgd/gd_io_file.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd_io_file.c Tue Oct 29 18:08:01 2002 @@ -71,7 +71,7 @@ ctx->ctx.tell = fileTell; ctx->ctx.seek = fileSeek; - ctx->ctx.free = gdFreeFileCtx; + ctx->ctx.gd_free = gdFreeFileCtx; return (gdIOCtx *) ctx; } Index: php4/ext/gd/libgd/gd_io_ss.c diff -u php4/ext/gd/libgd/gd_io_ss.c:1.1 php4/ext/gd/libgd/gd_io_ss.c:1.2 --- php4/ext/gd/libgd/gd_io_ss.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd_io_ss.c Tue Oct 29 18:08:01 2002 @@ -71,7 +71,7 @@ ctx->ctx.tell = NULL; ctx->ctx.seek = NULL; - ctx->ctx.free = gdFreeSsCtx; + ctx->ctx.gd_free = gdFreeSsCtx; return (gdIOCtx *) ctx; } Index: php4/ext/gd/libgd/gd_jpeg.c diff -u php4/ext/gd/libgd/gd_jpeg.c:1.3 php4/ext/gd/libgd/gd_jpeg.c:1.4 --- php4/ext/gd/libgd/gd_jpeg.c:1.3 Sun Aug 11 15:13:07 2002 +++ php4/ext/gd/libgd/gd_jpeg.c Tue Oct 29 18:08:01 2002 @@ -1,5 +1,3 @@ - - /* * gd_jpeg.c: Read and write JPEG (JFIF) format image files using the * gd graphics library (http://www.boutell.com/gd/). @@ -20,20 +18,21 @@ * major CGI brain damage */ -/* TBB: move this up so include files are not brought in */ -#ifdef HAVE_LIBJPEG - #include <stdio.h> #include <stdlib.h> #include <setjmp.h> #include <limits.h> #include <string.h> +#include "gd.h" +/* TBB: move this up so include files are not brought in */ +/* JCE: arrange HAVE_LIBJPEG so that it can be set in gd.h */ +#ifdef HAVE_LIBJPEG +#include "gdhelpers.h" + /* 1.8.1: remove dependency on jinclude.h */ #include "jpeglib.h" #include "jerror.h" -#include "gd.h" -#include "gdhelpers.h" static const char *const GD_JPEG_VERSION = "1.0"; @@ -85,7 +84,7 @@ { gdIOCtx *out = gdNewFileCtx (outFile); gdImageJpegCtx (im, out, quality); - out->free (out); + out->gd_free (out); } void * @@ -95,7 +94,7 @@ gdIOCtx *out = gdNewDynamicCtx (2048, NULL); gdImageJpegCtx (im, out, quality); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } @@ -249,7 +248,6 @@ } } jpeg_finish_compress (&cinfo); -/*error:*/ jpeg_destroy_compress (&cinfo); gdFree (row); } @@ -260,7 +258,7 @@ gdImagePtr im; gdIOCtx *in = gdNewFileCtx (inFile); im = gdImageCreateFromJpegCtx (in); - in->free (in); + in->gd_free (in); return im; } Index: php4/ext/gd/libgd/gd_png.c diff -u php4/ext/gd/libgd/gd_png.c:1.3 php4/ext/gd/libgd/gd_png.c:1.4 --- php4/ext/gd/libgd/gd_png.c:1.3 Sun Aug 11 09:50:27 2002 +++ php4/ext/gd/libgd/gd_png.c Tue Oct 29 18:08:01 2002 @@ -1,11 +1,12 @@ - -#ifdef HAVE_LIBPNG - #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include "gd.h" + +/* JCE: Arrange HAVE_LIBPNG so that it can be set in gd.h */ +#ifdef HAVE_LIBPNG + #include "gdhelpers.h" #include "png.h" /* includes zlib.h and setjmp.h */ @@ -101,7 +102,7 @@ gdImagePtr im; gdIOCtx *in = gdNewFileCtx (inFile); im = gdImageCreateFromPngCtx (in); - in->free (in); + in->gd_free (in); return im; } @@ -125,7 +126,7 @@ png_bytep image_data = NULL; png_bytepp row_pointers = NULL; gdImagePtr im = NULL; - int i, j, *open; + int i, j, *open = NULL; png_uint_32 ui, uj; volatile int transparent = -1; volatile int palette_allocated = FALSE; @@ -422,7 +423,7 @@ { gdIOCtx *out = gdNewFileCtx (outFile); gdImagePngCtx (im, out); - out->free (out); + out->gd_free (out); } void * @@ -432,7 +433,7 @@ gdIOCtx *out = gdNewDynamicCtx (2048, NULL); gdImagePngCtx (im, out); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } @@ -443,7 +444,7 @@ void gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile) { - int i, j, bit_depth, interlace_type; + int i, j, bit_depth = 0, interlace_type; int width = im->sx; int height = im->sy; int colors = im->colorsTotal; Index: php4/ext/gd/libgd/gd_ss.c diff -u php4/ext/gd/libgd/gd_ss.c:1.1 php4/ext/gd/libgd/gd_ss.c:1.2 --- php4/ext/gd/libgd/gd_ss.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd_ss.c Tue Oct 29 18:08:01 2002 @@ -16,12 +16,13 @@ /*#define GD_SS_DBG(s) (s) */ #define GD_SS_DBG(s) +#ifdef HAVE_LIBPNG void gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) { gdIOCtx *out = gdNewSSCtx (NULL, outSink); gdImagePngCtx (im, out); - out->free (out); + out->gd_free (out); } gdImagePtr @@ -32,7 +33,21 @@ im = gdImageCreateFromPngCtx (in); - in->free (in); + in->gd_free (in); return im; } +#else /* no HAVE_LIBPNG */ +void +gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink) +{ + fprintf(stderr,"PNG support is not available\n"); +} +gdImagePtr +gdImageCreateFromPngSource (gdSourcePtr inSource) +{ + fprintf(stderr,"PNG support is not available\n"); + return NULL; +} +#endif /* HAVE_LIBPNG */ + Index: php4/ext/gd/libgd/gd_wbmp.c diff -u php4/ext/gd/libgd/gd_wbmp.c:1.2 php4/ext/gd/libgd/gd_wbmp.c:1.3 --- php4/ext/gd/libgd/gd_wbmp.c:1.2 Sun Aug 11 09:50:27 2002 +++ php4/ext/gd/libgd/gd_wbmp.c Tue Oct 29 18:08:01 2002 @@ -188,7 +188,7 @@ gdImagePtr im; gdIOCtx *in = gdNewFileCtx (inFile); im = gdImageCreateFromWBMPCtx (in); - in->free (in); + in->gd_free (in); return (im); } @@ -200,7 +200,7 @@ { gdIOCtx *out = gdNewFileCtx (outFile); gdImageWBMPCtx (im, fg, out); - out->free (out); + out->gd_free (out); } /* gdImageWBMPPtr @@ -213,6 +213,6 @@ gdIOCtx *out = gdNewDynamicCtx (2048, NULL); gdImageWBMPCtx (im, fg, out); rv = gdDPExtractData (out, size); - out->free (out); + out->gd_free (out); return rv; } Index: php4/ext/gd/libgd/gdcache.h diff -u php4/ext/gd/libgd/gdcache.h:1.1 php4/ext/gd/libgd/gdcache.h:1.2 --- php4/ext/gd/libgd/gdcache.h:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gdcache.h Tue Oct 29 18:08:01 2002 @@ -40,7 +40,10 @@ /* header */ /*********************************************************/ -#include <malloc.h> +#include <stdlib.h> +#ifdef HAVE_MALLOC_H + #include <malloc.h> +#endif #ifndef NULL #define NULL (void *)0 #endif Index: php4/ext/gd/libgd/gdft.c diff -u php4/ext/gd/libgd/gdft.c:1.8 php4/ext/gd/libgd/gdft.c:1.9 --- php4/ext/gd/libgd/gdft.c:1.8 Thu Aug 22 12:21:32 2002 +++ php4/ext/gd/libgd/gdft.c Tue Oct 29 18:08:01 2002 @@ -15,7 +15,7 @@ #ifndef MSWIN32 #include <unistd.h> #else -#define R_OK 2 +#include <io.h> #endif #ifdef WIN32 extern int access(const char *pathname, int mode); @@ -352,7 +352,6 @@ fontsearchpath = getenv ("GDFONTPATH"); if (!fontsearchpath) fontsearchpath = DEFAULT_FONTPATH; - path = strdup (fontsearchpath); fontlist = strdup (a->fontlist); /* @@ -362,6 +361,8 @@ name = gd_strtok_r (0, LISTSEPARATOR, &strtok_ptr)) { + /* make a fresh copy each time - strtok corrupts it. */ + path = strdup (fontsearchpath); /* * Allocate an oversized buffer that is guaranteed to be * big enough for all paths to be tested. @@ -369,7 +370,7 @@ fullname = gdRealloc (fullname, strlen (fontsearchpath) + strlen (name) + 6); /* if name is an absolute filename then test directly */ - if (*name == '/') + if (*name == '/' || (name[0] != 0 && name[1] == ':' && (name[2] == '/' || +name[2] == '\\'))) { sprintf (fullname, "%s", name); if (access (fullname, R_OK) == 0) @@ -387,11 +388,23 @@ font_found++; break; } + sprintf (fullname, "%s/%s.pfa", dir, name); + if (access (fullname, R_OK) == 0) + { + font_found++; + break; } - if (font_found) + sprintf (fullname, "%s/%s.pfb", dir, name); + if (access (fullname, R_OK) == 0) + { + font_found++; break; } + } gdFree (path); + if (font_found) + break; + } gdFree (fontlist); if (!font_found) { @@ -481,7 +494,10 @@ * Computes a color in im's color table that is part way between * the background and foreground colors proportional to the gray * pixel value in the range 0-NUMCOLORS. The fg and bg colors must already - * be in the color table. + * be in the color table for palette images. For truecolor images the + * returned value simply has an alpha component and gdImageAlphaBlend + * does the work so that text can be alpha blended across a complex + * background (TBB; and for real in 2.0.2). */ static void * tweenColorFetch (char **error, void *key) @@ -500,31 +516,34 @@ /* if fg is specified by a negative color idx, then don't antialias */ if (fg < 0) { + if ((pixel + pixel) >= NUMCOLORS) a->tweencolor = -fg; + else + a->tweencolor = bg; } else { npixel = NUMCOLORS - pixel; if (im->trueColor) - { - /* 2.0.1: use gdImageSetPixel to do the alpha blending work, - or to just store the alpha level. All we have to do here - is incorporate our knowledge of the percentage of this - pixel that is really "lit" by pushing the alpha value - up toward transparency in edge regions. */ - a->tweencolor = gdTrueColorAlpha ( - gdTrueColorGetRed (fg), - gdTrueColorGetGreen (fg), - gdTrueColorGetBlue (fg), - gdAlphaMax - ((gdAlphaMax - gdTrueColorGetAlpha (fg)) * pixel / NUMCOLORS) ); - } + { + /* 2.0.1: use gdImageSetPixel to do the alpha blending work, + or to just store the alpha level. All we have to do here + is incorporate our knowledge of the percentage of this + pixel that is really "lit" by pushing the alpha value + up toward transparency in edge regions. */ + a->tweencolor = gdTrueColorAlpha ( + gdTrueColorGetRed (fg), + gdTrueColorGetGreen (fg), + gdTrueColorGetBlue (fg), + gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS)); + } else - { + { a->tweencolor = gdImageColorResolve (im, (pixel * im->red[fg] + npixel * im->red[bg]) / NUMCOLORS, (pixel * im->green[fg] + npixel * im->green[bg]) / NUMCOLORS, (pixel * im->blue[fg] + npixel * im->blue[bg]) / NUMCOLORS); - } + } } return (void *) a; } @@ -537,29 +556,84 @@ /* draw_bitmap - transfers glyph bitmap to GD image */ static char * -gdft_draw_bitmap (gdImage * im, int fg, FT_Bitmap bitmap, int pen_x, int pen_y) +gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitmap, +int pen_x, int pen_y) { - unsigned char *pixel; + unsigned char *pixel = NULL; + int *tpixel = NULL; int x, y, row, col, pc; tweencolor_t *tc_elem; tweencolorkey_t tc_key; - /* initialize tweenColorCache on first call */ - static gdCache_head_t *tc_cache; - - if (!tc_cache) - { - tc_cache = gdCacheCreate (TWEENCOLORCACHESIZE, - tweenColorTest, tweenColorFetch, tweenColorRelease); - } - /* copy to image, mapping colors */ tc_key.fgcolor = fg; tc_key.im = im; + /* Truecolor version; does not require the cache */ + if (im->trueColor) + { + for (row = 0; row < bitmap.rows; row++) + { + pc = row * bitmap.pitch; + y = pen_y + row; + /* clip if out of bounds */ + if (y >= im->sy || y < 0) + continue; + for (col = 0; col < bitmap.width; col++, pc++) + { + int level; + if (bitmap.pixel_mode == ft_pixel_mode_grays) + { + /* + * Scale to 128 levels of alpha for gd use. + * alpha 0 is opacity, so be sure to invert at the end + */ + level = (bitmap.buffer[pc] * gdAlphaMax / + (bitmap.num_grays - 1)); + } + else if (bitmap.pixel_mode == ft_pixel_mode_mono) + { + level = ((bitmap.buffer[pc / 8] + << (pc % 8)) & 128) ? gdAlphaOpaque : + gdAlphaTransparent; + } + else + { + return "Unsupported ft_pixel_mode"; + } + if (fg >= 0) { + /* Consider alpha in the foreground color itself to be an + upper bound on how opaque things get */ + level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax; + } + level = gdAlphaMax - level; + x = pen_x + col; + /* clip if out of bounds */ + if (x >= im->sx || x < 0) + continue; + /* get pixel location in gd buffer */ + tpixel = &im->tpixels[y][x]; + if (fg < 0) { + if (level < (gdAlphaMax / 2)) { + *tpixel = -fg; + } + } else { + if (im->alphaBlendingFlag) { + *tpixel = gdAlphaBlend(*tpixel, (level << 24) + (fg & 0xFFFFFF)); + } else { + *tpixel = (level << 24) + (fg & 0xFFFFFF); + } + } + } + } + return (char *) NULL; + } + /* Non-truecolor case, restored to its more or less original form */ for (row = 0; row < bitmap.rows; row++) { pc = row * bitmap.pitch; + if(bitmap.pixel_mode==ft_pixel_mode_mono) + pc *= 8; /* pc is measured in bits for monochrome images */ + y = pen_y + row; /* clip if out of bounds */ @@ -568,53 +642,49 @@ for (col = 0; col < bitmap.width; col++, pc++) { - x = pen_x + col; - - /* clip if out of bounds */ - if (x >= im->sx || x < 0) - continue; - - switch(bitmap.pixel_mode) { - case ft_pixel_mode_grays: + if (bitmap.pixel_mode == ft_pixel_mode_grays) + { /* * Round to NUMCOLORS levels of antialiasing for * index color images since only 256 colors are * available. */ - tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS) + bitmap.num_grays / 2) / (bitmap.num_grays - 1); - break; - case ft_pixel_mode_mono: + } + else if (bitmap.pixel_mode == ft_pixel_mode_mono) + { tc_key.pixel = ((bitmap.buffer[pc / 8] << (pc % 8)) & 128) ? NUMCOLORS : 0; - break; - default: + } + else + { return "Unsupported ft_pixel_mode"; } - - if (tc_key.pixel > 0) + if (tc_key.pixel > 0) /* if not background */ + { + x = pen_x + col; + + /* clip if out of bounds */ + if (x >= im->sx || x < 0) + continue; + /* get pixel location in gd buffer */ + pixel = &im->pixels[y][x]; + if (tc_key.pixel == NUMCOLORS) { - - if (im->trueColor) { - tc_elem = (tweencolor_t *) gdCacheGet ( - tc_cache, &tc_key); - - gdImageSetPixel(im, x, y, tc_elem->tweencolor); + /* use fg color directly. gd 2.0.2: watch out for + negative indexes (thanks to David Marwood). */ + *pixel = (fg < 0) ? -fg : fg; } - else { - pixel = &im->pixels[y][x]; - if (tc_key.pixel == NUMCOLORS) - *pixel = fg; - else { - tc_key.bgcolor = *pixel; + else + { + /* find antialised color */ + + tc_key.bgcolor = *pixel; tc_elem = (tweencolor_t *) gdCacheGet ( tc_cache, &tc_key); - *pixel = tc_elem->tweencolor; - - } - + *pixel = tc_elem->tweencolor; } } } @@ -622,23 +692,38 @@ return (char *) NULL; } +static int +gdroundupdown (FT_F26Dot6 v1, int updown) +{ + return (!updown) + ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) + : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6); +} + extern int any2eucjp (char *, char *, unsigned int); +/* Persistent font cache until explicitly cleared */ +/* Fonts can be used across multiple images */ +static gdCache_head_t *fontCache; +static FT_Library library; + +void +gdFreeFontCache() +{ + if (fontCache) + { + gdCacheDelete(fontCache); + FT_Done_FreeType(library); + } +} + /********************************************************************/ /* gdImageStringFT - render a utf8 string onto a gd image */ char * gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, - double ptsize, double angle, int x, int y, char *string) + double ptsize, double angle, int x, int y, char *string) { - return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, NULL); -} - -static int -gdroundupdown (FT_F26Dot6 v1, int updown) -{ - return (!updown) - ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) - : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6); + return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, +NULL); } char * @@ -665,18 +750,30 @@ char *tmpstr = 0; int render = (im && (im->trueColor || (fg <= 255 && fg >= -255))); FT_BitmapGlyph bm; + int render_mode = FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT; + + /* fine tuning */ + double linespace = LINESPACE; + + /* + * make a new tweenColorCache on every call + * because caching colormappings between calls + * is not safe. If the im-pointer points to a + * brand new image, the cache gives out bogus + * colorindexes. -- 27.06.2001 <[EMAIL PROTECTED]> + */ + gdCache_head_t *tc_cache; + + tc_cache = gdCacheCreate( TWEENCOLORCACHESIZE, + tweenColorTest, tweenColorFetch, tweenColorRelease ); - /* fine tuning */ - double linespace = LINESPACE; - /***** initialize font library and font cache on first call ******/ - static gdCache_head_t *fontCache; - static FT_Library library; if (!fontCache) { if (FT_Init_FreeType (&library)) { + gdCacheDelete( tc_cache ); return "Failure to initialize font library"; } fontCache = gdCacheCreate (FONTCACHESIZE, @@ -690,6 +787,7 @@ font = (font_t *) gdCacheGet (fontCache, &fontkey); if (!font) { + gdCacheDelete( tc_cache ); return fontCache->error; } face = font->face; /* shortcut */ @@ -698,17 +796,16 @@ if (FT_Set_Char_Size (face, 0, (FT_F26Dot6) (ptsize * 64), GD_RESOLUTION, GD_RESOLUTION)) { + gdCacheDelete( tc_cache ); return "Could not set character size"; } - /* pull in supplied extended settings */ - if (strex) { - if ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE) - linespace = strex->linespacing; - - } + /* pull in supplied extended settings */ + if (strex) { + if ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE) + linespace = strex->linespacing; + } - matrix.xx = (FT_Fixed) (cos_a * (1 << 16)); matrix.yx = (FT_Fixed) (sin_a * (1 << 16)); matrix.xy = -matrix.yx; @@ -720,12 +817,16 @@ use_kerning = FT_HAS_KERNING (face); previous = 0; + if (fg < 0) + { + render_mode |= FT_LOAD_MONOCHROME; + } #ifndef JISX0208 if (font->have_char_map_sjis) { #endif - if ((tmpstr = (char *) gdMalloc (BUFSIZ)) != NULL) + if ((tmpstr = (char *) gdMalloc (BUFSIZ))) { any2eucjp (tmpstr, string, BUFSIZ); next = tmpstr; @@ -749,8 +850,8 @@ if (ch == '\r') { penf.x = 0; - x1 = (int)(penf.x * cos_a - penf.y * sin_a + 32) / 64; - y1 = (int)(penf.x * sin_a + penf.y * cos_a + 32) / 64; + x1 = (penf.x * cos_a - penf.y * sin_a + 32) / 64; + y1 = (penf.x * sin_a + penf.y * cos_a + 32) / 64; pen.x = pen.y = 0; previous = 0; /* clear kerning flag */ next++; @@ -759,10 +860,10 @@ /* newlines */ if (ch == '\n') { - penf.y -= (long)(face->size->metrics.height * linespace); + penf.y -= face->size->metrics.height * LINESPACE; penf.y = (penf.y - 32) & -64; /* round to next pixel row */ - x1 = (int)(penf.x * cos_a - penf.y * sin_a + 32) / 64; - y1 = (int)(penf.x * sin_a + penf.y * cos_a + 32) / 64; + x1 = (penf.x * cos_a - penf.y * sin_a + 32) / 64; + y1 = (penf.x * sin_a + penf.y * cos_a + 32) / 64; pen.x = pen.y = 0; previous = 0; /* clear kerning flag */ next++; @@ -826,6 +927,9 @@ } } + /* set rotation transform */ + FT_Set_Transform(face, &matrix, NULL); + /* Convert character code to glyph index */ glyph_index = FT_Get_Char_Index (face, ch); @@ -838,24 +942,33 @@ } /* load glyph image into the slot (erase previous one) */ - err = FT_Load_Glyph (face, glyph_index, FT_LOAD_DEFAULT); + err = FT_Load_Glyph (face, glyph_index, render_mode); if (err) + { + gdCacheDelete( tc_cache ); return "Problem loading glyph"; + } /* transform glyph image */ FT_Get_Glyph (slot, &image); if (brect) { /* only if need brect */ FT_Glyph_Get_CBox (image, ft_glyph_bbox_gridfit, &glyph_bbox); - if (!i) - { /* if first character, init BB corner values */ - bbox.xMin = bbox.yMin = (1 << 30) - 1; - bbox.xMax = bbox.yMax = -bbox.xMin; - } glyph_bbox.xMin += penf.x; glyph_bbox.yMin += penf.y; glyph_bbox.xMax += penf.x; glyph_bbox.yMax += penf.y; + if (ch == ' ') /* special case for trailing space */ + glyph_bbox.xMax += slot->metrics.horiAdvance; + if (!i) + { /* if first character, init BB corner values */ + bbox.xMin = glyph_bbox.xMin; + bbox.yMin = glyph_bbox.yMin; + bbox.xMax = glyph_bbox.xMax; + bbox.yMax = glyph_bbox.yMax; + } + else + { if (bbox.xMin > glyph_bbox.xMin) bbox.xMin = glyph_bbox.xMin; if (bbox.yMin > glyph_bbox.yMin) @@ -864,24 +977,25 @@ bbox.xMax = glyph_bbox.xMax; if (bbox.yMax < glyph_bbox.yMax) bbox.yMax = glyph_bbox.yMax; + } i++; } - /* transform glyph image */ - FT_Glyph_Transform (image, &matrix, 0); - if (render) { if (image->format != ft_glyph_format_bitmap) { err = FT_Glyph_To_Bitmap (&image, ft_render_mode_normal, 0, 1); if (err) + { + gdCacheDelete( tc_cache ); return "Problem rendering glyph"; } + } /* now, draw to our target surface */ bm = (FT_BitmapGlyph) image; - gdft_draw_bitmap (im, fg, bm->bitmap, + gdft_draw_bitmap (tc_cache, im, fg, bm->bitmap, x + x1 + ((pen.x + 31) >> 6) + bm->left, y - y1 + ((pen.y + 31) >> 6) - bm->top); } @@ -927,6 +1041,7 @@ if (tmpstr) gdFree (tmpstr); + gdCacheDelete( tc_cache ); return (char *) NULL; } Index: php4/ext/gd/libgd/gdhelpers.h diff -u php4/ext/gd/libgd/gdhelpers.h:1.1 php4/ext/gd/libgd/gdhelpers.h:1.2 --- php4/ext/gd/libgd/gdhelpers.h:1.1 Fri Apr 12 22:03:09 2002 +++ php4/ext/gd/libgd/gdhelpers.h Tue Oct 29 18:08:01 2002 @@ -1,6 +1,8 @@ #ifndef GDHELPERS_H #define GDHELPERS_H 1 +#include <sys/types.h> + /* TBB: strtok_r is not universal; provide an implementation of it. */ extern char *gd_strtok_r(char *s, char *sep, char **state); Index: php4/ext/gd/libgd/gdkanji.c diff -u php4/ext/gd/libgd/gdkanji.c:1.1 php4/ext/gd/libgd/gdkanji.c:1.2 --- php4/ext/gd/libgd/gdkanji.c:1.1 Fri Apr 12 22:03:09 2002 +++ php4/ext/gd/libgd/gdkanji.c Tue Oct 29 18:08:01 2002 @@ -360,7 +360,7 @@ from_len = strlen ((const char *) from) + 1; to_len = BUFSIZ; - if (iconv (cd, (const char **) &from, &from_len, + if (iconv (cd, (char **) &from, &from_len, (char **) &to, &to_len) == -1) { #ifdef HAVE_ERRNO_H Index: php4/ext/gd/libgd/gdparttopng.c diff -u php4/ext/gd/libgd/gdparttopng.c:1.1 php4/ext/gd/libgd/gdparttopng.c:1.2 --- php4/ext/gd/libgd/gdparttopng.c:1.1 Fri Apr 12 22:03:09 2002 +++ php4/ext/gd/libgd/gdparttopng.c Tue Oct 29 18:08:01 2002 @@ -47,7 +47,11 @@ gdImageDestroy (im); exit (1); } +#ifdef HAVE_LIBPNG gdImagePng (im, out); +#else + fprintf(stderr, "No PNG library support.\n"); +#endif fclose (out); gdImageDestroy (im); Index: php4/ext/gd/libgd/gdtest.c diff -u php4/ext/gd/libgd/gdtest.c:1.1 php4/ext/gd/libgd/gdtest.c:1.2 --- php4/ext/gd/libgd/gdtest.c:1.1 Fri Apr 12 22:03:09 2002 +++ php4/ext/gd/libgd/gdtest.c Tue Oct 29 18:08:01 2002 @@ -82,7 +82,7 @@ CompareImages ("GD->PNG ptr->GD", ref, im2); gdImageDestroy (im2); - ctx->free (ctx); + ctx->gd_free (ctx); /* */ @@ -117,7 +117,7 @@ CompareImages ("GD->GD2 ptr->GD", ref, im2); gdImageDestroy (im2); - ctx->free (ctx); + ctx->gd_free (ctx); /* */ @@ -152,7 +152,7 @@ CompareImages ("GD->GD ptr->GD", ref, im2); gdImageDestroy (im2); - ctx->free (ctx); + ctx->gd_free (ctx); /* ** Test gdImageCreateFromPngSource'
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php