summaryrefslogtreecommitdiff
path: root/misc/pylib/robofab/pens/adapterPens.py
diff options
context:
space:
mode:
Diffstat (limited to 'misc/pylib/robofab/pens/adapterPens.py')
-rw-r--r--misc/pylib/robofab/pens/adapterPens.py293
1 files changed, 0 insertions, 293 deletions
diff --git a/misc/pylib/robofab/pens/adapterPens.py b/misc/pylib/robofab/pens/adapterPens.py
deleted file mode 100644
index 0cd9ae3f7..000000000
--- a/misc/pylib/robofab/pens/adapterPens.py
+++ /dev/null
@@ -1,293 +0,0 @@
-import math
-from fontTools.pens.basePen import AbstractPen
-from robofab.pens.pointPen import AbstractPointPen, BasePointToSegmentPen
-
-
-class FabToFontToolsPenAdapter:
-
- """Class that covers up the subtle differences between RoboFab
- Pens and FontTools Pens. 'Fab should eventually move to FontTools
- Pens, this class may help to make the transition smoother.
- """
-
- # XXX The change to FontTools pens has almost been completed. Any
- # usage of this class should be highly suspect.
-
- def __init__(self, fontToolsPen):
- self.fontToolsPen = fontToolsPen
-
- def moveTo(self, pt, **kargs):
- self.fontToolsPen.moveTo(pt)
-
- def lineTo(self, pt, **kargs):
- self.fontToolsPen.lineTo(pt)
-
- def curveTo(self, *pts, **kargs):
- self.fontToolsPen.curveTo(*pts)
-
- def qCurveTo(self, *pts, **kargs):
- self.fontToolsPen.qCurveTo(*pts)
-
- def closePath(self):
- self.fontToolsPen.closePath()
-
- def endPath(self):
- self.fontToolsPen.endPath()
-
- def addComponent(self, glyphName, offset=(0, 0), scale=(1, 1)):
- self.fontToolsPen.addComponent(glyphName,
- (scale[0], 0, 0, scale[1], offset[0], offset[1]))
-
- def setWidth(self, width):
- self.width = width
-
- def setNote(self, note):
- pass
-
- def addAnchor(self, name, pt):
- self.fontToolsPen.moveTo(pt)
- self.fontToolsPen.endPath()
-
- def doneDrawing(self):
- pass
-
-
-class PointToSegmentPen(BasePointToSegmentPen):
-
- """Adapter class that converts the PointPen protocol to the
- (Segment)Pen protocol.
- """
-
- def __init__(self, segmentPen, outputImpliedClosingLine=False):
- BasePointToSegmentPen.__init__(self)
- self.pen = segmentPen
- self.outputImpliedClosingLine = outputImpliedClosingLine
-
- def _flushContour(self, segments):
- assert len(segments) >= 1
- pen = self.pen
- if segments[0][0] == "move":
- # It's an open path.
- closed = False
- points = segments[0][1]
- assert len(points) == 1
- movePt, smooth, name, kwargs = points[0]
- del segments[0]
- else:
- # It's a closed path, do a moveTo to the last
- # point of the last segment.
- closed = True
- segmentType, points = segments[-1]
- movePt, smooth, name, kwargs = points[-1]
- if movePt is None:
- # quad special case: a contour with no on-curve points contains
- # one "qcurve" segment that ends with a point that's None. We
- # must not output a moveTo() in that case.
- pass
- else:
- pen.moveTo(movePt)
- outputImpliedClosingLine = self.outputImpliedClosingLine
- nSegments = len(segments)
- for i in range(nSegments):
- segmentType, points = segments[i]
- points = [pt for pt, smooth, name, kwargs in points]
- if segmentType == "line":
- assert len(points) == 1
- pt = points[0]
- if i + 1 != nSegments or outputImpliedClosingLine or not closed:
- pen.lineTo(pt)
- elif segmentType == "curve":
- pen.curveTo(*points)
- elif segmentType == "qcurve":
- pen.qCurveTo(*points)
- else:
- assert 0, "illegal segmentType: %s" % segmentType
- if closed:
- pen.closePath()
- else:
- pen.endPath()
-
- def addComponent(self, glyphName, transform):
- self.pen.addComponent(glyphName, transform)
-
-
-class SegmentToPointPen(AbstractPen):
-
- """Adapter class that converts the (Segment)Pen protocol to the
- PointPen protocol.
- """
-
- def __init__(self, pointPen, guessSmooth=True):
- if guessSmooth:
- self.pen = GuessSmoothPointPen(pointPen)
- else:
- self.pen = pointPen
- self.contour = None
-
- def _flushContour(self):
- pen = self.pen
- pen.beginPath()
- for pt, segmentType in self.contour:
- pen.addPoint(pt, segmentType=segmentType)
- pen.endPath()
-
- def moveTo(self, pt):
- self.contour = []
- self.contour.append((pt, "move"))
-
- def lineTo(self, pt):
- self.contour.append((pt, "line"))
-
- def curveTo(self, *pts):
- for pt in pts[:-1]:
- self.contour.append((pt, None))
- self.contour.append((pts[-1], "curve"))
-
- def qCurveTo(self, *pts):
- if pts[-1] is None:
- self.contour = []
- for pt in pts[:-1]:
- self.contour.append((pt, None))
- if pts[-1] is not None:
- self.contour.append((pts[-1], "qcurve"))
-
- def closePath(self):
- if len(self.contour) > 1 and self.contour[0][0] == self.contour[-1][0]:
- self.contour[0] = self.contour[-1]
- del self.contour[-1]
- else:
- # There's an implied line at the end, replace "move" with "line"
- # for the first point
- pt, tp = self.contour[0]
- if tp == "move":
- self.contour[0] = pt, "line"
- self._flushContour()
- self.contour = None
-
- def endPath(self):
- self._flushContour()
- self.contour = None
-
- def addComponent(self, glyphName, transform):
- assert self.contour is None
- self.pen.addComponent(glyphName, transform)
-
-
-class TransformPointPen(AbstractPointPen):
-
- """PointPen that transforms all coordinates, and passes them to another
- PointPen. It also transforms the transformation given to addComponent().
- """
-
- def __init__(self, outPen, transformation):
- if not hasattr(transformation, "transformPoint"):
- from fontTools.misc.transform import Transform
- transformation = Transform(*transformation)
- self._transformation = transformation
- self._transformPoint = transformation.transformPoint
- self._outPen = outPen
- self._stack = []
-
- def beginPath(self):
- self._outPen.beginPath()
-
- def endPath(self):
- self._outPen.endPath()
-
- def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
- pt = self._transformPoint(pt)
- self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs)
-
- def addComponent(self, glyphName, transformation):
- transformation = self._transformation.transform(transformation)
- self._outPen.addComponent(glyphName, transformation)
-
-
-class GuessSmoothPointPen(AbstractPointPen):
-
- """Filtering PointPen that tries to determine whether an on-curve point
- should be "smooth", ie. that it's a "tangent" point or a "curve" point.
- """
-
- def __init__(self, outPen):
- self._outPen = outPen
- self._points = None
-
- def _flushContour(self):
- points = self._points
- nPoints = len(points)
- if not nPoints:
- return
- if points[0][1] == "move":
- # Open path.
- indices = range(1, nPoints - 1)
- elif nPoints > 1:
- # Closed path. To avoid having to mod the contour index, we
- # simply abuse Python's negative index feature, and start at -1
- indices = range(-1, nPoints - 1)
- else:
- # closed path containing 1 point (!), ignore.
- indices = []
- for i in indices:
- pt, segmentType, dummy, name, kwargs = points[i]
- if segmentType is None:
- continue
- prev = i - 1
- next = i + 1
- if points[prev][1] is not None and points[next][1] is not None:
- continue
- # At least one of our neighbors is an off-curve point
- pt = points[i][0]
- prevPt = points[prev][0]
- nextPt = points[next][0]
- if pt != prevPt and pt != nextPt:
- dx1, dy1 = pt[0] - prevPt[0], pt[1] - prevPt[1]
- dx2, dy2 = nextPt[0] - pt[0], nextPt[1] - pt[1]
- a1 = math.atan2(dx1, dy1)
- a2 = math.atan2(dx2, dy2)
- if abs(a1 - a2) < 0.05:
- points[i] = pt, segmentType, True, name, kwargs
-
- for pt, segmentType, smooth, name, kwargs in points:
- self._outPen.addPoint(pt, segmentType, smooth, name, **kwargs)
-
- def beginPath(self):
- assert self._points is None
- self._points = []
- self._outPen.beginPath()
-
- def endPath(self):
- self._flushContour()
- self._outPen.endPath()
- self._points = None
-
- def addPoint(self, pt, segmentType=None, smooth=False, name=None, **kwargs):
- self._points.append((pt, segmentType, False, name, kwargs))
-
- def addComponent(self, glyphName, transformation):
- assert self._points is None
- self._outPen.addComponent(glyphName, transformation)
-
-
-if __name__ == "__main__":
- from fontTools.pens.basePen import _TestPen as PSPen
- from robofab.pens.pointPen import PrintingPointPen
- segmentPen = PSPen(None)
-# pen = PointToSegmentPen(SegmentToPointPen(PointToSegmentPen(PSPen(None))))
- pen = PointToSegmentPen(SegmentToPointPen(PrintingPointPen()))
-# pen = PrintingPointPen()
- pen = PointToSegmentPen(PSPen(None), outputImpliedClosingLine=False)
-# pen.beginPath()
-# pen.addPoint((50, 50), name="an anchor")
-# pen.endPath()
- pen.beginPath()
- pen.addPoint((-100, 0), segmentType="line")
- pen.addPoint((0, 0), segmentType="line")
- pen.addPoint((0, 100), segmentType="line")
- pen.addPoint((30, 200))
- pen.addPoint((50, 100), name="superbezcontrolpoint!")
- pen.addPoint((70, 200))
- pen.addPoint((100, 100), segmentType="curve")
- pen.addPoint((100, 0), segmentType="line")
- pen.endPath()
-# pen.addComponent("a", (1, 0, 0, 1, 100, 200))