Skip to content

Commit ba2d9e1

Browse files
committedSep 19, 2016
Merge branch 'PHP-5.6' into PHP-7.0
2 parents ca24c58 + fc2cadc commit ba2d9e1

File tree

6 files changed

+191
-83
lines changed

6 files changed

+191
-83
lines changed
 

‎ext/gd/gd.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3856,7 +3856,7 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int
38563856
{
38573857
zval *IM, *EXT = NULL;
38583858
gdImagePtr im=NULL;
3859-
zend_long col = -1, x = -1, y = -1;
3859+
zend_long col = -1, x = 0, y = 0;
38603860
size_t str_len, fontname_len;
38613861
int i, brect[8];
38623862
double ptsize, angle;

‎ext/gd/libgd/gdft.c

+66-61
Original file line numberDiff line numberDiff line change
@@ -749,9 +749,9 @@ static char * gdft_draw_bitmap (gdCache_head_t *tc_cache, gdImage * im, int fg,
749749
}
750750

751751
static int
752-
gdroundupdown (FT_F26Dot6 v1, int updown)
752+
gdroundupdown (FT_F26Dot6 v1, int roundup)
753753
{
754-
return (!updown) ? (v1 < 0 ? ((v1 - 63) >> 6) : v1 >> 6) : (v1 > 0 ? ((v1 + 63) >> 6) : v1 >> 6);
754+
return (!roundup) ? v1 >> 6 : (v1 + 63) >> 6;
755755
}
756756

757757
void gdFontCacheShutdown()
@@ -821,8 +821,6 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
821821
double cos_a = cos (angle);
822822
int len, i = 0, ch;
823823
int x1 = 0, y1 = 0;
824-
int xb = x, yb = y;
825-
int yd = 0;
826824
font_t *font;
827825
fontkey_t fontkey;
828826
char *next;
@@ -983,9 +981,6 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
983981
penf.y = (penf.y - 32) & -64; /* round to next pixel row */
984982
x1 = (int)(- penf.y * sin_a + 32) / 64;
985983
y1 = (int)(- penf.y * cos_a + 32) / 64;
986-
xb = x + x1;
987-
yb = y + y1;
988-
yd = 0;
989984
pen.x = pen.y = 0;
990985
previous = 0; /* clear kerning flag */
991986
continue;
@@ -1075,31 +1070,32 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
10751070
/* retrieve kerning distance and move pen position */
10761071
if (use_kerning && previous && glyph_index) {
10771072
FT_Get_Kerning(face, previous, glyph_index, ft_kerning_default, &delta);
1078-
pen.x += delta.x;
1073+
pen.x += (int)(delta.x * cos_a);
1074+
pen.y -= (int)(delta.x * sin_a);
10791075
penf.x += delta.x;
10801076
}
10811077

1082-
/* load glyph image into the slot (erase previous one) */
1083-
if (FT_Load_Glyph(face, glyph_index, render_mode)) {
1084-
if (tmpstr) {
1085-
gdFree(tmpstr);
1078+
if (brect) { /* only if need brect */
1079+
/* load glyph image into the slot (erase previous one) */
1080+
if (FT_Load_Glyph(face, glyph_index, render_mode | FT_LOAD_IGNORE_TRANSFORM)) {
1081+
if (tmpstr) {
1082+
gdFree(tmpstr);
1083+
}
1084+
gdCacheDelete(tc_cache);
1085+
gdMutexUnlock(gdFontCacheMutex);
1086+
return "Problem loading glyph";
10861087
}
1087-
gdCacheDelete(tc_cache);
1088-
gdMutexUnlock(gdFontCacheMutex);
1089-
return "Problem loading glyph";
1090-
}
10911088

1092-
/* transform glyph image */
1093-
if (FT_Get_Glyph(slot, &image)) {
1094-
if (tmpstr) {
1095-
gdFree(tmpstr);
1089+
/* transform glyph image */
1090+
if (FT_Get_Glyph(slot, &image)) {
1091+
if (tmpstr) {
1092+
gdFree(tmpstr);
1093+
}
1094+
gdCacheDelete(tc_cache);
1095+
gdMutexUnlock(gdFontCacheMutex);
1096+
return "Problem loading glyph";
10961097
}
1097-
gdCacheDelete(tc_cache);
1098-
gdMutexUnlock(gdFontCacheMutex);
1099-
return "Problem loading glyph";
1100-
}
11011098

1102-
if (brect) { /* only if need brect */
11031099
FT_Glyph_Get_CBox(image, ft_glyph_bbox_gridfit, &glyph_bbox);
11041100
glyph_bbox.xMin += penf.x;
11051101
glyph_bbox.yMin += penf.y;
@@ -1109,17 +1105,11 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
11091105
glyph_bbox.xMax += slot->metrics.horiAdvance;
11101106
}
11111107
if (!i) { /* if first character, init BB corner values */
1112-
yd = slot->metrics.height - slot->metrics.horiBearingY;
11131108
bbox.xMin = glyph_bbox.xMin;
11141109
bbox.yMin = glyph_bbox.yMin;
11151110
bbox.xMax = glyph_bbox.xMax;
11161111
bbox.yMax = glyph_bbox.yMax;
11171112
} else {
1118-
FT_Pos desc;
1119-
1120-
if ( (desc = (slot->metrics.height - slot->metrics.horiBearingY)) > yd) {
1121-
yd = desc;
1122-
}
11231113
if (bbox.xMin > glyph_bbox.xMin) {
11241114
bbox.xMin = glyph_bbox.xMin;
11251115
}
@@ -1136,7 +1126,35 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
11361126
i++;
11371127
}
11381128

1129+
/* increment (unrotated) pen position */
1130+
penf.x += slot->metrics.horiAdvance;
1131+
11391132
if (render) {
1133+
if (!brect || angle != 0) {
1134+
/* reload the rotated glyph (for bbox we needed FT_LOAD_IGNORE_TRANSFORM - bbox is rotated later) */
1135+
FT_Done_Glyph(image);
1136+
1137+
/* load glyph image into the slot (erase previous one) */
1138+
if (FT_Load_Glyph(face, glyph_index, render_mode)) {
1139+
if (tmpstr) {
1140+
gdFree(tmpstr);
1141+
}
1142+
gdCacheDelete(tc_cache);
1143+
gdMutexUnlock(gdFontCacheMutex);
1144+
return "Problem loading glyph";
1145+
}
1146+
1147+
/* transform glyph image */
1148+
if (FT_Get_Glyph(slot, &image)) {
1149+
if (tmpstr) {
1150+
gdFree(tmpstr);
1151+
}
1152+
gdCacheDelete(tc_cache);
1153+
gdMutexUnlock(gdFontCacheMutex);
1154+
return "Problem loading glyph";
1155+
}
1156+
}
1157+
11401158
if (image->format != ft_glyph_format_bitmap && FT_Glyph_To_Bitmap(&image, ft_render_mode_normal, 0, 1)) {
11411159
FT_Done_Glyph(image);
11421160
if (tmpstr) {
@@ -1159,8 +1177,6 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
11591177
pen.x += image->advance.x >> 10;
11601178
pen.y -= image->advance.y >> 10;
11611179

1162-
penf.x += slot->metrics.horiAdvance;
1163-
11641180
FT_Done_Glyph(image);
11651181
}
11661182

@@ -1169,36 +1185,25 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi
11691185
double d1 = sin (angle + 0.78539816339744830962);
11701186
double d2 = sin (angle - 0.78539816339744830962);
11711187

1172-
/* make the center of rotation at (0, 0) */
1173-
FT_BBox normbox;
1174-
1175-
normbox.xMin = 0;
1176-
normbox.yMin = 0;
1177-
normbox.xMax = bbox.xMax - bbox.xMin;
1178-
normbox.yMax = bbox.yMax - bbox.yMin;
1179-
1180-
brect[0] = brect[2] = brect[4] = brect[6] = (int) (yd * sin_a);
1181-
brect[1] = brect[3] = brect[5] = brect[7] = (int)(- yd * cos_a);
1182-
1183-
/* rotate bounding rectangle */
1184-
brect[0] += (int) (normbox.xMin * cos_a - normbox.yMin * sin_a);
1185-
brect[1] += (int) (normbox.xMin * sin_a + normbox.yMin * cos_a);
1186-
brect[2] += (int) (normbox.xMax * cos_a - normbox.yMin * sin_a);
1187-
brect[3] += (int) (normbox.xMax * sin_a + normbox.yMin * cos_a);
1188-
brect[4] += (int) (normbox.xMax * cos_a - normbox.yMax * sin_a);
1189-
brect[5] += (int) (normbox.xMax * sin_a + normbox.yMax * cos_a);
1190-
brect[6] += (int) (normbox.xMin * cos_a - normbox.yMax * sin_a);
1191-
brect[7] += (int) (normbox.xMin * sin_a + normbox.yMax * cos_a);
1188+
/* rotate bounding rectangle (at 0, 0) */
1189+
brect[0] = (int) (bbox.xMin * cos_a - bbox.yMin * sin_a);
1190+
brect[1] = (int) (bbox.xMin * sin_a + bbox.yMin * cos_a);
1191+
brect[2] = (int) (bbox.xMax * cos_a - bbox.yMin * sin_a);
1192+
brect[3] = (int) (bbox.xMax * sin_a + bbox.yMin * cos_a);
1193+
brect[4] = (int) (bbox.xMax * cos_a - bbox.yMax * sin_a);
1194+
brect[5] = (int) (bbox.xMax * sin_a + bbox.yMax * cos_a);
1195+
brect[6] = (int) (bbox.xMin * cos_a - bbox.yMax * sin_a);
1196+
brect[7] = (int) (bbox.xMin * sin_a + bbox.yMax * cos_a);
11921197

11931198
/* scale, round and offset brect */
1194-
brect[0] = xb + gdroundupdown(brect[0], d2 > 0);
1195-
brect[1] = yb - gdroundupdown(brect[1], d1 < 0);
1196-
brect[2] = xb + gdroundupdown(brect[2], d1 > 0);
1197-
brect[3] = yb - gdroundupdown(brect[3], d2 > 0);
1198-
brect[4] = xb + gdroundupdown(brect[4], d2 < 0);
1199-
brect[5] = yb - gdroundupdown(brect[5], d1 > 0);
1200-
brect[6] = xb + gdroundupdown(brect[6], d1 < 0);
1201-
brect[7] = yb - gdroundupdown(brect[7], d2 < 0);
1199+
brect[0] = x + gdroundupdown(brect[0], d2 > 0);
1200+
brect[1] = y - gdroundupdown(brect[1], d1 < 0);
1201+
brect[2] = x + gdroundupdown(brect[2], d1 > 0);
1202+
brect[3] = y - gdroundupdown(brect[3], d2 > 0);
1203+
brect[4] = x + gdroundupdown(brect[4], d2 < 0);
1204+
brect[5] = y - gdroundupdown(brect[5], d1 > 0);
1205+
brect[6] = x + gdroundupdown(brect[6], d1 < 0);
1206+
brect[7] = y - gdroundupdown(brect[7], d2 < 0);
12021207
}
12031208

12041209
if (tmpstr) {

‎ext/gd/tests/bug43073_1.phpt

+18-16
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ $delta_t = 360.0 / 16; # Make 16 steps around
1616
$g = imagecreate(800, 800);
1717
$bgnd = imagecolorallocate($g, 255, 255, 255);
1818
$black = imagecolorallocate($g, 0, 0, 0);
19+
$red = imagecolorallocate($g, 255, 0, 0);
1920
$x = 100;
2021
$y = 0;
2122
$cos_t = cos(deg2rad($delta_t));
2223
$sin_t = sin(deg2rad($delta_t));
2324
for ($angle = 0.0; $angle < 360.0; $angle += $delta_t) {
2425
$bbox = imagettftext($g, 24, $angle, 400+$x, 400+$y, $black, $font, 'ABCDEF');
26+
imagepolygon($g, $bbox, 4, $red);
2527
$s = vsprintf("(%d, %d), (%d, %d), (%d, %d), (%d, %d)\n", $bbox);
2628
echo $s;
2729
$temp = $cos_t * $x + $sin_t * $y;
@@ -33,19 +35,19 @@ imagepng($g, "$cwd/bug43073.png");
3335
--CLEAN--
3436
<?php @unlink(dirname(__FILE__) . '/bug43073.png'); ?>
3537
--EXPECTF--
36-
(500, 400), (610, 400), (610, 376), (500, 376)
37-
(492, 363), (591, 322), (580, 295), (480, 336)
38-
(470, 331), (548, 254), (527, 233), (449, 310)
39-
(439, 309), (483, 202), (461, 193), (416, 299)
40-
(400, 300), (400, 183), (380, 183), (380, 300)
41-
(362, 307), (316, 195), (291, 205), (337, 318)
42-
(330, 329), (246, 244), (224, 265), (308, 350)
43-
(308, 360), (202, 316), (190, 344), (296, 388)
44-
(300, 400), (187, 400), (187, 425), (300, 425)
45-
(306, 437), (195, 483), (206, 510), (318, 464)
46-
(328, 469), (240, 557), (260, 578), (349, 491)
47-
(359, 491), (312, 607), (334, 616), (382, 501)
48-
(400, 500), (400, 618), (419, 618), (419, 500)
49-
(436, 493), (483, 607), (507, 597), (461, 482)
50-
(468, 471), (555, 558), (577, 538), (490, 450)
51-
(490, 440), (600, 485), (611, 457), (502, 412)
38+
(501, 400), (611, 400), (611, 376), (501, 376)
39+
(492, 361), (595, 319), (586, 296), (483, 338)
40+
(470, 329), (549, 251), (531, 233), (453, 312)
41+
(439, 307), (481, 204), (458, 195), (416, 297)
42+
(400, 299), (400, 189), (376, 189), (376, 299)
43+
(361, 307), (319, 204), (296, 213), (338, 316)
44+
(329, 329), (251, 250), (233, 267), (311, 346)
45+
(307, 360), (204, 318), (195, 341), (297, 383)
46+
(299, 400), (189, 400), (189, 424), (299, 424)
47+
(307, 438), (204, 480), (213, 503), (316, 461)
48+
(329, 470), (250, 548), (267, 566), (346, 488)
49+
(360, 492), (318, 595), (341, 604), (383, 502)
50+
(400, 501), (400, 611), (424, 611), (424, 501)
51+
(438, 492), (480, 595), (503, 586), (461, 483)
52+
(470, 470), (548, 549), (566, 532), (488, 453)
53+
(492, 439), (595, 481), (604, 458), (502, 416)

‎ext/gd/tests/bug48732.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ echo 'Left Bottom: (' . $bbox[0] . ', ' . $bbox[1] . ')';
1919
--CLEAN--
2020
<?php @unlink(dirname(__FILE__) . '/bug48732.png'); ?>
2121
--EXPECTF--
22-
Left Bottom: (0, 47)
22+
Left Bottom: (0, 46)

‎ext/gd/tests/bug48801_1.phpt

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ echo '(' . $bbox[4] . ', ' . $bbox[5] . ")\n";
1919
echo '(' . $bbox[6] . ', ' . $bbox[7] . ")\n";
2020
?>
2121
--EXPECTF--
22-
(-1, 15)
23-
(15%d, 15)
24-
(15%d, -48)
25-
(-1, -48)
22+
(4, 15)
23+
(161, 15)
24+
(161, -47)
25+
(4, -47)

‎ext/gd/tests/bug53504.phpt

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
--TEST--
2+
Bug #53504 imagettfbbox/imageftbbox gives incorrect values for bounding box
3+
--SKIPIF--
4+
<?php
5+
if(!extension_loaded('gd')){ die('skip gd extension not available'); }
6+
if(!function_exists('imageftbbox')) die('skip imageftbbox() not available');
7+
8+
include dirname(__FILE__) . '/func.inc';
9+
if(version_compare(get_freetype_version(), '2.4.10') == -1) die('skip for freetype < 2.4.10');
10+
?>
11+
--FILE--
12+
<?php
13+
$cwd = dirname(__FILE__);
14+
$font = "$cwd/Tuffy.ttf";
15+
16+
$g = imagecreate(800, 800);
17+
$bgnd = imagecolorallocate($g, 255, 255, 255);
18+
$black = imagecolorallocate($g, 0, 0, 0);
19+
$red = imagecolorallocate($g, 255, 0, 0);
20+
$blue = imagecolorallocate($g, 0, 0, 255);
21+
22+
$tests = [
23+
// Kerning examples (unfortunately not available in "Tuffy" test font):
24+
['fontSize' => 50, 'angle' => 0, 'x' => 20, 'y' => 70, 'text' => 'AV Teg'],
25+
['fontSize' => 50, 'angle' => 90, 'x' => 70, 'y' => 350, 'text' => 'AV Teg'],
26+
['fontSize' => 50, 'angle' => 40, 'x' => 130, 'y' => 280, 'text' => 'AV Teg'],
27+
28+
// Shift-Test:
29+
['fontSize' => 100, 'angle' => 0, 'x' => 350, 'y' => 110, 'text' => 'H-Shift'],
30+
31+
// Small/single chars:
32+
['fontSize' => 100, 'angle' => 0, 'x' => 350, 'y' => 220, 'text' => '-'],
33+
['fontSize' => 100, 'angle' => 0, 'x' => 430, 'y' => 220, 'text' => ','],
34+
['fontSize' => 100, 'angle' => 0, 'x' => 510, 'y' => 220, 'text' => '.'],
35+
['fontSize' => 100, 'angle' => 0, 'x' => 590, 'y' => 220, 'text' => '|'],
36+
['fontSize' => 100, 'angle' => 0, 'x' => 670, 'y' => 220, 'text' => 'g'],
37+
38+
// Multi-Line + rotation:
39+
['fontSize' => 30, 'angle' => 0, 'x' => 20, 'y' => 400, 'text' => "Multi\nLine\nTest"],
40+
['fontSize' => 30, 'angle' => 40, 'x' => 150, 'y' => 420, 'text' => "Multi\nLine\nTest"],
41+
['fontSize' => 30, 'angle' => 90, 'x' => 250, 'y' => 340, 'text' => "Multi\nLine\nTest"],
42+
43+
// Some edge case glyphs:
44+
['fontSize' => 50, 'angle' => 90, 'x' => 70, 'y' => 750, 'text' => "iiiiiiiiiiii"],
45+
['fontSize' => 50, 'angle' => 90, 'x' => 150, 'y' => 750, 'text' => "~~~~~~~"],
46+
['fontSize' => 50, 'angle' => 50, 'x' => 210, 'y' => 750, 'text' => "iiiiiiiiiiii"],
47+
['fontSize' => 50, 'angle' => 50, 'x' => 300, 'y' => 750, 'text' => "~~~~~~~"],
48+
['fontSize' => 50, 'angle' => 0, 'x' => 430, 'y' => 650, 'text' => "iiiiiiiiiiii"],
49+
['fontSize' => 50, 'angle' => 0, 'x' => 430, 'y' => 750, 'text' => "~~~~~~~"],
50+
51+
// "Big" test:
52+
['fontSize' => 200, 'angle' => 0, 'x' => 400, 'y' => 500, 'text' => "Big"],
53+
];
54+
55+
foreach ($tests as $test) {
56+
$bbox = imageftbbox($test['fontSize'], $test['angle'], $font, $test['text']);
57+
vprintf("(%d, %d), (%d, %d), (%d, %d), (%d, %d)\n", $bbox);
58+
59+
$bboxDrawn = imagefttext($g, $test['fontSize'], $test['angle'],
60+
$test['x'], $test['y'], $black, $font, $test['text']);
61+
62+
// check if both bboxes match when adding x/y offset:
63+
for ($i = 0; $i < count($bbox); $i += 2) {
64+
if ($bbox[$i] + $test['x'] !== $bboxDrawn[$i]) echo "imageftbbox and imagefttext differ!\n";
65+
if ($bbox[$i + 1] + $test['y'] !== $bboxDrawn[$i + 1]) echo "imageftbbox and imagefttext differ!\n";
66+
}
67+
68+
// draw bounding box:
69+
imagepolygon($g, $bboxDrawn, 4, $red);
70+
71+
// draw baseline:
72+
$width = sqrt(pow($bboxDrawn[2] - $bboxDrawn[0], 2) + pow($bboxDrawn[3] - $bboxDrawn[1], 2));
73+
imageline($g, $test['x'], $test['y'],
74+
$test['x'] + $width * cos(deg2rad($test['angle'])),
75+
$test['y'] - $width * sin(deg2rad($test['angle'])), $blue);
76+
}
77+
78+
imagepng($g, "$cwd/bug53504.png");
79+
?>
80+
--CLEAN--
81+
<?php @unlink(dirname(__FILE__) . '/bug53504.png'); ?>
82+
--EXPECTF--
83+
(2, 15), (208, 15), (208, -48), (2, -48)
84+
(15, -1), (15, -208), (-48, -208), (-48, -2)
85+
(11, 11), (169, -122), (129, -171), (-30, -39)
86+
(8, 2), (385, 2), (385, -97), (8, -97)
87+
(7, -37), (51, -37), (51, -46), (7, -46)
88+
(7, 15), (21, 15), (21, -13), (7, -13)
89+
(7, 1), (21, 1), (21, -13), (7, -13)
90+
(8, 0), (17, 0), (17, -95), (8, -95)
91+
(5, 29), (60, 29), (60, -72), (5, -72)
92+
(2, 107), (80, 107), (80, -29), (2, -29)
93+
(70, 81), (131, 31), (43, -74), (-18, -24)
94+
(107, -1), (107, -80), (-29, -80), (-29, -2)
95+
(0, -4), (0, -165), (-47, -165), (-47, -4)
96+
(-19, -2), (-18, -167), (-29, -167), (-29, -2)
97+
(3, -3), (107, -127), (70, -157), (-34, -33)
98+
(-13, -13), (93, -141), (85, -147), (-21, -20)
99+
(4, 0), (165, 0), (165, -47), (4, -47)
100+
(2, -19), (167, -19), (167, -29), (2, -29)
101+
(16, 59), (330, 59), (330, -190), (16, -190)

0 commit comments

Comments
 (0)
Please sign in to comment.