Search code examples
pythonsvgtruetypefontforge

Import a sequence of .svg files into FontForge as glyphs and output a font file


I want to create a font with a large volume of glyphs. Think Japanese kanji, in the thousands. So there will definitely be some scripting / batch processing required. Luckily FontForge supports python scripting! Unluckily I haven't been able to get it working. [sadface]

Firstly, thanks to the user Hoff for posting code here that answered a big part of my question. But upon running his script I encounter problems which raise more questions:

Failed to find NameList: AGL For New Fonts
Warning: Font contained no glyphs

Updates:

  • The "font contained no glyphs" error is apparently a bug in FontForge that occurs when the font contains one or less glyph. Adding a second glyph 'B' resolved this.
  • I found the same syntax can be used whether saving .ttf .sfd .otf etc.
  • The NameList failure actually doesn't prevent the font file from being written. I was happy to discover this, but still don't understand how to provide the NameList it wants.

Here is Hoff's code:

import fontforge
font = fontforge.open('blank.sfd')
glyph = font.createMappedChar('A')
glyph.importOutlines('sourceimg.svg')
font.generate('testfont.ttf')

After five hours of struggling yesterday with building FontForge (a confusing process on a Mac). I appear to have it up and running properly. I had at first installed a pre-built version from a .dmg only to find it lacked python support. But since Hoff seemed not to encounter the same error I did, I'm not ruling out a build issue.

Either way, I don't understand the error involving AGL. What is AGL? I looked it up: "Adobe Glyph List - a standard glyph naming convention". Sounds like FontForge tried to map Unicode values to glyph names and couldn't.

So, why the AGL NameList problem? Thanks in advance for any help.


Solution

  • Try to rebuild your Fonforge. Because the code should work. I tested it and it runs fine.

    I successfully installed Fontforge with Python extension with Homebrew. This is the info:

    allcaps$ brew info fontforge
    fontforge: stable 20120731, HEAD
    http://fontforge.org/
    /usr/local/Cellar/fontforge/20120731 (377 files, 16M) *
      Built from source with: --with-x
    From: https://github.com/Homebrew/homebrew/commits/master/Library/Formula/fontforge.rb
    ==> Dependencies
    Required: gettext ✘, fontconfig ✔
    Recommended: jpeg ✔, libtiff ✔
    Optional: cairo ✔, pango ✘, libspiro ✘, czmq ✘
    ==> Options
    --with-cairo
      Build with cairo support
    --with-czmq
      Build with czmq support
    --with-gif
      Build with GIF support
    --with-libspiro
      Build with libspiro support
    --with-pango
      Build with pango support
    --with-x
      Build with X11 support, including FontForge.app
    --without-jpeg
      Build without jpeg support
    --without-libpng
      Build without libpng support
    --without-libtiff
      Build without libtiff support
    --without-python
      Build without python support
    --HEAD
      install HEAD version
    ==> Caveats
    Set PYTHONPATH if you need Python to find the installed site-packages:
      export PYTHONPATH=/usr/local/lib/python2.7/site-packages:$PYTHONPATH
    
    .app bundles were installed.
    Run `brew linkapps` to symlink these to /Applications.
    

    Set PYTHONPATH
    Run brew install fontforge of course with all flags you need.
    Run brew linkapps

    UPDATE

    Start with a empty font so the font isn't the problem:

    import fontforge
    font = fontforge.font() # create a new font
    

    To include a glyphlist (shouldn't be necessary) Download: http://partners.adobe.com/public/developer/en/opentype/glyphlist.txt and then:

    import fontforge
    fontforge.loadNamelist('glyphlist.txt') # load a name list
    ...
    

    Create the glyph by code point. createChar(uni[,name]) 'A' is 65 so

    char = font.createChar(65)
    

    Glyphs and their code points:

    >>> for c in u'ABC 賢治':  print ord(c). 
    >>> 65, 66, 67, 32, 36066, 27835. 
    

    The Unicode Consortium defines the Unicode standard. The 'CJK Unified Ideographs' live in 'Basic Multilingual Plane (BMP)'.

    Glyphs without a unicode point can be referenced within a font by name. And are useful for open type features or building blocks to compose new glyphs. You can create them like this:

    font.createChar(-1, 'some_name')
    

    UPDATE 2

    You should name all glyphs that occur in the Adobe Glyph List by their AGL glyph name. The rest of the glyphs should be named uniXXXX where XXXX is the Unicode index. During development you can use any human readable name. So use your own naming and replace it when you generate the font for shipping. See Typophile.