Discussion:
[fontforge-users] Fontforge Python scripting
Maximilian Paju
2015-07-16 09:49:14 UTC
Permalink
Hi,

I recently began working on a project at work that aims towards creating a
service for converting fonts from as many formats as possible to .woff and
subsetting the font glyphs to reduce the file size. I've looked through
some tools that may help with this and I've found FontForge to be quite
versatile. I'm now trying to do some scripting with the python extension.
However, the lack of documentation in some of the code have left me
helpless.

The problem I'm facing at the moment is applying the generate method in the
font-module to actually produce my .woff file. I've successfully subsetted
the font and been able to save it as a .sfd but when I try to generate the
woff the file won't open in FontForge afterwards.

[code]
import fontforge
import sys
import getopt
import os
import struct


def select_with_refs(font, unicode):
font.selection.select(('more', 'unicode'), unicode)
try:
for ref in font[unicode].references:
font.selection.select(('more',), ref[0])

except:
print('Resolving references on u+%04x failed' % unicode)

def main(argv):
optlist, args = getopt.gnu_getopt(argv, '', ['string=', 'strip_names',
'opentype-features', 'simplify', 'new', 'script', 'nmr', 'roundtrip',
'subset=', 'namelist', 'null'])
font_in, font_out = args

unicodes = range(0x20, 0x7f) # Basic latin
flags = ()

oldfont = fontforge.open(argv[0])
for i in unicodes:
select_with_refs(oldfont, i)

oldfont.copy()

newfont = fontforge.font()
newfont.sfnt_names = oldfont.sfnt_names
newfont.encoding = oldfont.encoding
newfont.em = oldfont.em
newfont.layers['Fore'].is_quadratic = oldfont.layers['Fore'].is_quadratic
for i in unicodes:
select_with_refs(newfont, i)

newfont.paste()

newfont.fontname="NewFont"
newfont.save(argv[1] + ".sfd")
newfont.generate(argv[1] + ".woff", flags = flags)

if __name__ == '__main__':
main(sys.argv[1:])
[/code]


Any help would be most appreciated!
Lasse Fister
2015-07-16 11:08:24 UTC
Permalink
Hi,

this is not a direct answer to your question, but I hope it helps.

Khaled Hosny did something like that in his Amiri project (he uses sorts
mill though, a fork of fontforge, but much of the python api is the
same)[1].

The make target "$(WEB)/%.ttf: %.ttf $(MAKEWEB)" uses the makeweb.py[2]
script makeweb.py which also subsets the fonts and safes as ttf
The make traget "$(WEB)/%.woff: $(WEB)/%.ttf" makes woff files by
converting the web-ttf with sfnttool
The make traget "$(WEB)/%.woff2: $(WEB)/%.ttf" makes woff2 converting
the web-ttfs using woff2_compress

fonttools is good for subsetting/subset.py [3]

To install all those font specific tools I made some dockerfiles, so I'm
not bound to a specific computer where they are installed[4][5] Though,
the images are not yet distributed anywhere; thus you'd have to built
them yourself. [5] also includes Fontforge.

1. https://github.com/khaledhosny/amiri-font/blob/master/Makefile
2. https://github.com/khaledhosny/amiri-font/blob/master/tools
3. https://github.com/behdad/fonttools/blob/master/Lib/fontTools/subset.py
4. https://github.com/graphicore/docker-sortsmill
5.
https://github.com/Tarobish/Jomhuria/blob/master/tools/docker_fontbuilder/Dockerfile

Lasse
Post by Maximilian Paju
Hi,
I recently began working on a project at work that aims towards
creating a service for converting fonts from as many formats as
possible to .woff and subsetting the font glyphs to reduce the file
size. I've looked through some tools that may help with this and I've
found FontForge to be quite versatile. I'm now trying to do some
scripting with the python extension. However, the lack of
documentation in some of the code have left me helpless.
The problem I'm facing at the moment is applying the generate method
in the font-module to actually produce my .woff file. I've
successfully subsetted the font and been able to save it as a .sfd but
when I try to generate the woff the file won't open in FontForge
afterwards.
[code]
import fontforge
import sys
import getopt
import os
import struct
font.selection.select(('more', 'unicode'), unicode)
font.selection.select(('more',), ref[0])
print('Resolving references on u+%04x failed' % unicode)
optlist, args = getopt.gnu_getopt(argv, '', ['string=', 'strip_names',
'opentype-features', 'simplify', 'new', 'script', 'nmr', 'roundtrip',
'subset=', 'namelist', 'null'])
font_in, font_out = args
unicodes = range(0x20, 0x7f) # Basic latin
flags = ()
oldfont = fontforge.open(argv[0])
select_with_refs(oldfont, i)
oldfont.copy()
newfont = fontforge.font()
newfont.sfnt_names = oldfont.sfnt_names
newfont.encoding = oldfont.encoding
newfont.em = oldfont.em
newfont.layers['Fore'].is_quadratic = oldfont.layers['Fore'].is_quadratic
select_with_refs(newfont, i)
newfont.paste()
newfont.fontname="NewFont"
newfont.save(argv[1] + ".sfd")
newfont.generate(argv[1] + ".woff", flags = flags)
main(sys.argv[1:])
[/code]
Any help would be most appreciated!
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
fontforge-users mailing list
https://lists.sourceforge.net/lists/listinfo/fontforge-users
http://fontforge.10959.n7.nabble.com/User-f8781.html
Lasse Fister
2015-07-16 11:04:14 UTC
Permalink
Hi,

this is not a direct answer to your question, but I hope it helps.

Khaled Hosny did something like that in his Amiri project (he uses sorts
mill though, a fork of fontforge, but much of the python api is the
same)[1].

The make target "$(WEB)/%.ttf: %.ttf $(MAKEWEB)" uses the makeweb.py[2]
script makeweb.py which also subsets the fonts and safes as ttf
The make traget "$(WEB)/%.woff: $(WEB)/%.ttf" makes woff files by
converting the web-ttf with sfnttool
The make traget "$(WEB)/%.woff2: $(WEB)/%.ttf" makes woff2 converting
the web-ttfs using woff2_compress

fonttools is good for subsetting/subset.py [3]

To install all those font specific tools I made some dockerfiles, so I'm
not bound to a specific computer where they are installed[4][5] Though,
the images are not yet distributed anywhere; thus you'd have to built
them yourself. [5] also includes Fontforge.

1. https://github.com/khaledhosny/amiri-font/blob/master/Makefile
2. https://github.com/khaledhosny/amiri-font/blob/master/tools
3. https://github.com/behdad/fonttools/blob/master/Lib/fontTools/subset.py
4. https://github.com/graphicore/docker-sortsmill
5.
https://github.com/Tarobish/Jomhuria/blob/master/tools/docker_fontbuilder/Dockerfile

Lasse
Post by Maximilian Paju
Hi,
I recently began working on a project at work that aims towards
creating a service for converting fonts from as many formats as
possible to .woff and subsetting the font glyphs to reduce the file
size. I've looked through some tools that may help with this and I've
found FontForge to be quite versatile. I'm now trying to do some
scripting with the python extension. However, the lack of
documentation in some of the code have left me helpless.
The problem I'm facing at the moment is applying the generate method
in the font-module to actually produce my .woff file. I've
successfully subsetted the font and been able to save it as a .sfd but
when I try to generate the woff the file won't open in FontForge
afterwards.
[code]
import fontforge
import sys
import getopt
import os
import struct
font.selection.select(('more', 'unicode'), unicode)
font.selection.select(('more',), ref[0])
print('Resolving references on u+%04x failed' % unicode)
optlist, args = getopt.gnu_getopt(argv, '', ['string=', 'strip_names',
'opentype-features', 'simplify', 'new', 'script', 'nmr', 'roundtrip',
'subset=', 'namelist', 'null'])
font_in, font_out = args
unicodes = range(0x20, 0x7f) # Basic latin
flags = ()
oldfont = fontforge.open(argv[0])
select_with_refs(oldfont, i)
oldfont.copy()
newfont = fontforge.font()
newfont.sfnt_names = oldfont.sfnt_names
newfont.encoding = oldfont.encoding
newfont.em = oldfont.em
newfont.layers['Fore'].is_quadratic = oldfont.layers['Fore'].is_quadratic
select_with_refs(newfont, i)
newfont.paste()
newfont.fontname="NewFont"
newfont.save(argv[1] + ".sfd")
newfont.generate(argv[1] + ".woff", flags = flags)
main(sys.argv[1:])
[/code]
Any help would be most appreciated!
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
fontforge-users mailing list
https://lists.sourceforge.net/lists/listinfo/fontforge-users
http://fontforge.10959.n7.nabble.com/User-f8781.html
m***@ansuz.sooke.bc.ca
2015-07-27 06:31:31 UTC
Permalink
Post by Maximilian Paju
I recently began working on a project at work that aims towards creating a
service for converting fonts from as many formats as possible to .woff and
I'm digging through my old mail, so apologies for the delay responding to
this, but: be aware of possible security issues if you are accepting
user-submitted binary font files, for instance in a Web-based "service."
There have historically been a lot of buffer overflow issues in software
that parses these formats, including FontForge specifically:
https://www.exploit-db.com/exploits/15732/
http://www.securityfocus.com/bid/29637/discuss
http://www.verisigninc.com/en_US/security-services/security-intelligence/vulnerability-reports/articles/index.xhtml?id=811

Formats like OpenType/TrueType in particular, which include a lot of
embedded pointers to data structures that are allowed to deliberately
overlap, are not always easy to read with proper bounds checking. We're
always working to improve the code, and each day it's better than the
last, but I wouldn't trust it in its current state on arbitrary
user-supplied font files uploaded to a Web service.
--
Matthew Skala
***@ansuz.sooke.bc.ca People before principles.
http://ansuz.sooke.bc.ca/

------------------------------------------------------------------------------
Loading...