Writing Hindi Fonts with GD Library do not render as desired

前端 未结 3 673
轻奢々
轻奢々 2020-12-16 08:31

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

相关标签:
3条回答
  • 2020-12-16 08:55

    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);
            }
    
    0 讨论(0)
  • 2020-12-16 08:55

    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.

    0 讨论(0)
  • 2020-12-16 08:56

    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.

    0 讨论(0)
提交回复
热议问题