summaryrefslogtreecommitdiffstats
path: root/examples/ffcopyglyphs.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ffcopyglyphs.py')
-rw-r--r--examples/ffcopyglyphs.py161
1 files changed, 161 insertions, 0 deletions
diff --git a/examples/ffcopyglyphs.py b/examples/ffcopyglyphs.py
new file mode 100644
index 0000000..3fcfe76
--- /dev/null
+++ b/examples/ffcopyglyphs.py
@@ -0,0 +1,161 @@
+#!/usr/bin/env python3
+'''FontForge: Copy glyphs from one font to another, without using ffbuilder'''
+__url__ = 'https://github.com/silnrsi/pysilfont'
+__copyright__ = 'Copyright (c) 2015-2019 SIL International (https://www.sil.org)'
+__license__ = 'Released under the MIT License (https://opensource.org/licenses/MIT)'
+__author__ = 'Martin Hosken'
+
+from silfont.core import execute
+import psMat
+import io
+
+
+''' This will need updating, since FontForge is no longer supported as a tool by execute() So:
+- ifont and ofont will need to be changed to have type 'filename'
+- ifont will then need to be opened using fontforge.open
+- The font will need to be saved with font.save
+- execute will need to be called with the tool set to None instead of "FF"
+'''
+
+
+argspec = [
+ ('ifont',{'help': 'Input font file'}, {'type': 'infont'}),
+ ('ofont',{'help': 'Output font file','nargs': '?' }, {'type': 'outfont', 'def': 'new'}),
+ ('-i','--input',{'help': 'Font to get glyphs from', 'required' : True}, {'type': 'infont'}),
+ ('-r','--range',{'help': 'StartUnicode..EndUnicode no spaces, e.g. 20..7E', 'action' : 'append'}, {}),
+ ('--rangefile',{'help': 'File with USVs e.g. 20 or a range e.g. 20..7E or both', 'action' : 'append'}, {}),
+ ('-n','--name',{'help': 'Include glyph named name', 'action' : 'append'}, {}),
+ ('--namefile',{'help': 'File with glyph names', 'action' : 'append'}, {}),
+ ('-a','--anchors',{'help' : 'Copy across anchor points', 'action' : 'store_true'}, {}),
+ ('-f','--force',{'help' : 'Overwrite existing glyphs in the font', 'action' : 'store_true'}, {}),
+ ('-s','--scale',{'type' : float, 'help' : 'Scale glyphs by this factor'}, {})
+]
+
+def copyglyph(font, infont, g, u, args) :
+ extras = set()
+ if args.scale is None :
+ scale = psMat.identity()
+ else :
+ scale = psMat.scale(args.scale)
+ o = font.findEncodingSlot(u)
+ if o == -1 :
+ glyph = font.createChar(u, g.glyphname)
+ else :
+ glyph = font[o]
+ if len(g.references) == 0 :
+ font.selection.select(glyph)
+ pen = glyph.glyphPen()
+ g.draw(pen)
+ glyph.transform(scale)
+ else :
+ for r in g.references :
+ t = psMat.compose(r[1], scale)
+ newt = psMat.compose(psMat.identity(), psMat.translate(t[4], t[5]))
+ glyph.addReference(r[0], newt)
+ extras.add(r[0])
+ glyph.width = g.width * scale[0]
+ if args.anchors :
+ for a in g.anchorPoints :
+ try :
+ l = font.getSubtableOfAnchor(a[1])
+ except EnvironmentError :
+ font.addAnchorClass("", a[0]*scale[0], a[1]*scale[3])
+ glyph.anchorPoints = g.anchorPoints
+ return list(extras)
+
+def doit(args) :
+ font = args.ifont
+ infont = args.input
+ font.encoding = "Original"
+ infont.encoding = "Original" # compact the font so findEncodingSlot will work
+ infont.layers["Fore"].is_quadratic = font.layers["Fore"].is_quadratic
+
+ # list of glyphs to copy
+ glist = list()
+
+ # glyphs specified on the command line
+ for n in args.name or [] :
+ glist.append(n)
+
+ # glyphs specified in a file
+ for filename in args.namefile or [] :
+ namefile = io.open(filename, 'r')
+ for line in namefile :
+ # ignore comments
+ line = line.partition('#')[0]
+ line = line.strip()
+
+ # ignore blank lines
+ if (line == ''):
+ continue
+
+ glist.append(line)
+
+ # copy glyphs by name
+ reportErrors = True
+ while len(glist) :
+ tglist = glist[:]
+ glist = []
+ for n in tglist:
+ if n in font and not args.force :
+ if reportErrors :
+ print("Glyph {} already present. Skipping".format(n))
+ continue
+ if n not in infont :
+ print("Can't find glyph {}".format(n))
+ continue
+ g = infont[n]
+ glist.extend(copyglyph(font, infont, g, -1, args))
+ reportErrors = False
+
+ # list of characters to copy
+ ulist = list()
+
+ # characters specified on the command line
+ for r in args.range or [] :
+ (rstart, rend) = [int(x, 16) for x in r.split('..')]
+ for u in range(rstart, rend + 1) :
+ ulist.append(u)
+
+ # characters specified in a file
+ for filename in args.rangefile or [] :
+ rangefile = io.open(filename, 'r')
+ for line in rangefile :
+ # ignore comments
+ line = line.partition('#')[0]
+ line = line.strip()
+
+ # ignore blank lines
+ if (line == ''):
+ continue
+
+ # obtain USVs
+ try:
+ (rstart, rend) = line.split('..')
+ except ValueError:
+ rstart = line
+ rend = line
+
+ rstart = int(rstart, 16)
+ rend = int(rend, 16)
+
+ for u in range(rstart, rend + 1):
+ ulist.append(u)
+
+ # copy the characters from the generated list
+ for u in ulist:
+ o = font.findEncodingSlot(u)
+ if o != -1 and not args.force :
+ print("Glyph for {:x} already present. Skipping".format(u))
+ continue
+ e = infont.findEncodingSlot(u)
+ if e == -1 :
+ print("Can't find glyph for {:04x}".format(u))
+ continue
+ g = infont[e]
+ copyglyph(font, infont, g, u, args)
+
+ return font
+
+def cmd() : execute("FF",doit,argspec)
+if __name__ == "__main__": cmd()