Merge pull request #1641 from fonttools/fix-singlepos-merge
Fix singlepos merge
diff --git a/Lib/fontTools/otlLib/builder.py b/Lib/fontTools/otlLib/builder.py
index f8b3ce3..a087b2d 100644
--- a/Lib/fontTools/otlLib/builder.py
+++ b/Lib/fontTools/otlLib/builder.py
@@ -1,4 +1,5 @@
from __future__ import print_function, division, absolute_import
+from collections import namedtuple
from fontTools import ttLib
from fontTools.ttLib.tables import otTables as ot
from fontTools.ttLib.tables.otBase import ValueRecord, valueRecordFormatDict
@@ -488,17 +489,25 @@
return tuple(result)
+_DeviceTuple = namedtuple("_DeviceTuple", "DeltaFormat StartSize EndSize DeltaValue")
+
+
def _makeDeviceTuple(device):
"""otTables.Device --> tuple, for making device tables unique"""
- return (device.DeltaFormat, device.StartSize, device.EndSize,
- tuple(device.DeltaValue))
+ return _DeviceTuple(
+ device.DeltaFormat,
+ device.StartSize,
+ device.EndSize,
+ () if device.DeltaFormat & 0x8000 else tuple(device.DeltaValue)
+ )
+
def _getSinglePosValueSize(valueKey):
"""Returns how many ushorts this valueKey (short form of ValueRecord) takes up"""
count = 0
- for k in valueKey[1:]:
- if hasattr(k[1], '__len__') and len(k[1]):
- count += len(k[1][3]) + 3
+ for _, v in valueKey[1:]:
+ if isinstance(v, _DeviceTuple):
+ count += len(v.DeltaValue) + 3
else:
count += 1
return count
diff --git a/Lib/fontTools/varLib/merger.py b/Lib/fontTools/varLib/merger.py
index d92eb7f..cd16ace 100644
--- a/Lib/fontTools/varLib/merger.py
+++ b/Lib/fontTools/varLib/merger.py
@@ -3,6 +3,7 @@
"""
from __future__ import print_function, division, absolute_import
import copy
+from operator import ior
from fontTools.misc.py23 import *
from fontTools.misc.fixedTools import otRound
from fontTools.misc import classifyTools
@@ -13,6 +14,7 @@
from fontTools.varLib.models import nonNone, allNone, allEqual, allEqualTo
from fontTools.varLib.varStore import VarStoreInstancer
from functools import reduce
+from fontTools.otlLib.builder import buildSinglePos
class Merger(object):
@@ -727,6 +729,30 @@
return lst
+def _Lookup_SinglePos_subtables_flatten(lst, font, min_inclusive_rec_format):
+ glyphs, _ = _merge_GlyphOrders(font,
+ [v.Coverage.glyphs for v in lst], None)
+ num_glyphs = len(glyphs)
+ new = ot.SinglePos()
+ new.Format = 2
+ new.ValueFormat = min_inclusive_rec_format
+ new.Coverage = ot.Coverage()
+ new.Coverage.glyphs = glyphs
+ new.ValueCount = num_glyphs
+ new.Value = [None] * num_glyphs
+ for singlePos in lst:
+ if singlePos.Format == 1:
+ val_rec = singlePos.Value
+ for gname in singlePos.Coverage.glyphs:
+ i = glyphs.index(gname)
+ new.Value[i] = copy.deepcopy(val_rec)
+ elif singlePos.Format == 2:
+ for j, gname in enumerate(singlePos.Coverage.glyphs):
+ val_rec = singlePos.Value[j]
+ i = glyphs.index(gname)
+ new.Value[i] = copy.deepcopy(val_rec)
+ return [new]
+
@AligningMerger.merger(ot.Lookup)
def merge(merger, self, lst):
subtables = merger.lookup_subtables = [l.SubTable for l in lst]
@@ -746,12 +772,28 @@
isPairPos = self.SubTable and isinstance(self.SubTable[0], ot.PairPos)
if isPairPos:
-
# AFDKO and feaLib sometimes generate two Format1 subtables instead of one.
# Merge those before continuing.
# https://github.com/fonttools/fonttools/issues/719
self.SubTable = _Lookup_PairPos_subtables_canonicalize(self.SubTable, merger.font)
subtables = merger.lookup_subtables = [_Lookup_PairPos_subtables_canonicalize(st, merger.font) for st in subtables]
+ else:
+ isSinglePos = self.SubTable and isinstance(self.SubTable[0], ot.SinglePos)
+ if isSinglePos:
+ numSubtables = [len(st) for st in subtables]
+ if not all([nums == numSubtables[0] for nums in numSubtables]):
+ # Flatten list of SinglePos subtables to single Format 2 subtable,
+ # with all value records set to the rec format type.
+ # We use buildSinglePos() to optimize the lookup after merging.
+ valueFormatList = [t.ValueFormat for st in subtables for t in st]
+ # Find the minimum value record that can accomodate all the singlePos subtables.
+ mirf = reduce(ior, valueFormatList)
+ self.SubTable = _Lookup_SinglePos_subtables_flatten(self.SubTable, merger.font, mirf)
+ subtables = merger.lookup_subtables = [
+ _Lookup_SinglePos_subtables_flatten(st, merger.font, mirf) for st in subtables]
+ flattened = True
+ else:
+ flattened = False
merger.mergeLists(self.SubTable, subtables)
self.SubTableCount = len(self.SubTable)
@@ -769,6 +811,16 @@
self.SubTable.pop(-1)
self.SubTableCount -= 1
+ elif isSinglePos and flattened:
+ singlePosTable = self.SubTable[0]
+ glyphs = singlePosTable.Coverage.glyphs
+ # We know that singlePosTable is Format 2, as this is set
+ # in _Lookup_SinglePos_subtables_flatten.
+ singlePosMapping = {
+ gname: valRecord
+ for gname, valRecord in zip(glyphs, singlePosTable.Value)
+ }
+ self.SubTable = buildSinglePos(singlePosMapping, merger.font.getReverseGlyphMap())
merger.mergeObjects(self, lst, exclude=['SubTable', 'SubTableCount'])
del merger.lookup_subtables
diff --git a/Tests/varLib/data/master_vpal_test/master_vpal_test_0.ttx b/Tests/varLib/data/master_vpal_test/master_vpal_test_0.ttx
new file mode 100644
index 0000000..1fbb45d
--- /dev/null
+++ b/Tests/varLib/data/master_vpal_test/master_vpal_test_0.ttx
@@ -0,0 +1,485 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.42">
+
+ <GlyphOrder>
+ <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+ <GlyphID id="0" name=".notdef"/>
+ <GlyphID id="1" name="uni3001"/>
+ <GlyphID id="2" name="uni30FB"/>
+ <GlyphID id="3" name="uniFF1A"/>
+ <GlyphID id="4" name="uniFF2D"/>
+ <GlyphID id="5" name="uni3073"/>
+ <GlyphID id="6" name="uni3074"/>
+ <GlyphID id="7" name="uni307B"/>
+ </GlyphOrder>
+
+ <head>
+ <!-- Most of this table will be recalculated by the compiler -->
+ <tableVersion value="1.0"/>
+ <fontRevision value="1.004"/>
+ <checkSumAdjustment value="0x90c6f91d"/>
+ <magicNumber value="0x5f0f3cf5"/>
+ <flags value="00000000 00000011"/>
+ <unitsPerEm value="1000"/>
+ <created value="Wed Jun 5 14:40:00 2019"/>
+ <modified value="Tue Jun 11 21:27:36 2019"/>
+ <xMin value="64"/>
+ <yMin value="-52"/>
+ <xMax value="974"/>
+ <yMax value="798"/>
+ <macStyle value="00000000 00000000"/>
+ <lowestRecPPEM value="3"/>
+ <fontDirectionHint value="2"/>
+ <indexToLocFormat value="0"/>
+ <glyphDataFormat value="0"/>
+ </head>
+
+ <hhea>
+ <tableVersion value="0x00010000"/>
+ <ascent value="1160"/>
+ <descent value="-317"/>
+ <lineGap value="0"/>
+ <advanceWidthMax value="1000"/>
+ <minLeftSideBearing value="64"/>
+ <minRightSideBearing value="26"/>
+ <xMaxExtent value="974"/>
+ <caretSlopeRise value="1"/>
+ <caretSlopeRun value="0"/>
+ <caretOffset value="0"/>
+ <reserved0 value="0"/>
+ <reserved1 value="0"/>
+ <reserved2 value="0"/>
+ <reserved3 value="0"/>
+ <metricDataFormat value="0"/>
+ <numberOfHMetrics value="2"/>
+ </hhea>
+
+ <maxp>
+ <tableVersion value="0x5000"/>
+ <numGlyphs value="8"/>
+ </maxp>
+
+ <OS_2>
+ <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+ will be recalculated by the compiler -->
+ <version value="3"/>
+ <xAvgCharWidth value="962"/>
+ <usWeightClass value="250"/>
+ <usWidthClass value="5"/>
+ <fsType value="00000000 00000100"/>
+ <ySubscriptXSize value="650"/>
+ <ySubscriptYSize value="600"/>
+ <ySubscriptXOffset value="0"/>
+ <ySubscriptYOffset value="75"/>
+ <ySuperscriptXSize value="650"/>
+ <ySuperscriptYSize value="600"/>
+ <ySuperscriptXOffset value="0"/>
+ <ySuperscriptYOffset value="350"/>
+ <yStrikeoutSize value="50"/>
+ <yStrikeoutPosition value="228"/>
+ <sFamilyClass value="0"/>
+ <panose>
+ <bFamilyType value="0"/>
+ <bSerifStyle value="0"/>
+ <bWeight value="3"/>
+ <bProportion value="0"/>
+ <bContrast value="0"/>
+ <bStrokeVariation value="0"/>
+ <bArmStyle value="0"/>
+ <bLetterForm value="0"/>
+ <bMidline value="0"/>
+ <bXHeight value="0"/>
+ </panose>
+ <ulUnicodeRange1 value="00000000 00000000 00000000 00000000"/>
+ <ulUnicodeRange2 value="00000000 00000111 00000000 00000000"/>
+ <ulUnicodeRange3 value="00000000 00000000 00000000 00010000"/>
+ <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+ <achVendID value="UKWN"/>
+ <fsSelection value="00000000 00000000"/>
+ <usFirstCharIndex value="12289"/>
+ <usLastCharIndex value="65325"/>
+ <sTypoAscender value="880"/>
+ <sTypoDescender value="-120"/>
+ <sTypoLineGap value="200"/>
+ <usWinAscent value="1160"/>
+ <usWinDescent value="317"/>
+ <ulCodePageRange1 value="00100000 00000010 00000000 10011111"/>
+ <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+ <sxHeight value="380"/>
+ <sCapHeight value="760"/>
+ <usDefaultChar value="0"/>
+ <usBreakChar value="32"/>
+ <usMaxContext value="1"/>
+ </OS_2>
+
+ <name>
+ <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
+ Copyright © 2018 Adobe systems Co., Ltd. All Rights Reserved.
+ </namerecord>
+ <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+ MasterSet_KanjiFullEX
+ </namerecord>
+ <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+ Regular
+ </namerecord>
+ <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+ 1.004;UKWN;MasterSet_KanjiFullEX-w0.00
+ </namerecord>
+ <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+ MasterSet_KanjiFullEX
+ </namerecord>
+ <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+ Version 1.004;hotconv 1.0.109;makeotfexe 2.5.65596
+ </namerecord>
+ <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+ MasterSet_KanjiFullEX-w0.00
+ </namerecord>
+ </name>
+
+ <cmap>
+ <tableVersion version="0"/>
+ <cmap_format_4 platformID="0" platEncID="3" language="0">
+ <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+ <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+ <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+ <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+ <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+ <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+ <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+ </cmap_format_4>
+ <cmap_format_12 platformID="0" platEncID="4" format="12" reserved="0" length="88" language="0" nGroups="6">
+ <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+ <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+ <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+ <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+ <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+ <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+ <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+ </cmap_format_12>
+ <cmap_format_4 platformID="3" platEncID="1" language="0">
+ <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+ <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+ <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+ <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+ <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+ <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+ <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+ </cmap_format_4>
+ <cmap_format_12 platformID="3" platEncID="10" format="12" reserved="0" length="88" language="0" nGroups="6">
+ <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+ <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+ <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+ <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+ <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+ <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+ <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+ </cmap_format_12>
+ </cmap>
+
+ <post>
+ <formatType value="3.0"/>
+ <italicAngle value="0.0"/>
+ <underlinePosition value="-75"/>
+ <underlineThickness value="50"/>
+ <isFixedPitch value="0"/>
+ <minMemType42 value="0"/>
+ <maxMemType42 value="0"/>
+ <minMemType1 value="0"/>
+ <maxMemType1 value="0"/>
+ </post>
+
+ <CFF>
+ <major value="1"/>
+ <minor value="0"/>
+ <CFFFont name="MasterSet_KanjiFullEX-w0.00">
+ <FamilyName value="MasterSet_KanjiFullEX"/>
+ <isFixedPitch value="0"/>
+ <ItalicAngle value="0"/>
+ <UnderlinePosition value="-100"/>
+ <UnderlineThickness value="50"/>
+ <PaintType value="0"/>
+ <CharstringType value="2"/>
+ <FontMatrix value="0.001 0 0 0.001 0 0"/>
+ <FontBBox value="64 -52 974 798"/>
+ <StrokeWidth value="0"/>
+ <!-- charset is dumped separately as the 'GlyphOrder' element -->
+ <Encoding name="StandardEncoding"/>
+ <Private>
+ <BlueValues value="0 0"/>
+ <BlueScale value="0.039625"/>
+ <BlueShift value="7"/>
+ <BlueFuzz value="1"/>
+ <ForceBold value="0"/>
+ <LanguageGroup value="0"/>
+ <ExpansionFactor value="0.06"/>
+ <initialRandomSeed value="0"/>
+ <defaultWidthX value="1000"/>
+ <nominalWidthX value="532"/>
+ </Private>
+ <CharStrings>
+ <CharString name=".notdef">
+ -282 endchar
+ </CharString>
+ <CharString name="uni3001">
+ 291 -43 rmoveto
+ 29 24 rlineto
+ -74 84 -84 83 -73 58 rrcurveto
+ -25 -24 rlineto
+ 72 -56 87 -85 68 -84 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uni3073">
+ 706 699 rmoveto
+ -32 -10 rlineto
+ 50 -192 56 -132 112 -115 rrcurveto
+ 24 26 rlineto
+ -143 124 -45 182 -22 117 rrcurveto
+ -592 -57 rmoveto
+ 3 -38 rlineto
+ 18 2 18 3 17 2 rrcurveto
+ 43 6 101 12 63 13 rrcurveto
+ -83 -80 -128 -166 0 -210 rrcurveto
+ 0 -150 92 -88 154 0 rrcurveto
+ 294 0 65 313 -48 302 rrcurveto
+ -29 79 rlineto
+ 64 -402 -96 -263 -249 0 rrcurveto
+ -109 0 -110 48 0 166 rrcurveto
+ 0 219 171 196 58 42 rrcurveto
+ 14 5 30 6 12 3 rrcurveto
+ -9 30 rlineto
+ -52 -21 -170 -26 -83 -3 rrcurveto
+ -18 -1 -21 0 -12 1 rrcurveto
+ 677 114 rmoveto
+ -26 -11 rlineto
+ 22 -34 33 -63 20 -42 rrcurveto
+ 30 14 rlineto
+ -21 41 -37 62 -21 33 rrcurveto
+ 97 40 rmoveto
+ -26 -13 rlineto
+ 24 -33 31 -59 21 -44 rrcurveto
+ 30 14 rlineto
+ -23 43 -36 60 -21 32 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uni3074">
+ 706 699 rmoveto
+ -32 -10 rlineto
+ 50 -192 56 -132 112 -115 rrcurveto
+ 24 26 rlineto
+ -143 124 -45 182 -22 117 rrcurveto
+ -592 -57 rmoveto
+ 3 -38 rlineto
+ 18 2 18 3 17 2 rrcurveto
+ 43 6 101 12 63 13 rrcurveto
+ -83 -80 -128 -166 0 -210 rrcurveto
+ 0 -150 92 -88 154 0 rrcurveto
+ 294 0 65 313 -48 302 rrcurveto
+ -29 79 rlineto
+ 64 -402 -96 -263 -249 0 rrcurveto
+ -109 0 -110 48 0 166 rrcurveto
+ 0 219 171 196 58 42 rrcurveto
+ 14 5 30 6 12 3 rrcurveto
+ -9 30 rlineto
+ -52 -21 -170 -26 -83 -3 rrcurveto
+ -18 -1 -21 0 -12 1 rrcurveto
+ 681 51 rmoveto
+ 0 42 33 33 41 0 rrcurveto
+ 41 0 33 -33 0 -42 rrcurveto
+ 0 -41 -33 -33 -41 0 rrcurveto
+ -42 0 -32 33 0 41 rrcurveto
+ -30 0 rmoveto
+ 0 -57 46 -47 58 0 rrcurveto
+ 57 0 48 47 0 57 rrcurveto
+ 0 58 -48 47 -57 0 rrcurveto
+ -58 0 -46 -47 0 -58 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uni307B">
+ 703 676 rmoveto
+ -28 0 rlineto
+ 0 -63 0 -106 0 -61 rrcurveto
+ 0 -103 14 -162 0 -52 rrcurveto
+ 0 -59 -17 -50 -97 0 rrcurveto
+ -91 0 -58 31 0 63 rrcurveto
+ 0 53 62 37 87 0 rrcurveto
+ 125 0 119 -56 94 -98 rrcurveto
+ 19 31 rlineto
+ -90 81 -113 69 -154 0 rrcurveto
+ -130 0 -47 -64 0 -53 rrcurveto
+ 0 -80 70 -42 105 0 rrcurveto
+ 85 0 58 36 0 74 rrcurveto
+ 0 68 -13 166 0 113 rrcurveto
+ 0 61 0 96 0 70 rrcurveto
+ -284 -213 rmoveto
+ 0 -31 rlineto
+ 168 -10 194 12 125 13 rrcurveto
+ 0 31 rlineto
+ -129 -15 -187 -13 -171 13 rrcurveto
+ 16 230 rmoveto
+ 0 -30 rlineto
+ 139 -7 200 11 108 11 rrcurveto
+ 0 30 rlineto
+ -111 -15 -197 -11 -139 11 rrcurveto
+ -207 51 rmoveto
+ -37 4 rlineto
+ 0 -11 -1 -14 -3 -19 rrcurveto
+ -13 -88 -37 -183 0 -143 rrcurveto
+ 0 -135 16 -105 20 -74 rrcurveto
+ 28 3 rlineto
+ -1 7 -2 12 -1 9 rrcurveto
+ -1 13 2 16 3 14 rrcurveto
+ 9 43 39 105 22 55 rrcurveto
+ -20 17 rlineto
+ -20 -48 -32 -89 -18 -56 rrcurveto
+ -10 78 -5 58 0 78 rrcurveto
+ 0 124 26 166 25 119 rrcurveto
+ 3 18 4 13 4 13 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uni30FB">
+ 500 465 rmoveto
+ -47 0 -38 -38 0 -47 rrcurveto
+ 0 -47 38 -38 47 0 rrcurveto
+ 47 0 38 38 0 47 rrcurveto
+ 0 47 -38 38 -47 0 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uniFF1A">
+ 500 572 rmoveto
+ 28 0 28 19 0 37 rrcurveto
+ 0 37 -28 19 -28 0 rrcurveto
+ -28 0 -28 -19 0 -37 rrcurveto
+ 0 -37 28 -19 28 0 rrcurveto
+ 0 -502 rmoveto
+ 28 0 28 19 0 37 rrcurveto
+ 0 37 -28 19 -28 0 rrcurveto
+ -28 0 -28 -19 0 -37 rrcurveto
+ 0 -37 28 -19 28 0 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uniFF2D">
+ 180 0 rmoveto
+ 35 0 rlineto
+ 0 502 rlineto
+ 0 57 -1 74 -2 59 rrcurveto
+ 5 0 rlineto
+ 67 -160 rlineto
+ 196 -451 rlineto
+ 39 0 rlineto
+ 195 451 rlineto
+ 69 160 rlineto
+ 5 0 rlineto
+ -2 -59 -3 -74 0 -57 rrcurveto
+ 0 -502 rlineto
+ 37 0 rlineto
+ 0 726 rlineto
+ -59 0 rlineto
+ -191 -438 rlineto
+ -23 -54 -20 -55 -24 -55 rrcurveto
+ -4 0 rlineto
+ -24 55 -23 55 -23 54 rrcurveto
+ -190 438 rlineto
+ -59 0 rlineto
+ 0 -726 rlineto
+ endchar
+ </CharString>
+ </CharStrings>
+ </CFFFont>
+
+ <GlobalSubrs>
+ <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+ </GlobalSubrs>
+ </CFF>
+
+ <GPOS>
+ <Version value="0x00010000"/>
+ <ScriptList>
+ <!-- ScriptCount=1 -->
+ <ScriptRecord index="0">
+ <ScriptTag value="DFLT"/>
+ <Script>
+ <DefaultLangSys>
+ <ReqFeatureIndex value="65535"/>
+ <!-- FeatureCount=1 -->
+ <FeatureIndex index="0" value="0"/>
+ </DefaultLangSys>
+ <!-- LangSysCount=0 -->
+ </Script>
+ </ScriptRecord>
+ </ScriptList>
+ <FeatureList>
+ <!-- FeatureCount=1 -->
+ <FeatureRecord index="0">
+ <FeatureTag value="vpal"/>
+ <Feature>
+ <!-- LookupCount=1 -->
+ <LookupListIndex index="0" value="0"/>
+ </Feature>
+ </FeatureRecord>
+ </FeatureList>
+ <LookupList>
+ <!-- LookupCount=1 -->
+ <Lookup index="0">
+ <LookupType value="1"/>
+ <LookupFlag value="0"/>
+ <!-- SubTableCount=5 -->
+ <SinglePos index="0" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uni3001"/>
+ <Glyph value="uniFF1A"/>
+ </Coverage>
+ <ValueFormat value="5"/>
+ <!-- ValueCount=2 -->
+ <Value index="0" XPlacement="-9" XAdvance="-500"/>
+ <Value index="1" XPlacement="-250" XAdvance="-500"/>
+ </SinglePos>
+ <SinglePos index="1" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uni30FB"/>
+ </Coverage>
+ <ValueFormat value="7"/>
+ <!-- ValueCount=1 -->
+ <Value index="0" XPlacement="-250" YPlacement="1" XAdvance="-500"/>
+ </SinglePos>
+ <SinglePos index="2" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uni3073"/>
+ <Glyph value="uni3074"/>
+ </Coverage>
+ <ValueFormat value="4"/>
+ <!-- ValueCount=2 -->
+ <Value index="0" XAdvance="-36"/>
+ <Value index="1" XAdvance="-30"/>
+ </SinglePos>
+ <SinglePos index="3" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uni307B"/>
+ </Coverage>
+ <ValueFormat value="1"/>
+ <!-- ValueCount=1 -->
+ <Value index="0" XPlacement="11"/>
+ </SinglePos>
+ <SinglePos index="4" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uniFF2D"/>
+ </Coverage>
+ <ValueFormat value="5"/>
+ <!-- ValueCount=1 -->
+ <Value index="0" XPlacement="12" XAdvance="23"/>
+ </SinglePos>
+ </Lookup>
+ </LookupList>
+ </GPOS>
+
+ <hmtx>
+ <mtx name=".notdef" width="250" lsb="0"/>
+ <mtx name="uni3001" width="1000" lsb="64"/>
+ <mtx name="uni3073" width="1000" lsb="114"/>
+ <mtx name="uni3074" width="1000" lsb="114"/>
+ <mtx name="uni307B" width="1000" lsb="137"/>
+ <mtx name="uni30FB" width="1000" lsb="415"/>
+ <mtx name="uniFF1A" width="1000" lsb="444"/>
+ <mtx name="uniFF2D" width="1000" lsb="180"/>
+ </hmtx>
+
+</ttFont>
diff --git a/Tests/varLib/data/master_vpal_test/master_vpal_test_1.ttx b/Tests/varLib/data/master_vpal_test/master_vpal_test_1.ttx
new file mode 100644
index 0000000..bb43958
--- /dev/null
+++ b/Tests/varLib/data/master_vpal_test/master_vpal_test_1.ttx
@@ -0,0 +1,473 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.42">
+
+ <GlyphOrder>
+ <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
+ <GlyphID id="0" name=".notdef"/>
+ <GlyphID id="1" name="uni3001"/>
+ <GlyphID id="2" name="uni30FB"/>
+ <GlyphID id="3" name="uniFF1A"/>
+ <GlyphID id="4" name="uniFF2D"/>
+ <GlyphID id="5" name="uni3073"/>
+ <GlyphID id="6" name="uni3074"/>
+ <GlyphID id="7" name="uni307B"/>
+ </GlyphOrder>
+
+ <head>
+ <!-- Most of this table will be recalculated by the compiler -->
+ <tableVersion value="1.0"/>
+ <fontRevision value="1.004"/>
+ <checkSumAdjustment value="0xfa2dc49e"/>
+ <magicNumber value="0x5f0f3cf5"/>
+ <flags value="00000000 00000011"/>
+ <unitsPerEm value="1000"/>
+ <created value="Wed Jun 5 14:40:08 2019"/>
+ <modified value="Tue Jun 11 21:27:55 2019"/>
+ <xMin value="33"/>
+ <yMin value="-87"/>
+ <xMax value="992"/>
+ <yMax value="855"/>
+ <macStyle value="00000000 00000000"/>
+ <lowestRecPPEM value="3"/>
+ <fontDirectionHint value="2"/>
+ <indexToLocFormat value="0"/>
+ <glyphDataFormat value="0"/>
+ </head>
+
+ <hhea>
+ <tableVersion value="0x00010000"/>
+ <ascent value="1160"/>
+ <descent value="-317"/>
+ <lineGap value="0"/>
+ <advanceWidthMax value="1000"/>
+ <minLeftSideBearing value="33"/>
+ <minRightSideBearing value="8"/>
+ <xMaxExtent value="992"/>
+ <caretSlopeRise value="1"/>
+ <caretSlopeRun value="0"/>
+ <caretOffset value="0"/>
+ <reserved0 value="0"/>
+ <reserved1 value="0"/>
+ <reserved2 value="0"/>
+ <reserved3 value="0"/>
+ <metricDataFormat value="0"/>
+ <numberOfHMetrics value="2"/>
+ </hhea>
+
+ <maxp>
+ <tableVersion value="0x5000"/>
+ <numGlyphs value="8"/>
+ </maxp>
+
+ <OS_2>
+ <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
+ will be recalculated by the compiler -->
+ <version value="3"/>
+ <xAvgCharWidth value="971"/>
+ <usWeightClass value="900"/>
+ <usWidthClass value="5"/>
+ <fsType value="00000000 00000100"/>
+ <ySubscriptXSize value="650"/>
+ <ySubscriptYSize value="600"/>
+ <ySubscriptXOffset value="0"/>
+ <ySubscriptYOffset value="75"/>
+ <ySuperscriptXSize value="650"/>
+ <ySuperscriptYSize value="600"/>
+ <ySuperscriptXOffset value="0"/>
+ <ySuperscriptYOffset value="350"/>
+ <yStrikeoutSize value="50"/>
+ <yStrikeoutPosition value="228"/>
+ <sFamilyClass value="0"/>
+ <panose>
+ <bFamilyType value="0"/>
+ <bSerifStyle value="0"/>
+ <bWeight value="10"/>
+ <bProportion value="0"/>
+ <bContrast value="0"/>
+ <bStrokeVariation value="0"/>
+ <bArmStyle value="0"/>
+ <bLetterForm value="0"/>
+ <bMidline value="0"/>
+ <bXHeight value="0"/>
+ </panose>
+ <ulUnicodeRange1 value="00000000 00000000 00000000 00000000"/>
+ <ulUnicodeRange2 value="00000000 00000111 00000000 00000000"/>
+ <ulUnicodeRange3 value="00000000 00000000 00000000 00010000"/>
+ <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
+ <achVendID value="UKWN"/>
+ <fsSelection value="00000000 00000000"/>
+ <usFirstCharIndex value="12289"/>
+ <usLastCharIndex value="65325"/>
+ <sTypoAscender value="880"/>
+ <sTypoDescender value="-120"/>
+ <sTypoLineGap value="200"/>
+ <usWinAscent value="1160"/>
+ <usWinDescent value="317"/>
+ <ulCodePageRange1 value="00100000 00000010 00000000 10011111"/>
+ <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
+ <sxHeight value="380"/>
+ <sCapHeight value="760"/>
+ <usDefaultChar value="0"/>
+ <usBreakChar value="32"/>
+ <usMaxContext value="1"/>
+ </OS_2>
+
+ <name>
+ <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
+ Copyright © 2018 Adobe systems Co., Ltd. All Rights Reserved.
+ </namerecord>
+ <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
+ MasterSet_KanjiFullEX
+ </namerecord>
+ <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
+ Regular
+ </namerecord>
+ <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
+ 1.004;UKWN;MasterSet_KanjiFullEX-w1000.00
+ </namerecord>
+ <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
+ MasterSet_KanjiFullEX
+ </namerecord>
+ <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
+ Version 1.004;hotconv 1.0.109;makeotfexe 2.5.65596
+ </namerecord>
+ <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
+ MasterSet_KanjiFullEX-w1000.00
+ </namerecord>
+ </name>
+
+ <cmap>
+ <tableVersion version="0"/>
+ <cmap_format_4 platformID="0" platEncID="3" language="0">
+ <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+ <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+ <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+ <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+ <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+ <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+ <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+ </cmap_format_4>
+ <cmap_format_12 platformID="0" platEncID="4" format="12" reserved="0" length="88" language="0" nGroups="6">
+ <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+ <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+ <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+ <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+ <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+ <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+ <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+ </cmap_format_12>
+ <cmap_format_4 platformID="3" platEncID="1" language="0">
+ <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+ <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+ <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+ <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+ <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+ <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+ <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+ </cmap_format_4>
+ <cmap_format_12 platformID="3" platEncID="10" format="12" reserved="0" length="88" language="0" nGroups="6">
+ <map code="0x3001" name="uni3001"/><!-- IDEOGRAPHIC COMMA -->
+ <map code="0x3073" name="uni3073"/><!-- HIRAGANA LETTER BI -->
+ <map code="0x3074" name="uni3074"/><!-- HIRAGANA LETTER PI -->
+ <map code="0x307b" name="uni307B"/><!-- HIRAGANA LETTER HO -->
+ <map code="0x30fb" name="uni30FB"/><!-- KATAKANA MIDDLE DOT -->
+ <map code="0xff1a" name="uniFF1A"/><!-- FULLWIDTH COLON -->
+ <map code="0xff2d" name="uniFF2D"/><!-- FULLWIDTH LATIN CAPITAL LETTER M -->
+ </cmap_format_12>
+ </cmap>
+
+ <post>
+ <formatType value="3.0"/>
+ <italicAngle value="0.0"/>
+ <underlinePosition value="-75"/>
+ <underlineThickness value="50"/>
+ <isFixedPitch value="0"/>
+ <minMemType42 value="0"/>
+ <maxMemType42 value="0"/>
+ <minMemType1 value="0"/>
+ <maxMemType1 value="0"/>
+ </post>
+
+ <CFF>
+ <major value="1"/>
+ <minor value="0"/>
+ <CFFFont name="MasterSet_KanjiFullEX-w1000.00">
+ <FamilyName value="MasterSet_KanjiFullEX"/>
+ <isFixedPitch value="0"/>
+ <ItalicAngle value="0"/>
+ <UnderlinePosition value="-100"/>
+ <UnderlineThickness value="50"/>
+ <PaintType value="0"/>
+ <CharstringType value="2"/>
+ <FontMatrix value="0.001 0 0 0.001 0 0"/>
+ <FontBBox value="33 -87 992 855"/>
+ <StrokeWidth value="0"/>
+ <!-- charset is dumped separately as the 'GlyphOrder' element -->
+ <Encoding name="StandardEncoding"/>
+ <Private>
+ <BlueValues value="0 0"/>
+ <BlueScale value="0.039625"/>
+ <BlueShift value="7"/>
+ <BlueFuzz value="1"/>
+ <ForceBold value="0"/>
+ <LanguageGroup value="0"/>
+ <ExpansionFactor value="0.06"/>
+ <initialRandomSeed value="0"/>
+ <defaultWidthX value="1000"/>
+ <nominalWidthX value="705"/>
+ </Private>
+ <CharStrings>
+ <CharString name=".notdef">
+ -455 endchar
+ </CharString>
+ <CharString name="uni3001">
+ 245 -76 rmoveto
+ 129 111 rlineto
+ -44 56 -100 103 -70 58 rrcurveto
+ -127 -109 rlineto
+ 69 -61 84 -86 59 -72 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uni3073">
+ 729 763 rmoveto
+ -152 -42 rlineto
+ 75 -225 86 -176 109 -123 rrcurveto
+ 97 140 rlineto
+ -155 146 -41 152 -19 128 rrcurveto
+ -677 -48 rmoveto
+ 11 -156 rlineto
+ 24 5 15 2 22 3 rrcurveto
+ 26 3 53 6 31 1 rrcurveto
+ -96 -130 -50 -109 0 -149 rrcurveto
+ 0 -190 149 -88 163 0 rrcurveto
+ 344 0 43 303 -58 260 rrcurveto
+ -142 223 rlineto
+ 96 -376 -59 -246 -221 0 rrcurveto
+ -92 0 -67 46 0 103 rrcurveto
+ 0 184 125 143 71 54 rrcurveto
+ 16 10 18 8 15 6 rrcurveto
+ -46 134 rlineto
+ -69 -25 -166 -20 -98 -5 rrcurveto
+ -19 -1 -20 0 -19 1 rrcurveto
+ 768 103 rmoveto
+ -88 -27 rlineto
+ 22 -45 16 -54 15 -49 rrcurveto
+ 87 28 rlineto
+ -11 41 -23 62 -18 44 rrcurveto
+ 110 37 rmoveto
+ -85 -28 rlineto
+ 21 -44 19 -57 14 -46 rrcurveto
+ 88 28 rlineto
+ -13 40 -22 63 -22 44 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uni3074">
+ 729 763 rmoveto
+ -152 -42 rlineto
+ 75 -225 86 -176 109 -123 rrcurveto
+ 97 140 rlineto
+ -155 146 -41 152 -19 128 rrcurveto
+ -677 -48 rmoveto
+ 11 -156 rlineto
+ 24 5 15 2 22 3 rrcurveto
+ 26 3 53 6 31 1 rrcurveto
+ -96 -130 -50 -109 0 -149 rrcurveto
+ 0 -190 149 -88 163 0 rrcurveto
+ 344 0 43 303 -58 260 rrcurveto
+ -142 223 rlineto
+ 96 -376 -59 -246 -221 0 rrcurveto
+ -92 0 -67 46 0 103 rrcurveto
+ 0 184 125 143 71 54 rrcurveto
+ 16 10 18 8 15 6 rrcurveto
+ -46 134 rlineto
+ -69 -25 -166 -20 -98 -5 rrcurveto
+ -19 -1 -20 0 -19 1 rrcurveto
+ 772 16 rmoveto
+ 0 27 22 22 27 0 rrcurveto
+ 27 0 22 -22 0 -27 rrcurveto
+ 0 -27 -22 -22 -27 0 rrcurveto
+ -27 0 -22 22 0 27 rrcurveto
+ -70 0 rmoveto
+ 0 -66 53 -53 66 0 rrcurveto
+ 66 0 53 53 0 66 rrcurveto
+ 0 66 -53 53 -66 0 rrcurveto
+ -66 0 -53 -53 0 -66 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uni307B">
+ 758 687 rmoveto
+ -141 0 rlineto
+ 0 -42 0 -111 0 -88 rrcurveto
+ 0 -104 8 -126 0 -63 rrcurveto
+ 0 -45 -23 -24 -49 0 rrcurveto
+ -37 0 -24 16 0 29 rrcurveto
+ 0 28 23 18 48 0 rrcurveto
+ 107 0 121 -81 97 -98 rrcurveto
+ 79 131 rlineto
+ -51 45 -135 115 -213 0 rrcurveto
+ -137 0 -76 -72 0 -97 rrcurveto
+ 0 -116 100 -52 119 0 rrcurveto
+ 142 0 55 65 0 93 rrcurveto
+ 0 97 -13 99 0 147 rrcurveto
+ 0 64 0 96 0 76 rrcurveto
+ -360 -167 rmoveto
+ 1 -139 rlineto
+ 195 -9 191 7 133 16 rrcurveto
+ 0 139 rlineto
+ -148 -18 -178 -11 -194 15 rrcurveto
+ 15 235 rmoveto
+ 0 -134 rlineto
+ 197 -9 162 8 126 14 rrcurveto
+ 0 134 rlineto
+ -127 -19 -163 -9 -195 15 rrcurveto
+ -117 26 rmoveto
+ -168 14 rlineto
+ -1 -37 -6 -47 -4 -29 rrcurveto
+ -11 -74 -26 -192 0 -153 rrcurveto
+ 0 -136 20 -117 21 -68 rrcurveto
+ 139 10 rlineto
+ -1 16 0 18 0 11 rrcurveto
+ 0 10 3 23 3 14 rrcurveto
+ 12 58 30 101 30 90 rrcurveto
+ -73 59 rlineto
+ -13 -30 -14 -23 -12 -29 rrcurveto
+ -1 4 0 20 0 3 rrcurveto
+ 0 93 33 237 12 52 rrcurveto
+ 4 18 14 62 9 22 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uni30FB">
+ 500 520 rmoveto
+ -77 0 -63 -63 0 -77 rrcurveto
+ 0 -77 63 -63 77 0 rrcurveto
+ 77 0 63 63 0 77 rrcurveto
+ 0 77 -63 63 -77 0 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uniFF1A">
+ 500 500 rmoveto
+ 60 0 46 46 0 58 rrcurveto
+ 0 60 -46 46 -60 0 rrcurveto
+ -60 0 -46 -46 0 -60 rrcurveto
+ 0 -58 46 -46 60 0 rrcurveto
+ 0 -470 rmoveto
+ 60 0 46 46 0 58 rrcurveto
+ 0 60 -46 46 -60 0 rrcurveto
+ -60 0 -46 -46 0 -60 rrcurveto
+ 0 -58 46 -46 60 0 rrcurveto
+ endchar
+ </CharString>
+ <CharString name="uniFF2D">
+ 113 0 rmoveto
+ 160 0 rlineto
+ 0 255 rlineto
+ 0 75 -12 113 -9 74 rrcurveto
+ 4 0 rlineto
+ 72 -182 rlineto
+ 121 -272 rlineto
+ 98 0 rlineto
+ 120 272 rlineto
+ 73 182 rlineto
+ 5 0 rlineto
+ -10 -74 -12 -113 0 -75 rrcurveto
+ 0 -255 rlineto
+ 163 0 rlineto
+ 0 748 rlineto
+ -194 0 rlineto
+ -135 -325 rlineto
+ -17 -43 -18 -47 -18 -46 rrcurveto
+ -5 0 rlineto
+ -16 46 -19 47 -16 43 rrcurveto
+ -142 325 rlineto
+ -193 0 rlineto
+ 0 -748 rlineto
+ endchar
+ </CharString>
+ </CharStrings>
+ </CFFFont>
+
+ <GlobalSubrs>
+ <!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
+ </GlobalSubrs>
+ </CFF>
+
+ <GPOS>
+ <Version value="0x00010000"/>
+ <ScriptList>
+ <!-- ScriptCount=1 -->
+ <ScriptRecord index="0">
+ <ScriptTag value="DFLT"/>
+ <Script>
+ <DefaultLangSys>
+ <ReqFeatureIndex value="65535"/>
+ <!-- FeatureCount=1 -->
+ <FeatureIndex index="0" value="0"/>
+ </DefaultLangSys>
+ <!-- LangSysCount=0 -->
+ </Script>
+ </ScriptRecord>
+ </ScriptList>
+ <FeatureList>
+ <!-- FeatureCount=1 -->
+ <FeatureRecord index="0">
+ <FeatureTag value="vpal"/>
+ <Feature>
+ <!-- LookupCount=1 -->
+ <LookupListIndex index="0" value="0"/>
+ </Feature>
+ </FeatureRecord>
+ </FeatureList>
+ <LookupList>
+ <!-- LookupCount=1 -->
+ <Lookup index="0">
+ <LookupType value="1"/>
+ <LookupFlag value="0"/>
+ <!-- SubTableCount=3 -->
+ <SinglePos index="0" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uni3001"/>
+ <Glyph value="uni30FB"/>
+ <Glyph value="uniFF1A"/>
+ </Coverage>
+ <ValueFormat value="5"/>
+ <!-- ValueCount=3 -->
+ <Value index="0" XPlacement="-3" XAdvance="-500"/>
+ <Value index="1" XPlacement="-250" XAdvance="-500"/>
+ <Value index="2" XPlacement="-250" XAdvance="-500"/>
+ </SinglePos>
+ <SinglePos index="1" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uni3073"/>
+ <Glyph value="uni3074"/>
+ </Coverage>
+ <ValueFormat value="4"/>
+ <!-- ValueCount=2 -->
+ <Value index="0" XAdvance="-35"/>
+ <Value index="1" XAdvance="-30"/>
+ </SinglePos>
+ <SinglePos index="2" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uniFF2D"/>
+ <Glyph value="uni307B"/>
+ </Coverage>
+ <ValueFormat value="1"/>
+ <!-- ValueCount=2 -->
+ <Value index="0" XPlacement="1"/>
+ <Value index="1" XPlacement="10"/>
+ </SinglePos>
+ </Lookup>
+ </LookupList>
+ </GPOS>
+
+ <hmtx>
+ <mtx name=".notdef" width="250" lsb="0"/>
+ <mtx name="uni3001" width="1000" lsb="33"/>
+ <mtx name="uni3073" width="1000" lsb="52"/>
+ <mtx name="uni3074" width="1000" lsb="52"/>
+ <mtx name="uni307B" width="1000" lsb="80"/>
+ <mtx name="uni30FB" width="1000" lsb="360"/>
+ <mtx name="uniFF1A" width="1000" lsb="394"/>
+ <mtx name="uniFF2D" width="1000" lsb="113"/>
+ </hmtx>
+
+</ttFont>
diff --git a/Tests/varLib/data/test_results/test_vpal.ttx b/Tests/varLib/data/test_results/test_vpal.ttx
new file mode 100644
index 0000000..334ced5
--- /dev/null
+++ b/Tests/varLib/data/test_results/test_vpal.ttx
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ttFont sfntVersion="OTTO" ttLibVersion="3.42">
+
+ <GPOS>
+ <Version value="0x00010000"/>
+ <ScriptList>
+ <!-- ScriptCount=1 -->
+ <ScriptRecord index="0">
+ <ScriptTag value="DFLT"/>
+ <Script>
+ <DefaultLangSys>
+ <ReqFeatureIndex value="65535"/>
+ <!-- FeatureCount=1 -->
+ <FeatureIndex index="0" value="0"/>
+ </DefaultLangSys>
+ <!-- LangSysCount=0 -->
+ </Script>
+ </ScriptRecord>
+ </ScriptList>
+ <FeatureList>
+ <!-- FeatureCount=1 -->
+ <FeatureRecord index="0">
+ <FeatureTag value="vpal"/>
+ <Feature>
+ <!-- LookupCount=1 -->
+ <LookupListIndex index="0" value="0"/>
+ </Feature>
+ </FeatureRecord>
+ </FeatureList>
+ <LookupList>
+ <!-- LookupCount=1 -->
+ <Lookup index="0">
+ <LookupType value="1"/>
+ <LookupFlag value="0"/>
+ <!-- SubTableCount=6 -->
+ <SinglePos index="0" Format="2">
+ <Coverage Format="1">
+ <Glyph value="uniFF1A"/>
+ <Glyph value="uni3074"/>
+ </Coverage>
+ <ValueFormat value="7"/>
+ <!-- ValueCount=2 -->
+ <Value index="0" XPlacement="-250" YPlacement="0" XAdvance="-500"/>
+ <Value index="1" XPlacement="0" YPlacement="0" XAdvance="-30"/>
+ </SinglePos>
+ <SinglePos index="1" Format="1">
+ <Coverage Format="1">
+ <Glyph value="uni3001"/>
+ </Coverage>
+ <ValueFormat value="23"/>
+ <Value XPlacement="-9" YPlacement="0" XAdvance="-500">
+ <XPlaDevice>
+ <StartSize value="0"/>
+ <EndSize value="4"/>
+ <DeltaFormat value="32768"/>
+ </XPlaDevice>
+ </Value>
+ </SinglePos>
+ <SinglePos index="2" Format="1">
+ <Coverage Format="1">
+ <Glyph value="uni30FB"/>
+ </Coverage>
+ <ValueFormat value="39"/>
+ <Value XPlacement="-250" YPlacement="1" XAdvance="-500">
+ <YPlaDevice>
+ <StartSize value="0"/>
+ <EndSize value="2"/>
+ <DeltaFormat value="32768"/>
+ </YPlaDevice>
+ </Value>
+ </SinglePos>
+ <SinglePos index="3" Format="1">
+ <Coverage Format="1">
+ <Glyph value="uniFF2D"/>
+ </Coverage>
+ <ValueFormat value="87"/>
+ <Value XPlacement="12" YPlacement="0" XAdvance="23">
+ <XPlaDevice>
+ <StartSize value="0"/>
+ <EndSize value="1"/>
+ <DeltaFormat value="32768"/>
+ </XPlaDevice>
+ <XAdvDevice>
+ <StartSize value="0"/>
+ <EndSize value="0"/>
+ <DeltaFormat value="32768"/>
+ </XAdvDevice>
+ </Value>
+ </SinglePos>
+ <SinglePos index="4" Format="1">
+ <Coverage Format="1">
+ <Glyph value="uni3073"/>
+ </Coverage>
+ <ValueFormat value="71"/>
+ <Value XPlacement="0" YPlacement="0" XAdvance="-36">
+ <XAdvDevice>
+ <StartSize value="0"/>
+ <EndSize value="3"/>
+ <DeltaFormat value="32768"/>
+ </XAdvDevice>
+ </Value>
+ </SinglePos>
+ <SinglePos index="5" Format="1">
+ <Coverage Format="1">
+ <Glyph value="uni307B"/>
+ </Coverage>
+ <ValueFormat value="23"/>
+ <Value XPlacement="11" YPlacement="0" XAdvance="0">
+ <XPlaDevice>
+ <StartSize value="0"/>
+ <EndSize value="2"/>
+ <DeltaFormat value="32768"/>
+ </XPlaDevice>
+ </Value>
+ </SinglePos>
+ </Lookup>
+ </LookupList>
+ </GPOS>
+
+</ttFont>
diff --git a/Tests/varLib/data/test_vpal.designspace b/Tests/varLib/data/test_vpal.designspace
new file mode 100644
index 0000000..a736927
--- /dev/null
+++ b/Tests/varLib/data/test_vpal.designspace
@@ -0,0 +1,35 @@
+<?xml version='1.0' encoding='utf-8'?>
+<designspace format="3">
+ <axes>
+ <axis default="0" maximum="1000" minimum="0" name="weight" tag="wght" />
+ </axes>
+ <sources>
+ <source filename="master_vpal_test/master_vpal_test_0.ufo" stylename="w0.00">
+ <info copy="1" />
+ <location>
+ <dimension name="weight" xvalue="0.00" />
+ </location>
+ </source>
+ <source filename="master_vpal_test/master_vpal_test_1.ufo" stylename="w1000.00">
+ <location>
+ <dimension name="weight" xvalue="1000.00" />
+ </location>
+ </source>
+ </sources>
+ <instances>
+ <instance familyname="SHSansJPVFTest" filename="instances/SHSansJPVFTest-ExtraLight.otf" postscriptfontname="SHSansJPVFTest-ExtraLight" stylename="ExtraLight">
+ <location>
+ <dimension name="weight" xvalue="0" />
+ </location>
+ <kerning />
+ <info />
+ </instance>
+ <instance familyname="SHSansJPVFTest" filename="instances/SHSansJPVFTest-Heavy.otf" postscriptfontname="SHSansJPVFTest-Heavy" stylename="Heavy">
+ <location>
+ <dimension name="weight" xvalue="1000" />
+ </location>
+ <kerning />
+ <info />
+ </instance>
+ </instances>
+</designspace>
diff --git a/Tests/varLib/varLib_test.py b/Tests/varLib/varLib_test.py
index 3be5c2e..e29befb 100644
--- a/Tests/varLib/varLib_test.py
+++ b/Tests/varLib/varLib_test.py
@@ -294,6 +294,28 @@
tables = ["fvar", "CFF2"]
self.expect_ttx(varfont, expected_ttx_path, tables)
+ def test_varlib_build_vpal(self):
+ ds_path = self.get_test_input('test_vpal.designspace')
+ ttx_dir = self.get_test_input("master_vpal_test")
+ expected_ttx_path = self.get_test_output("test_vpal.ttx")
+
+ self.temp_dir()
+ for path in self.get_file_list(ttx_dir, '.ttx', 'master_vpal_test_'):
+ self.compile_font(path, ".otf", self.tempdir)
+
+ ds = DesignSpaceDocument.fromfile(ds_path)
+ for source in ds.sources:
+ source.path = os.path.join(
+ self.tempdir, os.path.basename(source.filename).replace(".ufo", ".otf")
+ )
+ ds.updatePaths()
+
+ varfont, _, _ = build(ds)
+ varfont = reload_font(varfont)
+
+ tables = ["GPOS"]
+ self.expect_ttx(varfont, expected_ttx_path, tables)
+
def test_varlib_main_ttf(self):
"""Mostly for testing varLib.main()
"""