curveTo not working

Hey Guys —

I started noodling around with drawing points and paths with scripts. I got quite far with GSNodes but suddenly hit a wall when it was time to build curves. It seems like the Robofab Pens are recommended for general drawing? However curveTo isn’t working. I’m ending up with straight lines only. Faulty curveTo code below. Any help always wildly appreciated!

from import CurrentFont
from objectsGS import CurrentFont, RGlyph, GSLINE, GSCURVE, GSOFFCURVE, GSSHARP, GSSMOOTH
import random

f = CurrentFont()

thisLayers = Glyphs.font.selectedLayers[0]

newGlyph = f.newGlyph('demoDrawGlyph', clear=True)
newGlyph.width = 1000
pen = newGlyph.getPen()

pen.moveTo((100, 100))
pen.lineTo((800, 100))
pen.curveTo((1000, 300), (1000, 600), (800, 800))
pen.lineTo((100, 800))
pen.lineTo((100, 100))


How important is it for you to do it with RoboFab? I can tell you how to do it with the plain vanilla Python API:

#MenuTitle: Drawing Sample
# -*- coding: utf-8 -*-
Draw a sample path.


thisFont = Glyphs.font
thisLayer = thisFont.selectedLayers[0]

def addLineToPath( path, point ):
	newNode = GSNode()
	newNode.type = GSLINE
	newNode.position = point

def addCurveToPath( path, threePoints ):
	for i, point in enumerate( threePoints ):
		newNode = GSNode()
		if i == 2:
			newNode.type = GSCURVE
			newNode.type = GSOFFCURVE
		newNode.position = point

def addSegmentsToPath( path, segments ):
	for segment in segments:
		if len(segment) == 1:
			point = NSPoint( segment[0][0], segment[0][1] )
			addLineToPath( path, point )
		elif len(segment) == 3:
			points = (
				NSPoint( segment[0][0], segment[0][1] ),
				NSPoint( segment[1][0], segment[1][1] ),
				NSPoint( segment[2][0], segment[2][1] )
			addCurveToPath( path, points )

newPath = GSPath()
	( (800, 100) ),
	( (1000, 300), (1000, 600), (800, 800) ),
	( (100, 800) ),
	( (100, 100) )
newPath.close = True

Sorry to overcomplicate things a bit, but I could not resist abstracting into functions straight away.

Basically you create a GSNode, set its type to one of GSLINE, GSCURVE, or GSOFFCURVE, and set its position to an NSPoint. Then you append that node to a path’s nodes property, e.g., mypath.nodes.append(mynode). Eventually you set the path’s closed property to True and append the path to a layer’s paths property.

I just checked. Your code works fine for me. Do you have the latest roboFab and fontTools?

But here is much easier solution:

newGlyph = Font.glyphs['demoDrawGlyph']
if newGlyph is None:
    newGlyph = GSGlyph('demoDrawGlyph')
newLayer = newGlyph.layers[0]
newLayer.width = 1000
pen = newLayer.getPen()

pen.moveTo((100, 100))
pen.lineTo((800, 100))
pen.curveTo((1000, 300), (1000, 600), (800, 800))
pen.lineTo((100, 800))
pen.lineTo((100, 100))

That requires no roboFab and works fine.

1 Like

Thank you both. Always interesting to see different methodologies. In the end I struggled through using GSNodes and got something working. Now I can see how inelegant my code is! Output is not very forgiving should one set an incorrect node type, which threw me off having come from a more scriptographer pov.

What are the benefits of using vanilla python api over Georg’s pen? The pen looks so straight forward but what is lost?

Thanks again guys - you really are stars.

The pen is also plain vanilla. I just never really used pens so far.

The Glyphs pen API is very similarly to the roboFab/fontTools version but doesn’t need to libraries installed.

I’m not sure what went wrong for you but the roboFab version should work if you have the latest objectsGS file and roboFab.

Hey Georg —

I pasted that into the macro panel and it produced the new but empty glyph. I’m doing all the drawing with GSNodes which is a little messier but still, all good!


What versions if Glyphs do you have?

Version 2.3 (895)

What benefits do you find for using the native Pen over GSNode constructions?

Try the latest cutting edge version (see Preferences > Updates).

Matter of style, really. But pens are more elegant, at least in this case.