From 61cfa34e1194b5a026548508f9f34d6f6a8774da Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 16 Jan 2019 20:10:04 +0100 Subject: [PATCH] Fix #73614: gdImageFilledArc() doesn't properly draw pies MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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] --- NEWS | 1 + ext/gd/libgd/gd.c | 28 +++++++++++++++++++++++----- ext/gd/tests/bug73614.phpt | 27 +++++++++++++++++++++++++++ ext/gd/tests/bug73614.png | Bin 0 -> 2652 bytes 4 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 ext/gd/tests/bug73614.phpt create mode 100644 ext/gd/tests/bug73614.png diff --git a/NEWS b/NEWS index 71f69919ab..967afa21a0 100644 --- a/NEWS +++ b/NEWS @@ -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-- + +--FILE-- + +===DONE=== +--EXPECT-- +The images are equal. +===DONE=== diff --git a/ext/gd/tests/bug73614.png b/ext/gd/tests/bug73614.png new file mode 100644 index 0000000000000000000000000000000000000000..16b2db2623e16ccc608d0eeac348df6f228689eb GIT binary patch literal 2652 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