Synchronized bundled gd library with the latest stable GD, 2.0.6

Fixed a configuration problem with xpm.
Fixed 2 possible memory leaks in fontFetch().
This commit is contained in:
Ilia Alshanetsky 2002-11-25 01:51:53 +00:00
parent 5c851cba19
commit 9251486567
9 changed files with 212 additions and 154 deletions

View File

@ -112,7 +112,7 @@ AC_DEFUN(PHP_GD_XPM,[
fi
for i in include include/X11; do
test -f $GD_XPM_DIR/$i/xpm.h && GD_XPM_INC=$GD_XPM_DIR/$i
test -f $GD_XPM_DIR/$i/xpm.h && GD_XPM_INC=$GD_XPM_DIR/include
done
if test -z "$GD_XPM_INC"; then

View File

@ -244,7 +244,7 @@ gdImageColorClosestAlpha (gdImagePtr im, int r, int g, int b, int a)
#define RETURN_HWB(h, w, b) {HWB->H = h; HWB->W = w; HWB->B = b; return HWB;}
#define RETURN_RGB(r, g, b) {RGB->R = r; RGB->G = g; RGB->B = b; return RGB;}
#define HWB_UNDEFINED -1
#define SETUP_RGB(s, r, g, b) {s.R = r/255.0f; s.G = g/255.0f; s.B = b/255.0f;}
#define SETUP_RGB(s, r, g, b) {s.R = r/255.0; s.G = g/255.0; s.B = b/255.0;}
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@ -315,14 +315,14 @@ HWB_Diff (int r1, int g1, int b1, int r2, int g2, int b2)
if ((HWB1.H == HWB_UNDEFINED) || (HWB2.H == HWB_UNDEFINED))
{
diff = 0.0f; /* Undefined hues always match... */
diff = 0; /* Undefined hues always match... */
}
else
{
diff = fabsf (HWB1.H - HWB2.H);
if (diff > 3.0f)
diff = abs (HWB1.H - HWB2.H);
if (diff > 3)
{
diff = 6.0f - diff; /* Remember, it's a colour circle */
diff = 6 - diff; /* Remember, it's a colour circle */
}
}
@ -375,8 +375,9 @@ HWB_to_RGB (HWBType HWB, RGBType * RGB)
}
return RGB;
}
#endif /* 0 */
#endif
int
gdImageColorClosestHWB (gdImagePtr im, int r, int g, int b)
@ -516,12 +517,12 @@ gdImageColorResolveAlpha (gdImagePtr im, int r, int g, int b, int a)
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;
}
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);
@ -873,10 +874,15 @@ gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
if (dy <= dx)
{
/* More-or-less horizontal. use wid for vertical stroke */
wid = (int)(thick * cos (atan2 (dy, dx)));
if (wid == 0)
wid = 1;
/* Doug Claar: watch out for NaN in atan2 (2.0.5) */
if ((dx == 0) && (dy == 0)) {
wid = 1;
} else {
wid = thick * cos (atan2 (dy, dx));
if (wid == 0) {
wid = 1;
}
}
d = 2 * dy - dx;
incr1 = 2 * dy;
incr2 = 2 * (dy - dx);
@ -942,7 +948,7 @@ gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
else
{
/* More-or-less vertical. use wid for horizontal stroke */
wid = (int)(thick * sin (atan2 (dy, dx)));
wid = thick * sin (atan2 (dy, dx));
if (wid == 0)
wid = 1;
@ -1027,7 +1033,7 @@ gdImageDashedLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
if (dy <= dx)
{
/* More-or-less horizontal. use wid for vertical stroke */
wid = (int)(thick * sin (atan2 (dy, dx)));
wid = thick * sin (atan2 (dy, dx));
vert = 1;
d = 2 * dy - dx;
@ -1086,7 +1092,7 @@ gdImageDashedLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
else
{
/* More-or-less vertical. use wid for horizontal stroke */
wid = (int)(thick * sin (atan2 (dy, dx)));
wid = thick * sin (atan2 (dy, dx));
vert = 0;
d = 2 * dx - dy;
@ -1790,6 +1796,7 @@ gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int s
for (x = srcX; (x < (srcX + w)); x++)
{
int nc;
int mapTo;
c = gdImageGetPixel (src, x, y);
/* Added 7/24/95: support transparent copies */
if (gdImageGetTransparent (src) == c)
@ -1798,7 +1805,19 @@ gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int s
continue;
}
/* Have we established a mapping for this color? */
if (colorMap[c] == (-1))
if (src->trueColor)
{
/* 2.05: remap to the palette available in the
destination image. This is slow and
works badly, but it beats crashing! Thanks
to Padhrig McCarthy. */
mapTo = gdImageColorResolveAlpha (dst,
gdTrueColorGetRed (c),
gdTrueColorGetGreen (c),
gdTrueColorGetBlue (c),
gdTrueColorGetAlpha (c));
}
else if (colorMap[c] == (-1))
{
/* If it's the same image, mapping is trivial */
if (dst == src)
@ -1815,8 +1834,13 @@ gdImageCopy (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int s
src->blue[c], src->alpha[c]);
}
colorMap[c] = nc;
mapTo = colorMap[c];
}
gdImageSetPixel (dst, tox, toy, colorMap[c]);
else
{
mapTo = colorMap[c];
}
gdImageSetPixel (dst, tox, toy, mapTo);
tox++;
}
toy++;
@ -1856,12 +1880,12 @@ gdImageCopyMerge (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX,
{
dc = gdImageGetPixel (dst, tox, toy);
ncR = (int)( gdImageRed (src, c) * (pct / 100.0f)
+ gdImageRed (dst, dc) * ((100 - pct) / 100.0f));
ncG = (int)( gdImageGreen (src, c) * (pct / 100.0f)
+ gdImageGreen (dst, dc) * ((100 - pct) / 100.0f));
ncB = (int)( gdImageBlue (src, c) * (pct / 100.0f)
+ gdImageBlue (dst, dc) * ((100 - pct) / 100.0f));
ncR = gdImageRed (src, c) * (pct / 100.0)
+ gdImageRed (dst, dc) * ((100 - pct) / 100.0);
ncG = gdImageGreen (src, c) * (pct / 100.0)
+ gdImageGreen (dst, dc) * ((100 - pct) / 100.0);
ncB = gdImageBlue (src, c) * (pct / 100.0)
+ gdImageBlue (dst, dc) * ((100 - pct) / 100.0);
/* Find a reasonable color */
nc = gdImageColorResolve (dst, ncR, ncG, ncB);
@ -1906,19 +1930,19 @@ gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int sr
else
{
dc = gdImageGetPixel (dst, tox, toy);
g = 0.29900f * dst->red[dc]
+ 0.58700f * dst->green[dc]
+ 0.11400f * dst->blue[dc];
ncR = (int)( gdImageRed (src, c) * (pct / 100.0f)
+ gdImageRed (dst, dc) * g * ((100 - pct) / 100.0f));
ncG = (int)( gdImageGreen (src, c) * (pct / 100.0f)
+ gdImageGreen (dst, dc) * g * ((100 - pct) / 100.0f));
ncB = (int)( gdImageBlue (src, c) * (pct / 100.0f)
+ gdImageBlue (dst, dc) * g * ((100 - pct) / 100.0f));
g = 0.29900 * dst->red[dc]
+ 0.58700 * dst->green[dc]
+ 0.11400 * dst->blue[dc];
ncR = gdImageRed (src, c) * (pct / 100.0)
+ gdImageRed (dst, dc) * g *
((100 - pct) / 100.0);
ncG = gdImageGreen (src, c) * (pct / 100.0)
+ gdImageGreen (dst, dc) * g *
((100 - pct) / 100.0);
ncB = gdImageBlue (src, c) * (pct / 100.0)
+ gdImageBlue (dst, dc) * g *
((100 - pct) / 100.0);
/* First look for an exact match */
nc = gdImageColorExact (dst, ncR, ncG, ncB);
@ -2037,11 +2061,12 @@ gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX
else
{
/* Find or create the best match */
mapTo = gdImageColorResolveAlpha (dst,
gdTrueColorGetRed (c),
gdTrueColorGetGreen (c),
gdTrueColorGetBlue (c),
gdTrueColorGetAlpha (c));
/* 2.0.5: can't use gdTrueColorGetRed, etc with palette */
nc = gdImageColorResolveAlpha (dst,
gdImageRed (src, c),
gdImageGreen (src, c),
gdImageBlue (src, c),
gdImageAlpha (src, c));
}
colorMap[c] = nc;
}
@ -2088,37 +2113,36 @@ gdImageCopyResampled (gdImagePtr dst,
{
float sy1, sy2, sx1, sx2;
float sx, sy;
float spixels = 0.0f;
float red = 0.0f, green = 0.0f, blue = 0.0f, alpha = 0.0f;
float alpha_factor, alpha_sum = 0.0f, contrib_sum = 0.0f;
sy1 = ((float)(y - dstY)) * (float)srcH /
(float)dstH;
sy2 = ((float)(y + 1 - dstY)) * (float) srcH /
float spixels = 0;
float red = 0.0, green = 0.0, blue = 0.0, alpha = 0.0, alpha_sum = 0.0, contrib_sum = 0.0, alpha_factor;
sy1 = ((float) y - (float) dstY) * (float) srcH /
(float) dstH;
sy2 = ((float) (y + 1) - (float) dstY) * (float) srcH /
(float) dstH;
sy = sy1;
do
{
float yportion;
if (floorf(sy) == floorf(sy1))
if (floor (sy) == floor (sy1))
{
yportion = 1.0f - (sy - floorf(sy));
yportion = 1.0 - (sy - floor (sy));
if (yportion > sy2 - sy1)
{
yportion = sy2 - sy1;
}
sy = floorf(sy);
sy = floor (sy);
}
else if (sy == floorf(sy2))
else if (sy == floor (sy2))
{
yportion = sy2 - floorf(sy2);
yportion = sy2 - floor (sy2);
}
else
{
yportion = 1.0f;
yportion = 1.0;
}
sx1 = ((float)(x - dstX)) * (float) srcW /
sx1 = ((float) x - (float) dstX) * (float) srcW /
dstW;
sx2 = ((float)(x + 1 - dstX)) * (float) srcW /
sx2 = ((float) (x + 1) - (float) dstX) * (float) srcW /
dstW;
sx = sx1;
do
@ -2126,68 +2150,69 @@ gdImageCopyResampled (gdImagePtr dst,
float xportion;
float pcontribution;
int p;
if (floorf(sx) == floorf(sx1))
if (floor (sx) == floor (sx1))
{
xportion = 1.0f - (sx - floorf(sx));
xportion = 1.0 - (sx - floor (sx));
if (xportion > sx2 - sx1)
{
xportion = sx2 - sx1;
}
sx = floorf(sx);
sx = floor (sx);
}
else if (sx == floorf(sx2))
else if (sx == floor (sx2))
{
xportion = sx2 - floorf(sx2);
xportion = sx2 - floor (sx2);
}
else
{
xportion = 1.0f;
xportion = 1.0;
}
pcontribution = xportion * yportion;
p = gdImageGetTrueColorPixel (
src,
(int) sx + srcX,
(int) sy + srcY);
(int) sx,
(int) sy);
alpha_factor = ((gdAlphaMax - gdTrueColorGetAlpha(p))) * pcontribution;
red += gdTrueColorGetRed (p) * alpha_factor;
green += gdTrueColorGetGreen (p) * alpha_factor;
blue += gdTrueColorGetBlue (p) * alpha_factor;
green += gdTrueColorGetGreen (p) * pcontribution;
red += gdTrueColorGetRed (p) * alpha_factor;
blue += gdTrueColorGetBlue (p) * pcontribution;
green += gdTrueColorGetGreen (p) * alpha_factor;
alpha += gdTrueColorGetAlpha (p) * pcontribution;
alpha_sum += alpha_factor;
contrib_sum += pcontribution;
contrib_sum += pcontribution;
spixels += xportion * yportion;
sx += 1.0f;
sx += 1.0;
}
while (sx < sx2);
sy += 1.0f;
sy += 1.0;
}
while (sy < sy2);
if (spixels != 0.0f)
if (spixels != 0.0)
{
red /= spixels;
green /= spixels;
blue /= spixels;
alpha /= spixels;
}
if ( alpha_sum != 0.0f)
if ( alpha_sum != 0.0)
{
if( contrib_sum != 0.0f ) alpha_sum /= contrib_sum;
if( contrib_sum != 0.0 ) alpha_sum /= contrib_sum;
red /= alpha_sum;
green /= alpha_sum;
blue /= alpha_sum;
}
/* Clamping to allow for rounding errors above */
if (red > 255.0f)
if (red > 255.0)
{
red = 255.0f;
red = 255.0;
}
if (green > 255.0f)
if (green > 255.0)
{
green = 255.0f;
green = 255.0;
}
if (blue > 255.0f)
if (blue > 255.0)
{
blue = 255.0f;
blue = 255.0;
}
if (alpha > gdAlphaMax)
{
@ -2709,7 +2734,7 @@ gdImageCreateFromXbm (FILE * fd)
for (i = 0; (i < bytes); i++)
{
char h[3];
int b;
unsigned int b;
/* Skip spaces, commas, CRs, 0x */
while (1)
{

View File

@ -298,6 +298,8 @@ int gdImageColorClosest(gdImagePtr im, int r, int g, int b);
beats the exact same color with radically different
transparency */
int gdImageColorClosestAlpha(gdImagePtr im, int r, int g, int b, int a);
/* An alternate method */
int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b);
/* Returns exact, 100% opaque matches only */
int gdImageColorExact(gdImagePtr im, int r, int g, int b);
/* Returns an exact match only, including alpha */

View File

@ -18,6 +18,10 @@
#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_ZLIB
#include <zlib.h>
#define TRUE 1
@ -763,7 +767,7 @@ _gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt)
/* 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.02 + 12);
compMax = cs * bytesPerPixel * cs * 1.02 + 12;
/* */
/* Allocate the buffers. */
@ -922,3 +926,18 @@ gdImageGd2Ptr (gdImagePtr im, int cs, int fmt, int *size)
out->gd_free (out);
return rv;
}
#else /* no HAVE_ZLIB */
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_ZLIB */

View File

@ -281,9 +281,8 @@ gdImageCreateFromJpegCtx (gdIOCtx * infile)
volatile JSAMPROW row = 0;
volatile gdImagePtr im = 0;
JSAMPROW rowptr[1];
JDIMENSION i, j;
int i, j, retval;
JDIMENSION nrows;
int retval;
#ifdef JPEG_DEBUG
printf ("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
@ -812,7 +811,7 @@ term_destination (j_compress_ptr cinfo)
/* Write any data remaining in the buffer */
if (datacount > 0)
{
if ((size_t)gdPutBuf (dest->buffer, datacount, dest->outfile) != datacount)
if (gdPutBuf (dest->buffer, datacount, dest->outfile) != datacount)
ERREXIT (cinfo, JERR_FILE_WRITE);
}
}

View File

@ -7,7 +7,6 @@
/* JCE: Arrange HAVE_LIBPNG so that it can be set in gd.h */
#ifdef HAVE_LIBPNG
#include "png.h" /* includes zlib.h and setjmp.h */
#include "gdhelpers.h"
@ -128,7 +127,6 @@ gdImageCreateFromPngCtx (gdIOCtx * infile)
png_bytepp row_pointers = NULL;
gdImagePtr im = NULL;
int i, j, *open = NULL;
png_uint_32 ui, uj;
volatile int transparent = -1;
volatile int palette_allocated = FALSE;
@ -228,7 +226,7 @@ gdImageCreateFromPngCtx (gdIOCtx * infile)
im->alpha[i] = gdAlphaMax - (trans[i] >> 1);
if ((trans[i] == 0) && (firstZero))
{
transparent = i;
transparent = i;
firstZero = 0;
}
}
@ -321,9 +319,9 @@ gdImageCreateFromPngCtx (gdIOCtx * infile)
}
/* set the individual row_pointers to point at the correct offsets */
for (uj = 0; uj < height; ++uj)
for (j = 0; j < height; ++j)
{
row_pointers[uj] = image_data + uj * rowbytes;
row_pointers[j] = image_data + j * rowbytes;
}
png_read_image (png_ptr, row_pointers); /* read whole image... */
@ -354,44 +352,44 @@ gdImageCreateFromPngCtx (gdIOCtx * infile)
switch (color_type)
{
case PNG_COLOR_TYPE_RGB:
for (uj = 0; uj < height; uj++)
for (j = 0; j < height; j++)
{
int boffset = 0;
for (ui = 0; ui < width; ui++)
for (i = 0; i < width; i++)
{
register png_byte r = row_pointers[uj][boffset++];
register png_byte g = row_pointers[uj][boffset++];
register png_byte b = row_pointers[uj][boffset++];
im->tpixels[uj][ui] = gdTrueColor (r, g, b);
register png_byte r = row_pointers[j][boffset++];
register png_byte g = row_pointers[j][boffset++];
register png_byte b = row_pointers[j][boffset++];
im->tpixels[j][i] = gdTrueColor (r, g, b);
}
}
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
for (uj = 0; uj < height; uj++)
for (j = 0; j < height; j++)
{
int boffset = 0;
for (ui = 0; ui < width; ui++)
for (i = 0; i < width; i++)
{
register png_byte r = row_pointers[uj][boffset++];
register png_byte g = row_pointers[uj][boffset++];
register png_byte b = row_pointers[uj][boffset++];
register png_byte r = row_pointers[j][boffset++];
register png_byte g = row_pointers[j][boffset++];
register png_byte b = row_pointers[j][boffset++];
/* gd has only 7 bits of alpha channel resolution, and
127 is transparent, 0 opaque. A moment of convenience,
a lifetime of compatibility. */
register png_byte a = gdAlphaMax -
(row_pointers[uj][boffset++] >> 1);
im->tpixels[uj][ui] = gdTrueColorAlpha (r, g, b, a);
(row_pointers[j][boffset++] >> 1);
im->tpixels[j][i] = gdTrueColorAlpha (r, g, b, a);
}
}
break;
default:
/* Palette image, or something coerced to be one */
for (uj = 0; uj < height; ++uj)
for (j = 0; j < height; ++j)
{
for (ui = 0; ui < width; ++ui)
for (i = 0; i < width; ++i)
{
register png_byte idx = row_pointers[uj][ui];
im->pixels[uj][ui] = idx;
register png_byte idx = row_pointers[j][i];
im->pixels[j][i] = idx;
open[idx] = 0;
}
}
@ -597,7 +595,7 @@ gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile)
{
trans_values[i] = 255 -
((im->alpha[i] << 1) +
(im->alpha[i] >> 7));
(im->alpha[i] >> 6));
}
png_set_tRNS (png_ptr, info_ptr, trans_values, 256, NULL);
#endif
@ -616,9 +614,10 @@ gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile)
{
if (im->alpha[i] != gdAlphaOpaque)
{
/* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */
trans_values[j] = 255 -
((im->alpha[i] << 1) +
(im->alpha[i] >> 7));
(im->alpha[i] >> 6));
mapping[i] = j++;
}
else
@ -699,7 +698,8 @@ gdImagePngCtx (gdImagePtr im, gdIOCtx * outfile)
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]);
row_pointers[j][bo++] = 255 - ((a << 1) + (a >> 7));
/* Andrew Hull: >> 6, not >> 7! (gd 2.0.5) */
row_pointers[j][bo++] = 255 - ((a << 1) + (a >> 6));
}
}
}

View File

@ -70,7 +70,7 @@
void
gd_putout (int i, void *out)
{
gdPutC ((unsigned char)i, (gdIOCtx *) out);
gdPutC (i, (gdIOCtx *) out);
}

View File

@ -32,11 +32,20 @@ char *
gdImageStringTTF (gdImage * im, int *brect, int fg, char *fontlist,
double ptsize, double angle, int x, int y, char *string)
{
/* 2.0.6: valid return */
return gdImageStringFT (im, brect, fg, fontlist, ptsize,
angle, x, y, string);
}
#ifndef HAVE_LIBFREETYPE
char *
gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
double ptsize, double angle, int x, int y, char *string,
gdFTStringExtraPtr strex)
{
return "libgd was not built with FreeType font support\n";
}
char *
gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,
double ptsize, double angle, int x, int y, char *string)
@ -402,6 +411,7 @@ static void *fontFetch (char **error, void *key)
}
}
gdFree(path);
path = NULL;
if (font_found) {
break;
}
@ -416,6 +426,9 @@ static void *fontFetch (char **error, void *key)
if (!font_found) {
gdPFree(a->fontlist);
gdPFree(a);
if (fullname) {
gdFree(fullname);
}
*error = "Could not find/open font";
return NULL;
}
@ -424,6 +437,9 @@ static void *fontFetch (char **error, void *key)
if (err) {
gdPFree(a->fontlist);
gdPFree(a);
if (fullname) {
gdFree(fullname);
}
*error = "Could not read font";
return NULL;
}
@ -466,6 +482,8 @@ static void *fontFetch (char **error, void *key)
return NULL;
}
/* 2.0.5: we should actually return this */
a->face->charmap = found;
return (void *) a;
}
@ -563,7 +581,7 @@ gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitm
{
unsigned char *pixel = NULL;
int *tpixel = NULL;
int x, y, row, col, pc;
int x, y, row, col, pc, pcr;
tweencolor_t *tc_elem;
tweencolorkey_t tc_key;
@ -577,6 +595,7 @@ gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitm
for (row = 0; row < bitmap.rows; row++)
{
pc = row * bitmap.pitch;
pcr = pc;
y = pen_y + row;
/* clip if out of bounds */
if (y >= im->sy || y < 0)
@ -595,17 +614,20 @@ gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitm
}
else if (bitmap.pixel_mode == ft_pixel_mode_mono)
{
level = ((bitmap.buffer[pc / 8]
<< (pc % 8)) & 128) ? gdAlphaOpaque :
gdAlphaTransparent;
/* 2.0.5: mode_mono fix from Giuliano Pochini */
level = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07)))
? gdAlphaTransparent :
gdAlphaOpaque;
}
else
{
return "Unsupported ft_pixel_mode";
}
if (fg >= 0) {
if ((fg >= 0) && (im->trueColor)) {
/* Consider alpha in the foreground color itself to be an
upper bound on how opaque things get */
upper bound on how opaque things get, when truecolor is
available. Without truecolor this results in far too many
color indexes. */
level = level * (gdAlphaMax - gdTrueColorGetAlpha(fg)) / gdAlphaMax;
}
level = gdAlphaMax - level;
@ -633,7 +655,9 @@ gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitm
/* Non-truecolor case, restored to its more or less original form */
for (row = 0; row < bitmap.rows; row++)
{
int pcr;
pc = row * bitmap.pitch;
pcr = pc;
if(bitmap.pixel_mode==ft_pixel_mode_mono)
pc *= 8; /* pc is measured in bits for monochrome images */
@ -660,6 +684,9 @@ gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg, FT_Bitmap bitm
{
tc_key.pixel = ((bitmap.buffer[pc / 8]
<< (pc % 8)) & 128) ? NUMCOLORS : 0;
/* 2.0.5: mode_mono fix from Giuliano Pochini */
tc_key.pixel = ((bitmap.buffer[(col>>3)+pcr]) & (1<<(~col&0x07)))
? NUMCOLORS : 0;
}
else
{
@ -722,17 +749,19 @@ gdFreeFontCache()
/********************************************************************/
/* 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);
return gdImageStringFTEx(im, brect, fg, fontlist,
ptsize, angle, x, y, string, 0);
}
char *
gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
double ptsize, double angle, int x, int y, char *string,
gdFTStringExtra * strex)
gdFTStringExtraPtr strex)
{
FT_BBox bbox, glyph_bbox;
FT_Matrix matrix;
@ -754,10 +783,9 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
int render = (im && (im->trueColor || (fg <= 255 && fg >= -255)));
FT_BitmapGlyph bm;
int render_mode = FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT;
/* fine tuning */
/* Now tuneable thanks to Wez Furlong */
double linespace = LINESPACE;
/* 2.0.6: put this declaration with the other declarations! */
/*
* make a new tweenColorCache on every call
* because caching colormappings between calls
@ -767,6 +795,11 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
*/
gdCache_head_t *tc_cache;
if (strex) {
if ((strex->flags & gdFTEX_LINESPACE) == gdFTEX_LINESPACE) {
linespace = strex->linespacing;
}
}
tc_cache = gdCacheCreate( TWEENCOLORCACHESIZE,
tweenColorTest, tweenColorFetch, tweenColorRelease );
@ -803,12 +836,6 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
return "Could not set character size";
}
/* 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;
@ -853,8 +880,8 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
if (ch == '\r')
{
penf.x = 0;
x1 = (int)((penf.x * cos_a - penf.y * sin_a + 32.0) / 64.0);
y1 = (int)((penf.x * sin_a + penf.y * cos_a + 32.0) / 64.0);
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++;
@ -863,10 +890,10 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
/* newlines */
if (ch == '\n')
{
penf.y = penf.y - (int)(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.0) / 64.0);
y1 = (int)((penf.x * sin_a + penf.y * cos_a + 32.0) / 64.0);
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++;
@ -929,10 +956,8 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist,
next++;
}
}
/* set rotation transform */
FT_Set_Transform(face, &matrix, NULL);
/* Convert character code to glyph index */
glyph_index = FT_Get_Char_Index (face, ch);

View File

@ -7,21 +7,13 @@
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gd.h"
#include "gdhelpers.h"
#ifndef HAVE_XPM
gdImagePtr
gdImageCreateFromXpm (char *filename)
{
fprintf (stderr, "libgd was not built with xpm support\n");
return (NULL);
}
#ifdef HAVE_XPM
#else
#include "xpm.h"
#include <string.h>
#include <X11/xpm.h>
gdImagePtr
gdImageCreateFromXpm (char *filename)
@ -46,8 +38,6 @@ gdImageCreateFromXpm (char *filename)
number = image.ncolors;
colors = (int *) gdMalloc (sizeof (int) * number);
if (colors == NULL)
return (0);
for (i = 0; i < number; i++)
{
switch (strlen (image.colorTable[i].c_color))
@ -129,11 +119,9 @@ gdImageCreateFromXpm (char *filename)
}
apixel = (char *) gdMalloc (image.cpp + 1);
if (apixel == NULL)
return (0);
apixel[image.cpp] = '\0';
pointer = image.data;
pointer = (int *) image.data;
for (i = 0; i < image.height; i++)
{
for (j = 0; j < image.width; j++)