iliaa           Thu Dec 25 17:12:13 2003 EDT

  Modified files:              
    /php-src/ext/gd     config.m4 gd.c 
    /php-src/ext/gd/libgd       gd.c gd.h gd_gd2.c gd_io.c gd_io_file.c 
                                gd_jpeg.c gd_png.c gd_topal.c gdft.c 
                                gdhelpers.h 
  Log:
  Synchronized bundled GD library with GD 2.0.17
   . GD is now thread-safe thanks to wrappers around freetype library
   . Significant optimization to png writing code.
   . Miscellaneous fixes.
  Fixed memory leak inside php_imagettftext_common()
  Make ext/gd compile with GD 2.0.17+ (gdFreeFontCache() is not avaliable)
  
  
Index: php-src/ext/gd/config.m4
diff -u php-src/ext/gd/config.m4:1.143 php-src/ext/gd/config.m4:1.144
--- php-src/ext/gd/config.m4:1.143      Sun Dec  7 10:23:22 2003
+++ php-src/ext/gd/config.m4    Thu Dec 25 17:12:08 2003
@@ -1,5 +1,5 @@
 dnl
-dnl $Id: config.m4,v 1.143 2003/12/07 15:23:22 helly Exp $
+dnl $Id: config.m4,v 1.144 2003/12/25 22:12:08 iliaa Exp $
 dnl
 
 dnl
@@ -258,6 +258,7 @@
   PHP_CHECK_LIBRARY(gd, gdImageColorResolve,    [AC_DEFINE(HAVE_GDIMAGECOLORRESOLVE, 
1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
   PHP_CHECK_LIBRARY(gd, gdImageGifCtx,          [AC_DEFINE(HAVE_GD_GIF_CTX,          
1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
   PHP_CHECK_LIBRARY(gd, gdCacheCreate,          [AC_DEFINE(HAVE_GD_CACHE_CREATE,     
1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
+  PHP_CHECK_LIBRARY(gd, gdFontCacheShutdown,    [AC_DEFINE(HAVE_GD_THREAD_SAFE,      
1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
 ])
 
 dnl
Index: php-src/ext/gd/gd.c
diff -u php-src/ext/gd/gd.c:1.281 php-src/ext/gd/gd.c:1.282
--- php-src/ext/gd/gd.c:1.281   Thu Dec 18 03:17:45 2003
+++ php-src/ext/gd/gd.c Thu Dec 25 17:12:08 2003
@@ -18,7 +18,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: gd.c,v 1.281 2003/12/18 08:17:45 rasmus Exp $ */
+/* $Id: gd.c,v 1.282 2003/12/25 22:12:08 iliaa Exp $ */
 
 /* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center,
    Cold Spring Harbor Labs. */
@@ -442,14 +442,18 @@
 #if HAVE_LIBGD20 && HAVE_GD_STRINGFT
 PHP_RSHUTDOWN_FUNCTION(gd)
 {
+#if defined(HAVE_GD_THREAD_SAFE) || defined(HAVE_GD_BUNDLED)
+       gdFontCacheShutdown();
+#else 
        gdFreeFontCache();
+#endif
        return SUCCESS;
 }
 #endif
 /* }}} */
 
 #if HAVE_GD_BUNDLED
-#define PHP_GD_VERSION_STRING "bundled (2.0.15 compatible)"
+#define PHP_GD_VERSION_STRING "bundled (2.0.17 compatible)"
 #elif HAVE_LIBGD20
 #define PHP_GD_VERSION_STRING "2.0 or higher"
 #elif HAVE_GDIMAGECOLORRESOLVE
@@ -3077,7 +3081,7 @@
        char *error = NULL;
        int argc;
 #if HAVE_GD_STRINGFTEX
-       gdFTStringExtra strex;
+       gdFTStringExtra strex = {0};
 #endif
 
 #if !HAVE_GD_STRINGFTEX
@@ -3120,7 +3124,6 @@
                        HashPosition pos;
 
                        convert_to_array_ex(EXT);
-                       memset(&strex, 0, sizeof(strex));
 
                        /* walk the assoc array */
                        zend_hash_internal_pointer_reset_ex(HASH_OF(*EXT), &pos);
@@ -3156,8 +3159,11 @@
        l = strlen(str);
 
 #ifdef VIRTUAL_DIR
-       if (virtual_filepath(Z_STRVAL_PP(FONTNAME), (char **) &fontname TSRMLS_CC)) {
-               fontname = (unsigned char *) Z_STRVAL_PP(FONTNAME);
+       {
+               char tmp_font_path[MAXPATHLEN];
+               if (VCWD_REALPATH(Z_STRVAL_PP(FONTNAME), tmp_font_path)) {
+                       fontname = (unsigned char *) Z_STRVAL_PP(FONTNAME);
+               }
        }
 #else
        fontname = (unsigned char *) Z_STRVAL_PP(FONTNAME);
Index: php-src/ext/gd/libgd/gd.c
diff -u php-src/ext/gd/libgd/gd.c:1.67 php-src/ext/gd/libgd/gd.c:1.68
--- php-src/ext/gd/libgd/gd.c:1.67      Mon Nov  3 20:55:50 2003
+++ php-src/ext/gd/libgd/gd.c   Thu Dec 25 17:12:12 2003
@@ -94,7 +94,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);
+int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y);
 
 void php_gd_error_ex(int type, const char *format, ...) 
 {
@@ -751,7 +751,7 @@
        }
 }
 
-static int gdImageGetTrueColorPixel (gdImagePtr im, int x, int y)
+int gdImageGetTrueColorPixel (gdImagePtr im, int x, int y)
 {
        int p = gdImageGetPixel(im, x, y);
 
@@ -2255,20 +2255,12 @@
        sty = (int *) gdMalloc (sizeof (int) * srcH);
        accum = 0;
        
+       /* Fixed by Mao Morimoto 2.0.16 */
        for (i = 0; (i < srcW); i++) {
-               int got;
-               accum += (double) dstW / (double) srcW;
-               got = (int) floor (accum);
-               stx[i] = got;
-               accum -= got;
+               stx[i] = dstW * (i+1) / srcW - dstW * i / srcW ;
        }
-       accum = 0;
        for (i = 0; (i < srcH); i++) {
-               int got;
-               accum += (double) dstH / (double) srcH;
-               got = (int) floor (accum);
-               sty[i] = got;
-               accum -= got;
+               sty[i] = dstH * (i+1) / srcH - dstH * i / srcH ;
        }
        for (i = 0; (i < gdMaxColors); i++) {
                colorMap[i] = (-1);
@@ -3019,6 +3011,15 @@
                        maxy = p[i].y;
                }
        }
+
+       /* 2.0.16: Optimization by Ilia Chipitsine -- don't waste time offscreen */
+       if (miny < 0) {
+               miny = 0;
+       }
+       if (maxy >= gdImageSY(im)) {
+               maxy = gdImageSY(im) - 1;
+       } 
+
        /* Fix in 1.3: count a vertex only once */
        for (y = miny; y <= maxy; y++) {
                /*1.4           int interLast = 0; */
Index: php-src/ext/gd/libgd/gd.h
diff -u php-src/ext/gd/libgd/gd.h:1.18 php-src/ext/gd/libgd/gd.h:1.19
--- php-src/ext/gd/libgd/gd.h:1.18      Sun Jun 15 16:00:08 2003
+++ php-src/ext/gd/libgd/gd.h   Thu Dec 25 17:12:12 2003
@@ -295,8 +295,16 @@
 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();
+/* 2.0.16: for thread-safe use of gdImageStringFT and friends,
+ * call this before allowing any thread to call gdImageStringFT. 
+ * Otherwise it is invoked by the first thread to invoke
+ * gdImageStringFT, with a very small but real risk of a race condition. 
+ * Return 0 on success, nonzero on failure to initialize freetype.
+ */
+int gdFontCacheSetup(void);
+
+/* Optional: clean up after application is done using fonts in gdImageStringFT(). */
+void gdFontCacheShutdown(void);
 
 /* Calls gdImageStringFT. Provided for backwards compatibility only. */
 char *gdImageStringTTF(gdImage *im, int *brect, int fg, char *fontlist,
Index: php-src/ext/gd/libgd/gd_gd2.c
diff -u php-src/ext/gd/libgd/gd_gd2.c:1.13 php-src/ext/gd/libgd/gd_gd2.c:1.14
--- php-src/ext/gd/libgd/gd_gd2.c:1.13  Tue Jun  3 19:23:21 2003
+++ php-src/ext/gd/libgd/gd_gd2.c       Thu Dec 25 17:12:12 2003
@@ -539,7 +539,7 @@
                                                        }
                                                } else {
                                                        ch = gdGetC(in);
-                                                       if (ch == EOF) {
+                                                       if ((int)ch == EOF) {
                                                                ch = 0;
                                                        }
                                                }
Index: php-src/ext/gd/libgd/gd_io.c
diff -u php-src/ext/gd/libgd/gd_io.c:1.2 php-src/ext/gd/libgd/gd_io.c:1.3
--- php-src/ext/gd/libgd/gd_io.c:1.2    Wed Mar 12 21:22:31 2003
+++ php-src/ext/gd/libgd/gd_io.c        Thu Dec 25 17:12:12 2003
@@ -3,7 +3,7 @@
 /*
    * io.c
    *
-   * Implements the imple I/O 'helper' routines.
+   * Implements the simple I/O 'helper' routines.
    *
    * Not really essential, but these routines were used extensively in GD,
    * so they were moved here. They also make IOCtx calls look better...
Index: php-src/ext/gd/libgd/gd_io_file.c
diff -u php-src/ext/gd/libgd/gd_io_file.c:1.3 php-src/ext/gd/libgd/gd_io_file.c:1.4
--- php-src/ext/gd/libgd/gd_io_file.c:1.3       Wed Mar 12 21:22:31 2003
+++ php-src/ext/gd/libgd/gd_io_file.c   Thu Dec 25 17:12:12 2003
@@ -34,8 +34,6 @@
        FILE *f;
 } fileIOCtx;
 
-struct fileIOCtx *fileIOCtxPtr;
-
 gdIOCtx *newFileCtx (FILE * f);
 
 static int fileGetbuf (gdIOCtx *, void *, int);
Index: php-src/ext/gd/libgd/gd_jpeg.c
diff -u php-src/ext/gd/libgd/gd_jpeg.c:1.15 php-src/ext/gd/libgd/gd_jpeg.c:1.16
--- php-src/ext/gd/libgd/gd_jpeg.c:1.15 Thu Nov 13 05:32:04 2003
+++ php-src/ext/gd/libgd/gd_jpeg.c      Thu Dec 25 17:12:12 2003
@@ -328,6 +328,11 @@
                php_gd_error("gd-jpeg: warning: jpeg_finish_decompress reports 
suspended data source");
        }
 
+       /* Thanks to Truxton Fulton */
+       if (cinfo.err->num_warnings > 0) {
+               goto error;
+       }
+
        jpeg_destroy_decompress (&cinfo);
        gdFree (row);
 
Index: php-src/ext/gd/libgd/gd_png.c
diff -u php-src/ext/gd/libgd/gd_png.c:1.14 php-src/ext/gd/libgd/gd_png.c:1.15
--- php-src/ext/gd/libgd/gd_png.c:1.14  Tue Jun  3 19:42:31 2003
+++ php-src/ext/gd/libgd/gd_png.c       Thu Dec 25 17:12:12 2003
@@ -622,28 +622,39 @@
         */
 
        if (im->trueColor) {
+               /* performance optimizations by Phong Tran */
                int channels = im->saveAlphaFlag ? 4 : 3;
                /* Our little 7-bit alpha channel trick costs us a bit here. */
                png_bytep *row_pointers;
+               unsigned char* pOutputRow;
+               int **ptpixels = im->tpixels;
+               int *pThisRow;
+               unsigned char a;
+               int thisPixel;
+               png_bytep *prow_pointers;
+               int saveAlphaFlag = im->saveAlphaFlag;
+
                row_pointers = safe_emalloc(sizeof(png_bytep), height, 0);
+               prow_pointers = row_pointers;
                for (j = 0; j < height; ++j) {
-                       int bo = 0;
-                       row_pointers[j] = (png_bytep) safe_emalloc(width, channels, 0);
+                       *prow_pointers = (png_bytep) safe_emalloc(width, channels, 0);
+                       pOutputRow = *prow_pointers++;
+                       pThisRow = *ptpixels++;
                        for (i = 0; i < width; ++i) {
-                               unsigned char a;
-                               row_pointers[j][bo++] = 
gdTrueColorGetRed(im->tpixels[j][i]);
-                               row_pointers[j][bo++] = 
gdTrueColorGetGreen(im->tpixels[j][i]);
-                               row_pointers[j][bo++] = 
gdTrueColorGetBlue(im->tpixels[j][i]);
-                               if (im->saveAlphaFlag) {
+                               thisPixel = *pThisRow++;
+                               *pOutputRow++ = gdTrueColorGetRed(thisPixel);
+                               *pOutputRow++ = gdTrueColorGetGreen(thisPixel);
+                               *pOutputRow++ = gdTrueColorGetBlue(thisPixel);
+                               if (saveAlphaFlag) {
                                        /* convert the 7-bit alpha channel to an 8-bit 
alpha channel.
                                         * We do a little bit-flipping magic, 
repeating the MSB
                                         * as the LSB, to ensure that 0 maps to 0 and
                                         * 127 maps to 255. We also have to invert to 
match
                                         * PNG's convention in which 255 is opaque.
                                         */
-                                       a = gdTrueColorGetAlpha(im->tpixels[j][i]);
+                                       a = gdTrueColorGetAlpha(thisPixel);
                                        /* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */ 
-                                       row_pointers[j][bo++] = 255 - ((a << 1) + (a 
>> 6));
+                                       *pOutputRow++ = 255 - ((a << 1) + (a >> 6));
                                }
                        }
                }
Index: php-src/ext/gd/libgd/gd_topal.c
diff -u php-src/ext/gd/libgd/gd_topal.c:1.11 php-src/ext/gd/libgd/gd_topal.c:1.12
--- php-src/ext/gd/libgd/gd_topal.c:1.11        Sat Apr  5 12:23:55 2003
+++ php-src/ext/gd/libgd/gd_topal.c     Thu Dec 25 17:12:12 2003
@@ -703,7 +703,7 @@
        histptr histp;
        int c0, c1, c2;
        int c0min, c0max, c1min, c1max, c2min, c2max;
-       long count;
+       long count = 0;
        long total = 0;
        long c0total = 0;
        long c1total = 0;
@@ -735,9 +735,16 @@
        cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total >> 1)) / total);
        cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total >> 1)) / total);
 #else
-       im->red[icolor] = (int) ((c0total + (total >> 1)) / total);
-       im->green[icolor] = (int) ((c1total + (total >> 1)) / total);
-       im->blue[icolor] = (int) ((c2total + (total >> 1)) / total);
+       /* 2.0.16: Paul den Dulk found an occasion where total can be 0 */
+       if (count) {
+               im->red[icolor] = (int) ((c0total + (total >> 1)) / total);
+               im->green[icolor] = (int) ((c1total + (total >> 1)) / total);
+               im->blue[icolor] = (int) ((c2total + (total >> 1)) / total);
+       } else {
+               im->red[icolor] = 255;
+               im->green[icolor] = 255;
+               im->blue[icolor] = 255;
+       }
 #endif
 }
 
Index: php-src/ext/gd/libgd/gdft.c
diff -u php-src/ext/gd/libgd/gdft.c:1.29 php-src/ext/gd/libgd/gdft.c:1.30
--- php-src/ext/gd/libgd/gdft.c:1.29    Fri Dec 19 07:41:24 2003
+++ php-src/ext/gd/libgd/gdft.c Thu Dec 25 17:12:12 2003
@@ -92,8 +92,12 @@
  * if building this version of gd separate from graphviz.
  */
 #ifndef DEFAULT_FONTPATH
+#if defined(__APPLE__) || (defined(__MWERKS__) && defined(macintosh))
+#define DEFAULT_FONTPATH 
"/usr/share/fonts/truetype:/System/Library/Fonts:/Library/Fonts"
+#else
 #define DEFAULT_FONTPATH "/usr/share/fonts/truetype"
 #endif
+#endif
 #ifndef PATHSEPARATOR
 #define PATHSEPARATOR ":"
 #endif
@@ -408,26 +412,18 @@
                                }
                        }
 
-                       snprintf(fullname, sizeof(fullname) - 1, "%s/%s", dir, name);
-                       if (access(fullname, R_OK) == 0) {
-                               font_found++;
-                               break;
-                       }
-                       snprintf(fullname, sizeof(fullname) - 1, "%s/%s.ttf", dir, 
name);
-                       if (access(fullname, R_OK) == 0) {
-                               font_found++;
-                               break;
-                       }
-                       snprintf(fullname, sizeof(fullname) - 1, "%s/%s.pfa", dir, 
name);
-                       if (access(fullname, R_OK) == 0) {
-                               font_found++;
-                               break;
-                       }
-                       snprintf(fullname, sizeof(fullname) - 1, "%s/%s.pfb", dir, 
name);
-                       if (access(fullname, R_OK) == 0) {
-                               font_found++;
-                               break;
-                       }
+#define GD_CHECK_FONT_PATH(ext)        \
+       snprintf(fullname, sizeof(fullname) - 1, "%s/%s%s", dir, name, ext);    \
+       if (access(fullname, R_OK) == 0) {      \
+               font_found++;   \
+               break;  \
+       }       \
+
+                       GD_CHECK_FONT_PATH("");
+                       GD_CHECK_FONT_PATH(".ttf");
+                       GD_CHECK_FONT_PATH(".pfa");
+                       GD_CHECK_FONT_PATH(".pfb");
+                       GD_CHECK_FONT_PATH(".dfont");
                }
                gdFree(path);
                path = NULL;
@@ -458,6 +454,16 @@
        }
 
        /* FIXME - This mapping stuff is imcomplete - where is the spec? */
+       /* EAM   - It's worse than that. It's pointless to match character encodings 
here.
+        *         As currently written, the stored a->face->charmap only matches one 
of
+        *         the actual charmaps and we cannot know at this stage if it is the 
right
+        *         one. We should just skip all this stuff, and check in 
gdImageStringFTEx
+        *         if some particular charmap is preferred and if so whether it is 
held in
+        *         one of the a->face->charmaps[0..num_charmaps].
+        *         And why is it so bad not to find any recognized charmap?  The user 
may
+        *         still know what mapping to use, even if we do not.  In that case we 
can
+        *         just use the map in a->face->charmaps[num_charmaps] and be done 
with it.
+        */
 
        a->have_char_map_unicode = 0;
        a->have_char_map_big5 = 0;
@@ -467,6 +473,20 @@
                charmap = a->face->charmaps[n];
                platform = charmap->platform_id;
                encoding = charmap->encoding_id;
+
+/* EAM DEBUG - Newer versions of libfree2 make it easier by defining encodings */
+#ifdef FT_ENCODING_MS_SYMBOL
+       if (charmap->encoding == FT_ENCODING_MS_SYMBOL
+               || charmap->encoding == FT_ENCODING_ADOBE_CUSTOM
+               || charmap->encoding == FT_ENCODING_ADOBE_STANDARD) {
+               a->have_char_map_unicode = 1;
+               found = charmap;
+               a->face->charmap = charmap;
+               return (void *)a;
+       }
+#endif /* FT_ENCODING_MS_SYMBOL */
+/* EAM DEBUG */
+
                if ((platform == 3 && encoding == 1)            /* Windows Unicode */
                        || (platform == 3 && encoding == 0)     /* Windows Symbol */
                        || (platform == 2 && encoding == 1)     /* ISO Unicode */
@@ -511,16 +531,12 @@
 /********************************************************************/
 /* tweencolor cache functions                                            */
 
-static int
-tweenColorTest (void *element, void *key)
+static int tweenColorTest (void *element, void *key)
 {
-  tweencolor_t *a = (tweencolor_t *) element;
-  tweencolorkey_t *b = (tweencolorkey_t *) key;
+       tweencolor_t *a = (tweencolor_t *) element;
+       tweencolorkey_t *b = (tweencolorkey_t *) key;
 
-  return (a->pixel == b->pixel
-         && a->bgcolor == b->bgcolor
-         && a->fgcolor == b->fgcolor
-         && a->im == b->im);
+       return (a->pixel == b->pixel && a->bgcolor == b->bgcolor && a->fgcolor == 
b->fgcolor && a->im == b->im);
 }
 
 /*
@@ -610,7 +626,8 @@
         pcr = pc;
         y = pen_y + row;
         /* clip if out of bounds */
-        if (y >= im->sy || y < 0)
+        /* 2.0.16: clipping rectangle, not image bounds */             
+       if ((y > im->cy2) || (y < im->cy1))
          continue;
       for (col = 0; col < bitmap.width; col++, pc++)
        {
@@ -645,7 +662,8 @@
           level = gdAlphaMax - level;  
           x = pen_x + col;
              /* clip if out of bounds */
-             if (x >= im->sx || x < 0)
+             /* 2.0.16: clip to clipping rectangle, Matt McNabb */
+               if ((x > im->cx2) || (x < im->cx1))
                continue;
              /* get pixel location in gd buffer */
            tpixel = &im->tpixels[y][x];
@@ -745,30 +763,47 @@
 extern int any2eucjp (char *, char *, unsigned int);
 
 /* Persistent font cache until explicitly cleared */
-/*     Fonts can be used across multiple images */
+/* Fonts can be used across multiple images */
+
+/* 2.0.16: thread safety (the font cache is shared) */
+gdMutexDeclare(gdFontCacheMutex);
 static gdCache_head_t *fontCache = NULL;
 static FT_Library library;
 
-void
-gdFreeFontCache()
+void gdFontCacheShutdown()
 {
-  if (fontCache)
-    {
-      gdCacheDelete(fontCache);
-         fontCache = NULL;
-      FT_Done_FreeType(library);
-    }
+       if (fontCache) {
+               gdMutexShutdown(gdFontCacheMutex);
+               gdCacheDelete(fontCache);
+               fontCache = NULL;
+               FT_Done_FreeType(library);
+       }
 }
 
+int gdFontCacheSetup(void)
+{
+       if (fontCache) {
+               /* Already set up */
+               return 0;
+       }
+       gdMutexSetup(gdFontCacheMutex);
+       if (FT_Init_FreeType(&library)) {
+               gdMutexShutdown(gdFontCacheMutex);
+               return -1;
+       }
+       fontCache = gdCacheCreate (FONTCACHESIZE, fontTest, fontFetch, fontRelease);
+       return 0;
+}
+
+
 /********************************************************************/
 /* gdImageStringFT -  render a utf8 string onto a gd image          */
 
 char *
-gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,
+gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist, 
                 double ptsize, double angle, int x, int y, char *string)
 {
-       return gdImageStringFTEx(im, brect, fg, fontlist,
-               ptsize, angle, x, y, string, 0);
+       return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, 
0);
 }
 
 char *
@@ -815,20 +850,21 @@
        /***** initialize font library and font cache on first call ******/
 
        if (!fontCache) {
-               if (FT_Init_FreeType (&library)) {
-                       gdCacheDelete( tc_cache );
+               if (gdFontCacheSetup() != 0) {
+                       gdCacheDelete(tc_cache);
                        return "Failure to initialize font library";
                }
-               fontCache = gdCacheCreate(FONTCACHESIZE, fontTest, fontFetch, 
fontRelease);
        }
        /*****/
-
+       
+       gdMutexLock(gdFontCacheMutex);
        /* get the font (via font cache) */
        fontkey.fontlist = fontlist;
        fontkey.library = &library;
        font = (font_t *) gdCacheGet (fontCache, &fontkey);
        if (!font) {
                gdCacheDelete(tc_cache);
+               gdMutexUnlock(gdFontCacheMutex);
                return fontCache->error;
        }
        face = font->face;              /* shortcut */
@@ -836,6 +872,7 @@
 
        if (FT_Set_Char_Size (face, 0, (FT_F26Dot6) (ptsize * 64), GD_RESOLUTION, 
GD_RESOLUTION)) {
                gdCacheDelete(tc_cache);
+               gdMutexUnlock(gdFontCacheMutex);
                return "Could not set character size";
        }
 
@@ -887,6 +924,7 @@
        }
        if (!mfound) {
                /* No character set found! */
+               gdMutexUnlock(gdFontCacheMutex);
                return "No character set found";
        }
 
@@ -928,6 +966,21 @@
                          next++;
                          continue;
                }
+
+/* EAM DEBUG */
+#ifdef FT_ENCODING_MS_SYMBOL
+               if (font->face->charmap->encoding == FT_ENCODING_MS_SYMBOL) {
+                       /* I do not know the significance of the constant 0xf000.
+                        * It was determined by inspection of the character codes
+                        * stored in Microsoft font symbol.
+                        */
+                       len = gdTcl_UtfToUniChar (next, &ch);
+                       ch |= 0xf000;
+                       next += len;
+               } else
+#endif /* FT_ENCODING_MS_SYMBOL */
+/* EAM DEBUG */
+
                switch (m) {
                        case gdFTEX_Unicode:
                                if (font->have_char_map_unicode) {
@@ -1005,6 +1058,7 @@
                                gdFree(tmpstr);
                        }
                        gdCacheDelete(tc_cache);
+                       gdMutexUnlock(gdFontCacheMutex);
                        return "Problem loading glyph";
                }
 
@@ -1047,6 +1101,7 @@
                                        gdFree(tmpstr);
                                }
                                gdCacheDelete(tc_cache);
+                               gdMutexUnlock(gdFontCacheMutex);
                                return "Problem rendering glyph";
                        }
 
@@ -1097,6 +1152,7 @@
                gdFree(tmpstr);
        }
        gdCacheDelete(tc_cache);
+       gdMutexUnlock(gdFontCacheMutex);
        return (char *) NULL;
 }
 
Index: php-src/ext/gd/libgd/gdhelpers.h
diff -u php-src/ext/gd/libgd/gdhelpers.h:1.6 php-src/ext/gd/libgd/gdhelpers.h:1.7
--- php-src/ext/gd/libgd/gdhelpers.h:1.6        Sat Nov 23 20:20:13 2002
+++ php-src/ext/gd/libgd/gdhelpers.h    Thu Dec 25 17:12:12 2003
@@ -21,5 +21,19 @@
 #define gdPFree(ptr)           pefree(ptr, 1)
 #define gdPEstrdup(ptr)                pestrdup(ptr, 1)
 
+#ifdef ZTS
+#define gdMutexDeclare(x) MUTEX_T x
+#define gdMutexSetup(x) x = tsrm_mutex_alloc()
+#define gdMutexShutdown(x) tsrm_mutex_free(x)
+#define gdMutexLock(x) tsrm_mutex_lock(x)
+#define gdMutexUnlock(x) tsrm_mutex_unlock(x)
+#else
+#define gdMutexDeclare(x)
+#define gdMutexSetup(x)
+#define gdMutexShutdown(x)
+#define gdMutexLock(x)
+#define gdMutexUnlock(x)
+#endif
+
 #endif /* GDHELPERS_H */
 

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to