Merge branch 'fonttools:main' into main

This commit is contained in:
Eric Muller 2021-05-25 09:46:42 -07:00
commit bb5d59300c
11 changed files with 646 additions and 116 deletions

View File

@ -3,6 +3,6 @@ from fontTools.misc.loggingTools import configLogger
log = logging.getLogger(__name__)
version = __version__ = "4.24.3.dev0"
version = __version__ = "4.24.5.dev0"
__all__ = ["version", "log", "configLogger"]

View File

@ -358,13 +358,13 @@ class OTTableWriter(object):
tables, extTables, done = extTables, None, {}
# add Coverage table if it is sorted last.
sortCoverageLast = 0
sortCoverageLast = False
if hasattr(self, "sortCoverageLast"):
# Find coverage table
for i in range(numItems):
item = self.items[i]
if hasattr(item, "name") and (item.name == "Coverage"):
sortCoverageLast = 1
if getattr(item, 'name', None) == "Coverage":
sortCoverageLast = True
break
if id(item) not in done:
item._gatherTables(tables, extTables, done)
@ -377,7 +377,7 @@ class OTTableWriter(object):
if not hasattr(item, "getData"):
continue
if sortCoverageLast and (i==1) and item.name == 'Coverage':
if sortCoverageLast and (i==1) and getattr(item, 'name', None) == 'Coverage':
# we've already 'gathered' it above
continue

View File

@ -1503,7 +1503,6 @@ def fixLookupOverFlows(ttf, overflowRecord):
def splitMultipleSubst(oldSubTable, newSubTable, overflowRecord):
ok = 1
newSubTable.Format = oldSubTable.Format
oldMapping = sorted(oldSubTable.mapping.items())
oldLen = len(oldMapping)
@ -1529,7 +1528,6 @@ def splitMultipleSubst(oldSubTable, newSubTable, overflowRecord):
def splitAlternateSubst(oldSubTable, newSubTable, overflowRecord):
ok = 1
newSubTable.Format = oldSubTable.Format
if hasattr(oldSubTable, 'sortCoverageLast'):
newSubTable.sortCoverageLast = oldSubTable.sortCoverageLast
@ -1559,7 +1557,6 @@ def splitAlternateSubst(oldSubTable, newSubTable, overflowRecord):
def splitLigatureSubst(oldSubTable, newSubTable, overflowRecord):
ok = 1
newSubTable.Format = oldSubTable.Format
oldLigs = sorted(oldSubTable.ligatures.items())
oldLen = len(oldLigs)

View File

@ -993,7 +993,7 @@ def merge(merger, self, lst):
varidx = (dev.StartSize << 16) + dev.EndSize
delta = otRound(instancer[varidx])
setattr(self, name, getattr(self, name) + delta)
setattr(self, name, getattr(self, name, 0) + delta)
#

View File

@ -1,3 +1,18 @@
4.24.4 (released 2021-05-25)
----------------------------
- [subset/instancer] Fixed ``AttributeError`` when instantiating a VF that
contains GPOS ValueRecords with ``Device`` tables but without the respective
non-Device values (e.g. ``XAdvDevice`` without ``XAdvance``). When not
explicitly set, the latter are assumed to be 0 (#2323).
4.24.3 (released 2021-05-20)
----------------------------
- [otTables] Fixed ``AttributeError`` in methods that split LigatureSubst,
MultipleSubst and AlternateSubst subtables when an offset overflow occurs.
The ``Format`` attribute was removed in v4.22.0 (#2319).
4.24.2 (released 2021-05-20)
----------------------------

View File

@ -205,6 +205,36 @@ are required to unlock the extra features named "ufo", etc.
* `reportlab <https://pypi.python.org/pypi/reportlab>`__: Python toolkit
for generating PDFs and graphics.
How to make a new release
~~~~~~~~~~~~~~~~~~~~~~~~~
1) Update ``NEWS.rst`` with all the changes since the last release. Write a
changelog entry for each PR, with one or two short sentences summarizing it,
as well as links to the PR and relevant issues addressed by the PR.
2) Use semantic versioning to decide whether the new release will be a 'major',
'minor' or 'patch' release. It's usually one of the latter two, depending on
whether new backward compatible APIs were added, or simply some bugs were fixed.
3) Run ``python setup.py release`` command from the tip of the ``main`` branch.
By default this bumps the third or 'patch' digit only, unless you pass ``--major``
or ``--minor`` to bump respectively the first or second digit.
This bumps the package version string, extracts the changes since the latest
version from ``NEWS.rst``, and uses that text to create an annotated git tag
(or a signed git tag if you pass the ``--sign`` option and your git and Github
account are configured for `signing commits <https://docs.github.com/en/github/authenticating-to-github/managing-commit-signature-verification/signing-commits>`__
using a GPG key).
It also commits an additional version bump which opens the main branch for
the subsequent developmental cycle
4) Push both the tag and commit to the upstream repository, by running the command
``git push --follow-tags``.
5) Let the CI build the wheel and source distribution packages and verify both
get uploaded to the Python Package Index (PyPI).
6) [Optional] Go to fonttools `Github Releases <https://github.com/fonttools/fonttools/releases>`__
page and create a new release, copy-pasting the content of the git tag
message. This way, the release notes are nicely formatted as markdown, and
users watching the repo will get an email notification. One day we shall
automate that too.
Acknowledgements
~~~~~~~~~~~~~~~~

View File

@ -512,8 +512,11 @@ class InsertionMorphActionTest(unittest.TestCase):
for name, attrs, content in parseXML(self.MORPH_ACTION_XML):
a.fromXML(name, attrs, content, self.font)
writer = OTTableWriter()
a.compile(writer, self.font,
actionIndex={('B', 'C'): 9, ('B', 'A', 'D'): 7})
a.compile(
writer,
self.font,
actionIndex={('B', 'C'): 9, ('B', 'A', 'D'): 7},
)
self.assertEqual(hexStr(writer.getAllData()), "1234fc4300090007")
def testCompileActions_empty(self):
@ -551,13 +554,11 @@ class SplitMultipleSubstTest:
from fontTools.ttLib.tables.otBase import OverflowErrorRecord
oldSubTable = buildMultipleSubstSubtable({'e': 1, 'a': 2, 'b': 3, 'c': 4, 'd': 5})
oldSubTable.Format = 1
newSubTable = otTables.MultipleSubst()
ok = otTables.splitMultipleSubst(oldSubTable, newSubTable, OverflowErrorRecord((None, None, None, itemName, itemRecord)))
assert ok
assert oldSubTable.Format == newSubTable.Format
return oldSubTable.mapping, newSubTable.mapping
def test_Coverage(self):
@ -577,113 +578,113 @@ class SplitMultipleSubstTest:
def test_splitMarkBasePos():
from fontTools.otlLib.builder import buildAnchor, buildMarkBasePosSubtable
from fontTools.otlLib.builder import buildAnchor, buildMarkBasePosSubtable
marks = {
"acutecomb": (0, buildAnchor(0, 600)),
"gravecomb": (0, buildAnchor(0, 590)),
"cedillacomb": (1, buildAnchor(0, 0)),
}
bases = {
"a": {
0: buildAnchor(350, 500),
1: None,
},
"c": {
0: buildAnchor(300, 700),
1: buildAnchor(300, 0),
},
}
glyphOrder = ["a", "c", "acutecomb", "gravecomb", "cedillacomb"]
glyphMap = {g: i for i, g in enumerate(glyphOrder)}
marks = {
"acutecomb": (0, buildAnchor(0, 600)),
"gravecomb": (0, buildAnchor(0, 590)),
"cedillacomb": (1, buildAnchor(0, 0)),
}
bases = {
"a": {
0: buildAnchor(350, 500),
1: None,
},
"c": {
0: buildAnchor(300, 700),
1: buildAnchor(300, 0),
},
}
glyphOrder = ["a", "c", "acutecomb", "gravecomb", "cedillacomb"]
glyphMap = {g: i for i, g in enumerate(glyphOrder)}
oldSubTable = buildMarkBasePosSubtable(marks, bases, glyphMap)
newSubTable = otTables.MarkBasePos()
oldSubTable = buildMarkBasePosSubtable(marks, bases, glyphMap)
newSubTable = otTables.MarkBasePos()
ok = otTables.splitMarkBasePos(oldSubTable, newSubTable, overflowRecord=None)
ok = otTables.splitMarkBasePos(oldSubTable, newSubTable, overflowRecord=None)
assert ok
assert ok
assert getXML(oldSubTable.toXML) == [
'<MarkBasePos Format="1">',
' <MarkCoverage>',
' <Glyph value="acutecomb"/>',
' <Glyph value="gravecomb"/>',
' </MarkCoverage>',
' <BaseCoverage>',
' <Glyph value="a"/>',
' <Glyph value="c"/>',
' </BaseCoverage>',
' <!-- ClassCount=1 -->',
' <MarkArray>',
' <!-- MarkCount=2 -->',
' <MarkRecord index="0">',
' <Class value="0"/>',
' <MarkAnchor Format="1">',
' <XCoordinate value="0"/>',
' <YCoordinate value="600"/>',
' </MarkAnchor>',
' </MarkRecord>',
' <MarkRecord index="1">',
' <Class value="0"/>',
' <MarkAnchor Format="1">',
' <XCoordinate value="0"/>',
' <YCoordinate value="590"/>',
' </MarkAnchor>',
' </MarkRecord>',
' </MarkArray>',
' <BaseArray>',
' <!-- BaseCount=2 -->',
' <BaseRecord index="0">',
' <BaseAnchor index="0" Format="1">',
' <XCoordinate value="350"/>',
' <YCoordinate value="500"/>',
' </BaseAnchor>',
' </BaseRecord>',
' <BaseRecord index="1">',
' <BaseAnchor index="0" Format="1">',
' <XCoordinate value="300"/>',
' <YCoordinate value="700"/>',
' </BaseAnchor>',
' </BaseRecord>',
' </BaseArray>',
'</MarkBasePos>',
]
assert getXML(oldSubTable.toXML) == [
'<MarkBasePos Format="1">',
' <MarkCoverage>',
' <Glyph value="acutecomb"/>',
' <Glyph value="gravecomb"/>',
' </MarkCoverage>',
' <BaseCoverage>',
' <Glyph value="a"/>',
' <Glyph value="c"/>',
' </BaseCoverage>',
' <!-- ClassCount=1 -->',
' <MarkArray>',
' <!-- MarkCount=2 -->',
' <MarkRecord index="0">',
' <Class value="0"/>',
' <MarkAnchor Format="1">',
' <XCoordinate value="0"/>',
' <YCoordinate value="600"/>',
' </MarkAnchor>',
' </MarkRecord>',
' <MarkRecord index="1">',
' <Class value="0"/>',
' <MarkAnchor Format="1">',
' <XCoordinate value="0"/>',
' <YCoordinate value="590"/>',
' </MarkAnchor>',
' </MarkRecord>',
' </MarkArray>',
' <BaseArray>',
' <!-- BaseCount=2 -->',
' <BaseRecord index="0">',
' <BaseAnchor index="0" Format="1">',
' <XCoordinate value="350"/>',
' <YCoordinate value="500"/>',
' </BaseAnchor>',
' </BaseRecord>',
' <BaseRecord index="1">',
' <BaseAnchor index="0" Format="1">',
' <XCoordinate value="300"/>',
' <YCoordinate value="700"/>',
' </BaseAnchor>',
' </BaseRecord>',
' </BaseArray>',
'</MarkBasePos>',
]
assert getXML(newSubTable.toXML) == [
'<MarkBasePos Format="1">',
' <MarkCoverage>',
' <Glyph value="cedillacomb"/>',
' </MarkCoverage>',
' <BaseCoverage>',
' <Glyph value="a"/>',
' <Glyph value="c"/>',
' </BaseCoverage>',
' <!-- ClassCount=1 -->',
' <MarkArray>',
' <!-- MarkCount=1 -->',
' <MarkRecord index="0">',
' <Class value="0"/>',
' <MarkAnchor Format="1">',
' <XCoordinate value="0"/>',
' <YCoordinate value="0"/>',
' </MarkAnchor>',
' </MarkRecord>',
' </MarkArray>',
' <BaseArray>',
' <!-- BaseCount=2 -->',
' <BaseRecord index="0">',
' <BaseAnchor index="0" empty="1"/>',
' </BaseRecord>',
' <BaseRecord index="1">',
' <BaseAnchor index="0" Format="1">',
' <XCoordinate value="300"/>',
' <YCoordinate value="0"/>',
' </BaseAnchor>',
' </BaseRecord>',
' </BaseArray>',
'</MarkBasePos>',
]
assert getXML(newSubTable.toXML) == [
'<MarkBasePos Format="1">',
' <MarkCoverage>',
' <Glyph value="cedillacomb"/>',
' </MarkCoverage>',
' <BaseCoverage>',
' <Glyph value="a"/>',
' <Glyph value="c"/>',
' </BaseCoverage>',
' <!-- ClassCount=1 -->',
' <MarkArray>',
' <!-- MarkCount=1 -->',
' <MarkRecord index="0">',
' <Class value="0"/>',
' <MarkAnchor Format="1">',
' <XCoordinate value="0"/>',
' <YCoordinate value="0"/>',
' </MarkAnchor>',
' </MarkRecord>',
' </MarkArray>',
' <BaseArray>',
' <!-- BaseCount=2 -->',
' <BaseRecord index="0">',
' <BaseAnchor index="0" empty="1"/>',
' </BaseRecord>',
' <BaseRecord index="1">',
' <BaseAnchor index="0" Format="1">',
' <XCoordinate value="300"/>',
' <YCoordinate value="0"/>',
' </BaseAnchor>',
' </BaseRecord>',
' </BaseArray>',
'</MarkBasePos>',
]
if __name__ == "__main__":

View File

@ -0,0 +1,463 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.24">
<GlyphOrder>
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name="T"/>
<GlyphID id="2" name="o"/>
<GlyphID id="3" name="space"/>
</GlyphOrder>
<head>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="1.0"/>
<checkSumAdjustment value="0x95e7c646"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Tue May 25 09:10:37 2021"/>
<modified value="Tue May 25 10:10:18 2021"/>
<xMin value="32"/>
<yMin value="-200"/>
<xMax value="567"/>
<yMax value="800"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
<indexToLocFormat value="0"/>
<glyphDataFormat value="0"/>
</head>
<hhea>
<tableVersion value="0x00010000"/>
<ascent value="1000"/>
<descent value="-200"/>
<lineGap value="0"/>
<advanceWidthMax value="600"/>
<minLeftSideBearing value="32"/>
<minRightSideBearing value="33"/>
<xMaxExtent value="567"/>
<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>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="0x10000"/>
<numGlyphs value="4"/>
<maxPoints value="32"/>
<maxContours value="2"/>
<maxCompositePoints value="0"/>
<maxCompositeContours value="0"/>
<maxZones value="1"/>
<maxTwilightPoints value="0"/>
<maxStorage value="0"/>
<maxFunctionDefs value="0"/>
<maxInstructionDefs value="0"/>
<maxStackElements value="0"/>
<maxSizeOfInstructions value="0"/>
<maxComponentElements value="0"/>
<maxComponentDepth value="0"/>
</maxp>
<OS_2>
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
will be recalculated by the compiler -->
<version value="4"/>
<xAvgCharWidth value="575"/>
<usWeightClass value="400"/>
<usWidthClass value="5"/>
<fsType value="00000000 00001000"/>
<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="300"/>
<sFamilyClass value="0"/>
<panose>
<bFamilyType value="0"/>
<bSerifStyle value="0"/>
<bWeight value="0"/>
<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 00000001"/>
<ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
<achVendID value="NONE"/>
<fsSelection value="00000000 01000000"/>
<usFirstCharIndex value="32"/>
<usLastCharIndex value="111"/>
<sTypoAscender value="800"/>
<sTypoDescender value="-200"/>
<sTypoLineGap value="200"/>
<usWinAscent value="1000"/>
<usWinDescent value="200"/>
<ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
<ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
<sxHeight value="500"/>
<sCapHeight value="700"/>
<usDefaultChar value="0"/>
<usBreakChar value="32"/>
<usMaxContext value="2"/>
</OS_2>
<hmtx>
<mtx name=".notdef" width="500" lsb="50"/>
<mtx name="T" width="600" lsb="32"/>
<mtx name="o" width="600" lsb="58"/>
<mtx name="space" width="600" lsb="0"/>
</hmtx>
<cmap>
<tableVersion version="0"/>
<cmap_format_4 platformID="0" platEncID="3" language="0">
<map code="0x20" name="space"/><!-- SPACE -->
<map code="0x54" name="T"/><!-- LATIN CAPITAL LETTER T -->
<map code="0x6f" name="o"/><!-- LATIN SMALL LETTER O -->
</cmap_format_4>
<cmap_format_4 platformID="3" platEncID="1" language="0">
<map code="0x20" name="space"/><!-- SPACE -->
<map code="0x54" name="T"/><!-- LATIN CAPITAL LETTER T -->
<map code="0x6f" name="o"/><!-- LATIN SMALL LETTER O -->
</cmap_format_4>
</cmap>
<loca>
<!-- The 'loca' table will be calculated by the compiler -->
</loca>
<glyf>
<!-- The xMin, yMin, xMax and yMax values
will be recalculated by the compiler. -->
<TTGlyph name=".notdef" xMin="50" yMin="-200" xMax="450" yMax="800">
<contour>
<pt x="50" y="-200" on="1"/>
<pt x="50" y="800" on="1"/>
<pt x="450" y="800" on="1"/>
<pt x="450" y="-200" on="1"/>
</contour>
<contour>
<pt x="100" y="-150" on="1"/>
<pt x="400" y="-150" on="1"/>
<pt x="400" y="750" on="1"/>
<pt x="100" y="750" on="1"/>
</contour>
<instructions/>
</TTGlyph>
<TTGlyph name="T" xMin="32" yMin="0" xMax="567" yMax="710">
<contour>
<pt x="32" y="710" on="1"/>
<pt x="567" y="710" on="1"/>
<pt x="567" y="627" on="1"/>
<pt x="32" y="627" on="1"/>
</contour>
<contour>
<pt x="230" y="710" on="1"/>
<pt x="370" y="710" on="1"/>
<pt x="370" y="0" on="1"/>
<pt x="230" y="0" on="1"/>
</contour>
<instructions/>
</TTGlyph>
<TTGlyph name="o" xMin="58" yMin="-15" xMax="542" yMax="533">
<contour>
<pt x="300" y="-15" on="1"/>
<pt x="233" y="-15" on="0"/>
<pt x="123" y="59" on="0"/>
<pt x="58" y="184" on="0"/>
<pt x="58" y="259" on="1"/>
<pt x="58" y="335" on="0"/>
<pt x="123" y="459" on="0"/>
<pt x="233" y="533" on="0"/>
<pt x="300" y="533" on="1"/>
<pt x="367" y="533" on="0"/>
<pt x="477" y="459" on="0"/>
<pt x="542" y="335" on="0"/>
<pt x="542" y="259" on="1"/>
<pt x="542" y="184" on="0"/>
<pt x="477" y="59" on="0"/>
<pt x="367" y="-15" on="0"/>
</contour>
<contour>
<pt x="300" y="50" on="1"/>
<pt x="343" y="50" on="0"/>
<pt x="413" y="107" on="0"/>
<pt x="455" y="202" on="0"/>
<pt x="455" y="260" on="1"/>
<pt x="455" y="318" on="0"/>
<pt x="413" y="413" on="0"/>
<pt x="343" y="470" on="0"/>
<pt x="300" y="470" on="1"/>
<pt x="257" y="470" on="0"/>
<pt x="187" y="413" on="0"/>
<pt x="145" y="318" on="0"/>
<pt x="145" y="260" on="1"/>
<pt x="145" y="202" on="0"/>
<pt x="187" y="107" on="0"/>
<pt x="257" y="50" on="0"/>
</contour>
<instructions/>
</TTGlyph>
<TTGlyph name="space"/><!-- contains no outline data -->
</glyf>
<name>
<namerecord nameID="256" platformID="1" platEncID="0" langID="0x0" unicode="True">
Weight
</namerecord>
<namerecord nameID="257" platformID="1" platEncID="0" langID="0x0" unicode="True">
Regular
</namerecord>
<namerecord nameID="258" platformID="1" platEncID="0" langID="0x0" unicode="True">
Bold
</namerecord>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
New Font
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
1.000;NONE;NewFont-Regular
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
New Font Regular
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
Version 1.000
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
NewFont-Regular
</namerecord>
<namerecord nameID="256" platformID="3" platEncID="1" langID="0x409">
Weight
</namerecord>
<namerecord nameID="257" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="258" platformID="3" platEncID="1" langID="0x409">
Bold
</namerecord>
</name>
<post>
<formatType value="2.0"/>
<italicAngle value="0.0"/>
<underlinePosition value="-100"/>
<underlineThickness value="50"/>
<isFixedPitch value="0"/>
<minMemType42 value="0"/>
<maxMemType42 value="0"/>
<minMemType1 value="0"/>
<maxMemType1 value="0"/>
<psNames>
<!-- This file uses unique glyph names based on the information
found in the 'post' table. Since these names might not be unique,
we have to invent artificial names in case of clashes. In order to
be able to retain the original information, we need a name to
ps name mapping for those cases where they differ. That's what
you see below.
-->
</psNames>
<extraNames>
<!-- following are the name that are not taken from the standard Mac glyph order -->
</extraNames>
</post>
<GDEF>
<Version value="0x00010003"/>
<VarStore Format="1">
<Format value="1"/>
<VarRegionList>
<!-- RegionAxisCount=1 -->
<!-- RegionCount=1 -->
<Region index="0">
<VarRegionAxis index="0">
<StartCoord value="0.0"/>
<PeakCoord value="1.0"/>
<EndCoord value="1.0"/>
</VarRegionAxis>
</Region>
</VarRegionList>
<!-- VarDataCount=1 -->
<VarData index="0">
<!-- ItemCount=1 -->
<NumShorts value="0"/>
<!-- VarRegionCount=1 -->
<VarRegionIndex index="0" value="0"/>
<Item index="0" value="[-50]"/>
</VarData>
</VarStore>
</GDEF>
<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="kern"/>
<Feature>
<!-- LookupCount=1 -->
<LookupListIndex index="0" value="0"/>
</Feature>
</FeatureRecord>
</FeatureList>
<LookupList>
<!-- LookupCount=1 -->
<Lookup index="0">
<LookupType value="2"/>
<LookupFlag value="8"/><!-- ignoreMarks -->
<!-- SubTableCount=1 -->
<PairPos index="0" Format="1">
<Coverage>
<Glyph value="T"/>
</Coverage>
<ValueFormat1 value="64"/>
<ValueFormat2 value="0"/>
<!-- PairSetCount=1 -->
<PairSet index="0">
<!-- PairValueCount=1 -->
<PairValueRecord index="0">
<SecondGlyph value="o"/>
<Value1>
<XAdvDevice>
<StartSize value="0"/>
<EndSize value="0"/>
<DeltaFormat value="32768"/>
</XAdvDevice>
</Value1>
</PairValueRecord>
</PairSet>
</PairPos>
</Lookup>
</LookupList>
</GPOS>
<fvar>
<!-- Weight -->
<Axis>
<AxisTag>wght</AxisTag>
<Flags>0x0</Flags>
<MinValue>400.0</MinValue>
<DefaultValue>400.0</DefaultValue>
<MaxValue>700.0</MaxValue>
<AxisNameID>256</AxisNameID>
</Axis>
<!-- Regular -->
<NamedInstance flags="0x0" subfamilyNameID="257">
<coord axis="wght" value="400.0"/>
</NamedInstance>
<!-- Bold -->
<NamedInstance flags="0x0" subfamilyNameID="258">
<coord axis="wght" value="700.0"/>
</NamedInstance>
</fvar>
<gvar>
<version value="1"/>
<reserved value="0"/>
<glyphVariations glyph="T">
<tuple>
<coord axis="wght" value="1.0"/>
<delta pt="0" x="0" y="0"/>
<delta pt="1" x="0" y="0"/>
<delta pt="2" x="0" y="-27"/>
<delta pt="3" x="0" y="-27"/>
<delta pt="4" x="-30" y="0"/>
<delta pt="5" x="28" y="0"/>
<delta pt="6" x="28" y="0"/>
<delta pt="7" x="-30" y="0"/>
<delta pt="8" x="0" y="0"/>
<delta pt="9" x="0" y="0"/>
<delta pt="10" x="0" y="0"/>
<delta pt="11" x="0" y="0"/>
</tuple>
</glyphVariations>
<glyphVariations glyph="o">
<tuple>
<coord axis="wght" value="1.0"/>
<delta pt="0" x="0" y="0"/>
<delta pt="1" x="0" y="0"/>
<delta pt="2" x="0" y="0"/>
<delta pt="3" x="0" y="0"/>
<delta pt="4" x="0" y="0"/>
<delta pt="5" x="0" y="0"/>
<delta pt="6" x="0" y="0"/>
<delta pt="7" x="0" y="0"/>
<delta pt="8" x="0" y="0"/>
<delta pt="9" x="0" y="0"/>
<delta pt="10" x="0" y="0"/>
<delta pt="11" x="0" y="0"/>
<delta pt="12" x="0" y="0"/>
<delta pt="13" x="0" y="0"/>
<delta pt="14" x="0" y="0"/>
<delta pt="15" x="0" y="0"/>
<delta pt="16" x="0" y="30"/>
<delta pt="17" x="0" y="30"/>
<delta pt="18" x="-15" y="15"/>
<delta pt="19" x="-30" y="0"/>
<delta pt="20" x="-30" y="0"/>
<delta pt="21" x="-30" y="0"/>
<delta pt="22" x="-15" y="-15"/>
<delta pt="23" x="0" y="-30"/>
<delta pt="24" x="0" y="-30"/>
<delta pt="25" x="0" y="-30"/>
<delta pt="26" x="15" y="-15"/>
<delta pt="27" x="30" y="0"/>
<delta pt="28" x="30" y="0"/>
<delta pt="29" x="30" y="0"/>
<delta pt="30" x="15" y="15"/>
<delta pt="31" x="0" y="30"/>
<delta pt="32" x="0" y="0"/>
<delta pt="33" x="0" y="0"/>
<delta pt="34" x="0" y="0"/>
<delta pt="35" x="0" y="0"/>
</tuple>
</glyphVariations>
</gvar>
</ttFont>

View File

@ -936,6 +936,30 @@ class InstantiateOTLTest(object):
assert not hasattr(valueRec1, "XAdvDevice")
assert valueRec1.XAdvance == v2
def test_GPOS_ValueRecord_XAdvDevice_wtihout_XAdvance(self):
# Test VF contains a PairPos adjustment in which the default instance
# has no XAdvance but there are deltas in XAdvDevice (VariationIndex).
vf = ttLib.TTFont()
vf.importXML(os.path.join(TESTDATA, "PartialInstancerTest4-VF.ttx"))
pairPos = vf["GPOS"].table.LookupList.Lookup[0].SubTable[0]
assert pairPos.ValueFormat1 == 0x40
valueRec1 = pairPos.PairSet[0].PairValueRecord[0].Value1
assert not hasattr(valueRec1, "XAdvance")
assert valueRec1.XAdvDevice.DeltaFormat == 0x8000
outer = valueRec1.XAdvDevice.StartSize
inner = valueRec1.XAdvDevice.EndSize
assert vf["GDEF"].table.VarStore.VarData[outer].Item[inner] == [-50]
# check that MutatorMerger for ValueRecord doesn't raise AttributeError
# when XAdvDevice is present but there's no corresponding XAdvance.
instancer.instantiateOTL(vf, {"wght": 0.5})
pairPos = vf["GPOS"].table.LookupList.Lookup[0].SubTable[0]
assert pairPos.ValueFormat1 == 0x4
valueRec1 = pairPos.PairSet[0].PairValueRecord[0].Value1
assert not hasattr(valueRec1, "XAdvDevice")
assert valueRec1.XAdvance == -25
class InstantiateAvarTest(object):
@pytest.mark.parametrize("location", [{"wght": 0.0}, {"wdth": 0.0}])

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 4.24.3.dev0
current_version = 4.24.5.dev0
commit = True
tag = False
tag_name = {new_version}

View File

@ -441,7 +441,7 @@ if ext_modules:
setup_params = dict(
name="fonttools",
version="4.24.3.dev0",
version="4.24.5.dev0",
description="Tools to manipulate font files",
author="Just van Rossum",
author_email="just@letterror.com",