php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51135 imagettftext does not work for characters > 99999
Submitted: 2010-02-24 20:54 UTC Modified: 2017-08-16 16:28 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: sharon_correll at sil dot org Assigned:
Status: Suspended Package: GD related
PHP Version: 5.2.12 OS: Windows Vista
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2010-02-24 20:54 UTC] sharon_correll at sil dot org
Description:
------------
The imagettftext function doesn't not work for characters > 99999. For instance, U+1869F (99999) produces a null glyph for the font that I am using, but U+186A0 (100000) produces "𘚠".

(I am actually using PHP version 5.2.6. Please tell me if upgrading is likely to fix this problem.)

Reproduce code:
---------------
$point_size = 32;
$scratch_image = ImageCreateTrueColor(
        $point_size*10, $point_size*10);
$origin_x = 2 * $point_size;
$origin_y = 5 * $point_size;
$white = ImageColorAllocate($scratch_image, 255, 255, 255);
$black = ImageColorAllocate($scratch_image, 0, 0, 0);
ImageFill( $scratch_image, 0, 0, $white );
$glyph_text = "𘚠";

// FILL IN THE FONT NAME WITH SOME FONT THAT YOU HAVE AVAILABLE:
$box = imagettftext( $scratch_image, $point_size, 0, 
         $origin_x, $origin_y, $black,
         "FONT.TTF, $glyph_text );

$final_image = imagecreatetruecolor( 300, 200 );
ImageFill( $final_image, 0, 0, $white );
imagecopymerge( $final_image, $scratch_image, 0, 0, $box[6], $box[7],
        300, 200, 100 );
imagecolortransparent( $final_image, $white );
imagedestroy( $scratch_image ); 
imagepng( $final_image, "testbug.png" );

Expected result:
----------------
I expect the "testbug.png" file to show a "null" glyph (assuming the font doesn't have a glyph for U+186A0--I am using Code 2000 which has a wide range of Unicode characters, but not U+186A0.)

Actual result:
--------------
I see "𘚠" instead of the glyph.

Patches

bundled-libgd-non-bmp-entities (last revision 2010-03-05 16:24 UTC by aharvey@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-02-24 22:19 UTC] pajoye@php.net
Please try using this snapshot:

  http://snaps.php.net/php5.3-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2010-02-24 22:19 UTC] pajoye@php.net
or 5.3.3RC2 (http://windows.php.net/qa/)
 [2010-03-05 06:01 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Open". Thank you.
 [2010-03-05 06:38 UTC] aharvey@php.net
-Status: No Feedback +Status: Bogus
 [2010-03-05 06:38 UTC] aharvey@php.net
This is still happening in PHP_5_3, but it's not a PHP bug as such: it's a bug in 
libgd itself. There's already an open bug in the libgd issue tracker covering 
this issue, which still exists in the current HEAD of libgd:

http://bugs.libgd.org/?do=details&task_id=42
 [2010-03-05 15:45 UTC] sharon_correll at sil dot org
Thank you for the information; it's helpful to know the status.
 [2010-03-05 15:55 UTC] pajoye@php.net
-Status: Bogus +Status: Assigned
 [2010-03-05 15:55 UTC] pajoye@php.net
aharvey@php.net:

Not if the bundled is used. Which is the case on windows.

Tabe, can you verify this issue please?
 [2010-03-05 17:23 UTC] aharvey@php.net
This is still happening with an up-to-date PHP_5_3 SVN checkout using the bundled libgd. I've only tested it on Linux, but the relevant code in libgd/gdft.c doesn't appear to be platform specific.

It's exactly what the libgd bug indicates: gdTcl_UtfToUniChar() simply stops looking for the end of a numeric or hexadecimal entity reference two characters earlier than it should to cover all possible Unicode characters out to Plane 16. The patch for libgd is trivial, and I'll attach it after I post this comment.

I've created a tarball containing a test script, a font containing Plane 1 characters (which is valid, and does work to render characters in Plane 1 blocks in desktop applications), PNG images showing PHP and libgd's behaviour before and after the patch, and a mockup rendering showing roughly what this is actually meant to look like, which you can get from:
http://www.adamharvey.name/stuff/bug51135.tar.bz2

Note that the attached patch isn't actually the whole solution, as is clear if you compare with-patch.png to the mockup. It does make gdTcl_UtfToUniChar() decode the entities, but there are evidently other issues that prevent non-BMP characters from actually being rendered properly, as libgd bug 42 notes.
 [2010-03-05 17:24 UTC] aharvey@php.net
The following patch has been added/updated:

Patch Name: bundled-libgd-non-bmp-entities
Revision:   1267806282
URL:        http://bugs.php.net/patch-display.php?bug=51135&patch=bundled-libgd-non-bmp-entities&revision=1267806282&display=1
 [2010-11-04 00:11 UTC] sharon_correll at sil dot org
The responses to this report seem to imply that ImageTtfText WIIL work correctly for characters in the range U+10000 - U+1869F (65536 - 99999). However, this does not seem to be the case. When I call it with "𐀁" (U+10001), it produces an "missing" glyph, even using a font that contains the character (CODE2001.ttf).

This is a slightly different bug than what I originally reported, but I would guess it is related. Is it a known problem?
 [2016-08-22 14:32 UTC] cmb@php.net
-Status: Assigned +Status: Suspended -Assigned To: tabe +Assigned To: cmb
 [2016-08-22 14:32 UTC] cmb@php.net
Thanks for the analysis, the patch and the archive, Adam!

I can confirm that the patch correctly solves the issues with
decoding large numeric entities.

The non BMP characters are not rendered, because
FT_Get_Char_Index() returns 0, what corresponds to the missing
glyph. That is because the font file contains 4 charmaps, but GD
currently always uses the first charmap, and the non BMP
characters are contained in charmap 3. Switching to charmap 3 via
FT_Set_Charmap() delivers the same result as mockup.png.

I'll have to investigate on how to dynamically select the
appropriate charmap.

Anyhow, this is actually a libgd issue, and so I'm suspending this
ticket until <https://github.com/libgd/libgd/issues/185> is
resolved.
 [2017-08-16 16:28 UTC] cmb@php.net
-Assigned To: cmb +Assigned To:
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Dec 02 04:01:24 2020 UTC