Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I deal with characters unsupported by the font file when using imagettftext()?

I use Verdana font inside my images created by PHP GD library.

imagettftext($image, $fontSize, 0, 70, $y, $color, $font, $username );

Most of the cases imagettftext works very well for strings.
But some of my users use weird characters/symbols inside their names.
So when I try to print their names to images. For example:
enter image description here

This user uses ɦɪɲɣƙƨєʌɾ symbols. So Verdana can't print them.

I used this:

$username=iconv('UTF-8', 'ASCII//TRANSLIT', $username);

Output is this:
enter image description here

(Current locale changes between English and Deutsch. So maybe current locale can't handle these characters: ɦɪɲɣƙƨєʌɾ)

It seems like it's not possible to transliterate ɦ to h, ɲ to n without writing a very big str_replace() block. Like this.

  • So I wonder whether is it possible to check whether the font (Verdana) can show these symbols. If one of the character can't be shown inside string, so I can pass an empty string to imagettftext method. Can I check the supported characters inside font ? Or create a character map that includes Verdana supported symbols, and check whether my string includes non-supported symbols ?
    (I think it is not possible due to this question)

  • Or maybe another solution, is it possible to use multiple fonts in imagettftext() ?
    For example first try Verdana, if Verdana doesn't cover that symbols use Arial sans serif etc.

  • Or any other solution ?

Edit:
It seems like Verdana doesn't support these unicode characters in my text.
Verdana supported characters: http://www.fileformat.info/info/unicode/font/verdana/grid.htm
Verdana unspported characters: http://www.fileformat.info/info/unicode/font/verdana/missing.htm

like image 848
trante Avatar asked Mar 08 '14 16:03

trante


People also ask

Why is my file format unsupported?

Another cause for unsupported file format is the storage issue. There are times when the memory is full, and this might cause the files not to be loaded (although this is a rare case). Sometimes having the file in the storage itself causes the file to be broken, resulting in the unsupported format. 3. Sudden shutdown of device

Are embedded fonts allowed in PowerPoint V16 on the Mac?

Since I'm using Powerpoint v16 on the Mac, embedded fonts are not allowed. I have tried opening the file as text and searching for the fonts, but that didn't work, nor did substituting the font globally. I do not need a particular font, I just need to edit and save my presentation. Any suggestions for a fix? This thread is locked.

Can I use TTF fonts with Egnyte?

These fonts can be converted to TTF fonts for greater compatibility with Egnyte and other applications. Egnyte supports relative links, but when migrating to Egnyte, things can get tricky. Talk to our PS team to find the best solution for migration.

How do I change the font of a chart title?

First, click on the chart to select it, then set a new font for it. Then click the chart's title and set a new font for it. Try saving the file again.


Video Answer


2 Answers

My first choice would be switching to a font that supports the full range of characters that you want to be able to handle. But do not expect a single font will ever implement the million-or-so possible characters in UTF-8.

Now, if you want to take the (lazy ;) transliteration route, I will refer to this answer from Kemal Dağ:

  • PHP >= 5.4 : use the new built-in Transliterator class
  • PHP < 5.4 : use his excellent port

I don't have a v5.4 on hand right now so I cannot tell about Transliterator, but Kemal Dağ's port of JTransliteration performs pretty well:

<?php
    require 'transliteration/JTransliteration.php';

    $input = 'ɦɪɲɣƙƨєʌɾ';
    echo JTransliteration::transliterate($input); // output: hIngk2ie^r

    $input = 'Хეλлఒ Wओრলद';
    echo JTransliteration::transliterate($input);

Finally, if you want to check wether a given font supports a given character, it gets a bit more hairy. This library will help a lot. It requires >= 5.3 (use of namespaces):

<?php
    $fontFile = 'arial.ttf';
    $charToCheck = 'ɣ';

    require_once 'php-font-lib-master/src/FontLib/Autoloader.php';

    use FontLib\Font;
    use FontLib\TrueType\Collection;


    $font = Font::load($fontFile);
    if ($font instanceof Collection) {
        $font = $font->getFont(0);
    }
    $subtable = null;
    foreach($font->getData("cmap", "subtables") as $_subtable) {
        if ($_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) {
            $subtable = $_subtable;
            break;
        }
    }

    if (isset($subtable["glyphIndexArray"][ord_utf8($charToCheck)])) {
        $supported = 'Supported';
    } else {
        $supported = 'Not Supported';
    }

    echo "$charToCheck is $supported by font $fontFile";


    function ord_utf8($c) {
        $b0 = ord($c[0]);
        if ( $b0 < 0x10 ) {
            return $b0;
        }
        $b1 = ord($c[1]);
        if ( $b0 < 0xE0 ) {
            return (($b0 & 0x1F) << 6) + ($b1 & 0x3F);
        }
        return (($b0 & 0x0F) << 12) + (($b1 & 0x3F) << 6) + (ord($c[2]) & 0x3F);
    }

shamelessly pillaging code from font_info.php and R. Hill's ord_utf8()

P.S. The string "ɦɪɲɣƙƨєʌɾ" is made of characters from the International Phonetic Alphabet. I am not sure any locale supports these characters (since there is no practical need for it, as they are not used by any real human language).

like image 56
RandomSeed Avatar answered Sep 30 '22 15:09

RandomSeed


As long as you're using UTF-8, there is no reason for UTF-8 True Type font to show those letters (disclaimer for east-asian letters!)

Here my simple example, with a true type font:

// utf-8 text
$text   = 'ɦɪɲɣƙƨєʌɾ';

// if text read from a file (for example)
// and the default locale (for most of western countries)
// is ISO-8859-1, you can simly convert it to
// utf-8 using:

//$text = utf8_encode($text);

$png    = imagecreatefrompng('/tmp/sample.png');
$color  = imagecolorallocate($png, 0, 0, 0);

// True type font that support UTF-8!!!!
$font   = '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf';

imagettftext($png, 50, 0, 50, 50, $color, $font, $text);
imagepng($png, '/tmp/test.png');

And the results:

enter image description here

like image 40
Ziv Avatar answered Sep 30 '22 13:09

Ziv