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 robofab.world import CurrentFont
from objectsGS import CurrentFont, RGlyph, GSLINE, GSCURVE, GSOFFCURVE, GSSHARP, GSSMOOTH
import random
random.seed()


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))
pen.closePath()


newGlyph.update()
f.update()

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 -*-
__doc__="""
Draw a sample path.
"""

from GlyphApp import GSLINE, GSCURVE, GSOFFCURVE

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

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

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

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()
addSegmentsToPath(
	newPath,
	( (800, 100) ),
	( (1000, 300), (1000, 600), (800, 800) ),
	( (100, 800) ),
	( (100, 100) )
)
newPath.close = True
thisLayer.paths.append(newPath)

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.

1 Like

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')
    Font.glyphs.append(newGlyph)
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))
pen.closePath()
pen.endPath()

That requires no roboFab and works fine.

2 Likes

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!

Luke

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.