diff -Nur gd-2.0.1.orig/gd.c gd-2.0.1/gd.c --- gd-2.0.1.orig/gd.c Sat Aug 10 23:19:14 2002 +++ gd-2.0.1/gd.c Sat Aug 10 23:39:35 2002 @@ -473,6 +473,12 @@ op = c; /* Save open slot */ continue; /* Color not in use */ } + if (c == im->transparent) + { + /* don't ever resolve to the color that has + * been designated as the transparent color */ + continue; + } rd = (long) (im->red[c] - r); gd = (long) (im->green[c] - g); bd = (long) (im->blue[c] - b); @@ -1928,7 +1934,7 @@ else { /* Find or create the best match */ - mapTo = gdImageColorResolveAlpha (dst, + nc = gdImageColorResolveAlpha (dst, gdTrueColorGetRed (c), gdTrueColorGetGreen (c), gdTrueColorGetBlue (c), @@ -1978,7 +1984,7 @@ { for (x = dstX; (x < dstX + dstW); x++) { - int pd = gdImageGetPixel (dst, x, y); + /* int pd = gdImageGetPixel (dst, x, y); -- not used */ float sy1, sy2, sx1, sx2; float sx, sy; float spixels = 0; diff -Nur gd-2.0.1.orig/gd_gd2.c gd-2.0.1/gd_gd2.c --- gd-2.0.1.orig/gd_gd2.c Tue Apr 3 22:44:41 2001 +++ gd-2.0.1/gd_gd2.c Sat Aug 10 23:48:23 2002 @@ -635,10 +635,10 @@ { if (im->trueColor) { - ch = chunkBuf[chunkPos++] << 24 + - chunkBuf[chunkPos++] << 16 + - chunkBuf[chunkPos++] << 8 + - chunkBuf[chunkPos++]; + ch = chunkBuf[chunkPos++] << 24; + ch += chunkBuf[chunkPos++] << 16; + ch += chunkBuf[chunkPos++] << 8; + ch += chunkBuf[chunkPos++]; } else { diff -Nur gd-2.0.1.orig/gd_topal.c gd-2.0.1/gd_topal.c --- gd-2.0.1.orig/gd_topal.c Tue Apr 3 22:44:42 2001 +++ gd-2.0.1/gd_topal.c Sat Aug 10 23:55:17 2002 @@ -1035,6 +1035,8 @@ xx2 = inc2; for (ic2 = BOX_C2_ELEMS - 1; ic2 >= 0; ic2--) { + dist3 = dist2; + xx3 = inc3; for (ic3 = BOX_C3_ELEMS - 1; ic3 >= 0; ic3--) { if (dist3 < *bptr) diff -Nur gd-2.0.1.orig/gdft.c gd-2.0.1/gdft.c --- gd-2.0.1.orig/gdft.c Tue Apr 3 22:44:42 2001 +++ gd-2.0.1/gdft.c Sun Aug 11 00:19:56 2002 @@ -349,7 +349,6 @@ fontsearchpath = getenv ("GDFONTPATH"); if (!fontsearchpath) fontsearchpath = DEFAULT_FONTPATH; - path = strdup (fontsearchpath); fontlist = strdup (a->fontlist); /* @@ -358,7 +357,8 @@ for (name = gd_strtok_r (fontlist, LISTSEPARATOR, &strtok_ptr); name; 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. @@ -384,11 +384,23 @@ font_found++; break; } + sprintf (fullname, "%s/%s.pfa", dir, name); + if (access (fullname, R_OK) == 0) + { + font_found++; + break; + } + sprintf (fullname, "%s/%s.pfb", dir, name); + if (access (fullname, R_OK) == 0) + { + font_found++; + break; + } } if (font_found) break; + gdFree (path); } - gdFree (path); gdFree (fontlist); if (!font_found) { @@ -497,7 +509,10 @@ /* if fg is specified by a negative color idx, then don't antialias */ if (fg < 0) { - a->tweencolor = -fg; + if ((pixel + pixel) >= NUMCOLORS) + a->tweencolor = -fg; + else + a->tweencolor = bg; } else { @@ -534,7 +549,7 @@ /* 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; @@ -543,21 +558,15 @@ 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; 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 */ @@ -608,11 +617,11 @@ /* use fg color directly */ if (im->trueColor) { - *tpixel = fg; + *tpixel = abs( fg ); } else { - *pixel = fg; + *pixel = abs( fg ); } } else @@ -643,8 +652,29 @@ 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 */ @@ -671,15 +701,26 @@ 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; -/***** initialize font library and font cache on first call ******/ - static gdCache_head_t *fontCache; - static FT_Library library; + /* + * 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 + */ + gdCache_head_t *tc_cache; + + tc_cache = gdCacheCreate( TWEENCOLORCACHESIZE, + tweenColorTest, tweenColorFetch, tweenColorRelease ); +/***** initialize font library and font cache on first call ******/ if (!fontCache) { if (FT_Init_FreeType (&library)) { + gdCacheDelete( tc_cache ); return "Failure to initialize font library"; } fontCache = gdCacheCreate (FONTCACHESIZE, @@ -693,6 +734,7 @@ font = (font_t *) gdCacheGet (fontCache, &fontkey); if (!font) { + gdCacheDelete( tc_cache ); return fontCache->error; } face = font->face; /* shortcut */ @@ -701,6 +743,7 @@ if (FT_Set_Char_Size (face, 0, (FT_F26Dot6) (ptsize * 64), GD_RESOLUTION, GD_RESOLUTION)) { + gdCacheDelete( tc_cache ); return "Could not set character size"; } @@ -715,6 +758,10 @@ use_kerning = FT_HAS_KERNING (face); previous = 0; + if (fg < 0) + { + render_mode |= FT_LOAD_MONOCHROME; + } #ifndef JISX0208 if (font->have_char_map_sjis) @@ -821,6 +868,9 @@ } } + /* set rotation transform */ + FT_Set_Transform(face, &matrix, NULL); + /* Convert character code to glyph index */ glyph_index = FT_Get_Char_Index (face, ch); @@ -833,50 +883,60 @@ } /* 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) - return "Problem loading glyph"; + { + 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 (bbox.xMin > glyph_bbox.xMin) - bbox.xMin = glyph_bbox.xMin; - if (bbox.yMin > glyph_bbox.yMin) - bbox.yMin = glyph_bbox.yMin; - if (bbox.xMax < glyph_bbox.xMax) - bbox.xMax = glyph_bbox.xMax; - if (bbox.yMax < glyph_bbox.yMax) - bbox.yMax = glyph_bbox.yMax; + 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.yMin = glyph_bbox.yMin; + if (bbox.xMax < glyph_bbox.xMax) + 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) - return "Problem rendering glyph"; + { + 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); } @@ -922,15 +982,8 @@ 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 */