Spaces:
Runtime error
Runtime error
from fontTools.pens.basePen import AbstractPen | |
from fontTools.pens.pointPen import AbstractPointPen | |
from fontTools.pens.recordingPen import RecordingPen | |
class _PassThruComponentsMixin(object): | |
def addComponent(self, glyphName, transformation, **kwargs): | |
self._outPen.addComponent(glyphName, transformation, **kwargs) | |
class FilterPen(_PassThruComponentsMixin, AbstractPen): | |
"""Base class for pens that apply some transformation to the coordinates | |
they receive and pass them to another pen. | |
You can override any of its methods. The default implementation does | |
nothing, but passes the commands unmodified to the other pen. | |
>>> from fontTools.pens.recordingPen import RecordingPen | |
>>> rec = RecordingPen() | |
>>> pen = FilterPen(rec) | |
>>> v = iter(rec.value) | |
>>> pen.moveTo((0, 0)) | |
>>> next(v) | |
('moveTo', ((0, 0),)) | |
>>> pen.lineTo((1, 1)) | |
>>> next(v) | |
('lineTo', ((1, 1),)) | |
>>> pen.curveTo((2, 2), (3, 3), (4, 4)) | |
>>> next(v) | |
('curveTo', ((2, 2), (3, 3), (4, 4))) | |
>>> pen.qCurveTo((5, 5), (6, 6), (7, 7), (8, 8)) | |
>>> next(v) | |
('qCurveTo', ((5, 5), (6, 6), (7, 7), (8, 8))) | |
>>> pen.closePath() | |
>>> next(v) | |
('closePath', ()) | |
>>> pen.moveTo((9, 9)) | |
>>> next(v) | |
('moveTo', ((9, 9),)) | |
>>> pen.endPath() | |
>>> next(v) | |
('endPath', ()) | |
>>> pen.addComponent('foo', (1, 0, 0, 1, 0, 0)) | |
>>> next(v) | |
('addComponent', ('foo', (1, 0, 0, 1, 0, 0))) | |
""" | |
def __init__(self, outPen): | |
self._outPen = outPen | |
self.current_pt = None | |
def moveTo(self, pt): | |
self._outPen.moveTo(pt) | |
self.current_pt = pt | |
def lineTo(self, pt): | |
self._outPen.lineTo(pt) | |
self.current_pt = pt | |
def curveTo(self, *points): | |
self._outPen.curveTo(*points) | |
self.current_pt = points[-1] | |
def qCurveTo(self, *points): | |
self._outPen.qCurveTo(*points) | |
self.current_pt = points[-1] | |
def closePath(self): | |
self._outPen.closePath() | |
self.current_pt = None | |
def endPath(self): | |
self._outPen.endPath() | |
self.current_pt = None | |
class ContourFilterPen(_PassThruComponentsMixin, RecordingPen): | |
"""A "buffered" filter pen that accumulates contour data, passes | |
it through a ``filterContour`` method when the contour is closed or ended, | |
and finally draws the result with the output pen. | |
Components are passed through unchanged. | |
""" | |
def __init__(self, outPen): | |
super(ContourFilterPen, self).__init__() | |
self._outPen = outPen | |
def closePath(self): | |
super(ContourFilterPen, self).closePath() | |
self._flushContour() | |
def endPath(self): | |
super(ContourFilterPen, self).endPath() | |
self._flushContour() | |
def _flushContour(self): | |
result = self.filterContour(self.value) | |
if result is not None: | |
self.value = result | |
self.replay(self._outPen) | |
self.value = [] | |
def filterContour(self, contour): | |
"""Subclasses must override this to perform the filtering. | |
The contour is a list of pen (operator, operands) tuples. | |
Operators are strings corresponding to the AbstractPen methods: | |
"moveTo", "lineTo", "curveTo", "qCurveTo", "closePath" and | |
"endPath". The operands are the positional arguments that are | |
passed to each method. | |
If the method doesn't return a value (i.e. returns None), it's | |
assumed that the argument was modified in-place. | |
Otherwise, the return value is drawn with the output pen. | |
""" | |
return # or return contour | |
class FilterPointPen(_PassThruComponentsMixin, AbstractPointPen): | |
"""Baseclass for point pens that apply some transformation to the | |
coordinates they receive and pass them to another point pen. | |
You can override any of its methods. The default implementation does | |
nothing, but passes the commands unmodified to the other pen. | |
>>> from fontTools.pens.recordingPen import RecordingPointPen | |
>>> rec = RecordingPointPen() | |
>>> pen = FilterPointPen(rec) | |
>>> v = iter(rec.value) | |
>>> pen.beginPath(identifier="abc") | |
>>> next(v) | |
('beginPath', (), {'identifier': 'abc'}) | |
>>> pen.addPoint((1, 2), "line", False) | |
>>> next(v) | |
('addPoint', ((1, 2), 'line', False, None), {}) | |
>>> pen.addComponent("a", (2, 0, 0, 2, 10, -10), identifier="0001") | |
>>> next(v) | |
('addComponent', ('a', (2, 0, 0, 2, 10, -10)), {'identifier': '0001'}) | |
>>> pen.endPath() | |
>>> next(v) | |
('endPath', (), {}) | |
""" | |
def __init__(self, outPointPen): | |
self._outPen = outPointPen | |
def beginPath(self, **kwargs): | |
self._outPen.beginPath(**kwargs) | |
def endPath(self): | |
self._outPen.endPath() | |
def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs): | |
self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs) | |