draw each segment in a glyph?



  • I've been trying to figure out how to animate the drawing of each segment in a glyph (from DrawBot plugin in RF). For example this zigzag path, before it got outlined:

    0_1516917862444_zigzag_path_e.png

    I've tried writing something like:

    glyph = CurrentGlyph()
    newGlyph = RGlyph()
    for contour in glyph:
         newContour = RContour()
         newGlyph.appendContour(newContour)
         for segment in contour:
              newGlyph.appendSegment(segment)
              drawGlyph(newGlyph)
    

    so far I've found that appendSegment doesn't work as I would expect it to (or at all?). And I'm thinking there's a better way to do this using pens, but haven't been able to figure out how to step through each segment using a pen and draw them one by one.

    Eventually I'd like to draw only every nth frame so the animation goes faster.

    If anyone has suggestions for how to do this, please let me know. Thanks so much!



  • @cj Apart from writing your own "filter pen", one could do something like this:

    from fontTools.pens.recordingPen import RecordingPen
    
    g = CurrentGlyph()
    p = RecordingPen()
    g.draw(p)
    for op, args in p.value:
        print(op, args)
        #getattr(otherPen, op)(*args) # forward pen calls to another pen
    

    This way you get to see exactly which calls to the pen object glyph.draw(pen) causes.

    To use the pen protocol on a glyph, do something like:

    g = RGlyph()
    p = g.getPen()
    p.moveTo((100, 200))
    p.lineTo((100, 300))
    p.curveTo(p1, p2, p3)
    p.closePath()
    


  • @justvanrossum thanks so much!

    For anyone else trying this, for some reason I was getting an error when I had

    from fontTools.pens.recordingPen import RecordingPen
    

    error was

    ImportError: No module named recordingPen
    

    Perhaps because recordingPen.py isn't in the version of fontTools packaged with RoboFont?

    Anyway, I just copy/pasted the whole RecordingPen code from fontTools into my script:

    from fontTools.pens.basePen import AbstractPen
    
    
    class RecordingPen(AbstractPen):
    	"""Pen recording operations that can be accessed or replayed.
    
    	The recording can be accessed as pen.value; or replayed using
    	pen.replay(otherPen).
    
    	Usage example:
    	==============
    	from fontTools.ttLib import TTFont
    	from fontTools.pens.recordingPen import RecordingPen
    
    	glyph_name = 'dollar'
    	font_path = 'MyFont.otf'
    
    	font = TTFont(font_path)
    	glyphset = font.getGlyphSet()
    	glyph = glyphset[glyph_name]
    
    	pen = RecordingPen()
    	glyph.draw(pen)
    	print(pen.value)
    	"""
    
    	def __init__(self):
    		self.value = []
    	def moveTo(self, p0):
    		self.value.append(('moveTo', (p0,)))
    	def lineTo(self, p1):
    		self.value.append(('lineTo', (p1,)))
    	def qCurveTo(self, *points):
    		self.value.append(('qCurveTo', points))
    	def curveTo(self, *points):
    		self.value.append(('curveTo', points))
    	def closePath(self):
    		self.value.append(('closePath', ()))
    	def endPath(self):
    		self.value.append(('endPath', ()))
    	def addComponent(self, glyphName, transformation):
    		self.value.append(('addComponent', (glyphName, transformation)))
    	def replay(self, pen):
    		replayRecording(self.value, pen)
    

    and now I can run the script that Just wrote above. Thanks again!