Commits

Anonymous committed b623f93

- sync to 2.0.4

Comments (0)

Files changed (34)

 #Frequently Changed Settings
 
 #Correct include directories for freetype, zlib, libpng, XPM, JPEG, etc. 
-#If your include directories are different, add them here.
+#If your include directories are different, add them here. *Extra*
+#directories that don't happen to exist on your system shouldn't
+#cause an error (if they do, let me know).
 
-$includeDirs = "-I/usr/include/freetype2 -I/usr/include/X11 -I/usr/X11R6/include/X11 -I/usr/local/include"; 
+$includeDirs = "-I/usr/include/freetype2 -I/usr/local/include/freetype2 " .
+	"-I/usr/include/X11 -I/usr/X11R6/include/X11 -I/usr/local/include";
 
-#Typical install locations for freetype, zlib, xpm and libpng libraries.
+#Typical install locations for freetype, zlib, Xpm and libpng libraries.
 #If yours are somewhere else, other than a standard location
 #such as /lib or /usr/lib, then change this. This line shouldn't hurt 
 #if you don't actually have some of the optional libraries and directories.
-$libDirs = "-L/usr/local/lib -L/usr/lib/X11 -L/usr/X11R6/lib";
+$libDirs = "-L/usr/lib/X11 -L/usr/X11R6/lib -L/usr/local/lib";
 
 #If you don't have gcc, get it. If you really must, you can change this; 
 #but if you do, you must specify not only your compiler but options 
 } elsif ($os =~ /^(sunos)/i) {
 	$sharedLinkHead = "/usr/ccs/bin/ld -G";
 	$sharedLinkTail = "-ldl";
+	$socketLibForXpm = 1;
 	print "Found OS with sunos-like shared library link command\n";
 } elsif ($os =~ /^(darwin)/i) {
 	$sharedLinkHead = "ld -dynamic -flat_namespace -undefined suppress";
 	print "Warning: freetype 2.x library not found, freetype will not be supported.\n";
 }
 
-if (&testLibrary("xpm", "XpmReadFileToXpmImage(0, 0, 0)")) {
-	push @options, "xpm";
-	print "xpm library found.\n";
+#2.0.4 thanks to Len Makin: need optional libraries and uppercase X,
+#also -lsocket under Solaris
+
+if ($socketLibNeededForXpm) {
+	$xpmLibs = "-lX11 -lsocket";
 } else {
-	print "xpm library not found. That's OK. Almost no one needs xpm in gd.\n";
+	$xpmLibs = "-lX11";
+}
+
+if (&testLibrary("Xpm", "XpmReadFileToXpmImage(0, 0, 0)", $xpmLibs)) {
+	push @options, "Xpm";
+	push @options, "X11";
+	if ($socketLibNeededForXpm) {
+		push @options, "socket";
+	}
+	print "Xpm library found.\n";
+} else {
+	print "Xpm library not found. That's OK. Almost no one needs Xpm in gd.\n";
 }
 
 for $o (@options) {
 # Update these with each release!
 
 MAJOR_VERSION=2
-VERSION=2.0.3
+VERSION=2.0.4
 
 COMPILER=$compiler
 
 
 PROGRAMS=$safePrograms \$(TEST_PROGRAMS)
 
-TEST_PROGRAMS=gdtest gddemo gd2time gdtestft testac
+TEST_PROGRAMS=gdtest gddemo gd2time gdtestft testac fontwheeltest fontsizetest
 
 default: instructions
 
 gdtestft: gdtestft.o
 	\$(CC) --verbose gdtestft.o -o gdtestft \$(LIBDIRS) \$(LIBS)
 
+fontwheeltest: fontwheeltest.o
+	\$(CC) --verbose fontwheeltest.o -o fontwheeltest \$(LIBDIRS) \$(LIBS)
+
+fontsizetest: fontsizetest.o
+	\$(CC) --verbose fontsizetest.o -o fontsizetest \$(LIBDIRS) \$(LIBS)
+
 LIBOBJS=gd.o gd_gd.o gd_gd2.o gd_io.o gd_io_dp.o \\
 		gd_io_file.o gd_ss.o gd_io_ss.o gd_png.o gd_jpeg.o gdxpm.o \\
 		gdfontt.o gdfonts.o gdfontmb.o gdfontl.o gdfontg.o \\
 	-ranlib libgd.a
 
 clean:
-	rm -f *.o *.a *.so *.so.* \${PROGRAMS} test/gdtest.jpg test/gdtest.wbmp test/fttest.png test/fttest.jpg *test.errors
+	rm -f *.o *.a *.so *.so.* \${PROGRAMS} test/gdtest.jpg test/gdtest.wbmp test/fttest.png test/fttest.jpg *test.errors font*test?.png
 veryclean: clean
 	rm Makefile
 EOM
+------------- New fontwheel --------------
+times
+.....Hello, there!
+------------------------------------------
+------------- New fontwheel --------------
+times
+.....Hello, there!
+------------------------------------------
+------------- New fontwheel --------------
+arial
+.....Hello, there!
+------------------------------------------
+------------- New fontwheel --------------
+arial
+.....Hello, there!
+------------------------------------------

src/fontsizetest.c

+#include "gd.h"
+
+void dosizes(gdImagePtr im, int color, char *fontfile,
+             int x, int y, const char *string)
+{
+  int brect[8];
+  double curang = 0.0;
+  char *cp;
+  int cursize;
+  char buf[60];
+
+  for (cursize = 1; cursize <= 20; cursize++) 
+  {
+      sprintf(buf,"%d: %s", cursize, string);
+
+  /* The case of newlines is taken care of in the gdImageStringTTF call */
+#if defined(OLDER_GD)
+      cp = gdImageStringTTF (im, brect, color, fontfile, cursize, curang, x, y, buf);
+#else
+      cp = gdImageStringFT  (im, brect, color, fontfile, cursize, curang, x, y, buf);
+#endif
+    if (cp)
+      fprintf(stderr, "%s\n", cp);
+    y += cursize + 4;
+
+/* render the same fontsize with antialiasing turned off */
+#if defined(OLDER_GD)
+      cp = gdImageStringTTF (im, brect, 0-color, fontfile, cursize, curang, x, y, buf);
+#else
+      cp = gdImageStringFT  (im, brect, 0-color, fontfile, cursize, curang, x, y, buf);
+#endif
+    if (cp)
+      fprintf(stderr, "%s\n", cp);
+    y += cursize + 4;
+  }
+}
+
+void dotest(char *font, 
+ 	    int w, int h, char *string,
+            const char *filename)
+{
+  gdImagePtr im;
+  FILE *out;
+  int bg;
+  int fc;
+  int lc;
+
+  im = gdImageCreate(w, h);
+  bg = gdImageColorAllocate(im, 0, 0, 0);
+
+  gdImageFilledRectangle(im, 1, 1, w-1, h-1, bg);
+  
+  fc = gdImageColorAllocate(im, 255, 192, 192);
+  lc = gdImageColorAllocate(im, 192, 255, 255);
+
+  out = fopen(filename, "wb");
+
+  dosizes(im, fc, font, 20, 20, string);
+
+#if defined(HAVE_LIBPNG)
+  gdImagePng(im, out);
+#elif defined(HAVE_LIBJPEG)
+  gdImageJpeg(im, out, -1);
+#endif
+  fclose(out);
+}
+
+int main(int argc, char **argv)
+{
+
+#if defined(HAVE_LIBPNG)
+  dotest("times",     400, 600, ".....Hello, there!", "fontsizetest1.png");
+  dotest("cour",      400, 600, ".....Hello, there!", "fontsizetest2.png");
+  dotest("arial",     400, 600, ".....Hello, there!", "fontsizetest3.png");
+  dotest("luximr",   400, 600, ".....Hello, there!", "fontsizetest4.png");
+#elif defined(HAVE_LIBJPEG)
+  dotest("times",     400, 600, ".....Hello, there!", "fontsizetest1.jpeg");
+  dotest("cour",      400, 600, ".....Hello, there!", "fontsizetest2.jpeg");
+  dotest("arial",     400, 600, ".....Hello, there!", "fontsizetest3.jpeg");
+  dotest("luximr",   400, 600, ".....Hello, there!", "fontsizetest4.jpeg");
+#else
+  fprintf(stderr, "no PNG or JPEG support\n");
+#endif
+
+  return 0;
+}

src/fontwheeltest.c

+#include <math.h>
+#include "gd.h"
+#define DEGTORAD(x) ( (x) * (2.0 * 3.14159265) / 360.0 )
+
+void doerr(FILE *err, const char *msg)
+{
+  if (err)
+  {
+    fprintf(err, "%s\n", msg);
+    fflush(err);
+  }
+}
+
+void dowheel(gdImagePtr im, int color, char *fontfile,
+             int fontsize, double angle, int x, int y, char *string)
+{
+  int brect[8];
+  FILE *err;
+  double curang;
+  char *cp;
+  
+  err = fopen("err.out", "a");
+  doerr(err, "------------- New fontwheel --------------");
+  doerr(err, fontfile);
+  doerr(err, string);
+  doerr(err, "------------------------------------------");
+
+  for (curang=0.0; curang < 360.0; curang += angle)
+  {
+  /* The case of newlines is taken care of in the gdImageStringTTF call */
+#if defined(OLDER_GD)
+      cp = gdImageStringTTF (im, brect, color, fontfile, fontsize, DEGTORAD(curang), x, y, string);
+#else
+      cp = gdImageStringFT  (im, brect, color, fontfile, fontsize, DEGTORAD(curang), x, y, string);
+#endif
+    if (cp)
+      doerr(err, cp);
+  }
+
+  fclose(err);
+}
+
+void dolines(gdImagePtr im, int color, double incr, int x, int y, int offset, int length)
+{
+  double curang;
+  double angle;
+  double x0, x1, y0, y1;
+  for (curang=0.0; curang < 360.0; curang += incr )
+  {
+    angle = curang * (2.0 * 3.14159265) / 360.0;
+    x0 = cos(angle)*offset + x;
+    x1 = cos(angle)*(offset+length) + x;
+    y0 = sin(angle)*offset + y;
+    y1 = sin(angle)*(offset+length) + y;
+    gdImageLine(im, x0, y0, x1, y1, color);
+  }
+}
+
+void dotest(char *font, int size, double incr, 
+ 	    int w, int h, char *string,
+            const char *filename)
+{
+  gdImagePtr im;
+  FILE *out;
+  int bg;
+  int fc;
+  int lc;
+  int xc = w / 2;
+  int yc = h / 2;
+
+  im = gdImageCreate(w, h);
+  bg = gdImageColorAllocate(im, 0, 0, 0);
+
+  gdImageFilledRectangle(im, 1, 1, w-1, h-1, bg);
+  
+  fc = gdImageColorAllocate(im, 255, 192, 192);
+  lc = gdImageColorAllocate(im, 192, 255, 255);
+
+  out = fopen(filename, "wb");
+
+  dowheel(im, fc, font, size, incr, xc, yc, string);
+  dolines(im, lc, incr, xc, yc, 20, 120);
+
+#if defined(HAVE_LIBPNG)
+  gdImagePng(im, out);
+#elif defined(HAVE_LIBJPEG)
+  gdImageJpeg(im, out, -1);
+#endif
+
+  fclose(out);
+}
+
+int main(int argc, char **argv)
+{
+
+#if defined(HAVE_LIBPNG)
+  dotest("times", 16, 20.0, 400, 400, ".....Hello, there!", "fontwheeltest1.png");
+  dotest("times", 16, 30.0, 400, 400, ".....Hello, there!", "fontwheeltest2.png");
+  dotest("arial", 16, 45.0, 400, 400, ".....Hello, there!", "fontwheeltest3.png");
+  dotest("arial", 16, 90.0, 400, 400, ".....Hello, there!", "fontwheeltest4.png");
+#elif defined(HAVE_LIBJPEG)
+  dotest("times", 16, 20.0, 400, 400, ".....Hello, there!", "fontwheeltest1.jpeg");
+  dotest("times", 16, 30.0, 400, 400, ".....Hello, there!", "fontwheeltest2.jpeg");
+  dotest("arial", 16, 45.0, 400, 400, ".....Hello, there!", "fontwheeltest3.jpeg");
+  dotest("arial", 16, 90.0, 400, 400, ".....Hello, there!", "fontwheeltest4.jpeg");
+#else
+  fprintf(stderr, "no PNG or JPEG support\n");
+#endif
+
+  return 0;
+}
 
 static void gdImageBrushApply (gdImagePtr im, int x, int y);
 static void gdImageTileApply (gdImagePtr im, int x, int y);
+static int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y);
 
 gdImagePtr
 gdImageCreate (int sx, int sy)
 }
 
 
+#if 0
 /*
  * This is not actually used, but is here for completeness, in case someone wants to
  * use the HWB stuff for anything else...
   return RGB;
 
 }
+#endif
 
 int
 gdImageColorClosestHWB (gdImagePtr im, int r, int g, int b)
 	  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);
     }
   else
     {
+      p = gdImageGetPixel(im->tile, srcx, srcy);
       /* Allow for transparency */
       if (p != gdImageGetTransparent (im->tile))
 	{
     }
 }
 
-int
+static int
 gdImageGetTrueColorPixel (gdImagePtr im, int x, int y)
 {
   int p = gdImageGetPixel (im, x, y);
   int dashStep = 0;
   int on = 1;
   int wid;
-  int w, wstart, vert;
+  int vert;
   int thick = im->thick;
 
   dx = abs (x2 - x1);
   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;
 	  tox = dstX;
 	  for (x = srcX; (x < (srcX + srcW)); x++)
 	    {
-	      int nc;
+	      int nc = 0;
 	      int mapTo;
 	      if (!stx[x - srcX])
 		{
 		}
 	      if (dst->trueColor)
 		{
-		  int d;
 		  mapTo = gdImageGetTrueColorPixel (src, x, y);
 		  /* Added 7/24/95: support transparent copies */
 		  if (gdImageGetTransparent (src) == mapTo)
 		      int srcW, int srcH)
 {
   int x, y;
-  float sx, sy;
   if (!dst->trueColor)
     {
       gdImageCopyResized (
     {
       for (x = dstX; (x < dstX + dstW); x++)
 	{
-	  int pd = gdImageGetPixel (dst, x, y);
 	  float sy1, sy2, sx1, sx2;
 	  float sx, sy;
 	  float spixels = 0;
 extern "C" {
 #endif
 
-/* default fontpath for unix systems */
-#define DEFAULT_FONTPATH "/usr/share/fonts/truetype"
+/* default fontpath for unix systems  - whatever happened to standards ! */
+#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 ":"
 
 /* gd.h: declarations file for the graphic-draw module.
 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);
       gdImageDestroy (im);
       exit (1);
     }
+#ifdef HAVE_LIBPNG
   gdImagePng (im, out);
+#else
+  fprintf(stderr, "No PNG library support available.\n");
+#endif
   fclose (out);
   gdImageDestroy (im);
 
   in = gdNewFileCtx (inFile);
   im = gdImageCreateFromGdCtx (in);
 
-  in->free (in);
+  in->gd_free (in);
 
   return im;
 }
 _gdPutColors (gdImagePtr im, gdIOCtx * out)
 {
   int i;
-  int trans;
 
   gdPutC (im->trueColor, out);
   if (!im->trueColor)
 {
   gdIOCtx *out = gdNewFileCtx (outFile);
   _gdImageGd (im, out);
-  out->free (out);
+  out->gd_free (out);
 }
 
 void *
   gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
   _gdImageGd (im, out);
   rv = gdDPExtractData (out, size);
-  out->free (out);
+  out->gd_free (out);
   return rv;
 }
    *
  */
 
-/* 2.03: gd2 is no longer mandatory */
-#ifdef HAVE_LIBZ
-
 #include <stdio.h>
 #include <errno.h>
 #include <math.h>
 #include <string.h>
 #include <stdlib.h>
-#include <zlib.h>
 #include "gd.h"
 #include "gdhelpers.h"
 
+/* 2.03: gd2 is no longer mandatory */
+/* JCE - test after including gd.h so that HAVE_LIBZ can be set in
+ * a config.h file included by gd.h */
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+
 #define TRUE 1
 #define FALSE 0
 
 
   im = gdImageCreateFromGd2Ctx (in);
 
-  in->free (in);
+  in->gd_free (in);
 
   return im;
 }
   int i;
   int ncx, ncy, nc, cs, cx, cy;
   int x, y, ylo, yhi, xlo, xhi;
-  int ch, vers, fmt;
+  int vers, fmt;
   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. */
 
 
   im = gdImageCreateFromGd2PartCtx (in, srcx, srcy, w, h);
 
-  in->free (in);
+  in->gd_free (in);
 
   return im;
 }
   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;
 
 		    {
 		      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
 			{
   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"); */
 
 {
   gdIOCtx *out = gdNewFileCtx (outFile);
   _gdImageGd2 (im, out, cs, fmt);
-  out->free (out);
+  out->gd_free (out);
 }
 
 void *
   gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
   _gdImageGd2 (im, out, cs, fmt);
   rv = gdDPExtractData (out, size);
-  out->free (out);
+  out->gd_free (out);
   return rv;
 }
 
+#else /* no HAVE_LIBZ */
+gdImagePtr
+gdImageCreateFromGd2 (FILE * inFile)
+{
+  fprintf(stderr,"GD2 support is not available - no libz\n");
+  return NULL;
+}
+gdImagePtr
+gdImageCreateFromGd2Ctx (gdIOCtxPtr in)
+{
+  fprintf(stderr,"GD2 support is not available - no libz\n");
+  return NULL;
+}
 #endif /* HAVE_LIBZ */
 
 	int	(*seek)(struct gdIOCtx*, const int);
 	long	(*tell)(struct gdIOCtx*);
 
-	void    (*free)(struct gdIOCtx*);
+	void    (*gd_free)(struct gdIOCtx*);
 
 } gdIOCtx;
 
-
 /*
    * io_dp.c
    *
   ctx->ctx.seek = dynamicSeek;
   ctx->ctx.tell = dynamicTell;
 
-  ctx->ctx.free = gdFreeDynamicCtx;
+  ctx->ctx.gd_free = gdFreeDynamicCtx;
 
   return (gdIOCtx *) ctx;
 }
   ctx->ctx.tell = fileTell;
   ctx->ctx.seek = fileSeek;
 
-  ctx->ctx.free = gdFreeFileCtx;
+  ctx->ctx.gd_free = gdFreeFileCtx;
 
   return (gdIOCtx *) ctx;
 }
   ctx->ctx.tell = NULL;
   ctx->ctx.seek = NULL;
 
-  ctx->ctx.free = gdFreeSsCtx;
+  ctx->ctx.gd_free = gdFreeSsCtx;
 
   return (gdIOCtx *) ctx;
 }
-
-
 /*
  * gd_jpeg.c: Read and write JPEG (JFIF) format image files using the
  * gd graphics library (http://www.boutell.com/gd/).
  * 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";
 
 {
   gdIOCtx *out = gdNewFileCtx (outFile);
   gdImageJpegCtx (im, out, quality);
-  out->free (out);
+  out->gd_free (out);
 }
 
 void *
   gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
   gdImageJpegCtx (im, out, quality);
   rv = gdDPExtractData (out, size);
-  out->free (out);
+  out->gd_free (out);
   return rv;
 }
 
 	}
     }
   jpeg_finish_compress (&cinfo);
-error:
   jpeg_destroy_compress (&cinfo);
   gdFree (row);
 }
   gdImagePtr im;
   gdIOCtx *in = gdNewFileCtx (inFile);
   im = gdImageCreateFromJpegCtx (in);
-  in->free (in);
+  in->gd_free (in);
   return im;
 }
 
   dest->outfile = outfile;
 }
 
-#endif /* HAVE_JPEG */
+#endif /* HAVE_LIBJPEG */
-
-#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 */
 
   gdImagePtr im;
   gdIOCtx *in = gdNewFileCtx (inFile);
   im = gdImageCreateFromPngCtx (in);
-  in->free (in);
+  in->gd_free (in);
   return im;
 }
 
   png_bytep image_data = NULL;
   png_bytepp row_pointers = NULL;
   gdImagePtr im = NULL;
-  int i, j, *open;
+  int i, j, *open = NULL;
   volatile int transparent = -1;
   volatile int palette_allocated = FALSE;
 
 {
   gdIOCtx *out = gdNewFileCtx (outFile);
   gdImagePngCtx (im, out);
-  out->free (out);
+  out->gd_free (out);
 }
 
 void *
   gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
   gdImagePngCtx (im, out);
   rv = gdDPExtractData (out, size);
-  out->free (out);
+  out->gd_free (out);
   return rv;
 }
 
 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;
       int i;
       int j;
       int k;
-      int highTrans = -1;
       for (i = 0; (i < im->colorsTotal); i++)
 	{
 	  if ((!im->open[i]) &&
 /*#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
 
   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 */
-
-
 /*
  * gd_topal.c 
  * 
  * may not have done a great job of either. It's not Thomas G. Lane's fault.
  */
 
+#include <string.h>
 #include "gd.h"
 #include "gdhelpers.h"
 
   register int *bptr;		/* pointer into bestdist[] array */
   int *cptr;			/* pointer into bestcolor[] array */
   int dist0, dist1, dist2;	/* initial distance values */
-  register int dist3;		/* current distance in inner loop */
+  register int dist3 = 0;	/* current distance in inner loop */
   int xx0, xx1, xx2;		/* distance increments */
-  register int xx3;
+  register int xx3 = 0;
   int inc0, inc1, inc2, inc3;	/* initial values for increments */
   /* This array holds the distance to the nearest-so-far color for each cell */
   int bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS * BOX_C3_ELEMS];
 				gdTrueColorAlpha (im->red[i], im->green[i],
 						im->blue[i], im->alpha[i]));
       }
+#ifdef HAVE_LIBPNG
     gdImagePng (im2, out);
+#else
+    fprintf(stderr, "No PNG library support.\n");
+#endif
     fclose (out);
     gdImageDestroy (im2);
   }
   gdImagePtr im;
   gdIOCtx *in = gdNewFileCtx (inFile);
   im = gdImageCreateFromWBMPCtx (in);
-  in->free (in);
+  in->gd_free (in);
   return (im);
 }
 
 {
   gdIOCtx *out = gdNewFileCtx (outFile);
   gdImageWBMPCtx (im, fg, out);
-  out->free (out);
+  out->gd_free (out);
 }
 
 /* gdImageWBMPPtr
   gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
   gdImageWBMPCtx (im, fg, out);
   rv = gdDPExtractData (out, size);
-  out->free (out);
+  out->gd_free (out);
   return rv;
 }
 /* header                                                */
 /*********************************************************/
 
+#include <stdlib.h>
+#ifdef HAVE_MALLOC_H
 #include <malloc.h>
+#endif
 #ifndef NULL
 #define NULL (void *)0
 #endif
 int
 main (void)
 {
+#ifdef HAVE_LIBPNG
   /* Input and output files */
   FILE *in;
   FILE *out;
     {
       gdImageDestroy (im_in);
     }
+#else
+  fprintf(stderr,"No PNG library support.\n");
+#endif /* HAVE_LIBPNG */
   return 0;
 }
 #ifndef MSWIN32
 #include <unistd.h>
 #else
-#define R_OK 2
+#include <io.h>
 #endif
 
 /* number of antialised colors for indexed bitmaps */
   int n;
   int font_found = 0;
   unsigned short platform, encoding;
-  char *fontsearchpath, *fontpath, *fontlist;
+  char *fontsearchpath, *fontlist;
   char *fullname = NULL;
   char *name, *path, *dir;
   char *strtok_ptr;
   fontsearchpath = getenv ("GDFONTPATH");
   if (!fontsearchpath)
     fontsearchpath = DEFAULT_FONTPATH;
-  path = strdup (fontsearchpath);
   fontlist = strdup (a->fontlist);
 
   /*
        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.
       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)
 	      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)
     {
   /* 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 - (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;
 }
 
 
 /* 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;
-  int *tpixel;
+  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;
 	      level = (bitmap.buffer[pc] * gdAlphaMax /
                 (bitmap.num_grays - 1)); 
             }
-          else if (bitmap.pixel_mode = ft_pixel_mode_mono)
+          else if (bitmap.pixel_mode == ft_pixel_mode_mono)
             {
               level = ((bitmap.buffer[pc / 8]
 			       << (pc % 8)) & 128) ? gdAlphaOpaque :
   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 */
   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 *tmpstr = 0;
   int render = (im && (im->trueColor || (fg <= 255 && fg >= -255)));
   FT_BitmapGlyph bm;
+  int render_mode = FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT;
+
+  /*
+   *   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 <krisku@arrak.fi>
+   */
+  gdCache_head_t  *tc_cache;
+
+  tc_cache = gdCacheCreate( TWEENCOLORCACHESIZE,
+               tweenColorTest, tweenColorFetch, tweenColorRelease );
 
 /***** 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,
   font = (font_t *) gdCacheGet (fontCache, &fontkey);
   if (!font)
     {
+      gdCacheDelete( tc_cache );
       return fontCache->error;
     }
   face = font->face;		/* shortcut */
   if (FT_Set_Char_Size (face, 0, (FT_F26Dot6) (ptsize * 64),
 			GD_RESOLUTION, GD_RESOLUTION))
     {
+      gdCacheDelete( tc_cache );
       return "Could not set character size";
     }
 
 
   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))
+      if ((tmpstr = (char *) gdMalloc (BUFSIZ)))
 	{
 	  any2eucjp (tmpstr, string, BUFSIZ);
 	  next = tmpstr;
 	    }
 	}
 
+      /* set rotation transform */
+      FT_Set_Transform(face, &matrix, NULL);
+
       /* Convert character code to glyph index */
       glyph_index = FT_Get_Char_Index (face, ch);
 
 	}
 
       /* 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)
 	    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);
 	}
 
   if (tmpstr)
     gdFree (tmpstr);
+  gdCacheDelete( tc_cache );
   return (char *) NULL;
 }
 
-int
-gdroundupdown (FT_F26Dot6 v1, int updown)
-{
-  return (!updown)
-    ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6)
-    : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6);
-}
-
 #endif /* HAVE_LIBFREETYPE */
 #include "gd.h"
 #include "gdhelpers.h"
 #include <stdlib.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+#include <string.h>
 
 /* TBB: gd_strtok_r is not portable; provide an implementation */
 
 #ifndef GDHELPERS_H 
 #define GDHELPERS_H 1
 
+/* sys/types.h is needed for size_t on Sparc-SunOS-4.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);
   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

src/gdparttopng.c

       gdImageDestroy (im);
       exit (1);
     }
+#ifdef HAVE_LIBPNG
   gdImagePng (im, out);
+#else
+  fprintf(stderr, "No PNG library support.\n");
+#endif
   fclose (out);
   gdImageDestroy (im);
 
 int
 main (int argc, char **argv)
 {
+#ifdef HAVE_LIBPNG
   gdImagePtr im, ref, im2, im3;
   FILE *in, *out;
   void *iptr;
   CompareImages ("GD->PNG ptr->GD", ref, im2);
 
   gdImageDestroy (im2);
-  ctx->free (ctx);
+  ctx->gd_free (ctx);
 
 
   /* */
   CompareImages ("GD->GD2 ptr->GD", ref, im2);
 
   gdImageDestroy (im2);
-  ctx->free (ctx);
+  ctx->gd_free (ctx);
 
 
   /* */
   CompareImages ("GD->GD ptr->GD", ref, im2);
 
   gdImageDestroy (im2);
-  ctx->free (ctx);
+  ctx->gd_free (ctx);
 
   /*
      ** Test gdImageCreateFromPngSource'
   gdImageDestroy (im2);
   gdImageDestroy (im3);
 
-#ifdef HAVE_JPEG
+#ifdef HAVE_LIBJPEG
   out = fopen ("test/gdtest.jpg", "wb");
   if (!out)
     {
   printf ("Created test/gdtest.jpg successfully. Compare this image\n"
 	  "to the input image manually. Some difference must be\n"
 	  "expected as JPEG is a lossy file format.\n");
-#endif /* HAVE_JPEG */
+#endif /* HAVE_LIBJPEG */
   /* Assume the color closest to black is the foreground
      color for the B&W wbmp image. */
   fprintf (stderr, "NOTE: the WBMP output image will NOT match the original unless the original\n"
     }
   gdImageDestroy (im);
   gdImageDestroy (ref);
+#else
+  fprintf(stderr, "No PNG library support.\n");
+#endif /* HAVE_LIBPNG */
 
   return 0;
 }
-
 #include "gd.h"
 #include <string.h>
 
   out = fopen ("test/fttest.jpg", "wb");
   if (!out)
     {
-      fprintf (stderr, "Can't create test/fttest.png\n");
+      fprintf (stderr, "Can't create test/fttest.jpg\n");
       exit (1);
     }
   /* Fairly high JPEG quality setting */
   gdImageDestroy (im);
 
   return 0;
-#endif /* HAVE_FREETYPE */
+#endif /* HAVE_LIBFREETYPE */
 }
       gdImageDestroy (im);
       exit (1);
     }
+#ifdef HAVE_LIBPNG
   gdImagePng (im, out);
+#else
+  fprintf(stderr, "No PNG library support.\n");
+#endif
   fclose (out);
   gdImageDestroy (im);
 
 #include "gd.h"
 #include "gdhelpers.h"
 
-#ifndef HAVE_XPM
+#ifndef HAVE_LIBXPM
 gdImagePtr
 gdImageCreateFromXpm (char *filename)
 {
   gdFree (colors);
   return (im);
 }
-#endif
+#endif /* HAVE_LIBXPM */
 <HTML>
 <HEAD>
-<TITLE>gd 2.0.3</TITLE>
+<TITLE>gd 2.0.4</TITLE>
 </HEAD>
 <BODY>
 <!-- BANNER HERE -->
-<h1>This is gd 2.0.3.</h1>
+<h1>This is gd 2.0.4.</h1>
 <p>
-<H2>gd 2.0.3</H2>
+<H2>gd 2.0.4</H2>
 <H3>A graphics library for fast image creation</H3>
 <H3>Follow this link to the
 <A HREF="http://www.boutell.com/gd/">latest version
 of this document</A>.</H3>
 <blockquote>
 <strong>HEY! READ THIS!</strong>
-gd 2.0.3 creates PNG, JPEG and WBMP images, not GIF images. This is a 
+gd 2.0.4 creates PNG, JPEG and WBMP images, not GIF images. This is a 
 good thing.  PNG is a more compact format, and full compression is
 available.  JPEG works best with photographic images, and is still
 more compatible with the major Web browsers than even PNG is. WBMP is
 modern image formats such as PNG and JPEG as soon as possible.
 
 <p>
-gd 2.0.3 <strong>requires</strong> that the following libraries 
+gd 2.0.4 <strong>requires</strong> that the following libraries 
 also be installed, in order to produce the related image formats:
 <p>
 libpng (see the <a href="http://www.libpng.org/pub/png/">libpng home page</a>), if you want PNG
 <H3>Table of Contents</H3>
 <UL>
 <LI><A HREF="#notice">Credits and license terms</A>
-<LI><A HREF="#whatsnew2.0.3">What's new in version "XYZ" of GD?</A>
+<LI><A HREF="#whatsnew2.0.4">What's new in version "XYZ" of GD?</A>
 <LI><A HREF="#whatis">What is gd?</A>
 <LI><A HREF="#gdother">What if I want to use another programming language?</A>
 <LI><A HREF="#required">What else do I need to use gd?</A>
 <p>
 Portions relating to PNG copyright 1999, 2000, 2001, 2002 Greg Roelofs.
 <p>
-Portions relating to libttf copyright 1999, 2000, 2001, 2002 John Ellson (ellson@lucent.com).
+Portions relating to gdttf.c copyright 1999, 2000, 2001, 2002 John Ellson (ellson@lucent.com).
+<p>
+Portions relating to gdft.c copyright 2001, 2002 John Ellson (ellson@lucent.com).
 <p>
 Portions relating to JPEG and to color quantization copyright 2000, 2001, 2002, Doug Becker and copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, Thomas G. Lane.  This software is based 
 in part on the work of the Independent JPEG Group. See the file
 fitness for a particular purpose, with respect to this code and accompanying
 documentation.
 <p>
-Although their code does not appear in gd 2.0.3, the authors wish to 
+Although their code does not appear in gd 2.0.4, the authors wish to 
 thank David Koblas, David Rowley, and Hutchison Avenue Software 
 Corporation for their prior contributions.
 </blockquote>
 <A NAME="gdother"><H3>What if I want to use another programming
 language?</h3></A>
 Not all of these tools are necessarily up to date and fully compatible
-with 2.0.3.
+with 2.0.4.
 <h4>Perl</h4>
 gd can also be used from Perl, courtesy of
 Lincoln Stein's
 <a href="http://stein.cshl.org/WWW/software/GD/">
 GD.pm</a> library, which uses gd as the basis for a set of
 Perl 5.x classes. Highly recommended.
+<h4>Tcl</h4>
+gd can be used from Tcl with John Ellson's
+<a href=http://www.graphviz.org/pub/>Gdtclft</a>
+dynamically loaded extension package.
 <h4>Pascal</h4>
 Pascal enthusiasts should look into Michael Bradbury's
 <a href="http://www.elj.com/dev/free-pascal/gdfp/">gdfp</a> package.
 <li><a href="http://martin.gleeson.com/fly/">fly</a>, by Martin Gleeson
 </ul>
 <P>
+<A NAME="whatsnew2.0.4"><H3>What's new in version 2.0.4?</H3></A>
+The following contributions from John Ellson:
+<ul>
+<li>Various test programs now compile in the absence
+of PNG support
+<li>gdIOCtx correctly calls gdFree rather than free
+<li>Various cleanups to pass -Wall without warnings
+<li>Support for Adobe-style Type 1 fonts (.pfa and .pfb files)
+via freetype
+<li>gdImageColorResolve and gdImageColorResolveAlpha will not
+attempt to resolve a color request to the transparent color index
+(for palette-based images)
+<li>Improved font search path support
+<li>Antialiased freetype text on palette images works properly
+when more than one image is created in a single program lifetime
+with different color indexes
+<li>Better threshold for two-color "mono" images 
+<li>Memory leak fixes
+<li>Text rotation fix
+<li>More extensive default font path
+<li>fontwheeltest and fontsizetest test programs for freetype
+</ul>
+And the following additional fixes:
+<ul>
+<li><code>configure</code> now correctly detects and provides
+support for the Xpm library and its dependencies (Len Makin)
+</ul>
 <A NAME="whatsnew2.0.3"><H3>What's new in version 2.0.3?</H3></A>
 <ul>
 <li>The <code>configure</code> script has been extensively modified
 saving of alpha channel information to the file instead.
 <P>
 <A NAME="getgd"><H3>How do I get gd?</H3></A>
-<h4>By HTTP</h4>
-<ul>
-<li><a href="http://www.boutell.com/gd/http/gd-2.0.3.tar.gz">Gzipped Tar File (Unix)</a>
-<li><a href="http://www.boutell.com/gd/http/gd-2.0.3.zip">.ZIP File (Windows)</a>
-</ul>
-<h4>By FTP</h4>
 <ul>
-<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd-2.0.3.tar.gz">Gzipped Tar File (Unix)</a>
-<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd-2.0.3.zip">.ZIP File (Windows)</a>
+<li><a href="http://www.boutell.com/gd/http/gd-2.0.4.tar.gz">Gzipped Tar File (Unix)</a>
+<li><a href="http://www.boutell.com/gd/http/gd-2.0.4.zip">.ZIP File (Windows)</a>
 </ul>
 <P>
 <A NAME="buildgd"><H3>How do I build gd?</H3></A>
 consult with an experienced user of your system. Sorry, we cannot
 answer questions about basic Internet skills.
 <p>
-Unpacking the archive will produce a directory called "gd-2.0.3".
+Unpacking the archive will produce a directory called "gd-2.0.4".
 <p>
 <h4>For Unix</h4>
-<code>cd</code> to the 2.0.3 directory and type:
+<code>cd</code> to the 2.0.4 directory and type:
 <p>
 <code>./configure</code>
 <p>

src/makefile.sample

 #for your system. 
 AR=ar
 
-CFLAGS=-g  -DHAVE_LIBPNG -DHAVE_LIBZ -DHAVE_LIBJPEG -DHAVE_LIBFREETYPE
+CFLAGS=-g -DHAVE_LIBPNG -DHAVE_LIBZ -DHAVE_LIBJPEG -DHAVE_MALLOC_H -DHAVE_LIBFREETYPE -DHAVE_LIBXPM
 
 LIBS=-lgd  -lpng -lz -ljpeg -lfreetype -lm
 
 # Update these with each release!
 
 MAJOR_VERSION=2
-VERSION=2.0.2
+VERSION=2.0.3
 
 COMPILER=gcc -fPIC
 
 PROGRAMS=$(BIN_PROGRAMS) $(TEST_PROGRAMS)
 
 BIN_PROGRAMS=pngtogd pngtogd2 gdtopng gd2topng gd2copypal gdparttopng webpng
-TEST_PROGRAMS=gdtest gddemo gd2time gdtestft testac
+TEST_PROGRAMS=gdtest gddemo gd2time gdtestft testac fontsizetest fontwheeltest
 
 default: instructions
 
 gdtestft: gdtestft.o
 	$(CC) --verbose gdtestft.o -o gdtestft $(LIBDIRS) $(LIBS)
 
+fontwheeltest: fontwheeltest.o
+	$(CC) --verbose fontwheeltest.o -o fontwheeltest $(LIBDIRS) $(LIBS)
+
+fontsizetest: fontsizetest.o
+	$(CC) --verbose fontsizetest.o -o fontsizetest $(LIBDIRS) $(LIBS)
+
 LIBOBJS=gd.o gd_gd.o gd_gd2.o gd_io.o gd_io_dp.o \
 		gd_io_file.o gd_ss.o gd_io_ss.o gd_png.o gd_jpeg.o gdxpm.o \
 		gdfontt.o gdfonts.o gdfontmb.o gdfontl.o gdfontg.o \
 	-ranlib libgd.a
 
 clean:
-	rm -f *.o *.a *.so ${PROGRAMS} test/gdtest.jpg test/gdtest.wbmp test/fttest.png test/fttest.jpg
+	rm -f *.o *.a *.so ${PROGRAMS} test/gdtest.jpg test/gdtest.wbmp test/fttest.png test/fttest.jpg font*test*.png
 int
 main (int argc, char *argv[])
 {
+#ifdef HAVE_LIBPNG
   /* Input and output files */
   FILE *in;
   FILE *out;
   testDrawing (im_in, 2.0, 0, 1, "noblending-doublesize-palette.png");
   testDrawing (im_in, 2.0, 1, 1, "blending-doublesize-palette.png");
   gdImageDestroy (im_in);
+#else
+  fprintf(stderr, "No PNG library support.\n");
+#endif
+
   return 0;
 }
 
       gdImageTrueColorToPalette (im_out, 1, 256);
     }
 
+#ifdef HAVE_LIBPNG
   gdImagePng (im_out, out);
+#else
+  fprintf(stderr, "No PNG library support.\n");
+#endif
   fclose (out);
 
   gdImageDestroy (im_out);
       i = getin (in);
       if (i < 0)
 	return (-1);
-      mbi = mbi << 7 | i & 0x7f;
+      mbi = (mbi << 7) | (i & 0x7f);
     }
   while (i & 0x80);
 
       exit (1);
     }
   /* Now load the image. */
+#ifdef HAVE_LIBPNG
   im = gdImageCreateFromPng (in);
+#else
+  fprintf(stderr, "No PNG library support.\n");
+#endif
   fclose (in);
   /* If the load failed, it must not be a PNG file. */
   if (!im)
 	}
 
       /* Write the new PNG. */
+#ifdef HAVE_LIBPNG
       gdImagePng (im, out);
-
+#else
+      fprintf(stderr, "No PNG library support.\n");
+#endif
       if (!useStdinStdout)
 	{
 	  fclose (out);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.