Writing Hindi Fonts with GD Library do not render as desired
Asked Answered
A

3

3

If I want to write the following text on the image:

दीक्षा शिक्षा क्या क्या हो गया!

Then it does not not give the expected result but instead is printing out text on the picture as below. I have tried almost all the devanagari ttf and unicode fonts available for Hindi.

Hindi TExt

Here is the code:

$quote="दीक्षा शिक्षा क्या क्या हो गया!";
imagettftext($new_pic, $fontsize, 0, 170, 155-$hidd/2, $color, $font, $quote);

Any help will be very much appreciated.

Arana answered 17/1, 2014 at 14:20 Comment(6)
What is the desired way? To me (as a non-Hindu speaker), the text in the picture looks the same as the written text (I only see more accents (?) in the picture below the क् character, but that seems to be the intention).Vic
Hi, Many thanks for your response. The problem is that it is not supposed to be as it is coming. I have tried many ttf unicode fonts and all are giving same problems.Arana
To any one who knows Hindi. The text printed out on picture is wrong. RegardsArana
In addition to the present UTF-8, I have tried out UTF-16, UTF-32 without any success. The string prints fine on the document, but when it is sent to the imagettfext function, the output is garbled.Arana
so did you find any solution ??Preexist
Any solution working for u so far ?Grados
H
3

I had the same problem and came up with a solution in PHP using the mangal.ttf font. using this code your Hindi text will display correctly on your image file.

 $text = "की एक विधा" ; 
 $words = explode(" ", $text);        
for($k = 0; $k < count($words); $k++){

    // detect if the string was passed in as unicode
    $text_encoding = mb_detect_encoding($words[$k], 'UTF-8, ISO-8859-1');

    // make sure it's in unicode
    if ($text_encoding != 'UTF-8') {
        $words[$k] = mb_convert_encoding($words[$k], 'UTF-8', $text_encoding);
        }
 // html numerically-escape everything (&#[dec];)
    $words[$k] = mb_encode_numericentity($words[$k], array (0x0, 0xffff, 0, 0xffff), 'UTF-8');

    $arr = explode("&#", $words[$k]);
for ($i = 0; $i < (count($arr)-1); $i++){

        // interchange the order of "i" vowel
          if($arr[$i] == "2367;") {
            $arr[$i] = $arr[$i-1] . '';
            $arr[$i-1] = "2367;";
            }

        // letter "I" + Nukta forms letter vocalic "L"
          if($arr[$i] == "2311;") {
            if($arr[$i+1] == "2364;") {
                $arr[$i] = "2316;";
                $arr[$i+1] = '';
                }
            }

        // vowel sign vocalic "R" + sign Nukta forms vowel sign vocalic "Rr"
          if($arr[$i] == "2371;") {
              if($arr[$i+1] == "2364;") {
                $arr[$i] = "2372;";
                $arr[$i+1] = '';
                }
            }

        // Candrabindu + sign Nukta forms Om
          if($arr[$i] == "2305;") {
              if($arr[$i+1] == "2364;") {
                $arr[$i] = "2384;";
                $arr[$i+1] = '';
                }
            }

        // letter vocalic "R" + sign Nukta forms letter vocalic "Rr"
          if($arr[$i] == "2315;") {
              if($arr[$i+1] == "2364;") {
                $arr[$i] = "2400;";
                $arr[$i+1] = '';
                }
            }

        // letter "Ii" + sign Nukta forms letter vocalic "LI"
          if($arr[$i] == "2312;") {
              if($arr[$i+1] == "2364;") {
                $arr[$i] = "2401;";
                $arr[$i+1] = '';
                }
            }

        // vowel sign "I" + sign Nukta forms vowel sign vocalic "L"
          if($arr[$i] == "2367;") {
              if($arr[$i+1] == "2364;") {
                $arr[$i] = "2402;";
                $arr[$i+1] = '';
                }
            }

        // vowel sign "Ii" + sign Nukta forms vowel sign vocalic "LI"
          if($arr[$i] == "2368;") {
              if($arr[$i+1] == "2364;") {
                $arr[$i] = "2403;";
                $arr[$i+1] = '';
                }
            }

        // Danda + sign Nukta forms sign Avagraha
          if($arr[$i] == "2404;") {
              if($arr[$i+1] == "2364;") {
                $arr[$i] = "2365;";
                $arr[$i+1] = '';
                }
            }

        // consonant + Halant + Halant + consonant forms consonant + Halant + ZWNJ + consonant
          if($arr[$i] == "2381;") {
              if($arr[$i+1] == "2381;") {
              //$arr[$i+1] = '8204;';
                }
            }

        // consonant + Halant + Nukta + consonant forms consonant + Halant + ZWJ + Consonant
          if($arr[$i] == "2364;") {
              if($arr[$i+1] == "2381;") {
              //$arr[$i] = "2381;";
              //$arr[$i+1] = '8205;';
                }
            }

        }

    $words[$k] = implode('&#',$arr);
    }
$text = implode(" ", $words);

    $img_name = date('dmyhms');
    $image = $img_name.'.png';
    if(file_exists($imagefile)){    

            /*** create image ***/
             $im = @imagecreatefrompng($imagefile);
            /*** create the text color ***/
            $text_color = imagecolorallocate($im, 40, 50, 99);
           /***  set the font file ***/
            $font_file = 'mangal.ttf';
            // Convert HTML entities into ISO-8859-1
           // $text = html_entity_decode($text,ENT_QUOTES, "UTF-8");
            /*** splatter the image with text ***/
             imagefttext($im, 14,0,450, 390, $text_color, $font_file, $text);
            // Save the picture
             imagepng($im,$image);
            }else{
            /*** if the file does not exist we will create our own image ***/
            /*** Create a black image ***/
            $im  = imagecreatetruecolor(150, 30); /* Create a black image */
            /*** the background color ***/
            $bgc = imagecolorallocate($im, 255, 255, 255);
            /*** the text color ***/
            $tc  = imagecolorallocate($im, 0, 0, 0);
            /*** a little rectangle ***/
            imagefilledrectangle($im, 0, 0, 150, 30, $bgc);
            /*** output and error message ***/
            imagestring($im, 1, 5, 5, "Error loading $imagefile", $tc);
        }
Herrmann answered 1/2, 2017 at 10:4 Comment(3)
Do u happen to have a C# version ?Grados
This is a great solution. However, it hasn't covered नुक्ता yet. It prints out नुक ् ता. Any suggestions?Nicotiana
More on that: अख्तियार is not displayed correctly.Nicotiana
H
0

Please check my project for devanagari font rendering in Unity3d using Krutidev font. It is working for me in one of our internal projects. The example project is at this link. The idea is to convert the unicode to Krutidev and use the krutidev font.

Henley answered 15/3, 2018 at 18:27 Comment(0)
H
-2

I am not well versed in Hindi but I think the GD library you are using is not using the rules about Hindi language that changes the order in which glyphs are displayed. I don't know what these rules are, but guess they are encoded in the font's GSUB or GPOS tables. GSUB controls the way sequences of glyphs are displayed and GPOS controls the spacing of glyphs. I assume GD library does not process the GPOS or GSUB tables, which is why the order of your string in imagettfext is the order of the glyphs in the string. You may need to implement some string munging code in your script that takes strings, and orders the characters correctly knowing that GD Library will display them in the order they are in the string.

Please use the code below for the following hindi rule

string changeHindiGlyph(string originalText)
{
    string[] words = originalText.Split(new char[]{' '});

    for(int k = 0; k < words.Length; k++)
    {
        if(words[k].Contains("\u093f")) // check if the word contains "i" vowel
        {
            char[] arr = words[k].ToCharArray();
            for (int i = 0; i < arr.Length -1 ; i++)
            {
                //interchange the order of "i" vowel
                if(arr[i] == '\u093f')
                {
                    arr[i] = arr[i-1];
                    arr[i-1] = '\u093f';
                }
            }

            words[k] = new string(arr);
        }
    }

    originalText = string.Join(" ", words);

    return originalText;
}

I have used C# in the above code you can convert it to your scripting language. Similarly you can include more rules in the code so that you get the desired text in the GD library. Hope this solves your problem.

Henley answered 16/12, 2014 at 10:11 Comment(2)
It fixes u093f only which is working well but how r u fixing rest like Half form substitution & other features like in these 2 words : प्रस्थान शर्तGrados
@SourabhV just see swapnil jain's code and convert it to C#.Henley

© 2022 - 2024 — McMap. All rights reserved.