Merge branch 'master' into fealib-duplicate-sub-warning
This commit is contained in:
commit
720488ed4b
@ -4,6 +4,6 @@ from fontTools.misc.loggingTools import configLogger
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
version = __version__ = "4.2.1.dev0"
|
||||
version = __version__ = "4.2.3.dev0"
|
||||
|
||||
__all__ = ["version", "log", "configLogger"]
|
||||
|
@ -751,6 +751,20 @@ class FontBuilder(object):
|
||||
from .feaLib.builder import addOpenTypeFeaturesFromString
|
||||
addOpenTypeFeaturesFromString(self.font, features, filename=filename, tables=tables)
|
||||
|
||||
def addFeatureVariations(self, conditionalSubstitutions, featureTag="rvrn"):
|
||||
"""Add conditional substitutions to a Variable Font.
|
||||
|
||||
See `fontTools.varLib.featureVars.addFeatureVariations`.
|
||||
"""
|
||||
from .varLib import featureVars
|
||||
|
||||
if "fvar" not in self.font:
|
||||
raise KeyError("'fvar' table is missing; can't add FeatureVariations.")
|
||||
|
||||
featureVars.addFeatureVariations(
|
||||
self.font, conditionalSubstitutions, featureTag=featureTag
|
||||
)
|
||||
|
||||
|
||||
def buildCmapSubTable(cmapping, format, platformID, platEncID):
|
||||
subTable = cmap_classes[format](format)
|
||||
|
@ -1307,6 +1307,9 @@ def subset_features(self, feature_indices):
|
||||
self.ensureDecompiled()
|
||||
self.SubstitutionRecord = [r for r in self.SubstitutionRecord
|
||||
if r.FeatureIndex in feature_indices]
|
||||
# remap feature indices
|
||||
for r in self.SubstitutionRecord:
|
||||
r.FeatureIndex = feature_indices.index(r.FeatureIndex)
|
||||
self.SubstitutionCount = len(self.SubstitutionRecord)
|
||||
return bool(self.SubstitutionCount)
|
||||
|
||||
|
@ -1179,7 +1179,7 @@ class Glyph(object):
|
||||
for end in endPts:
|
||||
end = end + 1
|
||||
contour = coordinates[start:end]
|
||||
cFlags = flags[start:end]
|
||||
cFlags = [flagOnCurve & f for f in flags[start:end]]
|
||||
start = end
|
||||
if 1 not in cFlags:
|
||||
# There is not a single on-curve point on the curve,
|
||||
@ -1198,7 +1198,10 @@ class Glyph(object):
|
||||
while contour:
|
||||
nextOnCurve = cFlags.index(1) + 1
|
||||
if nextOnCurve == 1:
|
||||
pen.lineTo(contour[0])
|
||||
# Skip a final lineTo(), as it is implied by
|
||||
# pen.closePath()
|
||||
if len(contour) > 1:
|
||||
pen.lineTo(contour[0])
|
||||
else:
|
||||
pen.qCurveTo(*contour[:nextOnCurve])
|
||||
contour = contour[nextOnCurve:]
|
||||
@ -1230,7 +1233,7 @@ class Glyph(object):
|
||||
# Start with the appropriate segment type based on the final segment
|
||||
segmentType = "line" if cFlags[-1] == 1 else "qcurve"
|
||||
for i, pt in enumerate(contour):
|
||||
if cFlags[i] == 1:
|
||||
if cFlags[i] & flagOnCurve == 1:
|
||||
pen.addPoint(pt, segmentType=segmentType)
|
||||
segmentType = "line"
|
||||
else:
|
||||
|
@ -852,7 +852,11 @@ def validateLayerInfoVersion3Data(infoData):
|
||||
# -----------------
|
||||
|
||||
def _glifTreeFromFile(aFile):
|
||||
root = etree.parse(aFile).getroot()
|
||||
if etree._have_lxml:
|
||||
tree = etree.parse(aFile, parser=etree.XMLParser(remove_comments=True))
|
||||
else:
|
||||
tree = etree.parse(aFile)
|
||||
root = tree.getroot()
|
||||
if root.tag != "glyph":
|
||||
raise GlifLibError("The GLIF is not properly formatted.")
|
||||
if root.text and root.text.strip() != '':
|
||||
@ -862,7 +866,10 @@ def _glifTreeFromFile(aFile):
|
||||
|
||||
def _glifTreeFromString(aString):
|
||||
data = tobytes(aString, encoding="utf-8")
|
||||
root = etree.fromstring(data)
|
||||
if etree._have_lxml:
|
||||
root = etree.fromstring(data, parser=etree.XMLParser(remove_comments=True))
|
||||
else:
|
||||
root = etree.fromstring(data)
|
||||
if root.tag != "glyph":
|
||||
raise GlifLibError("The GLIF is not properly formatted.")
|
||||
if root.text and root.text.strip() != '':
|
||||
|
@ -141,8 +141,14 @@ def _add_avar(font, axes):
|
||||
assert axis.maximum == max(keys)
|
||||
assert axis.default in keys
|
||||
# No duplicates
|
||||
assert len(set(keys)) == len(keys)
|
||||
assert len(set(vals)) == len(vals)
|
||||
assert len(set(keys)) == len(keys), (
|
||||
f"{axis.tag} axis: All axis mapping input='...' "
|
||||
"values must be unique, but we found duplicates."
|
||||
)
|
||||
assert len(set(vals)) == len(vals), (
|
||||
f"{axis.tag} axis: All axis mapping output='...' "
|
||||
"values must be unique, but we found duplicates."
|
||||
)
|
||||
# Ascending values
|
||||
assert sorted(vals) == vals
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env python
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Tools to parse data files from the Unicode Character Database.
|
||||
"""
|
||||
|
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env python
|
||||
#! /usr/bin/env python3
|
||||
|
||||
"""usage: ttroundtrip [options] font1 ... fontN
|
||||
|
||||
|
18
NEWS.rst
18
NEWS.rst
@ -1,3 +1,21 @@
|
||||
4.2.2 (released 2019-12-12)
|
||||
---------------------------
|
||||
|
||||
- [subset] Fixed issue with subsetting FeatureVariations table when the index
|
||||
of features changes as features get dropped. The feature index need to be
|
||||
remapped to point to index of the remaining features (#1777, #1782).
|
||||
- [fontBuilder] Added `addFeatureVariations` method to `FontBuilder` class. This
|
||||
is a shorthand for calling `featureVars.addFeatureVariations` on the builder's
|
||||
TTFont object (#1781).
|
||||
- [glyf] Fixed the flags bug in glyph.drawPoints() like we did for glyph.draw()
|
||||
(#1771, #1774).
|
||||
|
||||
4.2.1 (released 2019-12-06)
|
||||
---------------------------
|
||||
|
||||
- [glyf] Use the ``flagOnCurve`` bit mask in ``glyph.draw()``, so that we ignore
|
||||
the ``overlap`` flag that may be set when instantiating variable fonts (#1771).
|
||||
|
||||
4.2.0 (released 2019-11-28)
|
||||
---------------------------
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env python
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# Sample script to convert legacy cmap subtables to format-4
|
||||
# subtables. Note that this is rarely what one needs. You
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
|
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env python
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# Illustrates how a fonttools script can construct variable fonts.
|
||||
#
|
||||
|
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env python
|
||||
#! /usr/bin/env python3
|
||||
|
||||
from fontTools.misc.py23 import *
|
||||
from fontTools.ttLib import TTFont
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
"""Script to add a suffix to all family names in the input font's `name` table,
|
||||
and to optionally rename the output files with the given suffix.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env python
|
||||
#! /usr/bin/env python3
|
||||
|
||||
from fontTools.misc.py23 import *
|
||||
from fontTools.ttLib import TTFont
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
""" Convert SVG paths to UFO glyphs. """
|
||||
|
||||
|
||||
__requires__ = ["FontTools", "ufoLib"]
|
||||
__requires__ = ["fontTools"]
|
||||
|
||||
from fontTools.misc.py23 import SimpleNamespace
|
||||
from fontTools.svgLib import SVGPath
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.32">
|
||||
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.2">
|
||||
|
||||
<GlyphOrder>
|
||||
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
|
||||
@ -19,7 +19,7 @@
|
||||
<unitsPerEm value="1024"/>
|
||||
<created value="Thu Nov 1 20:29:01 2018"/>
|
||||
<modified value="Thu Nov 1 20:29:01 2018"/>
|
||||
<xMin value="100"/>
|
||||
<xMin value="50"/>
|
||||
<yMin value="0"/>
|
||||
<xMax value="500"/>
|
||||
<yMax value="400"/>
|
||||
@ -36,7 +36,7 @@
|
||||
<descent value="200"/>
|
||||
<lineGap value="0"/>
|
||||
<advanceWidthMax value="600"/>
|
||||
<minLeftSideBearing value="100"/>
|
||||
<minLeftSideBearing value="50"/>
|
||||
<minRightSideBearing value="100"/>
|
||||
<xMaxExtent value="500"/>
|
||||
<caretSlopeRise value="1"/>
|
||||
@ -126,7 +126,7 @@
|
||||
<mtx name=".notdef" width="600" lsb="0"/>
|
||||
<mtx name=".null" width="600" lsb="0"/>
|
||||
<mtx name="A" width="600" lsb="100"/>
|
||||
<mtx name="a" width="600" lsb="100"/>
|
||||
<mtx name="a" width="600" lsb="50"/>
|
||||
</hmtx>
|
||||
|
||||
<cmap>
|
||||
@ -164,12 +164,12 @@
|
||||
<instructions/>
|
||||
</TTGlyph>
|
||||
|
||||
<TTGlyph name="a" xMin="100" yMin="0" xMax="500" yMax="400">
|
||||
<TTGlyph name="a" xMin="50" yMin="0" xMax="250" yMax="200">
|
||||
<contour>
|
||||
<pt x="100" y="0" on="1"/>
|
||||
<pt x="100" y="400" on="1"/>
|
||||
<pt x="500" y="400" on="1"/>
|
||||
<pt x="500" y="0" on="1"/>
|
||||
<pt x="50" y="0" on="1"/>
|
||||
<pt x="50" y="200" on="1"/>
|
||||
<pt x="250" y="200" on="1"/>
|
||||
<pt x="250" y="0" on="1"/>
|
||||
</contour>
|
||||
<instructions/>
|
||||
</TTGlyph>
|
||||
@ -269,6 +269,100 @@
|
||||
</extraNames>
|
||||
</post>
|
||||
|
||||
<GSUB>
|
||||
<Version value="0x00010001"/>
|
||||
<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="rclt"/>
|
||||
<Feature>
|
||||
<!-- LookupCount=0 -->
|
||||
</Feature>
|
||||
</FeatureRecord>
|
||||
</FeatureList>
|
||||
<LookupList>
|
||||
<!-- LookupCount=1 -->
|
||||
<Lookup index="0">
|
||||
<LookupType value="1"/>
|
||||
<LookupFlag value="0"/>
|
||||
<!-- SubTableCount=1 -->
|
||||
<SingleSubst index="0" Format="1">
|
||||
<Substitution in="A" out="a"/>
|
||||
</SingleSubst>
|
||||
</Lookup>
|
||||
</LookupList>
|
||||
<FeatureVariations>
|
||||
<Version value="0x00010000"/>
|
||||
<!-- FeatureVariationCount=2 -->
|
||||
<FeatureVariationRecord index="0">
|
||||
<ConditionSet>
|
||||
<!-- ConditionCount=2 -->
|
||||
<ConditionTable index="0" Format="1">
|
||||
<AxisIndex value="3"/>
|
||||
<FilterRangeMinValue value="0.8"/>
|
||||
<FilterRangeMaxValue value="1.0"/>
|
||||
</ConditionTable>
|
||||
<ConditionTable index="1" Format="1">
|
||||
<AxisIndex value="0"/>
|
||||
<FilterRangeMinValue value="0.8"/>
|
||||
<FilterRangeMaxValue value="1.0"/>
|
||||
</ConditionTable>
|
||||
</ConditionSet>
|
||||
<FeatureTableSubstitution>
|
||||
<Version value="0x00010000"/>
|
||||
<!-- SubstitutionCount=1 -->
|
||||
<SubstitutionRecord index="0">
|
||||
<FeatureIndex value="0"/>
|
||||
<Feature>
|
||||
<!-- LookupCount=1 -->
|
||||
<LookupListIndex index="0" value="0"/>
|
||||
</Feature>
|
||||
</SubstitutionRecord>
|
||||
</FeatureTableSubstitution>
|
||||
</FeatureVariationRecord>
|
||||
<FeatureVariationRecord index="1">
|
||||
<ConditionSet>
|
||||
<!-- ConditionCount=2 -->
|
||||
<ConditionTable index="0" Format="1">
|
||||
<AxisIndex value="1"/>
|
||||
<FilterRangeMinValue value="0.8"/>
|
||||
<FilterRangeMaxValue value="1.0"/>
|
||||
</ConditionTable>
|
||||
<ConditionTable index="1" Format="1">
|
||||
<AxisIndex value="2"/>
|
||||
<FilterRangeMinValue value="0.8"/>
|
||||
<FilterRangeMaxValue value="1.0"/>
|
||||
</ConditionTable>
|
||||
</ConditionSet>
|
||||
<FeatureTableSubstitution>
|
||||
<Version value="0x00010000"/>
|
||||
<!-- SubstitutionCount=1 -->
|
||||
<SubstitutionRecord index="0">
|
||||
<FeatureIndex value="0"/>
|
||||
<Feature>
|
||||
<!-- LookupCount=1 -->
|
||||
<LookupListIndex index="0" value="0"/>
|
||||
</Feature>
|
||||
</SubstitutionRecord>
|
||||
</FeatureTableSubstitution>
|
||||
</FeatureVariationRecord>
|
||||
</FeatureVariations>
|
||||
</GSUB>
|
||||
|
||||
<fvar>
|
||||
|
||||
<!-- Left -->
|
||||
|
@ -164,13 +164,20 @@ def test_build_var(tmpdir):
|
||||
pen.lineTo((500, 400))
|
||||
pen.lineTo((500, 000))
|
||||
pen.closePath()
|
||||
glyph1 = pen.glyph()
|
||||
|
||||
glyph = pen.glyph()
|
||||
pen = TTGlyphPen(None)
|
||||
pen.moveTo((50, 0))
|
||||
pen.lineTo((50, 200))
|
||||
pen.lineTo((250, 200))
|
||||
pen.lineTo((250, 0))
|
||||
pen.closePath()
|
||||
glyph2 = pen.glyph()
|
||||
|
||||
pen = TTGlyphPen(None)
|
||||
emptyGlyph = pen.glyph()
|
||||
|
||||
glyphs = {".notdef": emptyGlyph, "A": glyph, "a": glyph, ".null": emptyGlyph}
|
||||
glyphs = {".notdef": emptyGlyph, "A": glyph1, "a": glyph2, ".null": emptyGlyph}
|
||||
fb.setupGlyf(glyphs)
|
||||
metrics = {}
|
||||
glyphTable = fb.font["glyf"]
|
||||
@ -206,6 +213,19 @@ def test_build_var(tmpdir):
|
||||
]
|
||||
fb.setupGvar(variations)
|
||||
|
||||
fb.addFeatureVariations(
|
||||
[
|
||||
(
|
||||
[
|
||||
{"LEFT": (0.8, 1), "DOWN": (0.8, 1)},
|
||||
{"RGHT": (0.8, 1), "UPPP": (0.8, 1)},
|
||||
],
|
||||
{"A": "a"}
|
||||
)
|
||||
],
|
||||
featureTag="rclt",
|
||||
)
|
||||
|
||||
fb.setupOS2()
|
||||
fb.setupPost()
|
||||
fb.setupDummyDSIG()
|
||||
|
@ -1,5 +1,7 @@
|
||||
import io
|
||||
from fontTools.misc.py23 import *
|
||||
from fontTools import subset
|
||||
from fontTools.fontBuilder import FontBuilder
|
||||
from fontTools.ttLib import TTFont, newTable
|
||||
from fontTools.misc.loggingTools import CapturingLogHandler
|
||||
import difflib
|
||||
@ -728,5 +730,43 @@ class SubsetTest(unittest.TestCase):
|
||||
self.assertEqual(ttf.flavor, None)
|
||||
|
||||
|
||||
def test_subset_feature_variations():
|
||||
fb = FontBuilder(unitsPerEm=100)
|
||||
fb.setupGlyphOrder([".notdef", "f", "f_f", "dollar", "dollar.rvrn"])
|
||||
fb.setupCharacterMap({ord("f"): "f", ord("$"): "dollar"})
|
||||
fb.setupNameTable({"familyName": "TestFeatureVars", "styleName": "Regular"})
|
||||
fb.setupPost()
|
||||
fb.setupFvar(axes=[("wght", 100, 400, 900, "Weight")], instances=[])
|
||||
fb.addOpenTypeFeatures("""\
|
||||
feature dlig {
|
||||
sub f f by f_f;
|
||||
} dlig;
|
||||
""")
|
||||
fb.addFeatureVariations(
|
||||
[([{"wght": (0.20886, 1.0)}], {"dollar": "dollar.rvrn"})],
|
||||
featureTag="rvrn"
|
||||
)
|
||||
buf = io.BytesIO()
|
||||
fb.save(buf)
|
||||
buf.seek(0)
|
||||
|
||||
font = TTFont(buf)
|
||||
|
||||
options = subset.Options()
|
||||
subsetter = subset.Subsetter(options)
|
||||
subsetter.populate(unicodes=[ord("f"), ord("$")])
|
||||
subsetter.subset(font)
|
||||
|
||||
featureTags = {
|
||||
r.FeatureTag for r in font["GSUB"].table.FeatureList.FeatureRecord
|
||||
}
|
||||
# 'dlig' is discretionary so it is dropped by default
|
||||
assert "dlig" not in featureTags
|
||||
assert "f_f" not in font.getGlyphOrder()
|
||||
# 'rvrn' is required so it is kept by default
|
||||
assert "rvrn" in featureTags
|
||||
assert "dollar.rvrn" in font.getGlyphOrder()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(unittest.main())
|
||||
|
@ -2,6 +2,8 @@ from fontTools.misc.py23 import *
|
||||
from fontTools.misc.fixedTools import otRound
|
||||
from fontTools.misc.testTools import getXML, parseXML
|
||||
from fontTools.pens.ttGlyphPen import TTGlyphPen
|
||||
from fontTools.pens.recordingPen import RecordingPen, RecordingPointPen
|
||||
from fontTools.pens.pointPen import PointToSegmentPen
|
||||
from fontTools.ttLib import TTFont, newTable, TTLibError
|
||||
from fontTools.ttLib.tables._g_l_y_f import (
|
||||
GlyphCoordinates,
|
||||
@ -284,6 +286,58 @@ class glyfTableTest(unittest.TestCase):
|
||||
|
||||
composite.compact(glyfTable)
|
||||
|
||||
def test_bit6_draw_to_pen_issue1771(self):
|
||||
# https://github.com/fonttools/fonttools/issues/1771
|
||||
font = TTFont(sfntVersion="\x00\x01\x00\x00")
|
||||
# glyph00003 contains a bit 6 flag on the first point,
|
||||
# which triggered the issue
|
||||
font.importXML(GLYF_TTX)
|
||||
glyfTable = font['glyf']
|
||||
pen = RecordingPen()
|
||||
glyfTable["glyph00003"].draw(pen, glyfTable=glyfTable)
|
||||
expected = [('moveTo', ((501, 1430),)),
|
||||
('lineTo', ((683, 1430),)),
|
||||
('lineTo', ((1172, 0),)),
|
||||
('lineTo', ((983, 0),)),
|
||||
('lineTo', ((591, 1193),)),
|
||||
('lineTo', ((199, 0),)),
|
||||
('lineTo', ((12, 0),)),
|
||||
('closePath', ()),
|
||||
('moveTo', ((249, 514),)),
|
||||
('lineTo', ((935, 514),)),
|
||||
('lineTo', ((935, 352),)),
|
||||
('lineTo', ((249, 352),)),
|
||||
('closePath', ())]
|
||||
self.assertEqual(pen.value, expected)
|
||||
|
||||
def test_bit6_draw_to_pointpen(self):
|
||||
# https://github.com/fonttools/fonttools/issues/1771
|
||||
font = TTFont(sfntVersion="\x00\x01\x00\x00")
|
||||
# glyph00003 contains a bit 6 flag on the first point
|
||||
# which triggered the issue
|
||||
font.importXML(GLYF_TTX)
|
||||
glyfTable = font['glyf']
|
||||
pen = RecordingPointPen()
|
||||
glyfTable["glyph00003"].drawPoints(pen, glyfTable=glyfTable)
|
||||
expected = [
|
||||
('beginPath', (), {}),
|
||||
('addPoint', ((501, 1430), 'line', False, None), {}),
|
||||
('addPoint', ((683, 1430), 'line', False, None), {}),
|
||||
('addPoint', ((1172, 0), 'line', False, None), {}),
|
||||
('addPoint', ((983, 0), 'line', False, None), {}),
|
||||
]
|
||||
self.assertEqual(pen.value[:len(expected)], expected)
|
||||
|
||||
def test_draw_vs_drawpoints(self):
|
||||
font = TTFont(sfntVersion="\x00\x01\x00\x00")
|
||||
font.importXML(GLYF_TTX)
|
||||
glyfTable = font['glyf']
|
||||
pen1 = RecordingPen()
|
||||
pen2 = RecordingPen()
|
||||
glyfTable["glyph00003"].draw(pen1, glyfTable)
|
||||
glyfTable["glyph00003"].drawPoints(PointToSegmentPen(pen2), glyfTable)
|
||||
self.assertEqual(pen1.value, pen2.value)
|
||||
|
||||
|
||||
class GlyphComponentTest:
|
||||
|
||||
|
@ -161,3 +161,21 @@ class ReadWriteFuncTest(unittest.TestCase):
|
||||
def testXmlDeclaration(self):
|
||||
s = writeGlyphToString("a", _Glyph())
|
||||
self.assertTrue(s.startswith(XML_DECLARATION % "UTF-8"))
|
||||
|
||||
|
||||
def test_parse_xml_remove_comments():
|
||||
s = b"""<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- a comment -->
|
||||
<glyph name="A" format="2">
|
||||
<advance width="1290"/>
|
||||
<unicode hex="0041"/>
|
||||
<!-- another comment -->
|
||||
</glyph>
|
||||
"""
|
||||
|
||||
g = _Glyph()
|
||||
readGlyphFromString(s, g)
|
||||
|
||||
assert g.name == "A"
|
||||
assert g.width == 1290
|
||||
assert g.unicodes == [0x0041]
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 4.2.1.dev0
|
||||
current_version = 4.2.3.dev0
|
||||
commit = True
|
||||
tag = False
|
||||
tag_name = {new_version}
|
||||
|
4
setup.py
4
setup.py
@ -1,4 +1,4 @@
|
||||
#! /usr/bin/env python
|
||||
#! /usr/bin/env python3
|
||||
|
||||
from __future__ import print_function
|
||||
import io
|
||||
@ -345,7 +345,7 @@ def find_data_files(manpath="share/man"):
|
||||
|
||||
setup(
|
||||
name="fonttools",
|
||||
version="4.2.1.dev0",
|
||||
version="4.2.3.dev0",
|
||||
description="Tools to manipulate font files",
|
||||
author="Just van Rossum",
|
||||
author_email="just@letterror.com",
|
||||
|
Loading…
x
Reference in New Issue
Block a user