diff --git a/Lib/fontTools/ttLib/tables/ttProgram.py b/Lib/fontTools/ttLib/tables/ttProgram.py
index 182982f21..62e0e1a74 100644
--- a/Lib/fontTools/ttLib/tables/ttProgram.py
+++ b/Lib/fontTools/ttLib/tables/ttProgram.py
@@ -63,6 +63,7 @@ instructions = [
(0x66, 'FLOOR', 0, 'Floor', 1, 1), # n floor(n)
(0x46, 'GC', 1, 'GetCoordOnPVector', 1, 1), # p c
(0x88, 'GETINFO', 0, 'GetInfo', 1, 1), # selector result
+ (0x91, 'GETVARIATION', 0, 'GetVariation', 0, -1), # - a1,..,an
(0x0d, 'GFV', 0, 'GetFVector', 0, 2), # - px, py
(0x0c, 'GPV', 0, 'GetPVector', 0, 2), # - px, py
(0x52, 'GT', 0, 'GreaterThan', 2, 1), # e2, e1 b
diff --git a/Lib/fontTools/varLib/mutator.py b/Lib/fontTools/varLib/mutator.py
index 7a03e4548..3e9fb168d 100644
--- a/Lib/fontTools/varLib/mutator.py
+++ b/Lib/fontTools/varLib/mutator.py
@@ -5,8 +5,9 @@ $ fonttools varLib.mutator ./NotoSansArabic-VF.ttf wght=140 wdth=85
"""
from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
-from fontTools.misc.fixedTools import floatToFixedToFloat, otRound
-from fontTools.ttLib import TTFont
+from fontTools.misc.fixedTools import floatToFixedToFloat, otRound, floatToFixed
+from fontTools.ttLib import TTFont, newTable
+from fontTools.ttLib.tables import ttProgram
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
from fontTools.varLib import _GetCoordinates, _SetCoordinates
from fontTools.varLib.models import (
@@ -63,11 +64,11 @@ def instantiateVariableFont(varfont, location, inplace=False):
glyf = varfont['glyf']
# get list of glyph names in gvar sorted by component depth
glyphnames = sorted(
- gvar.variations.keys(),
- key=lambda name: (
- glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth
- if glyf[name].isComposite() else 0,
- name))
+ gvar.variations.keys(),
+ key=lambda name: (
+ glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth
+ if glyf[name].isComposite() else 0,
+ name))
for glyphname in glyphnames:
variations = gvar.variations[glyphname]
coordinates,_ = _GetCoordinates(varfont, glyphname)
@@ -112,7 +113,7 @@ def instantiateVariableFont(varfont, location, inplace=False):
if not delta:
continue
setattr(varfont[tableTag], itemName,
- getattr(varfont[tableTag], itemName) + delta)
+ getattr(varfont[tableTag], itemName) + delta)
if 'GDEF' in varfont:
log.info("Mutating GDEF/GPOS/GSUB tables")
@@ -121,6 +122,35 @@ def instantiateVariableFont(varfont, location, inplace=False):
log.info("Building interpolated tables")
merger.instantiate()
+ for glyph in glyf.glyphs.values():
+ if hasattr(glyph, "program"):
+ instructions = glyph.program.getAssembly()
+ # If GETVARIATION opcode is used in bytecode of any glyph add IDEF
+ addidef = False
+ for instruction in instructions:
+ if instruction.startswith("GETVARIATION"):
+ addidef = True
+ break
+ if addidef:
+ asm = []
+ if varfont.has_key('fpgm'):
+ fpgm = varfont['fpgm']
+ asm = fpgm.program.getAssembly()
+ else:
+ fpgm = newTable('fpgm')
+ fpgm.program = ttProgram.Program()
+ varfont['fpgm'] = fpgm
+ log.info("Adding IDEF to fpgm table for GETVARIATION opcode")
+ asm.append("PUSHB[000] 145")
+ asm.append("IDEF[ ]")
+ args = [str(len(loc))]
+ for val in loc.values():
+ args.append(str(floatToFixed(val, 14)))
+ asm.append("NPUSHW[ ] " + ' '.join(args))
+ asm.append("ENDF[ ]")
+ fpgm.program.fromAssembly(asm)
+ break
+
if 'name' in varfont:
log.info("Pruning name table")
exclude = {a.axisNameID for a in fvar.axes}
@@ -134,7 +164,7 @@ def instantiateVariableFont(varfont, location, inplace=False):
if "wght" in location and "OS/2" in varfont:
varfont["OS/2"].usWeightClass = otRound(
- max(1, min(location["wght"], 1000))
+ max(1, min(location["wght"], 1000))
)
if "wdth" in location:
wdth = location["wdth"]
@@ -160,22 +190,22 @@ def main(args=None):
import argparse
parser = argparse.ArgumentParser(
- "fonttools varLib.mutator", description="Instantiate a variable font")
+ "fonttools varLib.mutator", description="Instantiate a variable font")
parser.add_argument(
- "input", metavar="INPUT.ttf", help="Input variable TTF file.")
+ "input", metavar="INPUT.ttf", help="Input variable TTF file.")
parser.add_argument(
- "locargs", metavar="AXIS=LOC", nargs="*",
- help="List of space separated locations. A location consist in "
- "the name of a variation axis, followed by '=' and a number. E.g.: "
- " wght=700 wdth=80. The default is the location of the base master.")
+ "locargs", metavar="AXIS=LOC", nargs="*",
+ help="List of space separated locations. A location consist in "
+ "the name of a variation axis, followed by '=' and a number. E.g.: "
+ " wght=700 wdth=80. The default is the location of the base master.")
parser.add_argument(
- "-o", "--output", metavar="OUTPUT.ttf", default=None,
- help="Output instance TTF file (default: INPUT-instance.ttf).")
+ "-o", "--output", metavar="OUTPUT.ttf", default=None,
+ help="Output instance TTF file (default: INPUT-instance.ttf).")
logging_group = parser.add_mutually_exclusive_group(required=False)
logging_group.add_argument(
- "-v", "--verbose", action="store_true", help="Run more verbosely.")
+ "-v", "--verbose", action="store_true", help="Run more verbosely.")
logging_group.add_argument(
- "-q", "--quiet", action="store_true", help="Turn verbosity off.")
+ "-q", "--quiet", action="store_true", help="Turn verbosity off.")
options = parser.parse_args(args)
varfilename = options.input
diff --git a/Tests/varLib/data/master_ttx_getvar_ttf/Mutator_Getvar.ttx b/Tests/varLib/data/master_ttx_getvar_ttf/Mutator_Getvar.ttx
new file mode 100755
index 000000000..5360fe40b
--- /dev/null
+++ b/Tests/varLib/data/master_ttx_getvar_ttf/Mutator_Getvar.ttx
@@ -0,0 +1,555 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GETVARIATION[]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VarFont
+
+
+ Regular
+
+
+ VarFont Regular: 2017
+
+
+ VarFont Regular
+
+
+ VarFont-Regular
+
+
+ Width
+
+
+ Ascender
+
+
+ Regular
+
+
+ VarFont
+
+
+ Regular
+
+
+ VarFont Regular: 2017
+
+
+ VarFont Regular
+
+
+ VarFont-Regular
+
+
+ Width
+
+
+ Ascender
+
+
+ Regular
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ wdth
+ 60.0
+ 100.0
+ 100.0
+ 256
+
+
+
+
+ ASCN
+ 608.0
+ 608.0
+ 648.0
+ 257
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/varLib/data/test_results/Mutator_Getvar-instance.ttx b/Tests/varLib/data/test_results/Mutator_Getvar-instance.ttx
new file mode 100755
index 000000000..651a35faa
--- /dev/null
+++ b/Tests/varLib/data/test_results/Mutator_Getvar-instance.ttx
@@ -0,0 +1,297 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PUSHB[ ] /* 1 value pushed */
+ 145
+ IDEF[ ] /* InstructionDefinition */
+ NPUSHW[ ] /* 3 values pushed */
+ 2 -8192 8192
+ ENDF[ ] /* EndFunctionDefinition */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GETVARIATION[ ] /* GetVariation */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ VarFont
+
+
+ Regular
+
+
+ VarFont Regular: 2017
+
+
+ VarFont Regular
+
+
+ VarFont-Regular
+
+
+ VarFont
+
+
+ Regular
+
+
+ VarFont Regular: 2017
+
+
+ VarFont Regular
+
+
+ VarFont-Regular
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/varLib/mutator_test.py b/Tests/varLib/mutator_test.py
index de794f0f7..23e14ca83 100644
--- a/Tests/varLib/mutator_test.py
+++ b/Tests/varLib/mutator_test.py
@@ -117,6 +117,27 @@ class MutatorTest(unittest.TestCase):
expected_ttx_path = self.get_test_output(varfont_name + '.ttx')
self.expect_ttx(instfont, expected_ttx_path, tables)
+ def test_varlib_mutator_getvar_ttf(self):
+ suffix = '.ttf'
+ ttx_dir = self.get_test_input('master_ttx_getvar_ttf')
+
+ self.temp_dir()
+ ttx_paths = self.get_file_list(ttx_dir, '.ttx', 'Mutator_Getvar')
+ for path in ttx_paths:
+ self.compile_font(path, suffix, self.tempdir)
+
+ varfont_name = 'Mutator_Getvar'
+ varfont_path = os.path.join(self.tempdir, varfont_name + suffix)
+
+ args = [varfont_path, 'wdth=80', 'ASCN=628']
+ mutator(args)
+
+ instfont_path = os.path.splitext(varfont_path)[0] + '-instance' + suffix
+ instfont = TTFont(instfont_path)
+ tables = [table_tag for table_tag in instfont.keys() if table_tag != 'head']
+ expected_ttx_path = self.get_test_output(varfont_name + '-instance.ttx')
+ self.expect_ttx(instfont, expected_ttx_path, tables)
+
def test_varlib_mutator_iup_ttf(self):
suffix = '.ttf'
ufo_dir = self.get_test_input('master_ufo')