Update glyphLib.

Update tests.
Fix errors.
Add documenation.
This commit is contained in:
Ben Kiel 2018-06-11 15:03:54 -05:00
parent 5f8b600221
commit a7aa115fd8
9 changed files with 632 additions and 551 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ dist/
*.py[cod]
.eggs/
.tox/
/.pytest_cache

View File

@ -247,14 +247,15 @@ class UFOReader(object):
# metainfo.plist
def readMetaInfo(self, validate=self._validate):
def readMetaInfo(self, validate=None):
"""
Read metainfo.plist. Only used for internal operations.
``validate`` will validate the read data, by default it is set
to the class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
# should there be a blind try/except with a UFOLibError
# raised in except here (and elsewhere)? It would be nice to
# provide external callers with a single exception to catch.
@ -276,12 +277,14 @@ class UFOReader(object):
def _readGroups(self):
return self._getPlist(GROUPS_FILENAME, {})
def readGroups(self, validate=self._validate):
def readGroups(self, validate=None):
"""
Read groups.plist. Returns a dict.
``validate`` will validate the read data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
# handle up conversion
if self._formatVersion < 3:
self._upConvertKerning(validate)
@ -295,7 +298,7 @@ class UFOReader(object):
raise UFOLibError(message)
return groups
def getKerningGroupConversionRenameMaps(self, validate=self._validate):
def getKerningGroupConversionRenameMaps(self, validate=None):
"""
Get maps defining the renaming that was done during any
needed kerning group conversion. This method returns a
@ -312,6 +315,8 @@ class UFOReader(object):
``validate`` will validate the groups, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
if self._formatVersion >= 3:
return dict(side1={}, side2={})
# use the public group reader to force the load and
@ -327,7 +332,7 @@ class UFOReader(object):
raise UFOLibError("fontinfo.plist is not properly formatted.")
return data
def readInfo(self, info, validate=self._validate):
def readInfo(self, info, validate=None):
"""
Read fontinfo.plist. It requires an object that allows
setting attributes with names that follow the fontinfo.plist
@ -337,6 +342,8 @@ class UFOReader(object):
``validate`` will validate the read data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
infoDict = self._readInfo()
infoDataToSet = {}
# version 1
@ -381,13 +388,15 @@ class UFOReader(object):
data = self._getPlist(KERNING_FILENAME, {})
return data
def readKerning(self, validate=self._validate):
def readKerning(self, validate=None):
"""
Read kerning.plist. Returns a dict.
``validate`` will validate the kerning data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
# handle up conversion
if self._formatVersion < 3:
self._upConvertKerning(validate)
@ -409,13 +418,15 @@ class UFOReader(object):
# lib.plist
def readLib(self, validate=self._validate):
def readLib(self, validate=None):
"""
Read lib.plist. Returns a dict.
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
data = self._getPlist(LIB_FILENAME, {})
if validate:
valid, message = fontLibValidator(data)
@ -455,24 +466,28 @@ class UFOReader(object):
raise UFOLibError(error)
return contents
def getLayerNames(self, validate=self._validate):
def getLayerNames(self, validate=None):
"""
Get the ordered layer names from layercontents.plist.
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
layerContents = self._readLayerContents(validate)
layerNames = [layerName for layerName, directoryName in layerContents]
return layerNames
def getDefaultLayerName(self, validate=self._validate):
def getDefaultLayerName(self, validate=None):
"""
Get the default layer name from layercontents.plist.
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
layerContents = self._readLayerContents(validate)
for layerName, layerDirectory in layerContents:
if layerDirectory == DEFAULT_GLYPHS_DIRNAME:
@ -480,7 +495,7 @@ class UFOReader(object):
# this will already have been raised during __init__
raise UFOLibError("The default layer is not defined in layercontents.plist.")
def getGlyphSet(self, layerName=None, validate=self._validate):
def getGlyphSet(self, layerName=None, validateRead=None, validateWrite=None):
"""
Return the GlyphSet associated with the
glyphs directory mapped to layerName
@ -488,13 +503,19 @@ class UFOReader(object):
the name retrieved with getDefaultLayerName
will be used.
``validate`` will validate the data, by default it is set to the
``validateRead`` will validate the read data, by default it is set to the
class's validate value, can be overridden.
``validateWrte`` will validate the written data, by default it is set to the
class's validate value, can be overridden.
"""
if validateRead is None:
validateRead = self._validate
if validateWrite is None:
validateWrite = self._validate
if layerName is None:
layerName = self.getDefaultLayerName(validate=validate)
layerName = self.getDefaultLayerName(validate=validateRead)
directory = None
layerContents = self._readLayerContents(validate)
layerContents = self._readLayerContents(validateRead)
for storedLayerName, storedLayerDirectory in layerContents:
if layerName == storedLayerName:
directory = storedLayerDirectory
@ -502,14 +523,16 @@ class UFOReader(object):
if directory is None:
raise UFOLibError("No glyphs directory is mapped to \"%s\"." % layerName)
glyphsPath = os.path.join(self._path, directory)
return GlyphSet(glyphsPath, ufoFormatVersion=self._formatVersion, validate=validate)
return GlyphSet(glyphsPath, ufoFormatVersion=self._formatVersion, validateRead=validateRead, validateWrite=validateWrite)
def getCharacterMapping(self, layerName=None, validate=self._validate):
def getCharacterMapping(self, layerName=None, validate=None):
"""
Return a dictionary that maps unicode values (ints) to
lists of glyph names.
"""
glyphSet = self.getGlyphSet(layerName, validate=validate)
if validate is None:
validate = self._validate
glyphSet = self.getGlyphSet(layerName, validateRead=validate, validateWrite=True)
allUnicodes = glyphSet.getUnicodes()
cmap = {}
for glyphName, unicodes in allUnicodes.items():
@ -552,7 +575,7 @@ class UFOReader(object):
result.append(p)
return result
def getImageDirectoryListing(self, validate=self._validate):
def getImageDirectoryListing(self, validate=None):
"""
Returns a list of all image file names in
the images directory. Each of the images will
@ -561,6 +584,8 @@ class UFOReader(object):
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
if self._formatVersion < 3:
return []
path = os.path.join(self._path, IMAGES_DIRNAME)
@ -581,13 +606,15 @@ class UFOReader(object):
result.append(fileName)
return result
def readImage(self, fileName, validate=self._validate):
def readImage(self, fileName, validate=None):
"""
Return image data for the file named fileName.
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
if self._formatVersion < 3:
raise UFOLibError("Reading images is not allowed in UFO %d." % self._formatVersion)
data = self.readBytesFromPath(os.path.join(IMAGES_DIRNAME, fileName))
@ -860,7 +887,7 @@ class UFOWriter(object):
remap[dataName] = writeName
self._downConversionKerningData = dict(groupRenameMap=remap)
def writeGroups(self, groups, validate=self._validate):
def writeGroups(self, groups, validate=None):
"""
Write groups.plist. This method requires a
dict of glyph groups as an argument.
@ -868,6 +895,8 @@ class UFOWriter(object):
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
# validate the data structure
if validate:
valid, message = groupsValidator(groups)
@ -910,7 +939,7 @@ class UFOWriter(object):
# fontinfo.plist
def writeInfo(self, info, validate=self._validate):
def writeInfo(self, info, validate=None):
"""
Write info.plist. This method requires an object
that supports getting attributes that follow the
@ -921,6 +950,8 @@ class UFOWriter(object):
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
# gather version 3 data
infoData = {}
for attr in list(fontInfoAttributesVersion3ValueData.keys()):
@ -950,7 +981,7 @@ class UFOWriter(object):
# kerning.plist
def writeKerning(self, kerning, validate=self._validate):
def writeKerning(self, kerning, validate=None):
"""
Write kerning.plist. This method requires a
dict of kerning pairs as an argument.
@ -963,6 +994,8 @@ class UFOWriter(object):
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
# validate the data structure
if validate:
invalidFormatMessage = "The kerning is not properly formatted."
@ -1002,7 +1035,7 @@ class UFOWriter(object):
# lib.plist
def writeLib(self, libDict, validate=self._validate):
def writeLib(self, libDict, validate=None):
"""
Write lib.plist. This method requires a
lib dict as an argument.
@ -1010,6 +1043,8 @@ class UFOWriter(object):
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if validate is None:
validate = self._validate
if validate:
valid, message = fontLibValidator(libDict)
if not valid:
@ -1059,9 +1094,6 @@ class UFOWriter(object):
"""
Write the layercontents.plist file. This method *must* be called
after all glyph sets have been written.
``validate`` will validate the data, by default it is set to the
class's validate value, can be overridden.
"""
if self.formatVersion < 3:
return
@ -1092,7 +1124,7 @@ class UFOWriter(object):
raise UFOLibError("Could not locate a glyph set directory for the layer named %s." % layerName)
return foundDirectory
def getGlyphSet(self, layerName=None, defaultLayer=True, glyphNameToFileNameFunc=None, validate=self._validate):
def getGlyphSet(self, layerName=None, defaultLayer=True, glyphNameToFileNameFunc=None, validateRead=None, validateWrite=None):
"""
Return the GlyphSet object associated with the
appropriate glyph directory in the .ufo.
@ -1101,9 +1133,15 @@ class UFOWriter(object):
that the layer should be saved into the default
glyphs directory.
``validate`` will validate the data, by default it is set to the
``validateRead`` will validate the read data, by default it is set to the
class's validate value, can be overridden.
``validateWrte`` will validate the written data, by default it is set to the
class's validate value, can be overridden.
"""
if validateRead is None:
validateRead = self._validate
if validateWrite is None:
validateWrite = self._validate
# only default can be written in < 3
if self._formatVersion < 3 and (not defaultLayer or layerName is not None):
raise UFOLibError("Only the default layer can be writen in UFO %d." % self.formatVersion)
@ -1118,21 +1156,21 @@ class UFOWriter(object):
raise UFOLibError("A layer name must be provided for non-default layers.")
# move along to format specific writing
if self.formatVersion == 1:
return self._getGlyphSetFormatVersion1(glyphNameToFileNameFunc=glyphNameToFileNameFunc, validate)
return self._getGlyphSetFormatVersion1(validateRead, validateWrite, glyphNameToFileNameFunc=glyphNameToFileNameFunc)
elif self.formatVersion == 2:
return self._getGlyphSetFormatVersion2(glyphNameToFileNameFunc=glyphNameToFileNameFunc, validate)
return self._getGlyphSetFormatVersion2(validateRead, validateWrite, glyphNameToFileNameFunc=glyphNameToFileNameFunc)
elif self.formatVersion == 3:
return self._getGlyphSetFormatVersion3(layerName=layerName, defaultLayer=defaultLayer, glyphNameToFileNameFunc=glyphNameToFileNameFunc, validate)
return self._getGlyphSetFormatVersion3(validateRead, validateWrite, layerName=layerName, defaultLayer=defaultLayer, glyphNameToFileNameFunc=glyphNameToFileNameFunc)
def _getGlyphSetFormatVersion1(self, glyphNameToFileNameFunc=None, validate):
def _getGlyphSetFormatVersion1(self, validateRead, validateWrite, glyphNameToFileNameFunc=None):
glyphDir = self._makeDirectory(DEFAULT_GLYPHS_DIRNAME)
return GlyphSet(glyphDir, glyphNameToFileNameFunc, ufoFormatVersion=1, validate=validate)
return GlyphSet(glyphDir, glyphNameToFileNameFunc, ufoFormatVersion=1, validateRead=validateRead, validateWrite=validateWrite)
def _getGlyphSetFormatVersion2(self, glyphNameToFileNameFunc=None, validate):
def _getGlyphSetFormatVersion2(self, validateRead, validateWrite, glyphNameToFileNameFunc=None):
glyphDir = self._makeDirectory(DEFAULT_GLYPHS_DIRNAME)
return GlyphSet(glyphDir, glyphNameToFileNameFunc, ufoFormatVersion=2, validate=validate)
return GlyphSet(glyphDir, glyphNameToFileNameFunc, ufoFormatVersion=2, validateRead=validateRead, validateWrite=validateWrite)
def _getGlyphSetFormatVersion3(self, layerName=None, defaultLayer=True, glyphNameToFileNameFunc=None, validate):
def _getGlyphSetFormatVersion3(self, validateRead, validateWrite, layerName=None, defaultLayer=True, glyphNameToFileNameFunc=None):
# if the default flag is on, make sure that the default in the file
# matches the default being written. also make sure that this layer
# name is not already linked to a non-default layer.
@ -1167,7 +1205,7 @@ class UFOWriter(object):
# store the mapping
self.layerContents[layerName] = directory
# load the glyph set
return GlyphSet(path, glyphNameToFileNameFunc=glyphNameToFileNameFunc, ufoFormatVersion=3, validate=validate)
return GlyphSet(path, glyphNameToFileNameFunc=glyphNameToFileNameFunc, ufoFormatVersion=3, validateRead=validateRead, validateWrite=validateWrite)
def renameGlyphSet(self, layerName, newLayerName, defaultLayer=False):
"""
@ -1228,11 +1266,13 @@ class UFOWriter(object):
# /images
def writeImage(self, fileName, data, validate=self._validate):
def writeImage(self, fileName, data, validate=None):
"""
Write data to fileName in the images directory.
The data must be a valid PNG.
"""
if validate is None:
validate = self._validate
if self._formatVersion < 3:
raise UFOLibError("Images are not allowed in UFO %d." % self._formatVersion)
if validate:
@ -1345,7 +1385,7 @@ def writeDataFileAtomically(data, path):
# Format Conversion Functions
# ---------------------------
def convertUFOFormatVersion1ToFormatVersion2(inPath, outPath=None, validateRead=False. validateWrite=True):
def convertUFOFormatVersion1ToFormatVersion2(inPath, outPath=None, validateRead=False, validateWrite=True):
"""
Function for converting a version format 1 UFO
to version format 2. inPath should be a path

View File

@ -104,7 +104,7 @@ class GlyphSet(object):
glyphClass = Glyph
def __init__(self, dirName, glyphNameToFileNameFunc=None, ufoFormatVersion=3, validate=False):
def __init__(self, dirName, glyphNameToFileNameFunc=None, ufoFormatVersion=3, validateRead=False, validateWrite=True):
"""
'dirName' should be a path to an existing directory.
@ -113,6 +113,9 @@ class GlyphSet(object):
instance. It should return a file name (including the .glif
extension). The glyphNameToFileName function is called whenever
a file name is created for a given glyph name.
``validateRead`` will validate read operations. It's default is ``False``.
``validateWrite`` will validate write operations. It's default is ``True``.
"""
self.dirName = dirName
if ufoFormatVersion not in supportedUFOFormatVersions:
@ -121,15 +124,21 @@ class GlyphSet(object):
if glyphNameToFileNameFunc is None:
glyphNameToFileNameFunc = glyphNameToFileName
self.glyphNameToFileName = glyphNameToFileNameFunc
self._validateRead = validateRead
self._validateWrite = validateWrite
self.rebuildContents()
self._reverseContents = None
self._glifCache = {}
self._validate = validate
def rebuildContents(self):
def rebuildContents(self, validateRead=None):
"""
Rebuild the contents dict by loading contents.plist.
``validateRead`` will validate the data, by default it is set to the
class's ``validateRead`` value, can be overridden.
"""
if validateRead is None:
validateRead = self._validateRead
contentsPath = os.path.join(self.dirName, "contents.plist")
try:
contents = self._readPlist(contentsPath)
@ -137,7 +146,7 @@ class GlyphSet(object):
# missing, consider the glyphset empty.
contents = {}
# validate the contents
if validate:
if validateRead:
invalidFormat = False
if not isinstance(contents, dict):
invalidFormat = True
@ -181,7 +190,13 @@ class GlyphSet(object):
# layer info
def readLayerInfo(self, info):
def readLayerInfo(self, info, validateRead=None):
"""
``validateRead`` will validate the data, by default it is set to the
class's ``validateRead`` value, can be overridden.
"""
if validateRead is None:
validateRead = self._validateRead
path = os.path.join(self.dirName, LAYERINFO_FILENAME)
try:
infoDict = self._readPlist(path)
@ -189,7 +204,8 @@ class GlyphSet(object):
return
if not isinstance(infoDict, dict):
raise GlifLibError("layerinfo.plist is not properly formatted.")
infoDict = validateLayerInfoVersion3Data(infoDict)
if validateRead:
infoDict = validateLayerInfoVersion3Data(infoDict)
# populate the object
for attr, value in infoDict.items():
try:
@ -197,7 +213,13 @@ class GlyphSet(object):
except AttributeError:
raise GlifLibError("The supplied layer info object does not support setting a necessary attribute (%s)." % attr)
def writeLayerInfo(self, info):
def writeLayerInfo(self, info, validateWrite=None):
"""
``validateWrite`` will validate the data, by default it is set to the
class's ``validateWrite`` value, can be overridden.
"""
if validateWrite is None:
validateWrite = self._validateWrite
if self.ufoFormatVersion < 3:
raise GlifLibError("layerinfo.plist is not allowed in UFO %d." % self.ufoFormatVersion)
# gather data
@ -212,7 +234,8 @@ class GlyphSet(object):
continue
infoData[attr] = value
# validate
infoData = validateLayerInfoVersion3Data(infoData)
if validateWrite:
infoData = validateLayerInfoVersion3Data(infoData)
# write file
path = os.path.join(self.dirName, LAYERINFO_FILENAME)
with open(path, "wb") as f:
@ -271,7 +294,7 @@ class GlyphSet(object):
# reading/writing API
def readGlyph(self, glyphName, glyphObject=None, pointPen=None):
def readGlyph(self, glyphName, glyphObject=None, pointPen=None, validate=None):
"""
Read a .glif file for 'glyphName' from the glyph set. The
'glyphObject' argument can be any kind of object (even None);
@ -301,7 +324,12 @@ class GlyphSet(object):
readGlyph() will raise KeyError if the glyph is not present in
the glyph set.
``validate`` will validate the data, by default it is set to the
class's ``validateRead`` value, can be overridden.
"""
if validate is None:
validate = self._validateRead
text = self.getGLIF(glyphName)
self._purgeCachedGLIF(glyphName)
tree = _glifTreeFromString(text)
@ -309,9 +337,9 @@ class GlyphSet(object):
formatVersions = (1,)
else:
formatVersions = (1, 2)
_readGlyphFromTree(tree, glyphObject, pointPen, formatVersions=formatVersions)
_readGlyphFromTree(tree, glyphObject, pointPen, formatVersions=formatVersions, validate=validate)
def writeGlyph(self, glyphName, glyphObject=None, drawPointsFunc=None, formatVersion=None):
def writeGlyph(self, glyphName, glyphObject=None, drawPointsFunc=None, formatVersion=None, validate=None):
"""
Write a .glif file for 'glyphName' to the glyph set. The
'glyphObject' argument can be any kind of object (even None);
@ -338,6 +366,9 @@ class GlyphSet(object):
The GLIF format version will be chosen based on the ufoFormatVersion
passed during the creation of this object. If a particular format
version is desired, it can be passed with the formatVersion argument.
``validate`` will validate the data, by default it is set to the
class's ``validateWrite`` value, can be overridden.
"""
if formatVersion is None:
if self.ufoFormatVersion >= 3:
@ -349,8 +380,10 @@ class GlyphSet(object):
raise GlifLibError("Unsupported GLIF format version: %s" % formatVersion)
if formatVersion == 2 and self.ufoFormatVersion < 3:
raise GlifLibError("Unsupported GLIF format version (%d) for UFO format version %d." % (formatVersion, self.ufoFormatVersion))
if validate is None:
validate = self._validateWrite
self._purgeCachedGLIF(glyphName)
data = writeGlyphToString(glyphName, glyphObject, drawPointsFunc, formatVersion=formatVersion)
data = writeGlyphToString(glyphName, glyphObject, drawPointsFunc, formatVersion=formatVersion, validate=validate)
fileName = self.contents.get(glyphName)
if fileName is None:
fileName = self.glyphNameToFileName(glyphName, self)
@ -479,7 +512,7 @@ def glyphNameToFileName(glyphName, glyphSet):
# GLIF To and From String
# -----------------------
def readGlyphFromString(aString, glyphObject=None, pointPen=None, formatVersions=(1, 2)):
def readGlyphFromString(aString, glyphObject=None, pointPen=None, formatVersions=(1, 2), validate=False):
"""
Read .glif data from a string into a glyph object.
@ -510,12 +543,14 @@ def readGlyphFromString(aString, glyphObject=None, pointPen=None, formatVersions
The formatVersions argument defined the GLIF format versions
that are allowed to be read.
``validate`` will validate the read data. It is set to ``False`` by default.
"""
tree = _glifTreeFromString(aString)
_readGlyphFromTree(tree, glyphObject, pointPen, formatVersions=formatVersions)
_readGlyphFromTree(tree, glyphObject, pointPen, formatVersions=formatVersions, validate=validate)
def writeGlyphToString(glyphName, glyphObject=None, drawPointsFunc=None, writer=None, formatVersion=2):
def writeGlyphToString(glyphName, glyphObject=None, drawPointsFunc=None, writer=None, formatVersion=2, validate=True):
"""
Return .glif data for a glyph as a UTF-8 encoded string.
The 'glyphObject' argument can be any kind of object (even None);
@ -540,6 +575,8 @@ def writeGlyphToString(glyphName, glyphObject=None, drawPointsFunc=None, writer=
proper PointPen methods to transfer the outline to the .glif file.
The GLIF format version can be specified with the formatVersion argument.
``validate`` will validate the written data. It is set to ``True`` by default.
"""
if writer is None:
try:
@ -569,27 +606,27 @@ def writeGlyphToString(glyphName, glyphObject=None, drawPointsFunc=None, writer=
_writeNote(glyphObject, writer)
# image
if formatVersion >= 2 and getattr(glyphObject, "image", None):
_writeImage(glyphObject, writer)
_writeImage(glyphObject, writer, validate)
# guidelines
if formatVersion >= 2 and getattr(glyphObject, "guidelines", None):
_writeGuidelines(glyphObject, writer, identifiers)
_writeGuidelines(glyphObject, writer, identifiers, validate)
# anchors
anchors = getattr(glyphObject, "anchors", None)
if formatVersion >= 2 and anchors:
_writeAnchors(glyphObject, writer, identifiers)
_writeAnchors(glyphObject, writer, identifiers, validate)
# outline
if drawPointsFunc is not None:
writer.begintag("outline")
writer.newline()
pen = GLIFPointPen(writer, identifiers=identifiers)
pen = GLIFPointPen(writer, identifiers=identifiers, validate=validate)
drawPointsFunc(pen)
if formatVersion == 1 and anchors:
_writeAnchorsFormat1(pen, anchors)
_writeAnchorsFormat1(pen, anchors, validate)
writer.endtag("outline")
writer.newline()
# lib
if getattr(glyphObject, "lib", None):
_writeLib(glyphObject, writer)
_writeLib(glyphObject, writer, validate)
# end
writer.endtag("glyph")
writer.newline()
@ -650,9 +687,9 @@ def _writeNote(glyphObject, writer):
writer.endtag("note")
writer.newline()
def _writeImage(glyphObject, writer):
def _writeImage(glyphObject, writer, validate):
image = getattr(glyphObject, "image", None)
if not imageValidator(image):
if validate and not imageValidator(image):
raise GlifLibError("image attribute must be a dict or dict-like object with the proper structure.")
attrs = [
("fileName", image["fileName"])
@ -667,9 +704,9 @@ def _writeImage(glyphObject, writer):
writer.simpletag("image", attrs)
writer.newline()
def _writeGuidelines(glyphObject, writer, identifiers):
def _writeGuidelines(glyphObject, writer, identifiers, validate):
guidelines = getattr(glyphObject, "guidelines", [])
if not guidelinesValidator(guidelines):
if validate and not guidelinesValidator(guidelines):
raise GlifLibError("guidelines attribute does not have the proper structure.")
for guideline in guidelines:
attrs = []
@ -697,8 +734,8 @@ def _writeGuidelines(glyphObject, writer, identifiers):
writer.simpletag("guideline", attrs)
writer.newline()
def _writeAnchorsFormat1(pen, anchors):
if not anchorsValidator(anchors):
def _writeAnchorsFormat1(pen, anchors, validate):
if validate and not anchorsValidator(anchors):
raise GlifLibError("anchors attribute does not have the proper structure.")
for anchor in anchors:
attrs = []
@ -713,9 +750,9 @@ def _writeAnchorsFormat1(pen, anchors):
pen.addPoint((x, y), segmentType="move", name=name)
pen.endPath()
def _writeAnchors(glyphObject, writer, identifiers):
def _writeAnchors(glyphObject, writer, identifiers, validate):
anchors = getattr(glyphObject, "anchors", [])
if not anchorsValidator(anchors):
if validate and not anchorsValidator(anchors):
raise GlifLibError("anchors attribute does not have the proper structure.")
for anchor in anchors:
attrs = []
@ -738,11 +775,12 @@ def _writeAnchors(glyphObject, writer, identifiers):
writer.simpletag("anchor", attrs)
writer.newline()
def _writeLib(glyphObject, writer):
def _writeLib(glyphObject, writer, validate):
lib = getattr(glyphObject, "lib", None)
valid, message = glyphLibValidator(lib)
if not valid:
raise GlifLibError(message)
if validate:
valid, message = glyphLibValidator(lib)
if not valid:
raise GlifLibError(message)
if not isinstance(lib, dict):
lib = dict(lib)
writer.begintag("lib")
@ -827,7 +865,7 @@ def _glifTreeFromString(aString):
raise GlifLibError("Invalid GLIF structure.")
return root
def _readGlyphFromTree(tree, glyphObject=None, pointPen=None, formatVersions=(1, 2)):
def _readGlyphFromTree(tree, glyphObject=None, pointPen=None, formatVersions=(1, 2), validate=False):
# check the format version
formatVersion = tree.get("format")
if formatVersion is None:
@ -840,14 +878,14 @@ def _readGlyphFromTree(tree, glyphObject=None, pointPen=None, formatVersions=(1,
if formatVersion not in formatVersions:
raise GlifLibError("Forbidden GLIF format version: %s" % formatVersion)
if formatVersion == 1:
_readGlyphFromTreeFormat1(tree=tree, glyphObject=glyphObject, pointPen=pointPen)
_readGlyphFromTreeFormat1(tree=tree, glyphObject=glyphObject, pointPen=pointPen, validate=validate)
elif formatVersion == 2:
_readGlyphFromTreeFormat2(tree=tree, glyphObject=glyphObject, pointPen=pointPen)
_readGlyphFromTreeFormat2(tree=tree, glyphObject=glyphObject, pointPen=pointPen, validate=validate)
else:
raise GlifLibError("Unsupported GLIF format version: %s" % formatVersion)
def _readGlyphFromTreeFormat1(tree, glyphObject=None, pointPen=None):
def _readGlyphFromTreeFormat1(tree, glyphObject=None, pointPen=None, validate=None):
# get the name
_readName(glyphObject, tree)
# populate the sub elements
@ -862,7 +900,7 @@ def _readGlyphFromTreeFormat1(tree, glyphObject=None, pointPen=None):
if element.text and element.text.strip() != '':
raise GlifLibError("Invalid outline structure.")
haveSeenOutline = True
buildOutlineFormat1(glyphObject, pointPen, element)
buildOutlineFormat1(glyphObject, pointPen, element, validate)
elif glyphObject is None:
continue
elif element.tag == "advance":
@ -887,14 +925,14 @@ def _readGlyphFromTreeFormat1(tree, glyphObject=None, pointPen=None):
if haveSeenLib:
raise GlifLibError("The lib element occurs more than once.")
haveSeenLib = True
_readLib(glyphObject, element)
_readLib(glyphObject, element, validate)
else:
raise GlifLibError("Unknown element in GLIF: %s" % element)
# set the collected unicodes
if unicodes:
_relaxedSetattr(glyphObject, "unicodes", unicodes)
def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None):
def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None, validate=None):
# get the name
_readName(glyphObject, tree)
# populate the sub elements
@ -913,7 +951,7 @@ def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None):
raise GlifLibError("Invalid outline structure.")
haveSeenOutline = True
if pointPen is not None:
buildOutlineFormat2(glyphObject, pointPen, element, identifiers)
buildOutlineFormat2(glyphObject, pointPen, element, identifiers, validate)
elif glyphObject is None:
continue
elif element.tag == "advance":
@ -949,7 +987,7 @@ def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None):
if len(element):
raise GlifLibError("Unknown children in image element.")
haveSeenImage = True
_readImage(glyphObject, element)
_readImage(glyphObject, element, validate)
elif element.tag == "note":
if haveSeenNote:
raise GlifLibError("The note element occurs more than once.")
@ -959,7 +997,7 @@ def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None):
if haveSeenLib:
raise GlifLibError("The lib element occurs more than once.")
haveSeenLib = True
_readLib(glyphObject, element)
_readLib(glyphObject, element, validate)
else:
raise GlifLibError("Unknown element in GLIF: %s" % element)
# set the collected unicodes
@ -994,21 +1032,22 @@ def _readNote(glyphObject, note):
note = "\n".join(line.strip() for line in lines if line.strip())
_relaxedSetattr(glyphObject, "note", note)
def _readLib(glyphObject, lib):
def _readLib(glyphObject, lib, validate):
assert len(lib) == 1
child = lib[0]
plist = readPlistFromTree(child)
valid, message = glyphLibValidator(plist)
if not valid:
raise GlifLibError(message)
if validate:
valid, message = glyphLibValidator(plist)
if not valid:
raise GlifLibError(message)
_relaxedSetattr(glyphObject, "lib", plist)
def _readImage(glyphObject, image):
def _readImage(glyphObject, image, validate):
imageData = image.attrib
for attr, default in _transformationInfo:
value = imageData.get(attr, default)
imageData[attr] = _number(value)
if not imageValidator(imageData):
if validate and not imageValidator(imageData):
raise GlifLibError("The image element is not properly formatted.")
_relaxedSetattr(glyphObject, "image", imageData)
@ -1026,7 +1065,7 @@ pointTypeOptions = set(["move", "line", "offcurve", "curve", "qcurve"])
# format 1
def buildOutlineFormat1(glyphObject, pen, outline):
def buildOutlineFormat1(glyphObject, pen, outline, validate):
anchors = []
for element in outline:
if element.tag == "contour":
@ -1038,14 +1077,14 @@ def buildOutlineFormat1(glyphObject, pen, outline):
anchors.append(anchor)
continue
if pen is not None:
_buildOutlineContourFormat1(pen, element)
_buildOutlineContourFormat1(pen, element, validate)
elif element.tag == "component":
if pen is not None:
_buildOutlineComponentFormat1(pen, element)
else:
raise GlifLibError("Unknown element in outline element: %s" % element)
if glyphObject is not None and anchors:
if not anchorsValidator(anchors):
if validate and not anchorsValidator(anchors):
raise GlifLibError("GLIF 1 anchors are not properly formatted.")
_relaxedSetattr(glyphObject, "anchors", anchors)
@ -1066,7 +1105,7 @@ def _buildAnchorFormat1(point):
anchor = dict(x=x, y=y, name=name)
return anchor
def _buildOutlineContourFormat1(pen, contour):
def _buildOutlineContourFormat1(pen, contour, validate):
if contour.attrib:
raise GlifLibError("Unknown attributes in contour element.")
pen.beginPath()
@ -1105,16 +1144,16 @@ def _buildOutlineComponentFormat1(pen, component):
# format 2
def buildOutlineFormat2(glyphObject, pen, outline, identifiers):
def buildOutlineFormat2(glyphObject, pen, outline, identifiers, validate):
for element in outline:
if element.tag == "contour":
_buildOutlineContourFormat2(pen, element, identifiers)
_buildOutlineContourFormat2(pen, element, identifiers, validate)
elif element.tag == "component":
_buildOutlineComponentFormat2(pen, element, identifiers)
_buildOutlineComponentFormat2(pen, element, identifiers, validate)
else:
raise GlifLibError("Unknown element in outline element: %s" % element.tag)
def _buildOutlineContourFormat2(pen, contour, identifiers):
def _buildOutlineContourFormat2(pen, contour, identifiers, validate):
for attr in contour.attrib.keys():
if attr not in contourAttributesFormat2:
raise GlifLibError("Unknown attribute in contour element: %s" % attr)
@ -1122,7 +1161,7 @@ def _buildOutlineContourFormat2(pen, contour, identifiers):
if identifier is not None:
if identifier in identifiers:
raise GlifLibError("The identifier %s is used more than once." % identifier)
if not identifierValidator(identifier):
if validate and not identifierValidator(identifier):
raise GlifLibError("The contour identifier %s is not valid." % identifier)
identifiers.add(identifier)
try:
@ -1132,10 +1171,10 @@ def _buildOutlineContourFormat2(pen, contour, identifiers):
warn("The beginPath method needs an identifier kwarg. The contour's identifier value has been discarded.", DeprecationWarning)
if len(contour):
_validateAndMassagePointStructures(contour, pointAttributesFormat2)
_buildOutlinePointsFormat2(pen, contour, identifiers)
_buildOutlinePointsFormat2(pen, contour, identifiers, validate)
pen.endPath()
def _buildOutlinePointsFormat2(pen, contour, identifiers):
def _buildOutlinePointsFormat2(pen, contour, identifiers, validate):
for element in contour:
x = element.attrib["x"]
y = element.attrib["y"]
@ -1146,7 +1185,7 @@ def _buildOutlinePointsFormat2(pen, contour, identifiers):
if identifier is not None:
if identifier in identifiers:
raise GlifLibError("The identifier %s is used more than once." % identifier)
if not identifierValidator(identifier):
if validate and not identifierValidator(identifier):
raise GlifLibError("The identifier %s is not valid." % identifier)
identifiers.add(identifier)
try:
@ -1155,7 +1194,7 @@ def _buildOutlinePointsFormat2(pen, contour, identifiers):
pen.addPoint((x, y), segmentType=segmentType, smooth=smooth, name=name)
warn("The addPoint method needs an identifier kwarg. The point's identifier value has been discarded.", DeprecationWarning)
def _buildOutlineComponentFormat2(pen, component, identifiers):
def _buildOutlineComponentFormat2(pen, component, identifiers, validate):
if len(component):
raise GlifLibError("Unknown child elements of component element.")
for attr in component.attrib.keys():
@ -1176,7 +1215,7 @@ def _buildOutlineComponentFormat2(pen, component, identifiers):
if identifier is not None:
if identifier in identifiers:
raise GlifLibError("The identifier %s is used more than once." % identifier)
if not identifierValidator(identifier):
if validate and not identifierValidator(identifier):
raise GlifLibError("The identifier %s is not valid." % identifier)
identifiers.add(identifier)
try:
@ -1443,7 +1482,7 @@ class GLIFPointPen(AbstractPointPen):
part of .glif files.
"""
def __init__(self, xmlWriter, formatVersion=2, identifiers=None):
def __init__(self, xmlWriter, formatVersion=2, identifiers=None, validate=True):
if identifiers is None:
identifiers = set()
self.formatVersion = formatVersion
@ -1451,13 +1490,14 @@ class GLIFPointPen(AbstractPointPen):
self.writer = xmlWriter
self.prevOffCurveCount = 0
self.prevPointTypes = []
self.validate = validate
def beginPath(self, identifier=None, **kwargs):
attrs = []
if identifier is not None and self.formatVersion >= 2:
if identifier in self.identifiers:
raise GlifLibError("identifier used more than once: %s" % identifier)
if not identifierValidator(identifier):
if self.validate and not identifierValidator(identifier):
raise GlifLibError("identifier not formatted properly: %s" % identifier)
attrs.append(("identifier", identifier))
self.identifiers.add(identifier)
@ -1514,7 +1554,7 @@ class GLIFPointPen(AbstractPointPen):
if identifier is not None and self.formatVersion >= 2:
if identifier in self.identifiers:
raise GlifLibError("identifier used more than once: %s" % identifier)
if not identifierValidator(identifier):
if self.validate and not identifierValidator(identifier):
raise GlifLibError("identifier not formatted properly: %s" % identifier)
attrs.append(("identifier", identifier))
self.identifiers.add(identifier)
@ -1531,7 +1571,7 @@ class GLIFPointPen(AbstractPointPen):
if identifier is not None and self.formatVersion >= 2:
if identifier in self.identifiers:
raise GlifLibError("identifier used more than once: %s" % identifier)
if not identifierValidator(identifier):
if self.validate and not identifierValidator(identifier):
raise GlifLibError("identifier not formatted properly: %s" % identifier)
attrs.append(("identifier", identifier))
self.identifiers.add(identifier)

View File

@ -32,7 +32,7 @@ class TestGLIF2(unittest.TestCase):
glif = stripText(glif)
glif = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + glif
glyph = Glyph()
readGlyphFromString(glif, glyphObject=glyph, pointPen=glyph)
readGlyphFromString(glif, glyphObject=glyph, pointPen=glyph, validate=True)
return glyph.py()
def testTopElement(self):

View File

@ -37,7 +37,7 @@ class ReadFontInfoVersion1TestCase(unittest.TestCase):
originalData = dict(fontInfoVersion1)
self._writeInfoToPlist(originalData)
infoObject = TestInfoObject()
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
reader.readInfo(infoObject)
for attr in dir(infoObject):
if attr not in fontInfoVersion2:
@ -57,7 +57,7 @@ class ReadFontInfoVersion1TestCase(unittest.TestCase):
info = dict(fontInfoVersion1)
info["fontStyle"] = old
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
infoObject = TestInfoObject()
reader.readInfo(infoObject)
self.assertEqual(new, infoObject.styleMapStyleName)
@ -78,7 +78,7 @@ class ReadFontInfoVersion1TestCase(unittest.TestCase):
info = dict(fontInfoVersion1)
info["widthName"] = old
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
infoObject = TestInfoObject()
reader.readInfo(infoObject)
self.assertEqual(new, infoObject.openTypeOS2WidthClass)

View File

@ -37,7 +37,7 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
originalData = dict(fontInfoVersion2)
self._writeInfoToPlist(originalData)
infoObject = TestInfoObject()
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
reader.readInfo(infoObject)
readData = {}
for attr in list(fontInfoVersion2.keys()):
@ -49,92 +49,92 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
info = dict(fontInfoVersion2)
info["familyName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# styleName
info = dict(fontInfoVersion2)
info["styleName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# styleMapFamilyName
info = dict(fontInfoVersion2)
info["styleMapFamilyName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# styleMapStyleName
## not a string
info = dict(fontInfoVersion2)
info["styleMapStyleName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## out of range
info = dict(fontInfoVersion2)
info["styleMapStyleName"] = "REGULAR"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# versionMajor
info = dict(fontInfoVersion2)
info["versionMajor"] = "1"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# versionMinor
info = dict(fontInfoVersion2)
info["versionMinor"] = "0"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# copyright
info = dict(fontInfoVersion2)
info["copyright"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# trademark
info = dict(fontInfoVersion2)
info["trademark"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# unitsPerEm
info = dict(fontInfoVersion2)
info["unitsPerEm"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# descender
info = dict(fontInfoVersion2)
info["descender"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# xHeight
info = dict(fontInfoVersion2)
info["xHeight"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# capHeight
info = dict(fontInfoVersion2)
info["capHeight"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# ascender
info = dict(fontInfoVersion2)
info["ascender"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# italicAngle
info = dict(fontInfoVersion2)
info["italicAngle"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
def testHeadRead(self):
@ -143,25 +143,25 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
info = dict(fontInfoVersion2)
info["openTypeHeadCreated"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## invalid format
info = dict(fontInfoVersion2)
info["openTypeHeadCreated"] = "2000-Jan-01 00:00:00"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeHeadLowestRecPPEM
info = dict(fontInfoVersion2)
info["openTypeHeadLowestRecPPEM"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeHeadFlags
info = dict(fontInfoVersion2)
info["openTypeHeadFlags"] = [-1]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
def testHheaRead(self):
@ -169,37 +169,37 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
info = dict(fontInfoVersion2)
info["openTypeHheaAscender"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeHheaDescender
info = dict(fontInfoVersion2)
info["openTypeHheaDescender"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeHheaLineGap
info = dict(fontInfoVersion2)
info["openTypeHheaLineGap"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeHheaCaretSlopeRise
info = dict(fontInfoVersion2)
info["openTypeHheaCaretSlopeRise"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeHheaCaretSlopeRun
info = dict(fontInfoVersion2)
info["openTypeHheaCaretSlopeRun"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeHheaCaretOffset
info = dict(fontInfoVersion2)
info["openTypeHheaCaretOffset"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
def testNameRead(self):
@ -207,91 +207,91 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
info = dict(fontInfoVersion2)
info["openTypeNameDesigner"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameDesignerURL
info = dict(fontInfoVersion2)
info["openTypeNameDesignerURL"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameManufacturer
info = dict(fontInfoVersion2)
info["openTypeNameManufacturer"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameManufacturerURL
info = dict(fontInfoVersion2)
info["openTypeNameManufacturerURL"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameLicense
info = dict(fontInfoVersion2)
info["openTypeNameLicense"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameLicenseURL
info = dict(fontInfoVersion2)
info["openTypeNameLicenseURL"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameVersion
info = dict(fontInfoVersion2)
info["openTypeNameVersion"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameUniqueID
info = dict(fontInfoVersion2)
info["openTypeNameUniqueID"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameDescription
info = dict(fontInfoVersion2)
info["openTypeNameDescription"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNamePreferredFamilyName
info = dict(fontInfoVersion2)
info["openTypeNamePreferredFamilyName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNamePreferredSubfamilyName
info = dict(fontInfoVersion2)
info["openTypeNamePreferredSubfamilyName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameCompatibleFullName
info = dict(fontInfoVersion2)
info["openTypeNameCompatibleFullName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameSampleText
info = dict(fontInfoVersion2)
info["openTypeNameSampleText"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameWWSFamilyName
info = dict(fontInfoVersion2)
info["openTypeNameWWSFamilyName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeNameWWSSubfamilyName
info = dict(fontInfoVersion2)
info["openTypeNameWWSSubfamilyName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
def testOS2Read(self):
@ -300,210 +300,210 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
info = dict(fontInfoVersion2)
info["openTypeOS2WidthClass"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## out or range
info = dict(fontInfoVersion2)
info["openTypeOS2WidthClass"] = 15
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2WeightClass
info = dict(fontInfoVersion2)
## not an int
info["openTypeOS2WeightClass"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## out of range
info["openTypeOS2WeightClass"] = -50
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2Selection
info = dict(fontInfoVersion2)
info["openTypeOS2Selection"] = [-1]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2VendorID
info = dict(fontInfoVersion2)
info["openTypeOS2VendorID"] = 1234
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2Panose
## not an int
info = dict(fontInfoVersion2)
info["openTypeOS2Panose"] = [0, 1, 2, 3, 4, 5, 6, 7, 8, str(9)]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## too few values
info = dict(fontInfoVersion2)
info["openTypeOS2Panose"] = [0, 1, 2, 3]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## too many values
info = dict(fontInfoVersion2)
info["openTypeOS2Panose"] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2FamilyClass
## not an int
info = dict(fontInfoVersion2)
info["openTypeOS2FamilyClass"] = [1, str(1)]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## too few values
info = dict(fontInfoVersion2)
info["openTypeOS2FamilyClass"] = [1]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## too many values
info = dict(fontInfoVersion2)
info["openTypeOS2FamilyClass"] = [1, 1, 1]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## out of range
info = dict(fontInfoVersion2)
info["openTypeOS2FamilyClass"] = [1, 201]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2UnicodeRanges
## not an int
info = dict(fontInfoVersion2)
info["openTypeOS2UnicodeRanges"] = ["0"]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## out of range
info = dict(fontInfoVersion2)
info["openTypeOS2UnicodeRanges"] = [-1]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2CodePageRanges
## not an int
info = dict(fontInfoVersion2)
info["openTypeOS2CodePageRanges"] = ["0"]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## out of range
info = dict(fontInfoVersion2)
info["openTypeOS2CodePageRanges"] = [-1]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2TypoAscender
info = dict(fontInfoVersion2)
info["openTypeOS2TypoAscender"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2TypoDescender
info = dict(fontInfoVersion2)
info["openTypeOS2TypoDescender"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2TypoLineGap
info = dict(fontInfoVersion2)
info["openTypeOS2TypoLineGap"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2WinAscent
info = dict(fontInfoVersion2)
info["openTypeOS2WinAscent"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2WinDescent
info = dict(fontInfoVersion2)
info["openTypeOS2WinDescent"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2Type
## not an int
info = dict(fontInfoVersion2)
info["openTypeOS2Type"] = ["1"]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
## out of range
info = dict(fontInfoVersion2)
info["openTypeOS2Type"] = [-1]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2SubscriptXSize
info = dict(fontInfoVersion2)
info["openTypeOS2SubscriptXSize"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2SubscriptYSize
info = dict(fontInfoVersion2)
info["openTypeOS2SubscriptYSize"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2SubscriptXOffset
info = dict(fontInfoVersion2)
info["openTypeOS2SubscriptXOffset"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2SubscriptYOffset
info = dict(fontInfoVersion2)
info["openTypeOS2SubscriptYOffset"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2SuperscriptXSize
info = dict(fontInfoVersion2)
info["openTypeOS2SuperscriptXSize"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2SuperscriptYSize
info = dict(fontInfoVersion2)
info["openTypeOS2SuperscriptYSize"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2SuperscriptXOffset
info = dict(fontInfoVersion2)
info["openTypeOS2SuperscriptXOffset"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2SuperscriptYOffset
info = dict(fontInfoVersion2)
info["openTypeOS2SuperscriptYOffset"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2StrikeoutSize
info = dict(fontInfoVersion2)
info["openTypeOS2StrikeoutSize"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeOS2StrikeoutPosition
info = dict(fontInfoVersion2)
info["openTypeOS2StrikeoutPosition"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
def testVheaRead(self):
@ -511,37 +511,37 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
info = dict(fontInfoVersion2)
info["openTypeVheaVertTypoAscender"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeVheaVertTypoDescender
info = dict(fontInfoVersion2)
info["openTypeVheaVertTypoDescender"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeVheaVertTypoLineGap
info = dict(fontInfoVersion2)
info["openTypeVheaVertTypoLineGap"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeVheaCaretSlopeRise
info = dict(fontInfoVersion2)
info["openTypeVheaCaretSlopeRise"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeVheaCaretSlopeRun
info = dict(fontInfoVersion2)
info["openTypeVheaCaretSlopeRun"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# openTypeVheaCaretOffset
info = dict(fontInfoVersion2)
info["openTypeVheaCaretOffset"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
def testFONDRead(self):
@ -549,13 +549,13 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
info = dict(fontInfoVersion2)
info["macintoshFONDFamilyID"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# macintoshFONDName
info = dict(fontInfoVersion2)
info["macintoshFONDName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
def testPostscriptRead(self):
@ -563,211 +563,211 @@ class ReadFontInfoVersion2TestCase(unittest.TestCase):
info = dict(fontInfoVersion2)
info["postscriptFontName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# postscriptFullName
info = dict(fontInfoVersion2)
info["postscriptFullName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# postscriptSlantAngle
info = dict(fontInfoVersion2)
info["postscriptSlantAngle"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, info=TestInfoObject())
# postscriptUniqueID
info = dict(fontInfoVersion2)
info["postscriptUniqueID"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptUnderlineThickness
info = dict(fontInfoVersion2)
info["postscriptUnderlineThickness"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptUnderlinePosition
info = dict(fontInfoVersion2)
info["postscriptUnderlinePosition"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptIsFixedPitch
info = dict(fontInfoVersion2)
info["postscriptIsFixedPitch"] = 2
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptBlueValues
## not a list
info = dict(fontInfoVersion2)
info["postscriptBlueValues"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## uneven value count
info = dict(fontInfoVersion2)
info["postscriptBlueValues"] = [500]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## too many values
info = dict(fontInfoVersion2)
info["postscriptBlueValues"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptOtherBlues
## not a list
info = dict(fontInfoVersion2)
info["postscriptOtherBlues"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## uneven value count
info = dict(fontInfoVersion2)
info["postscriptOtherBlues"] = [500]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## too many values
info = dict(fontInfoVersion2)
info["postscriptOtherBlues"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptFamilyBlues
## not a list
info = dict(fontInfoVersion2)
info["postscriptFamilyBlues"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## uneven value count
info = dict(fontInfoVersion2)
info["postscriptFamilyBlues"] = [500]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## too many values
info = dict(fontInfoVersion2)
info["postscriptFamilyBlues"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptFamilyOtherBlues
## not a list
info = dict(fontInfoVersion2)
info["postscriptFamilyOtherBlues"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## uneven value count
info = dict(fontInfoVersion2)
info["postscriptFamilyOtherBlues"] = [500]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## too many values
info = dict(fontInfoVersion2)
info["postscriptFamilyOtherBlues"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptStemSnapH
## not list
info = dict(fontInfoVersion2)
info["postscriptStemSnapH"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## too many values
info = dict(fontInfoVersion2)
info["postscriptStemSnapH"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptStemSnapV
## not list
info = dict(fontInfoVersion2)
info["postscriptStemSnapV"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
## too many values
info = dict(fontInfoVersion2)
info["postscriptStemSnapV"] = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160]
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptBlueFuzz
info = dict(fontInfoVersion2)
info["postscriptBlueFuzz"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptBlueShift
info = dict(fontInfoVersion2)
info["postscriptBlueShift"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptBlueScale
info = dict(fontInfoVersion2)
info["postscriptBlueScale"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptForceBold
info = dict(fontInfoVersion2)
info["postscriptForceBold"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptDefaultWidthX
info = dict(fontInfoVersion2)
info["postscriptDefaultWidthX"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptNominalWidthX
info = dict(fontInfoVersion2)
info["postscriptNominalWidthX"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptWeightName
info = dict(fontInfoVersion2)
info["postscriptWeightName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptDefaultCharacter
info = dict(fontInfoVersion2)
info["postscriptDefaultCharacter"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# postscriptWindowsCharacterSet
info = dict(fontInfoVersion2)
info["postscriptWindowsCharacterSet"] = -1
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# macintoshFONDFamilyID
info = dict(fontInfoVersion2)
info["macintoshFONDFamilyID"] = "abc"
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())
# macintoshFONDName
info = dict(fontInfoVersion2)
info["macintoshFONDName"] = 123
self._writeInfoToPlist(info)
reader = UFOReader(self.dstDir)
reader = UFOReader(self.dstDir, validate=True)
self.assertRaises(UFOLibError, reader.readInfo, TestInfoObject())

File diff suppressed because it is too large Load Diff

View File

@ -224,7 +224,7 @@ class KerningUpConversionTestCase(unittest.TestCase):
def testUFO1(self):
self.makeUFO(formatVersion=2)
reader = UFOReader(self.ufoPath)
reader = UFOReader(self.ufoPath, validate=True)
kerning = reader.readKerning()
self.assertEqual(self.expectedKerning, kerning)
groups = reader.readGroups()
@ -234,7 +234,7 @@ class KerningUpConversionTestCase(unittest.TestCase):
def testUFO2(self):
self.makeUFO(formatVersion=2)
reader = UFOReader(self.ufoPath)
reader = UFOReader(self.ufoPath, validate=True)
kerning = reader.readKerning()
self.assertEqual(self.expectedKerning, kerning)
groups = reader.readGroups()

View File

@ -23,8 +23,8 @@ class GlyphSetTests(unittest.TestCase):
import difflib
srcDir = GLYPHSETDIR
dstDir = self.dstDir
src = GlyphSet(srcDir, ufoFormatVersion=2)
dst = GlyphSet(dstDir, ufoFormatVersion=2)
src = GlyphSet(srcDir, ufoFormatVersion=2, validateRead=True, validateWrite=True)
dst = GlyphSet(dstDir, ufoFormatVersion=2, validateRead=True, validateWrite=True)
for glyphName in src.keys():
g = src[glyphName]
g.drawPoints(None) # load attrs
@ -49,13 +49,13 @@ class GlyphSetTests(unittest.TestCase):
"%s.glif file differs after round tripping" % glyphName)
def testRebuildContents(self):
gset = GlyphSet(GLYPHSETDIR)
gset = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True)
contents = gset.contents
gset.rebuildContents()
self.assertEqual(contents, gset.contents)
def testReverseContents(self):
gset = GlyphSet(GLYPHSETDIR)
gset = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True)
d = {}
for k, v in gset.getReverseContents().items():
d[v] = k
@ -65,8 +65,8 @@ class GlyphSetTests(unittest.TestCase):
self.assertEqual(d, org)
def testReverseContents2(self):
src = GlyphSet(GLYPHSETDIR)
dst = GlyphSet(self.dstDir)
src = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True)
dst = GlyphSet(self.dstDir, validateRead=True, validateWrite=True)
dstMap = dst.getReverseContents()
self.assertEqual(dstMap, {})
for glyphName in src.keys():
@ -83,8 +83,8 @@ class GlyphSetTests(unittest.TestCase):
def testCustomFileNamingScheme(self):
def myGlyphNameToFileName(glyphName, glyphSet):
return "prefix" + glyphNameToFileName(glyphName, glyphSet)
src = GlyphSet(GLYPHSETDIR)
dst = GlyphSet(self.dstDir, myGlyphNameToFileName)
src = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True)
dst = GlyphSet(self.dstDir, myGlyphNameToFileName, validateRead=True, validateWrite=True)
for glyphName in src.keys():
g = src[glyphName]
g.drawPoints(None) # load attrs
@ -95,7 +95,7 @@ class GlyphSetTests(unittest.TestCase):
self.assertEqual(d, dst.contents)
def testGetUnicodes(self):
src = GlyphSet(GLYPHSETDIR)
src = GlyphSet(GLYPHSETDIR, validateRead=True, validateWrite=True)
unicodes = src.getUnicodes()
for glyphName in src.keys():
g = src[glyphName]