Merge branch 'fonttools:main' into main
This commit is contained in:
commit
bb5d59300c
@ -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"]
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
#
|
||||
|
15
NEWS.rst
15
NEWS.rst
@ -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)
|
||||
----------------------------
|
||||
|
||||
|
30
README.rst
30
README.rst
@ -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
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -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__":
|
||||
|
463
Tests/varLib/instancer/data/PartialInstancerTest4-VF.ttx
Normal file
463
Tests/varLib/instancer/data/PartialInstancerTest4-VF.ttx
Normal 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>
|
@ -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}])
|
||||
|
@ -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}
|
||||
|
Loading…
x
Reference in New Issue
Block a user