diff options
Diffstat (limited to 'misc/pylib/robofab/pens/adapterPens.py')
-rw-r--r-- | misc/pylib/robofab/pens/adapterPens.py | 293 |
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)) |