summaryrefslogtreecommitdiff
path: root/misc/pylib/robofab/pens/rfUFOPen.pyx
blob: 265d7aea027f0ec0bea6c4f638f1648d51a59620 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""Pens for creating UFO glyphs."""

from robofab.objects.objectsBase import MOVE, LINE, CORNER, CURVE, QCURVE, OFFCURVE
from robofab.objects.objectsRF import RContour, RSegment, RPoint
from robofab.pens.pointPen import BasePointToSegmentPen
from robofab.pens.adapterPens import SegmentToPointPen


class RFUFOPen(SegmentToPointPen):

	def __init__(self, glyph):
		SegmentToPointPen.__init__(self, RFUFOPointPen(glyph))


class RFUFOPointPen(BasePointToSegmentPen):
	
	"""Point pen for building objectsRF glyphs"""
	
	def __init__(self, glyph):
		BasePointToSegmentPen.__init__(self)
		self.glyph = glyph
	
	def _flushContour(self, segments):
		#
		# adapted from robofab.pens.adapterPens.PointToSegmentPen
		#
		assert len(segments) >= 1
		# if we only have one point and it has a name, we must have an anchor
		first = segments[0]
		segmentType, points = first
		pt, smooth, name, kwargs = points[0]
		if len(segments) == 1 and name != None:
			self.glyph.appendAnchor(name, pt)
			return
		# we must have a contour
		contour = RContour()
		contour.setParent(self.glyph)
		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. only if it isn't a qcurve
			closed = True
			segmentType, points = segments[-1]
			movePt, smooth, name, kwargs = points[-1]
			## THIS IS STILL UNDECIDED!!!
			# since objectsRF currently follows the FL model of not
			# allowing open contours, remove the last segment
			# since it is being replaced by a move
			if segmentType == 'line':
				del segments[-1]
		# construct a move segment and apply it to the contour if we aren't dealing with a qcurve
		segment = RSegment()
		segment.setParent(contour)
		segment.smooth = smooth
		rPoint = RPoint(x=movePt[0], y=movePt[1], pointType=MOVE, name=name)
		rPoint.setParent(segment)
		segment.points = [rPoint]
		contour.segments.append(segment)
		# do the rest of the segments
		for segmentType, points in segments:
			points = [(pt, name) for pt, smooth, name, kwargs in points]
			if segmentType == "line":
				assert len(points) == 1
				sType = LINE
			elif segmentType == "curve":
				sType = CURVE
			elif segmentType == "qcurve":
				sType = QCURVE
			else:
				assert 0, "illegal segmentType: %s" % segmentType
			segment = RSegment()
			segment.setParent(contour)
			segment.smooth = smooth
			rPoints = []
			# handle the offCurves
			for point in points[:-1]:
				point, name = point
				rPoint = RPoint(x=point[0], y=point[1], pointType=OFFCURVE, name=name)
				rPoint.setParent(segment)
				rPoints.append(rPoint)
			# now the onCurve
			point, name = points[-1]
			rPoint = RPoint(x=point[0], y=point[1], pointType=sType, name=name)
			rPoint.setParent(segment)
			rPoints.append(rPoint)
			# apply them to the segment
			segment.points = rPoints
			contour.segments.append(segment)
		if contour.segments[-1].type == "curve":
			contour.segments[-1].points[-1].name = None
		self.glyph.contours.append(contour)
		
	def addComponent(self, glyphName, transform):
		xx, xy, yx, yy, dx, dy = transform
		self.glyph.appendComponent(baseGlyph=glyphName, offset=(dx, dy), scale=(xx, yy))