From: Pierre Joye Date: Sun, 17 Jun 2007 10:56:51 +0000 (+0000) Subject: - MFH: #41717, imagepolygon does not respect thickness X-Git-Tag: php-5.2.4RC1~338 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bf348c8c469a677164dbc7f0b1214bb43011c895;p=php - MFH: #41717, imagepolygon does not respect thickness (sync with libgd) --- diff --git a/NEWS b/NEWS index 882f22b791..cda5ab3615 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,7 @@ PHP NEWS - Fixed PECL bug #11216 (crash in ZipArchive::addEmptyDir when a directory already exists). (Pierre) +- Fixed bug #41717 (imagepolygon does not respect thickness). (Pierre) - Fixed bug #41655 (open_basedir bypass via glob()). (Ilia) - Fixed bug #41640 (get_class_vars produces error on class constants). (Johannes) diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index c76a06c4b9..3ca009c8f2 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -1039,86 +1039,93 @@ void gdImageAABlend (gdImagePtr im) } } +static void gdImageHLine(gdImagePtr im, int y, int x1, int x2, int col) +{ + if (im->thick > 1) { + int thickhalf = im->thick >> 1; + gdImageFilledRectangle(im, x1, y - thickhalf, x2, y + im->thick - thickhalf - 1, col); + } else { + if (x2 < x1) { + int t = x2; + x2 = x1; + x1 = t; + } + + for (;x1 <= x2; x1++) { + gdImageSetPixel(im, x1, y, col); + } + } + return; +} + +static void gdImageVLine(gdImagePtr im, int x, int y1, int y2, int col) +{ + if (im->thick > 1) { + int thickhalf = im->thick >> 1; + gdImageFilledRectangle(im, x - thickhalf, y1, x + im->thick - thickhalf - 1, y2, col); + } else { + if (y2 < y1) { + int t = y1; + y1 = y2; + y2 = t; + } + + for (;y1 <= y2; y1++) { + gdImageSetPixel(im, x, y1, col); + } + } + return; +} /* Bresenham as presented in Foley & Van Dam */ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) { - int t; int dx, dy, incr1, incr2, d, x, y, xend, yend, xdirflag, ydirflag; int wid; int w, wstart; int thick = im->thick; + if (color == gdAntiAliased) + { + /* + gdAntiAliased passed as color: use the much faster, much cheaper + and equally attractive gdImageAALine implementation. That + clips too, so don't clip twice. + */ + gdImageAALine(im, x1, y1, x2, y2, im->AA_color); + return; + } + /* 2.0.10: Nick Atty: clip to edges of drawing rectangle, return if no points need to be drawn */ if (!clip_1d(&x1,&y1,&x2,&y2,gdImageSX(im)) || !clip_1d(&y1,&x1,&y2,&x2,gdImageSY(im))) { return; } - /* Vertical */ - if (x1==x2) { - if (thick > 1) { - int thickhalf = thick >> 1; - thickhalf = thick >> 1; - gdImageFilledRectangle(im, x1 - thickhalf, y1, x1 + thick - thickhalf - 1, y2, color); - } else { - if (y2 < y1) { - t = y2; - y2 = y1; - y1 = t; - } + dx = abs (x2 - x1); + dy = abs (y2 - y1); - for (;y1 <= y2; y1++) { - gdImageSetPixel(im, x1,y1, color); - } - } + if (dx == 0) { + gdImageVLine(im, x1, y1, y2, color); return; - } else if (y1==y2) { /* Horizontal */ - if (thick > 1) { - int thickhalf = thick >> 1; - thickhalf = thick >> 1; - gdImageFilledRectangle(im, x1, y1 - thickhalf, x2, y2 + thick - thickhalf - 1, color); - } else { - if (x2 < x1) { - t = x2; - x2 = x1; - x1 = t; - } - - for (;x1 <= x2; x1++) { - gdImageSetPixel(im, x1,y1, color); - } - } + } else if (dy == 0) { + gdImageHLine(im, y1, x1, x2, color); return; } - /* gdAntiAliased passed as color: set anti-aliased line (AAL) global vars. */ - if (color == gdAntiAliased) { - im->AAL_x1 = x1; - im->AAL_y1 = y1; - im->AAL_x2 = x2; - im->AAL_y2 = y2; - - /* Compute what we can for point-to-line distance calculation later. */ - im->AAL_Bx_Ax = x2 - x1; - im->AAL_By_Ay = y2 - y1; - im->AAL_LAB_2 = (im->AAL_Bx_Ax * im->AAL_Bx_Ax) + (im->AAL_By_Ay * im->AAL_By_Ay); - im->AAL_LAB = sqrt (im->AAL_LAB_2); - - /* For AA, we must draw pixels outside the width of the line. Keep in - * mind that this will be curtailed by cos/sin of theta later. - */ - thick += 4; - } - - dx = abs(x2 - x1); - dy = abs(y2 - y1); if (dy <= dx) { /* More-or-less horizontal. use wid for vertical stroke */ /* Doug Claar: watch out for NaN in atan2 (2.0.5) */ if ((dx == 0) && (dy == 0)) { wid = 1; } else { - wid = (int)(thick * cos (atan2 (dy, dx))); + /* 2.0.12: Michael Schwartz: divide rather than multiply; +TBB: but watch out for /0! */ + double ac = cos (atan2 (dy, dx)); + if (ac != 0) { + wid = thick / ac; + } else { + wid = 1; + } if (wid == 0) { wid = 1; } @@ -1176,15 +1183,16 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) } else { /* More-or-less vertical. use wid for horizontal stroke */ /* 2.0.12: Michael Schwartz: divide rather than multiply; - TBB: but watch out for /0! */ - double as = sin(atan2(dy, dx)); + TBB: but watch out for /0! */ + double as = sin (atan2 (dy, dx)); if (as != 0) { - if (!(wid = thick / as)) { - wid = 1; - } + wid = thick / as; } else { wid = 1; } + if (wid == 0) { + wid = 1; + } d = 2 * dx - dy; incr1 = 2 * dx; @@ -1237,11 +1245,6 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) } } } - - /* If this is the only line we are drawing, go ahead and blend. */ - if (color == gdAntiAliased && !im->AA_polygon) { - gdImageAABlend(im); - } }