def reverse(self): """Reverse the winding direction of the pen.""" dp = DATPen() rp = ReverseContourPen(dp) self.replay(rp) self.value = dp.value return self
def _deepCopyContours(glyphSet, parent, component, transformation): """Copy contours from component to parent, including nested components.""" for nestedComponent in component.components: try: nestedBaseGlyph = glyphSet[nestedComponent.baseGlyph] except KeyError: logger.warning( "dropping non-existent component '%s' in glyph '%s'", nestedComponent.baseGlyph, parent.name) else: _deepCopyContours( glyphSet, parent, nestedBaseGlyph, transformation.transform(nestedComponent.transformation)) if component != parent: if transformation == Identity: pen = parent.getPen() else: pen = TransformPen(parent.getPen(), transformation) # if the transformation has a negative determinant, it will # reverse the contour direction of the component xx, xy, yx, yy = transformation[:4] if xx * yy - xy * yx < 0: pen = ReverseContourPen(pen) component.draw(pen)
def draw(layer, instance, pen): pen = PointToSegmentPen(pen) for path in layer.paths: nodes = list(path.nodes) pen.beginPath() if nodes: if not path.closed: node = nodes.pop(0) assert node.type == "line", "Open path starts with off-curve points" pen.addPoint(tuple(node.position), segmentType="move") else: # In Glyphs.app, the starting node of a closed contour is always # stored at the end of the nodes list. nodes.insert(0, nodes.pop()) for node in nodes: node_type = node.type if node_type not in ["line", "curve", "qcurve"]: node_type = None pen.addPoint(tuple(node.position), segmentType=node_type, smooth=node.smooth) pen.endPath(); for component in layer.components: componentLayer = getLayer(component.component, instance) transform = component.transform.value componentPen = pen.pen if transform != DEFAULT_TRANSFORM: componentPen = TransformPen(pen.pen, transform) xx, xy, yx, yy = transform[:4] if xx * yy - xy * yx < 0: componentPen = ReverseContourPen(componentPen) draw(componentLayer, instance, componentPen) return pen.pen
def addComponent(self, name, transform): pen = self if transform != Identity: pen = TransformPen(pen, transform) xx, xy, yx, yy = transform[:4] if xx * yy - xy * yx < 0: pen = ReverseContourPen(pen) self._layerSet[name].draw(pen)
def reverse(self): """Reverse the winding direction of the pen.""" if self.unended(): self.closePath() dp = type(self)() rp = ReverseContourPen(dp) self.replay(rp) self.value = dp.value return self
def deepCopyContours(glyphSet, parent, composite, transformation, specificComponents=None): """Copy contours from component to parent, including nested components. specificComponent: an optional list of glyph name strings. If not passed or None, decompose all components of a glyph unconditionally and completely. If passed, only completely decompose components whose baseGlyph is in the list. """ for nestedComponent in composite.components: # Because this function works recursively, test at each turn if we are going to # recurse into a specificComponent. If so, set the specificComponents argument # to None so we unconditionally decompose the possibly nested component # completely. specificComponentsEffective = specificComponents if specificComponentsEffective: if nestedComponent.baseGlyph not in specificComponentsEffective: continue else: specificComponentsEffective = None try: nestedBaseGlyph = glyphSet[nestedComponent.baseGlyph] except KeyError: logger.warning( "dropping non-existent component '%s' in glyph '%s'", nestedComponent.baseGlyph, parent.name, ) else: deepCopyContours( glyphSet, parent, nestedBaseGlyph, transformation.transform(nestedComponent.transformation), specificComponents=specificComponentsEffective, ) # Check if there are any contours to copy before instantiating pens. if composite != parent and len(composite): if transformation == Identity: pen = parent.getPen() else: pen = TransformPen(parent.getPen(), transformation) # if the transformation has a negative determinant, it will # reverse the contour direction of the component xx, xy, yx, yy = transformation[:4] if xx * yy - xy * yx < 0: pen = ReverseContourPen(pen) for contour in composite: contour.draw(pen)
def _deepCopyContours(ufo, parent, component, transformation): """Copy contours from component to parent, including nested components.""" for nested in component.components: _deepCopyContours(ufo, parent, ufo[nested.baseGlyph], transformation.transform(nested.transformation)) if component != parent: pen = TransformPen(parent.getPen(), transformation) # if the transformation has a negative determinant, it will reverse # the contour direction of the component xx, xy, yx, yy = transformation[:4] if xx * yy - xy * yx < 0: pen = ReverseContourPen(pen) component.draw(pen)
def __init__(self, other_pen, max_err, reverse_direction=False, stats=None, ignore_single_points=False): if reverse_direction: self.pen = ReverseContourPen(other_pen) else: self.pen = other_pen self.max_err = max_err self.stats = stats if ignore_single_points: import warnings warnings.warn("ignore_single_points is deprecated and " "will be removed in future versions", UserWarning, stacklevel=2) self.ignore_single_points = ignore_single_points self.start_pt = None self.current_pt = None
def _set_segments(glyph, segments, reverse_direction): """Draw segments as extracted by GetSegmentsPen back to a glyph.""" glyph.clearContours() pen = glyph.getPen() if reverse_direction: pen = ReverseContourPen(pen) for tag, args in segments: if tag == 'move': pen.moveTo(*args) elif tag == 'line': pen.lineTo(*args) elif tag == 'curve': pen.curveTo(*args[1:]) elif tag == 'qcurve': pen.qCurveTo(*args[1:]) elif tag == 'close': pen.closePath() elif tag == 'end': pen.endPath() else: raise AssertionError('Unhandled segment type "%s"' % tag)
def test_reverse_pen(contour, expected): recpen = RecordingPen() revpen = ReverseContourPen(recpen) for operator, operands in contour: getattr(revpen, operator)(*operands) assert recpen.value == expected