summaryrefslogtreecommitdiff
path: root/misc/pylib/robofab/pens/flPen.py
diff options
context:
space:
mode:
Diffstat (limited to 'misc/pylib/robofab/pens/flPen.py')
-rwxr-xr-xmisc/pylib/robofab/pens/flPen.py274
1 files changed, 0 insertions, 274 deletions
diff --git a/misc/pylib/robofab/pens/flPen.py b/misc/pylib/robofab/pens/flPen.py
deleted file mode 100755
index d5a867cd9..000000000
--- a/misc/pylib/robofab/pens/flPen.py
+++ /dev/null
@@ -1,274 +0,0 @@
-"""Pens for creating glyphs in FontLab."""
-
-
-__all__ = ["FLPen", "FLPointPen", "drawFLGlyphOntoPointPen"]
-
-
-from FL import *
-
-try:
- from fl_cmd import *
-except ImportError:
- print "The fl_cmd module is not available here. flPen.py"
-
-from robofab.tools.toolsFL import NewGlyph
-from robofab.pens.pointPen import AbstractPointPen
-from robofab.pens.adapterPens import SegmentToPointPen
-
-
-def roundInt(x):
- return int(round(x))
-
-
-class FLPen(SegmentToPointPen):
-
- def __init__(self, glyph):
- SegmentToPointPen.__init__(self, FLPointPen(glyph))
-
-
-class FLPointPen(AbstractPointPen):
-
- def __init__(self, glyph):
- if hasattr(glyph, "isRobofab"):
- self.glyph = glyph.naked()
- else:
- self.glyph = glyph
- self.currentPath = None
-
- def beginPath(self):
- self.currentPath = []
-
- def endPath(self):
- # Love is... abstracting away FL's madness.
- path = self.currentPath
- self.currentPath = None
- glyph = self.glyph
- if len(path) == 1 and path[0][3] is not None:
- # Single point on the contour, it has a name. Make it an anchor.
- x, y = path[0][0]
- name = path[0][3]
- anchor = Anchor(name, roundInt(x), roundInt(y))
- glyph.anchors.append(anchor)
- return
- firstOnCurveIndex = None
- for i in range(len(path)):
- if path[i][1] is not None:
- firstOnCurveIndex = i
- break
- if firstOnCurveIndex is None:
- # TT special case: on-curve-less contour. FL doesn't support that,
- # so we insert an implied point at the end.
- x1, y1 = path[0][0]
- x2, y2 = path[-1][0]
- impliedPoint = 0.5 * (x1 + x2), 0.5 * (y1 + y2)
- path.append((impliedPoint, "qcurve", True, None))
- firstOnCurveIndex = 0
- path = path[firstOnCurveIndex + 1:] + path[:firstOnCurveIndex + 1]
- firstPoint, segmentType, smooth, name = path[-1]
- closed = True
- if segmentType == "move":
- path = path[:-1]
- closed = False
- # XXX The contour is not closed, but I can't figure out how to
- # create an open contour in FL. Creating one by hand shows type"0x8011"
- # for a move node in an open contour, but I'm not able to access
- # that flag.
- elif segmentType == "line":
- # The contour is closed and ends in a lineto, which is redundant
- # as it's implied by closepath.
- path = path[:-1]
- x, y = firstPoint
- node = Node(nMOVE, Point(roundInt(x), roundInt(y)))
- if smooth and closed:
- if segmentType == "line" or path[0][1] == "line":
- node.alignment = nFIXED
- else:
- node.alignment = nSMOOTH
- glyph.Insert(node, len(glyph))
- segment = []
- nPoints = len(path)
- for i in range(nPoints):
- pt, segmentType, smooth, name = path[i]
- segment.append(pt)
- if segmentType is None:
- continue
- if segmentType == "curve":
- if len(segment) < 2:
- segmentType = "line"
- elif len(segment) == 2:
- segmentType = "qcurve"
- if segmentType == "qcurve":
- for x, y in segment[:-1]:
- glyph.Insert(Node(nOFF, Point(roundInt(x), roundInt(y))), len(glyph))
- x, y = segment[-1]
- node = Node(nLINE, Point(roundInt(x), roundInt(y)))
- glyph.Insert(node, len(glyph))
- elif segmentType == "curve":
- if len(segment) == 3:
- cubicSegments = [segment]
- else:
- from fontTools.pens.basePen import decomposeSuperBezierSegment
- cubicSegments = decomposeSuperBezierSegment(segment)
- nSegments = len(cubicSegments)
- for i in range(nSegments):
- pt1, pt2, pt3 = cubicSegments[i]
- x, y = pt3
- node = Node(nCURVE, Point(roundInt(x), roundInt(y)))
- node.points[1].x, node.points[1].y = roundInt(pt1[0]), roundInt(pt1[1])
- node.points[2].x, node.points[2].y = roundInt(pt2[0]), roundInt(pt2[1])
- if i != nSegments - 1:
- node.alignment = nSMOOTH
- glyph.Insert(node, len(self.glyph))
- elif segmentType == "line":
- assert len(segment) == 1, segment
- x, y = segment[0]
- node = Node(nLINE, Point(roundInt(x), roundInt(y)))
- glyph.Insert(node, len(glyph))
- else:
- assert 0, "unsupported curve type (%s)" % segmentType
- if smooth:
- if i + 1 < nPoints or closed:
- # Can't use existing node, as you can't change node attributes
- # AFTER it's been appended to the glyph.
- node = glyph[-1]
- if segmentType == "line" or path[(i+1) % nPoints][1] == "line":
- # tangent
- node.alignment = nFIXED
- else:
- # curve
- node.alignment = nSMOOTH
- segment = []
- if closed:
- # we may have output a node too much
- node = glyph[-1]
- if node.type == nLINE and (node.x, node.y) == (roundInt(firstPoint[0]), roundInt(firstPoint[1])):
- glyph.DeleteNode(len(glyph) - 1)
-
- def addPoint(self, pt, segmentType=None, smooth=None, name=None, **kwargs):
- self.currentPath.append((pt, segmentType, smooth, name))
-
- def addComponent(self, baseName, transformation):
- assert self.currentPath is None
- # make base glyph if needed, Component() needs the index
- NewGlyph(self.glyph.parent, baseName, updateFont=False)
- baseIndex = self.glyph.parent.FindGlyph(baseName)
- if baseIndex == -1:
- raise KeyError, "couldn't find or make base glyph"
- xx, xy, yx, yy, dx, dy = transformation
- # XXX warn when xy or yx != 0
- new = Component(baseIndex, Point(dx, dy), Point(xx, yy))
- self.glyph.components.append(new)
-
-
-def drawFLGlyphOntoPointPen(flGlyph, pen):
- """Draw a FontLab glyph onto a PointPen."""
- for anchor in flGlyph.anchors:
- pen.beginPath()
- pen.addPoint((anchor.x, anchor.y), name=anchor.name)
- pen.endPath()
- for contour in _getContours(flGlyph):
- pen.beginPath()
- for pt, segmentType, smooth in contour:
- pen.addPoint(pt, segmentType=segmentType, smooth=smooth)
- pen.endPath()
- for baseGlyph, tranform in _getComponents(flGlyph):
- pen.addComponent(baseGlyph, tranform)
-
-
-
-class FLPointContourPen(FLPointPen):
- """Same as FLPointPen, except that it ignores components."""
- def addComponent(self, baseName, transformation):
- pass
-
-
-NODE_TYPES = {nMOVE: "move", nLINE: "line", nCURVE: "curve",
- nOFF: None}
-
-def _getContours(glyph):
- contours = []
- for i in range(len(glyph)):
- node = glyph[i]
- segmentType = NODE_TYPES[node.type]
- if segmentType == "move":
- contours.append([])
- for pt in node.points[1:]:
- contours[-1].append(((pt.x, pt.y), None, False))
- smooth = node.alignment != nSHARP
- contours[-1].append(((node.x, node.y), segmentType, smooth))
-
- for contour in contours:
- # filter out or change the move
- movePt, segmentType, smooth = contour[0]
- assert segmentType == "move"
- lastSegmentType = contour[-1][1]
- if movePt == contour[-1][0] and lastSegmentType == "curve":
- contour[0] = contour[-1]
- contour.pop()
- elif lastSegmentType is None:
- contour[0] = movePt, "qcurve", smooth
- else:
- assert lastSegmentType in ("line", "curve")
- contour[0] = movePt, "line", smooth
-
- # change "line" to "qcurve" if appropriate
- previousSegmentType = "ArbitraryValueOtherThanNone"
- for i in range(len(contour)):
- pt, segmentType, smooth = contour[i]
- if segmentType == "line" and previousSegmentType is None:
- contour[i] = pt, "qcurve", smooth
- previousSegmentType = segmentType
-
- return contours
-
-
-def _simplifyValues(*values):
- """Given a set of numbers, convert items to ints if they are
- integer float values, eg. 0.0, 1.0."""
- newValues = []
- for v in values:
- i = int(v)
- if v == i:
- v = i
- newValues.append(v)
- return newValues
-
-
-def _getComponents(glyph):
- components = []
- for comp in glyph.components:
- baseName = glyph.parent[comp.index].name
- dx, dy = comp.delta.x, comp.delta.y
- sx, sy = comp.scale.x, comp.scale.y
- dx, dy, sx, sy = _simplifyValues(dx, dy, sx, sy)
- components.append((baseName, (sx, 0, 0, sy, dx, dy)))
- return components
-
-
-def test():
- g = fl.glyph
- g.Clear()
-
- p = PLPen(g)
- p.moveTo((50, 50))
- p.lineTo((150,50))
- p.lineTo((170, 200), smooth=2)
- p.curveTo((173, 225), (150, 250), (120, 250), smooth=1)
- p.curveTo((85, 250), (50, 200), (50, 200))
- p.closePath()
-
- p.moveTo((300, 300))
- p.lineTo((400, 300))
- p.curveTo((450, 325), (450, 375), (400, 400))
- p.qCurveTo((400, 500), (350, 550), (300, 500), (300, 400))
- p.closePath()
- p.setWidth(600)
- p.setNote("Hello, this is a note")
- p.addAnchor("top", (250, 600))
-
- fl.UpdateGlyph(-1)
- fl.UpdateFont(-1)
-
-
-if __name__ == "__main__":
- test()