1""" 2Interpolate OpenType Layout tables (GDEF / GPOS / GSUB). 3""" 4from __future__ import print_function, division, absolute_import 5from fontTools.misc.py23 import * 6from fontTools.ttLib import TTFont 7from fontTools.varLib import models, VarLibError, load_designspace, load_masters 8from fontTools.varLib.merger import InstancerMerger 9import os.path 10import logging 11from copy import deepcopy 12from pprint import pformat 13 14log = logging.getLogger("fontTools.varLib.interpolate_layout") 15 16 17def interpolate_layout(designspace, loc, master_finder=lambda s:s, mapped=False): 18 """ 19 Interpolate GPOS from a designspace file and location. 20 21 If master_finder is set, it should be a callable that takes master 22 filename as found in designspace file and map it to master font 23 binary as to be opened (eg. .ttf or .otf). 24 25 If mapped is False (default), then location is mapped using the 26 map element of the axes in designspace file. If mapped is True, 27 it is assumed that location is in designspace's internal space and 28 no mapping is performed. 29 """ 30 if hasattr(designspace, "sources"): # Assume a DesignspaceDocument 31 pass 32 else: # Assume a file path 33 from fontTools.designspaceLib import DesignSpaceDocument 34 designspace = DesignSpaceDocument.fromfile(designspace) 35 36 ds = load_designspace(designspace) 37 log.info("Building interpolated font") 38 39 log.info("Loading master fonts") 40 master_fonts = load_masters(designspace, master_finder) 41 font = deepcopy(master_fonts[ds.base_idx]) 42 43 log.info("Location: %s", pformat(loc)) 44 if not mapped: 45 loc = {name: ds.axes[name].map_forward(v) for name,v in loc.items()} 46 log.info("Internal location: %s", pformat(loc)) 47 loc = models.normalizeLocation(loc, ds.internal_axis_supports) 48 log.info("Normalized location: %s", pformat(loc)) 49 50 # Assume single-model for now. 51 model = models.VariationModel(ds.normalized_master_locs) 52 assert 0 == model.mapping[ds.base_idx] 53 54 merger = InstancerMerger(font, model, loc) 55 56 log.info("Building interpolated tables") 57 # TODO GSUB/GDEF 58 merger.mergeTables(font, master_fonts, ['GPOS']) 59 return font 60 61 62def main(args=None): 63 from fontTools import configLogger 64 65 import sys 66 if args is None: 67 args = sys.argv[1:] 68 69 designspace_filename = args[0] 70 locargs = args[1:] 71 outfile = os.path.splitext(designspace_filename)[0] + '-instance.ttf' 72 73 # TODO: allow user to configure logging via command-line options 74 configLogger(level="INFO") 75 76 finder = lambda s: s.replace('master_ufo', 'master_ttf_interpolatable').replace('.ufo', '.ttf') 77 78 loc = {} 79 for arg in locargs: 80 tag,val = arg.split('=') 81 loc[tag] = float(val) 82 83 font = interpolate_layout(designspace_filename, loc, finder) 84 log.info("Saving font %s", outfile) 85 font.save(outfile) 86 87 88if __name__ == "__main__": 89 import sys 90 if len(sys.argv) > 1: 91 sys.exit(main()) 92 import doctest 93 sys.exit(doctest.testmod().failed) 94