title: Generate character images with a font whose name cannot be correctly decoded
body: <p>I am creating images of Chinese <a href="http://en.wikipedia.org/wiki/Seal_script" rel="noreferrer">seal script</a>. I have three true type fonts for this task (<a href="https://dl.dropboxusercontent.com/u/1335302/Jin_Wen_Da_Zhuan_Ti.7z" rel="noreferrer">Jin_Wen_Da_Zhuan_Ti.7z</a>, <a href="https://dl.dropboxusercontent.com/u/1335302/Zhong_Guo_Long_Jin_Shi_Zhuan.7z" rel="noreferrer">Zhong_Guo_Long_Jin_Shi_Zhuan.7z</a>, <a href="https://dl.dropboxusercontent.com/u/1335302/Zhong_Yan_Yuan_Jin_Wen.7z" rel="noreferrer">Zhong_Yan_Yuan_Jin_Wen.7z</a>, for testing purpose only). Below are the appearances in Microsoft Word</p>
  
  <p><img src="https://i.stack.imgur.com/6gR1s.png" alt="appearance in Word"></p>
  
  <p>of the Chinese character "我" (I/me). Here is my Python script:</p>
  
  <pre><code>import numpy as np
  from PIL import Image, ImageFont, ImageDraw, ImageChops
  import itertools
  import os
  
  
  def grey2binary(grey, white_value=1):
      grey[np.where(grey &lt;= 127)] = 0
      grey[np.where(grey &gt; 127)] = white_value
      return grey
  
  
  def create_testing_images(characters,
                            font_path,
                            save_to_folder,
                            sub_folder=None,
                            image_size=64):
      font_size = image_size * 2
      if sub_folder is None:
          sub_folder = os.path.split(font_path)[-1]
          sub_folder = os.path.splitext(sub_folder)[0]
      sub_folder_full = os.path.join(save_to_folder, sub_folder)
      if not os.path.exists(sub_folder_full):
          os.mkdir(sub_folder_full)
      font = ImageFont.truetype(font_path,font_size)
      bg = Image.new('L',(font_size,font_size),'white')
  
      for char in characters:
          img = Image.new('L',(font_size,font_size),'white')
          draw = ImageDraw.Draw(img)
          draw.text((0,0), text=char, font=font)
          diff = ImageChops.difference(img, bg)
          bbox = diff.getbbox()
          if bbox:
              img = img.crop(bbox)
              img = img.resize((image_size, image_size), resample=Image.BILINEAR)
  
              img_array = np.array(img)
              img_array = grey2binary(img_array, white_value=255)
  
              edge_top = img_array[0, range(image_size)]
              edge_left = img_array[range(image_size), 0]
              edge_bottom = img_array[image_size - 1, range(image_size)]
              edge_right = img_array[range(image_size), image_size - 1]
  
              criterion = sum(itertools.chain(edge_top, edge_left, 
                                             edge_bottom, edge_right))
  
              if criteria &gt; 255 * image_size * 2:
                  img = Image.fromarray(np.uint8(img_array))
                  img.save(os.path.join(sub_folder_full, char) + '.gif')
  </code></pre>
  
  <p>where the core snippet is </p>
  
  <pre><code>        font = ImageFont.truetype(font_path,font_size)
          img = Image.new('L',(font_size,font_size),'white')
          draw = ImageDraw.Draw(img)
          draw.text((0,0), text=char, font=font)
  </code></pre>
  
  <p>For example, if you put those fonts in the folder <code>./fonts</code>, and call it with</p>
  
  <pre><code>create_testing_images(['我'], 'fonts/金文大篆体.ttf', save_to_folder='test')
  </code></pre>
  
  <p>the script will create <code>./test/金文大篆体/我.gif</code> in your file system.</p>
  
  <p>Now the problem is, though it works well with the first font 金文大篆体.ttf (in Jin_Wen_Da_Zhuan_Ti.7z), the script does not work on the other two fonts, even if they can be rendered correctly in Microsoft Word: for 中國龍金石篆.ttf (in Zhong_Guo_Long_Jin_Shi_Zhuan.7z), it draws nothing so <code>bbox</code> will be <code>None</code>; for 中研院金文.ttf (in Zhong_Yan_Yuan_Jin_Wen.7z), it will draw a black frame with no character in the picture.</p>
  
  <p><img src="https://i.stack.imgur.com/HU5x8.png" alt="enter image description here"></p>
  
  <p>and thus fails to pass the test of <code>criterion</code>, whose purpose is for testing an all-black output. I used <a href="http://fontforge.org/" rel="noreferrer">FontForge</a> to check the properties of the fonts, and found that the first font 金文大篆体.ttf (in Jin_Wen_Da_Zhuan_Ti.7z) uses UnicodeBmp</p>
  
  <p><img src="https://i.stack.imgur.com/2upCF.png" alt="UnicodeBmp"></p>
  
  <p>while the other two use Big5hkscs</p>
  
  <p><img src="https://i.stack.imgur.com/51wWJ.png" alt="Big5hkscs_中國龍金石篆">
  <img src="https://i.stack.imgur.com/bkRtF.png" alt="中研院金文"></p>
  
  <p>which is not the encoding scheme of my system. This may be the reason that the font names are unrecognizable in my system:</p>
  
  <p><img src="https://i.stack.imgur.com/gqwQ8.png" alt="font viewer"></p>
  
  <p>Actually I also try to solve this by trying to get the font with the messy font name. I tried <code>pycairo</code> after installing those fonts:</p>
  
  <pre><code>import cairo
  
  # adapted from
  # http://heuristically.wordpress.com/2011/01/31/pycairo-hello-world/
  
  # setup a place to draw
  surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 100, 100)
  ctx = cairo.Context (surface)
  
  # paint background
  ctx.set_source_rgb(1, 1, 1)
  ctx.rectangle(0, 0, 100, 100)
  ctx.fill()
  
  # draw text
  ctx.select_font_face('金文大篆体')
  ctx.set_font_size(80)
  ctx.move_to(12,80)
  ctx.set_source_rgb(0, 0, 0)
  ctx.show_text('我')
  
  # finish up
  ctx.stroke() # commit to surface
  surface.write_to_png('我.gif')
  </code></pre>
  
  <p>This works well again with 金文大篆体.ttf (in Jin_Wen_Da_Zhuan_Ti.7z):</p>
  
  <p><img src="https://i.stack.imgur.com/RIwku.png" alt="enter image description here"></p>
  
  <p>but still not with others. For example: neither <code>ctx.select_font_face('中國龍金石篆')</code> (which reports <code>_cairo_win32_scaled_font_ucs4_to_index:GetGlyphIndicesW</code>) nor <code>ctx.select_font_face('¤¤°êÀsª÷¥Û½f')</code> (which draws with the default font) works. (The latter name is the messy code displayed in the font viewer as shown above, obtained by a line of Mathematica code <code>ToCharacterCode["中國龍金石篆", "CP950"] // FromCharacterCode</code> where <code>CP950</code> is the code page of Big5.)</p>
  
  <p>So I think I've tried my best to tackle this issue, but still cannot solve it. I've also come up with other ways like renaming the font name with FontForge or changing the system encoding to Big5, but I would still prefer a solution that involves Python only and thus needs less additional actions from the user. Any hints will be greatly appreciated. Thank you.</p>
  
  <p><strong>To the moderators of stackoverflow</strong>: this problem may seem "too localized" at its first glance, but it could happen in other languages / other encodings / other fonts, and the solution can be generalized to other cases, so please don't close it with this reason. Thank you.</p>
  
  <p><strong>UPDATE</strong>: Weirdly Mathematica can recognize the font name in CP936 (GBK, which can be thought of as my system encoding). Take 中國龍金石篆.ttf (in Zhong_Guo_Long_Jin_Shi_Zhuan.7z) for an example:</p>
  
  <p><img src="https://i.stack.imgur.com/L1f6z.png" alt="Mathematica"></p>
  
  <p>But setting <code>ctx.select_font_face('ÖÐøý½ðÊ¯*­')</code> does not work either, which will create the character image with the default font.</p>