aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/pens/filterPen.py
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2018-07-03 17:43:11 -0700
committerHaibo Huang <hhb@google.com>2018-07-04 06:00:25 +0000
commit8b3c57bdcbbbd9cb1dc98546b567a138207b7638 (patch)
treeaf539e10dc3b2b42edd3197b34f1c8b5ee9a82a0 /Lib/fontTools/pens/filterPen.py
parentcc9a86e36194f2ef4456e14d98b810e41e4fa52d (diff)
downloadfonttools-8b3c57bdcbbbd9cb1dc98546b567a138207b7638.tar.gz
1. Add METADATA. 2. Run tools/external_updater/updater.sh update fonttools Test: m checkbuild Change-Id: Iab9e8c5da04f4c06347a924b4cea04f743f274c3
Diffstat (limited to 'Lib/fontTools/pens/filterPen.py')
-rw-r--r--Lib/fontTools/pens/filterPen.py121
1 files changed, 121 insertions, 0 deletions
diff --git a/Lib/fontTools/pens/filterPen.py b/Lib/fontTools/pens/filterPen.py
new file mode 100644
index 00000000..2f945507
--- /dev/null
+++ b/Lib/fontTools/pens/filterPen.py
@@ -0,0 +1,121 @@
+from __future__ import print_function, division, absolute_import
+from fontTools.misc.py23 import *
+from fontTools.pens.basePen import AbstractPen
+from fontTools.pens.recordingPen import RecordingPen
+
+
+class _PassThruComponentsMixin(object):
+
+ def addComponent(self, glyphName, transformation):
+ self._outPen.addComponent(glyphName, transformation)
+
+
+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
+
+ def moveTo(self, pt):
+ self._outPen.moveTo(pt)
+
+ def lineTo(self, pt):
+ self._outPen.lineTo(pt)
+
+ def curveTo(self, *points):
+ self._outPen.curveTo(*points)
+
+ def qCurveTo(self, *points):
+ self._outPen.qCurveTo(*points)
+
+ def closePath(self):
+ self._outPen.closePath()
+
+ def endPath(self):
+ self._outPen.endPath()
+
+
+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