cvs: php4 /ext/gd/libgd gd.c gd.h gd_png.c gdft.c webpng.c
| From: | Wez Furlong | Date: | Sun, 21 Apr 2002 13:48:22 +0000 |
| Subject: | cvs: php4 /ext/gd/libgd gd.c gd.h gd_png.c gdft.c webpng.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-11294@lists.php.net to get a copy of this message | ||
wez Sun Apr 21 09:48:22 2002 EDT
Modified files:
/php4/ext/gd/libgd gd.c gd.h gd_png.c gdft.c webpng.c
Log:
Apply that patch I wrote ages ago that fixes some problems with true-color
vs palette based handling.
Also implements the gdImageStringFTEx function.
Index: php4/ext/gd/libgd/gd.c diff -u php4/ext/gd/libgd/gd.c:1.1 php4/ext/gd/libgd/gd.c:1.2 --- php4/ext/gd/libgd/gd.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd.c Sun Apr 21 09:48:22 2002 @@ -1651,18 +1651,37 @@ if (dst->trueColor) { /* 2.0: much easier when the destination is truecolor. */ + + if (src->trueColor) { for (y = 0; (y < h); y++) { for (x = 0; (x < w); x++) { int c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y); + gdImageSetPixel (dst, + dstX + x, + dstY + y, + c); + } + } + + } + else { + /* source is palette based */ + for (y = 0; (y < h); y++) + { + for (x = 0; (x < w); x++) + { + int c = gdImageGetPixel (src, srcX + x, + srcY + y); if (c != src->transparent) { gdImageSetPixel (dst, dstX + x, dstY + y, - c); + gdTrueColor(src->red[c], src->green[c], src->blue[c])); + } } } } Index: php4/ext/gd/libgd/gd.h diff -u php4/ext/gd/libgd/gd.h:1.1 php4/ext/gd/libgd/gd.h:1.2 --- php4/ext/gd/libgd/gd.h:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd.h Sun Apr 21 09:48:22 2002 @@ -251,6 +251,19 @@ char *gdImageStringFT(gdImage *im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string); +typedef struct { + int flags; /* for future expansion logical OR of gdFTEX_ values */ + double linespacing; /* fine tune line spacing for '\n' */ +} gdFTStringExtra, *gdFTStringExtraPtr; +#define gdFTEX_LINESPACE 1 + +/* FreeType 2 text output with fine tuning */ +char * +gdImageStringFTEx(gdImage * im, int *brect, int fg, char * fontlist, + double ptsize, double angle, int x, int y, char * string, + gdFTStringExtraPtr strex); + + /* Point type for use in polygon drawing. */ typedef struct { int x, y; Index: php4/ext/gd/libgd/gd_png.c diff -u php4/ext/gd/libgd/gd_png.c:1.1 php4/ext/gd/libgd/gd_png.c:1.2 --- php4/ext/gd/libgd/gd_png.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd_png.c Sun Apr 21 09:48:22 2002 @@ -225,7 +225,7 @@ im->alpha[i] = gdAlphaMax - (trans[i] >> 1); if ((trans[i] == 0) && (firstZero)) { - im->transparent = i; + transparent = i; firstZero = 0; } } Index: php4/ext/gd/libgd/gdft.c diff -u php4/ext/gd/libgd/gdft.c:1.1 php4/ext/gd/libgd/gdft.c:1.2 --- php4/ext/gd/libgd/gdft.c:1.1 Fri Apr 12 22:03:09 2002 +++ php4/ext/gd/libgd/gdft.c Sun Apr 21 09:48:22 2002 @@ -513,7 +513,8 @@ gdTrueColorGetRed (fg), gdTrueColorGetGreen (fg), gdTrueColorGetBlue (fg), - gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS)); + gdAlphaMax - ((gdAlphaMax - gdTrueColorGetAlpha (fg)) * pixel / NUMCOLORS) + ); } else { @@ -566,76 +567,53 @@ for (col = 0; col < bitmap.width; col++, pc++) { - if (bitmap.pixel_mode == ft_pixel_mode_grays) - { + x = pen_x + col; + + /* clip if out of bounds */ + if (x >= im->sx || x < 0) + continue; + + switch(bitmap.pixel_mode) { + case ft_pixel_mode_grays: /* * Round to NUMCOLORS levels of antialiasing for * index color images since only 256 colors are * available. */ + tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS) + bitmap.num_grays / 2) / (bitmap.num_grays - 1); - } - else if (bitmap.pixel_mode == ft_pixel_mode_mono) - { + break; + case ft_pixel_mode_mono: tc_key.pixel = ((bitmap.buffer[pc / 8] << (pc % 8)) & 128) ? NUMCOLORS : 0; - } - else - { + break; + default: return "Unsupported ft_pixel_mode"; } if (tc_key.pixel > 0) - { /* if not background */ - x = pen_x + col; - - /* clip if out of bounds */ - if (x >= im->sx || x < 0) - continue; - /* get pixel location in gd buffer */ - if (im->trueColor) { - tpixel = &im->tpixels[y][x]; + + if (im->trueColor) { + tc_elem = (tweencolor_t *) gdCacheGet ( + tc_cache, &tc_key); + + gdImageSetPixel(im, x, y, tc_elem->tweencolor); } - else - { + else { pixel = &im->pixels[y][x]; - } if (tc_key.pixel == NUMCOLORS) - { - /* use fg color directly */ - if (im->trueColor) - { - *tpixel = fg; - } - else - { *pixel = fg; - } - } - else - { - /* find antialised color */ - if (im->trueColor) - { - tc_key.bgcolor = *tpixel; - } - else - { + else { tc_key.bgcolor = *pixel; - } tc_elem = (tweencolor_t *) gdCacheGet ( tc_cache, &tc_key); - if (im->trueColor) - { - *tpixel = tc_elem->tweencolor; - } - else - { *pixel = tc_elem->tweencolor; + } + } } } @@ -647,11 +625,18 @@ /********************************************************************/ /* 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) { + return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, NULL); +} + +char * +gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, + double ptsize, double angle, int x, int y, char *string, + gdFTStringExtra * strex) +{ FT_BBox bbox, glyph_bbox; FT_Matrix matrix; FT_Vector pen, delta, penf; @@ -672,6 +657,9 @@ int render = (im && (im->trueColor || (fg <= 255 && fg >= -255))); FT_BitmapGlyph bm; + /* fine tuning */ + double linespace = LINESPACE; + /***** initialize font library and font cache on first call ******/ static gdCache_head_t *fontCache; static FT_Library library; @@ -704,6 +692,14 @@ 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; @@ -754,7 +750,7 @@ /* newlines */ if (ch == '\n') { - penf.y -= face->size->metrics.height * LINESPACE; + penf.y -= face->size->metrics.height * linespace; penf.y = (penf.y - 32) & -64; /* round to next pixel row */ x1 = (penf.x * cos_a - penf.y * sin_a + 32) / 64; y1 = (penf.x * sin_a + penf.y * cos_a + 32) / 64; Index: php4/ext/gd/libgd/webpng.c diff -u php4/ext/gd/libgd/webpng.c:1.1 php4/ext/gd/libgd/webpng.c:1.2 --- php4/ext/gd/libgd/webpng.c:1.1 Fri Apr 12 22:03:09 2002 +++ php4/ext/gd/libgd/webpng.c Sun Apr 21 09:48:22 2002 @@ -168,12 +168,12 @@ t = gdImageGetTransparent (im); if (t != (-1)) { - printf ("First 100% transparent index: %d\n", t); + printf ("First 100%% transparent index: %d\n", t); } else { /* -1 means the image is not transparent. */ - printf ("First 100% transparent index: none\n"); + printf ("First 100%% transparent index: none\n"); } if (gdImageGetInterlaced (im)) { @@ -185,6 +185,40 @@ } no = 0; } + else if (!strcmp(argv[i], "-a")) + { + int maxx, maxy, x, y, alpha, pix, nalpha = 0; + + maxx = gdImageSX(im); + maxy = gdImageSY(im); + + printf("alpha channel information:\n"); + + if (im->trueColor) { + for (y = 0; y < maxy; y++) { + for (x = 0; x < maxx; x++) { + pix = gdImageGetPixel(im, x, y); + alpha = gdTrueColorGetAlpha(pix); + + if (alpha > gdAlphaOpaque) { + /* Use access macros to learn colors. */ + printf ("%d %d %d %d\n", + gdTrueColorGetRed(pix), + gdTrueColorGetGreen(pix), + gdTrueColorGetBlue(pix), + alpha); + nalpha++; + } + + } + } + } + else + printf("NOT a true color image\n"); + no = 0; + printf("%d alpha channels\n", nalpha); + + } else { fprintf (stderr, "Unknown argument: %s\n", argv[i]); @@ -202,6 +236,7 @@ " -l Prints the table of color indexes\n" " -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n" " -d Reports the dimensions and other characteristics of the image.\n" + " -a Prints all alpha channels that are not 100%% opaque.\n" "\n" "If you specify '-' as the input file, stdin/stdout will be used input/output.\n" );
Index: php4/ext/gd/libgd/gd.c diff -u php4/ext/gd/libgd/gd.c:1.1 php4/ext/gd/libgd/gd.c:1.2 --- php4/ext/gd/libgd/gd.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd.c Sun Apr 21 09:48:22 2002 @@ -1651,18 +1651,37 @@ if (dst->trueColor) { /* 2.0: much easier when the destination is truecolor. */ + + if (src->trueColor) { for (y = 0; (y < h); y++) { for (x = 0; (x < w); x++) { int c = gdImageGetTrueColorPixel (src, srcX + x, srcY + y); + gdImageSetPixel (dst, + dstX + x, + dstY + y, + c); + } + } + + } + else { + /* source is palette based */ + for (y = 0; (y < h); y++) + { + for (x = 0; (x < w); x++) + { + int c = gdImageGetPixel (src, srcX + x, + srcY + y); if (c != src->transparent) { gdImageSetPixel (dst, dstX + x, dstY + y, - c); + gdTrueColor(src->red[c], src->green[c], src->blue[c])); + } } } } Index: php4/ext/gd/libgd/gd.h diff -u php4/ext/gd/libgd/gd.h:1.1 php4/ext/gd/libgd/gd.h:1.2 --- php4/ext/gd/libgd/gd.h:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd.h Sun Apr 21 09:48:22 2002 @@ -251,6 +251,19 @@ char *gdImageStringFT(gdImage *im, int *brect, int fg, char *fontlist, double ptsize, double angle, int x, int y, char *string); +typedef struct { + int flags; /* for future expansion logical OR of gdFTEX_ values */ + double linespacing; /* fine tune line spacing for '\n' */ +} gdFTStringExtra, *gdFTStringExtraPtr; +#define gdFTEX_LINESPACE 1 + +/* FreeType 2 text output with fine tuning */ +char * +gdImageStringFTEx(gdImage * im, int *brect, int fg, char * fontlist, + double ptsize, double angle, int x, int y, char * string, + gdFTStringExtraPtr strex); + + /* Point type for use in polygon drawing. */ typedef struct { int x, y; Index: php4/ext/gd/libgd/gd_png.c diff -u php4/ext/gd/libgd/gd_png.c:1.1 php4/ext/gd/libgd/gd_png.c:1.2 --- php4/ext/gd/libgd/gd_png.c:1.1 Fri Apr 12 22:03:08 2002 +++ php4/ext/gd/libgd/gd_png.c Sun Apr 21 09:48:22 2002 @@ -225,7 +225,7 @@ im->alpha[i] = gdAlphaMax - (trans[i] >> 1); if ((trans[i] == 0) && (firstZero)) { - im->transparent = i; + transparent = i; firstZero = 0; } } Index: php4/ext/gd/libgd/gdft.c diff -u php4/ext/gd/libgd/gdft.c:1.1 php4/ext/gd/libgd/gdft.c:1.2 --- php4/ext/gd/libgd/gdft.c:1.1 Fri Apr 12 22:03:09 2002 +++ php4/ext/gd/libgd/gdft.c Sun Apr 21 09:48:22 2002 @@ -513,7 +513,8 @@ gdTrueColorGetRed (fg), gdTrueColorGetGreen (fg), gdTrueColorGetBlue (fg), - gdAlphaMax - (gdTrueColorGetAlpha (fg) * pixel / NUMCOLORS)); + gdAlphaMax - ((gdAlphaMax - gdTrueColorGetAlpha (fg)) * pixel / NUMCOLORS) + ); } else { @@ -566,76 +567,53 @@ for (col = 0; col < bitmap.width; col++, pc++) { - if (bitmap.pixel_mode == ft_pixel_mode_grays) - { + x = pen_x + col; + + /* clip if out of bounds */ + if (x >= im->sx || x < 0) + continue; + + switch(bitmap.pixel_mode) { + case ft_pixel_mode_grays: /* * Round to NUMCOLORS levels of antialiasing for * index color images since only 256 colors are * available. */ + tc_key.pixel = ((bitmap.buffer[pc] * NUMCOLORS) + bitmap.num_grays / 2) / (bitmap.num_grays - 1); - } - else if (bitmap.pixel_mode == ft_pixel_mode_mono) - { + break; + case ft_pixel_mode_mono: tc_key.pixel = ((bitmap.buffer[pc / 8] << (pc % 8)) & 128) ? NUMCOLORS : 0; - } - else - { + break; + default: return "Unsupported ft_pixel_mode"; } if (tc_key.pixel > 0) - { /* if not background */ - x = pen_x + col; - - /* clip if out of bounds */ - if (x >= im->sx || x < 0) - continue; - /* get pixel location in gd buffer */ - if (im->trueColor) { - tpixel = &im->tpixels[y][x]; + + if (im->trueColor) { + tc_elem = (tweencolor_t *) gdCacheGet ( + tc_cache, &tc_key); + + gdImageSetPixel(im, x, y, tc_elem->tweencolor); } - else - { + else { pixel = &im->pixels[y][x]; - } if (tc_key.pixel == NUMCOLORS) - { - /* use fg color directly */ - if (im->trueColor) - { - *tpixel = fg; - } - else - { *pixel = fg; - } - } - else - { - /* find antialised color */ - if (im->trueColor) - { - tc_key.bgcolor = *tpixel; - } - else - { + else { tc_key.bgcolor = *pixel; - } tc_elem = (tweencolor_t *) gdCacheGet ( tc_cache, &tc_key); - if (im->trueColor) - { - *tpixel = tc_elem->tweencolor; - } - else - { *pixel = tc_elem->tweencolor; + } + } } } @@ -647,11 +625,18 @@ /********************************************************************/ /* 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) { + return gdImageStringFTEx(im, brect, fg, fontlist, ptsize, angle, x, y, string, NULL); +} + +char * +gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, + double ptsize, double angle, int x, int y, char *string, + gdFTStringExtra * strex) +{ FT_BBox bbox, glyph_bbox; FT_Matrix matrix; FT_Vector pen, delta, penf; @@ -672,6 +657,9 @@ int render = (im && (im->trueColor || (fg <= 255 && fg >= -255))); FT_BitmapGlyph bm; + /* fine tuning */ + double linespace = LINESPACE; + /***** initialize font library and font cache on first call ******/ static gdCache_head_t *fontCache; static FT_Library library; @@ -704,6 +692,14 @@ 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; @@ -754,7 +750,7 @@ /* newlines */ if (ch == '\n') { - penf.y -= face->size->metrics.height * LINESPACE; + penf.y -= face->size->metrics.height * linespace; penf.y = (penf.y - 32) & -64; /* round to next pixel row */ x1 = (penf.x * cos_a - penf.y * sin_a + 32) / 64; y1 = (penf.x * sin_a + penf.y * cos_a + 32) / 64; Index: php4/ext/gd/libgd/webpng.c diff -u php4/ext/gd/libgd/webpng.c:1.1 php4/ext/gd/libgd/webpng.c:1.2 --- php4/ext/gd/libgd/webpng.c:1.1 Fri Apr 12 22:03:09 2002 +++ php4/ext/gd/libgd/webpng.c Sun Apr 21 09:48:22 2002 @@ -168,12 +168,12 @@ t = gdImageGetTransparent (im); if (t != (-1)) { - printf ("First 100% transparent index: %d\n", t); + printf ("First 100%% transparent index: %d\n", t); } else { /* -1 means the image is not transparent. */ - printf ("First 100% transparent index: none\n"); + printf ("First 100%% transparent index: none\n"); } if (gdImageGetInterlaced (im)) { @@ -185,6 +185,40 @@ } no = 0; } + else if (!strcmp(argv[i], "-a")) + { + int maxx, maxy, x, y, alpha, pix, nalpha = 0; + + maxx = gdImageSX(im); + maxy = gdImageSY(im); + + printf("alpha channel information:\n"); + + if (im->trueColor) { + for (y = 0; y < maxy; y++) { + for (x = 0; x < maxx; x++) { + pix = gdImageGetPixel(im, x, y); + alpha = gdTrueColorGetAlpha(pix); + + if (alpha > gdAlphaOpaque) { + /* Use access macros to learn colors. */ + printf ("%d %d %d %d\n", + gdTrueColorGetRed(pix), + gdTrueColorGetGreen(pix), + gdTrueColorGetBlue(pix), + alpha); + nalpha++; + } + + } + } + } + else + printf("NOT a true color image\n"); + no = 0; + printf("%d alpha channels\n", nalpha); + + } else { fprintf (stderr, "Unknown argument: %s\n", argv[i]); @@ -202,6 +236,7 @@ " -l Prints the table of color indexes\n" " -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n" " -d Reports the dimensions and other characteristics of the image.\n" + " -a Prints all alpha channels that are not 100%% opaque.\n" "\n" "If you specify '-' as the input file, stdin/stdout will be used input/output.\n" );