Make the $num_points parameter of php_imagepolygon optional

That parameter is mostly useless in practise, and likely has been
directly ported from the underlying `gdImagePolygon()` and friends,
which require that parameter since the number of elements of the point
array would otherwise be unknown.  Typical usages of `imagepolygon()`,
`imageopenpolygon()` and `imagefilledpolygon()` pass `count($points)/2`
or hard-code this value as literal.  Since explicitly specifying this
parameter is annoying and error-prone, we offer the possibility to omit
it, in which case the `$points` array must have an even number of
elements, and the number of points is calculated as `count($points)/2`.
This commit is contained in:
Christoph M. Becker 2019-11-14 09:46:43 +01:00
parent d65e59de9b
commit 2de79f0855
14 changed files with 41 additions and 26 deletions

1
NEWS
View file

@ -19,6 +19,7 @@ PHP NEWS
- GD:
. Fixed bug #55005 (imagepolygon num_points requirement). (cmb)
. Replaced gd resources with objects. (Mark Randall)
. Made the $num_points parameter of php_imagepolygon optional. (cmb)
. Removed deprecated image2wbmp(). (cmb)
. Removed deprecated png2wbmp() and jpeg2wbmp(). (cmb)

View file

@ -355,6 +355,12 @@ PHP 8.0 UPGRADE NOTES
9. Other Changes to Extensions
========================================
- GD:
. The $num_points parameter of imagepolygon(), imageopenpolygon() and
imagefilledpolygon() is now optional, i.e. these functions may be called
with either 3 or 4 arguments. If the arguments is omitted, it is calculated
as count($points)/2.
========================================
10. New Global Constants
========================================

View file

@ -2735,9 +2735,18 @@ static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled)
gdPointPtr points;
int npoints, col, nelem, i;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oall", &IM, gd_image_ce, &POINTS, &NPOINTS, &COL) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oal|l", &IM, gd_image_ce, &POINTS, &NPOINTS, &COL) == FAILURE) {
return;
}
if (ZEND_NUM_ARGS() == 3) {
COL = NPOINTS;
NPOINTS = zend_hash_num_elements(Z_ARRVAL_P(POINTS));
if (NPOINTS % 2 != 0) {
zend_value_error("Points array must have an even number of elements");
return;
}
NPOINTS /= 2;
}
im = php_gd_libgdimageptr_from_zval_p(IM);

View file

@ -186,11 +186,11 @@ function imagecolortransparent(GdImage $im, int $col = UNKNOWN): ?int {}
function imageinterlace(GdImage $im, int $interlace = UNKNOWN): ?int {}
function imagepolygon(GdImage $im, array $points, int $num_pos, int $col): bool {}
function imagepolygon(GdImage $im, array $points, int $num_points_or_col, int $col = UNKNOWN): bool {}
function imageopenpolygon(GdImage $im, array $points, int $num_pos, int $col): bool {}
function imageopenpolygon(GdImage $im, array $points, int $num_points_or_col, int $col = UNKNOWN): bool {}
function imagefilledpolygon(GdImage $im, array $points, int $num_pos, int $col): bool {}
function imagefilledpolygon(GdImage $im, array $points, int $num_points_or_col, int $col = UNKNOWN): bool {}
function imagefontwidth(int $font): int {}

View file

@ -367,10 +367,10 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imageinterlace, 0, 1, IS_LONG, 1
ZEND_ARG_TYPE_INFO(0, interlace, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagepolygon, 0, 4, _IS_BOOL, 0)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagepolygon, 0, 3, _IS_BOOL, 0)
ZEND_ARG_OBJ_INFO(0, im, GdImage, 0)
ZEND_ARG_TYPE_INFO(0, points, IS_ARRAY, 0)
ZEND_ARG_TYPE_INFO(0, num_pos, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, num_points_or_col, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, col, IS_LONG, 0)
ZEND_END_ARG_INFO()

View file

@ -38,7 +38,7 @@ $cos_t = cos(deg2rad($delta_t));
$sin_t = sin(deg2rad($delta_t));
for ($angle = 0.0, $i = 0; $angle < 360.0; $angle += $delta_t, $i++) {
$bbox = imagettftext($g, 24, $angle, 400+$x, 400+$y, $black, $font, 'ABCDEF');
imagepolygon($g, $bbox, 4, $red);
imagepolygon($g, $bbox, $red);
printf("%2d: ", $i);
for ($j = 0; $j < 8; $j++) {
if ($bbox[$j] >= $exp[$i][$j] - 1 && $bbox[$j] <= $exp[$i][$j] + 1) {

View file

@ -72,7 +72,7 @@ foreach ($tests as $testnum => $test) {
}
// draw bounding box:
imagepolygon($g, $bboxDrawn, 4, $red);
imagepolygon($g, $bboxDrawn, $red);
// draw baseline:
$width = sqrt(pow($bboxDrawn[2] - $bboxDrawn[0], 2) + pow($bboxDrawn[3] - $bboxDrawn[1], 2));

View file

@ -16,6 +16,6 @@ trycatch_dump(
fn () => imagepolygon($g, array(200,10, 200,100, 280,100), 2, $fgnd)
);
?>
--EXPECT--
--EXPECTF--
!! [ValueError] Polygon must have at least 3 points
!! [ValueError] Polygon must have at least 3 points

View file

@ -18,14 +18,14 @@ $points = array(
100, 200,
100, 300
);
imagefilledpolygon($im, $points, 3, 0xFFFF00);
imagefilledpolygon($im, $points, 0xFFFF00);
$points = array(
300, 200,
400, 200,
500, 200
);
imagefilledpolygon($im, $points, 3, 0xFFFF00);
imagefilledpolygon($im, $points, 0xFFFF00);
$ex = imagecreatefrompng(__DIR__ . '/bug64641.png');
if (($diss = calc_image_dissimilarity($ex, $im)) < 1e-5) {

View file

@ -36,7 +36,7 @@ $bg = imagecolorallocate($image, 0, 0, 0);
$col_poly = imagecolorallocate($image, 0, 255, 0);
// draw the polygon
imagefilledpolygon($image, $points, count($points)/2, $col_poly);
imagefilledpolygon($image, $points, $col_poly);
// output the picture to a file
imagepng($image, $dest);

View file

@ -16,10 +16,10 @@ $green = imagecolorallocate($im, 0, 128, 0);
$blue = imagecolorallocate($im, 0, 0, 255);
imagefilledrectangle($im, 0,0, 99,99, $white);
imageopenpolygon($im, [10,10, 49,89, 89,10], 3, $black);
imageopenpolygon($im, [10,89, 35,10, 60,89, 85,10], 4, $red);
imageopenpolygon($im, [10,49, 30,89, 50,10, 70,89, 90,10], 5, $green);
imageopenpolygon($im, [10,50, 25,10, 40,89, 55,10, 80,89, 90,50], 6, $blue);
imageopenpolygon($im, [10,10, 49,89, 89,10], $black);
imageopenpolygon($im, [10,89, 35,10, 60,89, 85,10], $red);
imageopenpolygon($im, [10,49, 30,89, 50,10, 70,89, 90,10], $green);
imageopenpolygon($im, [10,50, 25,10, 40,89, 55,10, 80,89, 90,50], $blue);
test_image_equals_file(__DIR__ . DIRECTORY_SEPARATOR . 'imageopenpolygon.png', $im);
?>

View file

@ -14,7 +14,7 @@ $black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0,0, 99,99, $white);
imageantialias($im, true);
imagepolygon($im, [10,10, 49,89, 89,49], 3, $black);
imagepolygon($im, [10,10, 49,89, 89,49], $black);
test_image_equals_file(__DIR__ . DIRECTORY_SEPARATOR . 'imagepolygon_aa.png', $im);
?>

View file

@ -33,7 +33,6 @@ imagepolygon($image, array (
100, 200,
300, 200
),
3,
$col_poly);
// output the picture to a file

View file

@ -33,7 +33,7 @@ $points = array(
$x+$d, ($top+$bot)/2,
$x, $bot
);
imagefilledpolygon($im, $points, 5, $yellow);
imagefilledpolygon($im, $points, $yellow);
// left-facing M not on baseline
$top = 40;
@ -47,7 +47,7 @@ $points = array(
$left, $bot,
($left+$right)/2, ($top+$bot)/2
);
imagefilledpolygon($im, $points, 5, $purple);
imagefilledpolygon($im, $points, $purple);
// left-facing M on baseline
$top = 240;
@ -61,7 +61,7 @@ $points = array(
$left, $bot,
($left+$right)/2, ($top+$bot)/2
);
imagefilledpolygon($im, $points, 5, $magenta);
imagefilledpolygon($im, $points, $magenta);
// left-facing M on ceiling
$top = -15;
@ -75,23 +75,23 @@ $points = array(
$left, $bot,
($left+$right)/2, ($top+$bot)/2
);
imagefilledpolygon($im, $points, 5, $blue);
imagefilledpolygon($im, $points, $blue);
$d = 30;
$x = 150;
$y = 150;
$diamond = array($x-$d, $y, $x, $y+$d, $x+$d, $y, $x, $y-$d);
imagefilledpolygon($im, $diamond, 4, $green);
imagefilledpolygon($im, $diamond, $green);
$x = 180;
$y = 225;
$diamond = array($x-$d, $y, $x, $y+$d, $x+$d, $y, $x, $y-$d);
imagefilledpolygon($im, $diamond, 4, $red);
imagefilledpolygon($im, $diamond, $red);
$x = 225;
$y = 255;
$diamond = array($x-$d, $y, $x, $y+$d, $x+$d, $y, $x, $y-$d);
imagefilledpolygon($im, $diamond, 4, $cyan);
imagefilledpolygon($im, $diamond, $cyan);
// M (bridge) not touching bottom boundary
$top = 100;
@ -104,7 +104,7 @@ $points = array(
$x+$d, ($top+$bot)/2,
$x, $bot
);
imagefilledpolygon($im, $points, 5, $black);
imagefilledpolygon($im, $points, $black);
include_once __DIR__ . '/func.inc';
test_image_equals_file(__DIR__ . '/libgd00100.png', $im);