diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2019-01-16 20:10:04 +0100 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2019-01-16 20:10:04 +0100 |
commit | 61cfa34e1194b5a026548508f9f34d6f6a8774da (patch) | |
tree | 64e020c0c60acb1a71d76326c80adda3b667a96a | |
parent | 5ac9990ddf0521b1c79b5e061a342a6dfb53d30c (diff) | |
download | php-git-61cfa34e1194b5a026548508f9f34d6f6a8774da.tar.gz |
Fix #73614: gdImageFilledArc() doesn't properly draw pies
The fix for PHP bug 43828[1] changed the algorithm from drawing filled
pies from drawing multiple triangles to drawing a single polygon. Due
to quirks of the filled polygon drawing algorithm, we had to filter out
extraneous vertices. This lead, however, to a bug regarding displaced
starting and ending points near 90° and 270° degrees, which we fix by
reinserting these vertices if they had been removed.
This fix is a port of libgd/libgd@1406b1a.
[1] <https://bugs.php.net/bug.php?id=43828>
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/gd/libgd/gd.c | 28 | ||||
-rw-r--r-- | ext/gd/tests/bug73614.phpt | 27 | ||||
-rw-r--r-- | ext/gd/tests/bug73614.png | bin | 0 -> 2652 bytes |
4 files changed, 51 insertions, 5 deletions
@@ -8,6 +8,7 @@ PHP NEWS - GD: . Fixed bug #73281 (imagescale(…, IMG_BILINEAR_FIXED) can cause black border). (cmb) + . Fixed bug #73614 (gdImageFilledArc() doesn't properly draw pies). (cmb) . Fixed bug #77272 (imagescale() may return image resource on failure). (cmb) . Fixed bug #77391 (1bpp BMPs may fail to be loaded). (Romain Déoux, cmb) diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index c96e2085f0..6284d09190 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -1593,7 +1593,7 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e int i, pti; int lx = 0, ly = 0; int fx = 0, fy = 0; - + int startx, starty, endx, endy; if ((s % 360) == (e % 360)) { s = 0; e = 360; @@ -1620,8 +1620,8 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e for (i = s, pti = 1; i <= e; i++, pti++) { int x, y; - x = ((long) gdCosT[i % 360] * (long) w / (2 * 1024)) + cx; - y = ((long) gdSinT[i % 360] * (long) h / (2 * 1024)) + cy; + x = endx = ((long) gdCosT[i % 360] * (long) w / (2 * 1024)) + cx; + y = endy = ((long) gdSinT[i % 360] * (long) h / (2 * 1024)) + cy; if (i != s) { if (!(style & gdChord)) { if (style & gdNoFill) { @@ -1646,8 +1646,8 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e if (!(style & (gdChord | gdNoFill))) { pts[0].x = cx; pts[0].y = cy; - pts[pti].x = x; - pts[pti].y = y; + pts[pti].x = startx = x; + pts[pti].y = starty = y; } } lx = x; @@ -1676,6 +1676,24 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e gdImageLine(im, cx, cy, fx, fy, color); } } else { + if (e - s < 360) { + if (pts[1].x != startx && pts[1].y == starty) { + /* start point has been removed due to y-coord fix => insert it */ + for (i = pti; i > 1; i--) { + pts[i].x = pts[i-1].x; + pts[i].y = pts[i-1].y; + } + pts[1].x = startx; + pts[1].y = starty; + pti++; + } + if (pts[pti-1].x != endx && pts[pti-1].y == endy) { + /* end point has been removed due to y-coord fix => insert it */ + pts[pti].x = endx; + pts[pti].y = endy; + pti++; + } + } pts[pti].x = cx; pts[pti].y = cy; gdImageFilledPolygon(im, pts, pti+1, color); diff --git a/ext/gd/tests/bug73614.phpt b/ext/gd/tests/bug73614.phpt new file mode 100644 index 0000000000..f94881e2f3 --- /dev/null +++ b/ext/gd/tests/bug73614.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #73614 (gdImageFilledArc() doesn't properly draw pies) +--SKIPIF-- +<?php +if (!extension_loaded('gd')) die('skip gd extension not available'); +if (!GD_BUNDLED && version_compare(GD_VERSION, '2.2.5', '<=')) die('skip upstream bugfix not yet released'); +?> +--FILE-- +<?php +require_once __DIR__ . '/func.inc'; + +$image = imagecreatetruecolor(500, 500); + +$white = imagecolorallocate($image, 0xFF, 0xFF, 0xFF); +$navy = imagecolorallocate($image, 0x00, 0x00, 0x80); +$red = imagecolorallocate($image, 0xFF, 0x00, 0x00); + +imagefilledarc($image, 250, 250, 500, 250, 0, 88, $white, IMG_ARC_PIE); +imagefilledarc($image, 250, 250, 500, 250, 88, 91 , $navy, IMG_ARC_PIE); +imagefilledarc($image, 250, 250, 500, 250, 91, 360 , $red, IMG_ARC_PIE); + +test_image_equals_file(__DIR__ . '/bug73614.png', $image); +?> +===DONE=== +--EXPECT-- +The images are equal. +===DONE=== diff --git a/ext/gd/tests/bug73614.png b/ext/gd/tests/bug73614.png Binary files differnew file mode 100644 index 0000000000..16b2db2623 --- /dev/null +++ b/ext/gd/tests/bug73614.png |