diff --git a/Lib/ufoLib/__init__.py b/Lib/ufoLib/__init__.py index aaa0e2893..8ee588454 100755 --- a/Lib/ufoLib/__init__.py +++ b/Lib/ufoLib/__init__.py @@ -151,7 +151,7 @@ class UFOReader(object): ``validate`` will validate the data. """ - if self._upConvertedKerningData: + if validate and self._upConvertedKerningData: testKerning = self._readKerning() if testKerning != self._upConvertedKerningData["originalKerning"]: raise UFOLibError("The data in kerning.plist has been modified since it was converted to UFO 3 format.") @@ -326,9 +326,9 @@ class UFOReader(object): # fontinfo.plist - def _readInfo(self): + def _readInfo(self, validate): data = self._getPlist(FONTINFO_FILENAME, {}) - if not isinstance(data, dict): + if validate and not isinstance(data, dict): raise UFOLibError("fontinfo.plist is not properly formatted.") return data @@ -344,7 +344,7 @@ class UFOReader(object): """ if validate is None: validate = self._validate - infoDict = self._readInfo() + infoDict = self._readInfo(validate) infoDataToSet = {} # version 1 if self._formatVersion == 1: @@ -493,7 +493,8 @@ class UFOReader(object): if layerDirectory == DEFAULT_GLYPHS_DIRNAME: return layerName # this will already have been raised during __init__ - raise UFOLibError("The default layer is not defined in layercontents.plist.") + if validate: + raise UFOLibError("The default layer is not defined in layercontents.plist.") def getGlyphSet(self, layerName=None, validateRead=None, validateWrite=None): """ @@ -615,10 +616,10 @@ class UFOReader(object): """ if validate is None: validate = self._validate - if self._formatVersion < 3: + if validate and self._formatVersion < 3: raise UFOLibError("Reading images is not allowed in UFO %d." % self._formatVersion) data = self.readBytesFromPath(os.path.join(IMAGES_DIRNAME, fileName)) - if data is None: + if validate and data is None: raise UFOLibError("No image file named %s." % fileName) if validate: valid, error = pngValidator(data=data) @@ -661,10 +662,10 @@ class UFOWriter(object): previousFormatVersion = int(previousFormatVersion) except: raise UFOLibError("The existing metainfo.plist is not properly formatted.") - if previousFormatVersion not in supportedUFOFormatVersions: + if validate and previousFormatVersion not in supportedUFOFormatVersions: raise UFOLibError("Unsupported UFO format (%d)." % formatVersion) # catch down conversion - if previousFormatVersion is not None and previousFormatVersion > formatVersion: + if validate and previousFormatVersion is not None and previousFormatVersion > formatVersion: raise UFOLibError("The UFO located at this path is a higher version (%d) than the version (%d) that is trying to be written. This is not supported." % (previousFormatVersion, formatVersion)) # handle the layer contents self.layerContents = {} @@ -1056,15 +1057,18 @@ class UFOWriter(object): # features.fea - def writeFeatures(self, features): + def writeFeatures(self, features, validate=None): """ Write features.fea. This method requires a features string as an argument. """ - if self._formatVersion == 1: - raise UFOLibError("features.fea is not allowed in UFO Format Version 1.") - if not isinstance(features, basestring): - raise UFOLibError("The features are not text.") + if validate is None: + validate = self._validate + if validate: + if self._formatVersion == 1: + raise UFOLibError("features.fea is not allowed in UFO Format Version 1.") + if not isinstance(features, basestring): + raise UFOLibError("The features are not text.") self._makeDirectory() path = os.path.join(self._path, FEATURES_FILENAME) writeFileAtomically(features, path) @@ -1090,11 +1094,13 @@ class UFOWriter(object): contents[layerName] = directoryName self.layerContents = contents - def writeLayerContents(self, layerOrder=None): + def writeLayerContents(self, layerOrder=None, validate=None): """ Write the layercontents.plist file. This method *must* be called after all glyph sets have been written. """ + if validate is None: + validate = self._validate if self.formatVersion < 3: return if layerOrder is not None: @@ -1106,7 +1112,7 @@ class UFOWriter(object): layerOrder = newOrder else: layerOrder = list(self.layerContents.keys()) - if set(layerOrder) != set(self.layerContents.keys()): + if validate and set(layerOrder) != set(self.layerContents.keys()): raise UFOLibError("The layer order contents does not match the glyph sets that have been created.") layerContents = [(layerName, self.layerContents[layerName]) for layerName in layerOrder] self._writePlist(LAYERCONTENTS_FILENAME, layerContents) @@ -1143,7 +1149,7 @@ class UFOWriter(object): 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): + if validateWrite and 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) # locate a layer name when None has been given if layerName is None and defaultLayer: @@ -1152,7 +1158,7 @@ class UFOWriter(object): layerName = existingLayerName if layerName is None: layerName = DEFAULT_LAYER_NAME - elif layerName is None and not defaultLayer: + elif validateWrite and layerName is None and not defaultLayer: raise UFOLibError("A layer name must be provided for non-default layers.") # move along to format specific writing if self.formatVersion == 1: @@ -1175,12 +1181,13 @@ class UFOWriter(object): # matches the default being written. also make sure that this layer # name is not already linked to a non-default layer. if defaultLayer: - for existingLayerName, directory in list(self.layerContents.items()): - if directory == DEFAULT_GLYPHS_DIRNAME: - if existingLayerName != layerName: - raise UFOLibError("Another layer is already mapped to the default directory.") - elif existingLayerName == layerName: - raise UFOLibError("The layer name is already mapped to a non-default layer.") + if validateRead: + for existingLayerName, directory in list(self.layerContents.items()): + if directory == DEFAULT_GLYPHS_DIRNAME: + if existingLayerName != layerName: + raise UFOLibError("Another layer is already mapped to the default directory.") + elif existingLayerName == layerName: + raise UFOLibError("The layer name is already mapped to a non-default layer.") # get an existing directory name if layerName in self.layerContents: directory = self.layerContents[layerName] @@ -1282,24 +1289,30 @@ class UFOWriter(object): path = os.path.join(IMAGES_DIRNAME, fileName) self.writeBytesToPath(path, data) - def removeImage(self, fileName): + def removeImage(self, fileName, validate=None): """ Remove the file named fileName from the images directory. """ - if self._formatVersion < 3: - raise UFOLibError("Images are not allowed in UFO %d." % self._formatVersion) + if validate is None: + validate = self._validate + if validate: + if self._formatVersion < 3: + raise UFOLibError("Images are not allowed in UFO %d." % self._formatVersion) path = os.path.join(IMAGES_DIRNAME, fileName) self.removeFileForPath(path) - def copyImageFromReader(self, reader, sourceFileName, destFileName): + def copyImageFromReader(self, reader, sourceFileName, destFileName, validate=None): """ Copy the sourceFileName in the provided UFOReader to destFileName in this writer. This uses the most memory efficient method possible for copying the data possible. """ - if self._formatVersion < 3: - raise UFOLibError("Images are not allowed in UFO %d." % self._formatVersion) + if validate is None: + validate = self._validate + if validate: + if self._formatVersion < 3: + raise UFOLibError("Images are not allowed in UFO %d." % self._formatVersion) sourcePath = os.path.join("images", sourceFileName) destPath = os.path.join("images", destFileName) self.copyFromReader(reader, sourcePath, destPath) diff --git a/Lib/ufoLib/glifLib.py b/Lib/ufoLib/glifLib.py index 935077d89..c866c9cd5 100755 --- a/Lib/ufoLib/glifLib.py +++ b/Lib/ufoLib/glifLib.py @@ -202,9 +202,9 @@ class GlyphSet(object): infoDict = self._readPlist(path) except MissingPlistError: return - if not isinstance(infoDict, dict): - raise GlifLibError("layerinfo.plist is not properly formatted.") if validateRead: + if not isinstance(infoDict, dict): + raise GlifLibError("layerinfo.plist is not properly formatted.") infoDict = validateLayerInfoVersion3Data(infoDict) # populate the object for attr, value in infoDict.items(): @@ -220,7 +220,7 @@ class GlyphSet(object): """ if validateWrite is None: validateWrite = self._validateWrite - if self.ufoFormatVersion < 3: + if validateWrite and self.ufoFormatVersion < 3: raise GlifLibError("layerinfo.plist is not allowed in UFO %d." % self.ufoFormatVersion) # gather data infoData = {} @@ -375,7 +375,7 @@ class GlyphSet(object): formatVersion = 2 else: formatVersion = 1 - else: + elif validate: if formatVersion not in supportedGLIFFormatVersions: raise GlifLibError("Unsupported GLIF format version: %s" % formatVersion) if formatVersion == 2 and self.ufoFormatVersion < 3: @@ -590,20 +590,20 @@ def writeGlyphToString(glyphName, glyphObject=None, drawPointsFunc=None, writer= aFile = None identifiers = set() # start - if not isinstance(glyphName, basestring): + if validate and not isinstance(glyphName, basestring): raise GlifLibError("The glyph name is not properly formatted.") - if len(glyphName) == 0: + if validate and len(glyphName) == 0: raise GlifLibError("The glyph name is empty.") writer.begintag("glyph", [("name", glyphName), ("format", formatVersion)]) writer.newline() # advance - _writeAdvance(glyphObject, writer) + _writeAdvance(glyphObject, writer, validate) # unicodes if getattr(glyphObject, "unicodes", None): - _writeUnicodes(glyphObject, writer) + _writeUnicodes(glyphObject, writer, validate) # note if getattr(glyphObject, "note", None): - _writeNote(glyphObject, writer) + _writeNote(glyphObject, writer, validate) # image if formatVersion >= 2 and getattr(glyphObject, "image", None): _writeImage(glyphObject, writer, validate) @@ -636,16 +636,16 @@ def writeGlyphToString(glyphName, glyphObject=None, drawPointsFunc=None, writer= else: return None -def _writeAdvance(glyphObject, writer): +def _writeAdvance(glyphObject, writer, validate): width = getattr(glyphObject, "width", None) if width is not None: - if not isinstance(width, (int, float)): + if validate and not isinstance(width, (int, float)): raise GlifLibError("width attribute must be int or float") if width == 0: width = None height = getattr(glyphObject, "height", None) if height is not None: - if not isinstance(height, (int, float)): + if validate and not isinstance(height, (int, float)): raise GlifLibError("height attribute must be int or float") if height == 0: height = None @@ -659,13 +659,13 @@ def _writeAdvance(glyphObject, writer): writer.simpletag("advance", height=repr(height)) writer.newline() -def _writeUnicodes(glyphObject, writer): +def _writeUnicodes(glyphObject, writer, validate): unicodes = getattr(glyphObject, "unicodes", None) - if isinstance(unicodes, int): + if validate and isinstance(unicodes, int): unicodes = [unicodes] seen = set() for code in unicodes: - if not isinstance(code, int): + if validate and not isinstance(code, int): raise GlifLibError("unicode values must be int") if code in seen: continue @@ -674,9 +674,9 @@ def _writeUnicodes(glyphObject, writer): writer.simpletag("unicode", hex=hexCode) writer.newline() -def _writeNote(glyphObject, writer): +def _writeNote(glyphObject, writer, validate): note = getattr(glyphObject, "note", None) - if not isinstance(note, basestring): + if validate and not isinstance(note, basestring): raise GlifLibError("note attribute must be str or unicode") note = note.encode("utf-8") writer.begintag("note") @@ -727,7 +727,7 @@ def _writeGuidelines(glyphObject, writer, identifiers, validate): attrs.append(("color", color)) identifier = guideline.get("identifier") if identifier is not None: - if identifier in identifiers: + if validate and identifier in identifiers: raise GlifLibError("identifier used more than once: %s" % identifier) attrs.append(("identifier", identifier)) identifiers.add(identifier) @@ -768,7 +768,7 @@ def _writeAnchors(glyphObject, writer, identifiers, validate): attrs.append(("color", color)) identifier = anchor.get("identifier") if identifier is not None: - if identifier in identifiers: + if validate and identifier in identifiers: raise GlifLibError("identifier used more than once: %s" % identifier) attrs.append(("identifier", identifier)) identifiers.add(identifier) @@ -868,14 +868,14 @@ def _glifTreeFromString(aString): def _readGlyphFromTree(tree, glyphObject=None, pointPen=None, formatVersions=(1, 2), validate=False): # check the format version formatVersion = tree.get("format") - if formatVersion is None: + if validate and formatVersion is None: raise GlifLibError("Unspecified format version in GLIF.") try: v = int(formatVersion) formatVersion = v except ValueError: pass - if formatVersion not in formatVersions: + if validate and formatVersion not in formatVersions: raise GlifLibError("Forbidden GLIF format version: %s" % formatVersion) if formatVersion == 1: _readGlyphFromTreeFormat1(tree=tree, glyphObject=glyphObject, pointPen=pointPen, validate=validate) @@ -887,24 +887,25 @@ def _readGlyphFromTree(tree, glyphObject=None, pointPen=None, formatVersions=(1, def _readGlyphFromTreeFormat1(tree, glyphObject=None, pointPen=None, validate=None): # get the name - _readName(glyphObject, tree) + _readName(glyphObject, tree, validate) # populate the sub elements unicodes = [] haveSeenAdvance = haveSeenOutline = haveSeenLib = haveSeenNote = False for element in tree: if element.tag == "outline": - if haveSeenOutline: - raise GlifLibError("The outline element occurs more than once.") - if element.attrib: - raise GlifLibError("The outline element contains unknown attributes.") - if element.text and element.text.strip() != '': - raise GlifLibError("Invalid outline structure.") + if validate: + if haveSeenOutline: + raise GlifLibError("The outline element occurs more than once.") + if element.attrib: + raise GlifLibError("The outline element contains unknown attributes.") + if element.text and element.text.strip() != '': + raise GlifLibError("Invalid outline structure.") haveSeenOutline = True buildOutlineFormat1(glyphObject, pointPen, element, validate) elif glyphObject is None: continue elif element.tag == "advance": - if haveSeenAdvance: + if validate and haveSeenAdvance: raise GlifLibError("The advance element occurs more than once.") haveSeenAdvance = True _readAdvance(glyphObject, element) @@ -917,12 +918,12 @@ def _readGlyphFromTreeFormat1(tree, glyphObject=None, pointPen=None, validate=No except ValueError: raise GlifLibError("Illegal value for hex attribute of unicode element.") elif element.tag == "note": - if haveSeenNote: + if validate and haveSeenNote: raise GlifLibError("The note element occurs more than once.") haveSeenNote = True _readNote(glyphObject, element) elif element.tag == "lib": - if haveSeenLib: + if validate and haveSeenLib: raise GlifLibError("The lib element occurs more than once.") haveSeenLib = True _readLib(glyphObject, element, validate) @@ -934,7 +935,7 @@ def _readGlyphFromTreeFormat1(tree, glyphObject=None, pointPen=None, validate=No def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None, validate=None): # get the name - _readName(glyphObject, tree) + _readName(glyphObject, tree, validate) # populate the sub elements unicodes = [] guidelines = [] @@ -943,19 +944,20 @@ def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None, validate=No identifiers = set() for element in tree: if element.tag == "outline": - if haveSeenOutline: - raise GlifLibError("The outline element occurs more than once.") - if element.attrib: - raise GlifLibError("The outline element contains unknown attributes.") - if element.text and element.text.strip() != '': - raise GlifLibError("Invalid outline structure.") + if validate: + if haveSeenOutline: + raise GlifLibError("The outline element occurs more than once.") + if element.attrib: + raise GlifLibError("The outline element contains unknown attributes.") + if element.text and element.text.strip() != '': + raise GlifLibError("Invalid outline structure.") haveSeenOutline = True if pointPen is not None: buildOutlineFormat2(glyphObject, pointPen, element, identifiers, validate) elif glyphObject is None: continue elif element.tag == "advance": - if haveSeenAdvance: + if validate and haveSeenAdvance: raise GlifLibError("The advance element occurs more than once.") haveSeenAdvance = True _readAdvance(glyphObject, element) @@ -968,33 +970,34 @@ def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None, validate=No except ValueError: raise GlifLibError("Illegal value for hex attribute of unicode element.") elif element.tag == "guideline": - if len(element): + if validate and len(element): raise GlifLibError("Unknown children in guideline element.") for attr in ("x", "y", "angle"): if attr in element.attrib: element.attrib[attr] = _number(element.attrib[attr]) guidelines.append(element.attrib) elif element.tag == "anchor": - if len(element): + if validate and len(element): raise GlifLibError("Unknown children in anchor element.") for attr in ("x", "y"): if attr in element.attrib: element.attrib[attr] = _number(element.attrib[attr]) anchors.append(element.attrib) elif element.tag == "image": - if haveSeenImage: - raise GlifLibError("The image element occurs more than once.") - if len(element): - raise GlifLibError("Unknown children in image element.") + if validate: + if haveSeenImage: + raise GlifLibError("The image element occurs more than once.") + if len(element): + raise GlifLibError("Unknown children in image element.") haveSeenImage = True _readImage(glyphObject, element, validate) elif element.tag == "note": - if haveSeenNote: + if validate and haveSeenNote: raise GlifLibError("The note element occurs more than once.") haveSeenNote = True _readNote(glyphObject, element) elif element.tag == "lib": - if haveSeenLib: + if validate and haveSeenLib: raise GlifLibError("The lib element occurs more than once.") haveSeenLib = True _readLib(glyphObject, element, validate) @@ -1005,18 +1008,18 @@ def _readGlyphFromTreeFormat2(tree, glyphObject=None, pointPen=None, validate=No _relaxedSetattr(glyphObject, "unicodes", unicodes) # set the collected guidelines if guidelines: - if not guidelinesValidator(guidelines, identifiers): + if validate and not guidelinesValidator(guidelines, identifiers): raise GlifLibError("The guidelines are improperly formatted.") _relaxedSetattr(glyphObject, "guidelines", guidelines) # set the collected anchors if anchors: - if not anchorsValidator(anchors, identifiers): + if validate and not anchorsValidator(anchors, identifiers): raise GlifLibError("The anchors are improperly formatted.") _relaxedSetattr(glyphObject, "anchors", anchors) -def _readName(glyphObject, root): +def _readName(glyphObject, root, validate): glyphName = root.get("name") - if not glyphName: + if validate and not glyphName: raise GlifLibError("Empty glyph name in GLIF.") if glyphName and glyphObject is not None: _relaxedSetattr(glyphObject, "name", glyphName) @@ -1072,7 +1075,7 @@ def buildOutlineFormat1(glyphObject, pen, outline, validate): if len(element) == 1: point = element[0] if point.tag == "point": - anchor = _buildAnchorFormat1(point) + anchor = _buildAnchorFormat1(point, validate) if anchor is not None: anchors.append(anchor) continue @@ -1080,7 +1083,7 @@ def buildOutlineFormat1(glyphObject, pen, outline, validate): _buildOutlineContourFormat1(pen, element, validate) elif element.tag == "component": if pen is not None: - _buildOutlineComponentFormat1(pen, element) + _buildOutlineComponentFormat1(pen, element, validate) else: raise GlifLibError("Unknown element in outline element: %s" % element) if glyphObject is not None and anchors: @@ -1088,7 +1091,7 @@ def buildOutlineFormat1(glyphObject, pen, outline, validate): raise GlifLibError("GLIF 1 anchors are not properly formatted.") _relaxedSetattr(glyphObject, "anchors", anchors) -def _buildAnchorFormat1(point): +def _buildAnchorFormat1(point, validate): if point.get("type") != "move": return None name = point.get("name") @@ -1096,9 +1099,9 @@ def _buildAnchorFormat1(point): return None x = point.get("x") y = point.get("y") - if x is None: + if validate and x is None: raise GlifLibError("Required x attribute is missing in point element.") - if y is None: + if validate and y is None: raise GlifLibError("Required y attribute is missing in point element.") x = _number(x) y = _number(y) @@ -1106,7 +1109,7 @@ def _buildAnchorFormat1(point): return anchor def _buildOutlineContourFormat1(pen, contour, validate): - if contour.attrib: + if validate and contour.attrib: raise GlifLibError("Unknown attributes in contour element.") pen.beginPath() if len(contour): @@ -1123,14 +1126,15 @@ def _buildOutlinePointsFormat1(pen, contour): name = element.attrib["name"] pen.addPoint((x, y), segmentType=segmentType, smooth=smooth, name=name) -def _buildOutlineComponentFormat1(pen, component): - if len(component): - raise GlifLibError("Unknown child elements of component element.") - for attr in component.attrib.keys(): - if attr not in componentAttributesFormat1: - raise GlifLibError("Unknown attribute in component element: %s" % attr) +def _buildOutlineComponentFormat1(pen, component, validate): + if validate: + if len(component): + raise GlifLibError("Unknown child elements of component element.") + for attr in component.attrib.keys(): + if attr not in componentAttributesFormat1: + raise GlifLibError("Unknown attribute in component element: %s" % attr) baseGlyphName = component.get("base") - if baseGlyphName is None: + if validate and baseGlyphName is None: raise GlifLibError("The base attribute is not defined in the component.") transformation = [] for attr, default in _transformationInfo: @@ -1154,15 +1158,17 @@ def buildOutlineFormat2(glyphObject, pen, outline, identifiers, validate): raise GlifLibError("Unknown element in outline element: %s" % element.tag) 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) + if validate: + for attr in contour.attrib.keys(): + if attr not in contourAttributesFormat2: + raise GlifLibError("Unknown attribute in contour element: %s" % attr) identifier = contour.get("identifier") if identifier is not None: - if identifier in identifiers: - raise GlifLibError("The identifier %s is used more than once." % identifier) - if validate and not identifierValidator(identifier): - raise GlifLibError("The contour identifier %s is not valid." % identifier) + if validate: + if identifier in identifiers: + raise GlifLibError("The identifier %s is used more than once." % identifier) + if not identifierValidator(identifier): + raise GlifLibError("The contour identifier %s is not valid." % identifier) identifiers.add(identifier) try: pen.beginPath(identifier=identifier) @@ -1183,10 +1189,11 @@ def _buildOutlinePointsFormat2(pen, contour, identifiers, validate): name = element.attrib["name"] identifier = element.get("identifier") if identifier is not None: - if identifier in identifiers: - raise GlifLibError("The identifier %s is used more than once." % identifier) - if validate and not identifierValidator(identifier): - raise GlifLibError("The identifier %s is not valid." % identifier) + if validate: + if identifier in identifiers: + raise GlifLibError("The identifier %s is used more than once." % identifier) + if not identifierValidator(identifier): + raise GlifLibError("The identifier %s is not valid." % identifier) identifiers.add(identifier) try: pen.addPoint((x, y), segmentType=segmentType, smooth=smooth, name=name, identifier=identifier) @@ -1195,13 +1202,14 @@ def _buildOutlinePointsFormat2(pen, contour, identifiers, validate): warn("The addPoint method needs an identifier kwarg. The point's identifier value has been discarded.", DeprecationWarning) def _buildOutlineComponentFormat2(pen, component, identifiers, validate): - if len(component): - raise GlifLibError("Unknown child elements of component element.") - for attr in component.attrib.keys(): - if attr not in componentAttributesFormat2: - raise GlifLibError("Unknown attribute in component element: %s" % attr) + if validate: + if len(component): + raise GlifLibError("Unknown child elements of component element.") + for attr in component.attrib.keys(): + if attr not in componentAttributesFormat2: + raise GlifLibError("Unknown attribute in component element: %s" % attr) baseGlyphName = component.get("base") - if baseGlyphName is None: + if validate and baseGlyphName is None: raise GlifLibError("The base attribute is not defined in the component.") transformation = [] for attr, default in _transformationInfo: @@ -1213,10 +1221,11 @@ def _buildOutlineComponentFormat2(pen, component, identifiers, validate): transformation.append(value) identifier = component.get("identifier") if identifier is not None: - if identifier in identifiers: - raise GlifLibError("The identifier %s is used more than once." % identifier) - if validate and not identifierValidator(identifier): - raise GlifLibError("The identifier %s is not valid." % identifier) + if validate: + if identifier in identifiers: + raise GlifLibError("The identifier %s is used more than once." % identifier) + if validate and not identifierValidator(identifier): + raise GlifLibError("The identifier %s is not valid." % identifier) identifiers.add(identifier) try: pen.addComponent(baseGlyphName, tuple(transformation), identifier=identifier) @@ -1496,10 +1505,11 @@ class GLIFPointPen(AbstractPointPen): 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 self.validate and not identifierValidator(identifier): - raise GlifLibError("identifier not formatted properly: %s" % identifier) + if self.validate: + if identifier in self.identifiers: + raise GlifLibError("identifier used more than once: %s" % identifier) + if not identifierValidator(identifier): + raise GlifLibError("identifier not formatted properly: %s" % identifier) attrs.append(("identifier", identifier)) self.identifiers.add(identifier) self.writer.begintag("contour", attrs) @@ -1508,7 +1518,7 @@ class GLIFPointPen(AbstractPointPen): def endPath(self): if self.prevPointTypes and self.prevPointTypes[0] == "move": - if self.prevPointTypes[-1] == "offcurve": + if self.validate and self.prevPointTypes[-1] == "offcurve": raise GlifLibError("open contour has loose offcurve point") self.writer.endtag("contour") self.writer.newline() @@ -1520,20 +1530,22 @@ class GLIFPointPen(AbstractPointPen): attrs = [] # coordinates if pt is not None: - for coord in pt: - if not isinstance(coord, (int, float)): - raise GlifLibError("coordinates must be int or float") + if self.validate: + for coord in pt: + if not isinstance(coord, (int, float)): + raise GlifLibError("coordinates must be int or float") attrs.append(("x", repr(pt[0]))) attrs.append(("y", repr(pt[1]))) # segment type if segmentType == "offcurve": segmentType = None - if segmentType == "move" and self.prevPointTypes: - raise GlifLibError("move occurs after a point has already been added to the contour.") - if segmentType in ("move", "line") and self.prevPointTypes and self.prevPointTypes[-1] == "offcurve": - raise GlifLibError("offcurve occurs before %s point." % segmentType) - if segmentType == "curve" and self.prevOffCurveCount > 2: - raise GlifLibError("too many offcurve points before curve point.") + if self.validate: + if segmentType == "move" and self.prevPointTypes: + raise GlifLibError("move occurs after a point has already been added to the contour.") + if segmentType in ("move", "line") and self.prevPointTypes and self.prevPointTypes[-1] == "offcurve": + raise GlifLibError("offcurve occurs before %s point." % segmentType) + if segmentType == "curve" and self.prevOffCurveCount > 2: + raise GlifLibError("too many offcurve points before curve point.") if segmentType is not None: attrs.append(("type", segmentType)) else: @@ -1545,7 +1557,7 @@ class GLIFPointPen(AbstractPointPen): self.prevPointTypes.append(segmentType) # smooth if smooth: - if segmentType == "offcurve": + if self.validate and segmentType == "offcurve": raise GlifLibError("can't set smooth in an offcurve point.") attrs.append(("smooth", "yes")) # name @@ -1553,10 +1565,11 @@ class GLIFPointPen(AbstractPointPen): attrs.append(("name", name)) # identifier if identifier is not None and self.formatVersion >= 2: - if identifier in self.identifiers: - raise GlifLibError("identifier used more than once: %s" % identifier) - if self.validate and not identifierValidator(identifier): - raise GlifLibError("identifier not formatted properly: %s" % identifier) + if self.validate: + if identifier in self.identifiers: + raise GlifLibError("identifier used more than once: %s" % identifier) + if not identifierValidator(identifier): + raise GlifLibError("identifier not formatted properly: %s" % identifier) attrs.append(("identifier", identifier)) self.identifiers.add(identifier) self.writer.simpletag("point", attrs) @@ -1565,15 +1578,16 @@ class GLIFPointPen(AbstractPointPen): def addComponent(self, glyphName, transformation, identifier=None, **kwargs): attrs = [("base", glyphName)] for (attr, default), value in zip(_transformationInfo, transformation): - if not isinstance(value, (int, float)): + if self.validate and not isinstance(value, (int, float)): raise GlifLibError("transformation values must be int or float") if value != default: attrs.append((attr, repr(value))) if identifier is not None and self.formatVersion >= 2: - if identifier in self.identifiers: - raise GlifLibError("identifier used more than once: %s" % identifier) - if self.validate and not identifierValidator(identifier): - raise GlifLibError("identifier not formatted properly: %s" % identifier) + if self.validate: + if identifier in self.identifiers: + raise GlifLibError("identifier used more than once: %s" % identifier) + if self.validate and not identifierValidator(identifier): + raise GlifLibError("identifier not formatted properly: %s" % identifier) attrs.append(("identifier", identifier)) self.identifiers.add(identifier) self.writer.simpletag("component", attrs) diff --git a/Lib/ufoLib/test/test_GLIF1.py b/Lib/ufoLib/test/test_GLIF1.py index 9b3c4bf42..e7ea66b79 100644 --- a/Lib/ufoLib/test/test_GLIF1.py +++ b/Lib/ufoLib/test/test_GLIF1.py @@ -24,7 +24,7 @@ class TestGLIF1(unittest.TestCase): py = stripText(py) glyph = Glyph() exec(py, {"glyph" : glyph, "pointPen" : glyph}) - glif = writeGlyphToString(glyph.name, glyphObject=glyph, drawPointsFunc=glyph.drawPoints, formatVersion=1) + glif = writeGlyphToString(glyph.name, glyphObject=glyph, drawPointsFunc=glyph.drawPoints, formatVersion=1, validate=True) glif = "\n".join(glif.splitlines()[1:]) return glif @@ -32,7 +32,7 @@ class TestGLIF1(unittest.TestCase): glif = stripText(glif) glif = "\n" + glif glyph = Glyph() - readGlyphFromString(glif, glyphObject=glyph, pointPen=glyph) + readGlyphFromString(glif, glyphObject=glyph, pointPen=glyph, validate=True) return glyph.py() def testTopElement(self): diff --git a/Lib/ufoLib/test/test_GLIF2.py b/Lib/ufoLib/test/test_GLIF2.py index c907f0769..b614a8d54 100644 --- a/Lib/ufoLib/test/test_GLIF2.py +++ b/Lib/ufoLib/test/test_GLIF2.py @@ -24,7 +24,7 @@ class TestGLIF2(unittest.TestCase): py = stripText(py) glyph = Glyph() exec(py, {"glyph" : glyph, "pointPen" : glyph}) - glif = writeGlyphToString(glyph.name, glyphObject=glyph, drawPointsFunc=glyph.drawPoints, formatVersion=2) + glif = writeGlyphToString(glyph.name, glyphObject=glyph, drawPointsFunc=glyph.drawPoints, formatVersion=2, validate=True) glif = "\n".join(glif.splitlines()[1:]) return glif