Made _validateAndMassagePointStructures run about 0.00003985 seconds faster. This should resolve ticket #22.

git-svn-id: http://svn.robofab.com/branches/ufo3k@506 b5fa9d6c-a76f-4ffd-b3cb-f825fc41095c
This commit is contained in:
Tal Leming 2011-12-06 15:35:44 +00:00
parent 5571ca07de
commit b836b3287a

View File

@ -1207,20 +1207,25 @@ def _buildOutlineComponentFormat2(pen, (attrs, children), identifiers):
def _validateAndMassagePointStructures(children, pointAttributes, openContourOffCurveLeniency=False): def _validateAndMassagePointStructures(children, pointAttributes, openContourOffCurveLeniency=False):
if not children: if not children:
return children return children
# store some data for later validation
pointTypes = []
haveOnCurvePoint = False
haveOffCurvePoint = False
# validate and massage the individual point elements # validate and massage the individual point elements
for index, (subElement, attrs, dummy) in enumerate(children): for index, (subElement, attrs, dummy) in enumerate(children):
# not <point> # not <point>
if subElement != "point": if subElement != "point":
raise GlifLibError("Unknown child element (%s) of contour element." % subElement) raise GlifLibError("Unknown child element (%s) of contour element." % subElement)
# unknown attributes # unknown attributes
if set(attrs.keys()) - pointAttributes: unknownAttributes = [attr for attr in attrs.keys() if attr not in pointAttributes]
if unknownAttributes:
raise GlifLibError("Unknown attributes in point element.") raise GlifLibError("Unknown attributes in point element.")
# search for unknown children # search for unknown children
if len(dummy): if len(dummy):
raise GlifLibError("Unknown child elements in point element.") raise GlifLibError("Unknown child elements in point element.")
# x and y are required # x and y are required
x = attrs.get("x", "undefined") x = attrs.get("x")
y = attrs.get("y", "undefined") y = attrs.get("y")
if x is None: if x is None:
raise GlifLibError("Required x attribute is missing in point element.") raise GlifLibError("Required x attribute is missing in point element.")
if y is None: if y is None:
@ -1228,14 +1233,19 @@ def _validateAndMassagePointStructures(children, pointAttributes, openContourOff
x = attrs["x"] = _number(x) x = attrs["x"] = _number(x)
y = attrs["y"] = _number(y) y = attrs["y"] = _number(y)
# segment type # segment type
segmentType = attrs.get("type", "offcurve") pointType = attrs.pop("type", "offcurve")
if segmentType not in pointTypeOptions: if pointType not in pointTypeOptions:
raise GlifLibError("Unknown point type: %s" % segmentType) raise GlifLibError("Unknown point type: %s" % pointType)
if segmentType == "offcurve": if pointType == "offcurve":
segmentType = None pointType = None
attrs["segmentType"] = segmentType attrs["segmentType"] = pointType
if pointType is None:
haveOffCurvePoint = True
else:
haveOnCurvePoint = True
pointTypes.append(pointType)
# move can only occur as the first point # move can only occur as the first point
if segmentType == "move" and index != 0: if pointType == "move" and index != 0:
raise GlifLibError("A move point occurs after the first point in the contour.") raise GlifLibError("A move point occurs after the first point in the contour.")
# smooth is optional # smooth is optional
smooth = attrs.get("smooth", "no") smooth = attrs.get("smooth", "no")
@ -1245,8 +1255,8 @@ def _validateAndMassagePointStructures(children, pointAttributes, openContourOff
smooth = smooth == "yes" smooth = smooth == "yes"
attrs["smooth"] = smooth attrs["smooth"] = smooth
# smooth can only be applied to curve and qcurve # smooth can only be applied to curve and qcurve
if smooth and segmentType not in ("curve", "qcurve"): if smooth and pointType not in ("curve", "qcurve"):
raise GlifLibError("smooth attribute set in a %s point." % segmentType) raise GlifLibError("smooth attribute set in a %s point." % pointType)
# name is optional # name is optional
if "name" not in attrs: if "name" not in attrs:
attrs["name"] = None attrs["name"] = None
@ -1262,39 +1272,39 @@ def _validateAndMassagePointStructures(children, pointAttributes, openContourOff
break break
elif attrs["segmentType"] is None: elif attrs["segmentType"] is None:
# remove the point # remove the point
pointTypes.pop(-1)
pass pass
break break
children.reverse() children.reverse()
# validate the segments # validate the off-curves in the segments
pointTypes = [a.get("type", "offcurve") for s, a, d in children] if haveOffCurvePoint and haveOnCurvePoint:
if set(pointTypes) != set(["offcurve"]): while pointTypes[-1] is None:
while pointTypes[-1] == "offcurve":
pointTypes.insert(0, pointTypes.pop(-1)) pointTypes.insert(0, pointTypes.pop(-1))
segments = [] segment = []
for pointType in reversed(pointTypes): for pointType in pointTypes:
if pointType != "offcurve": if pointType is None:
segments.append([pointType]) segment.append(pointType)
else:
segments[-1].append(pointType)
for segment in segments:
if len(segment) == 1:
continue continue
segmentType = segment[0] segment.append(pointType)
offCurves = segment[1:] if len(segment) > 1:
# move and line can't be preceded by off-curves segmentType = segment[-1]
if segmentType == "move": offCurves = segment[:-1]
# this will have been filtered out already # move and line can't be preceded by off-curves
raise GlifLibError("move can not have an offcurve.") if segmentType == "move":
elif segmentType == "line": # this will have been filtered out already
raise GlifLibError("line can not have an offcurve.") raise GlifLibError("move can not have an offcurve.")
elif segmentType == "curve": elif segmentType == "line":
if len(offCurves) > 2: raise GlifLibError("line can not have an offcurve.")
raise GlifLibError("Too many offcurves defined for curve.") elif segmentType == "curve":
elif segmentType == "qcurve": if len(offCurves) > 2:
pass raise GlifLibError("Too many offcurves defined for curve.")
else: elif segmentType == "qcurve":
# unknown segement type. it'll be caught later. pass
pass else:
# unknown segement type. it'll be caught later.
pass
# reset
segment = []
return children return children
# --------------------- # ---------------------