GSPath.segments and nodes

When I set p.segments = ..., does Glyphs rebuild the node list and automatically create the relevant GSNodes for me? If so, how does it know whether the connections should be smooth or sharp?

The background is, when editing a path, I find it easier to work on segments rather than on nodes: you see the points in context, you get to think in terms of Beziers and lines, and you don’t have to go hunting backwards and forwards in the node array for the points that you need. So I’ve been hacking on a little library that lets you explore paths using segments instead of nodes. It makes path.segments return an array of proxied “GSSegment” objects:

> s = Glyphs.font.selectedLayers[0].paths[0]
> print(s.segments[2])
<GSSegment (433.0, 424.0)..[448.0,461.0]..[459.0,476.0]..(497.0, 476.0)>

> print(s.segments[2].area())

> print(s.segments[1])
<GSSegment (264.0, 7.0)--(433.0, 424.0)>

> print(s.segments[1].length(), s.segments[1].angle())
(449.9444410146657, 1.185750154209631)

Having messed about with the segments, the ideal, of course, would be if we could build or edit a path by saying p.segments = (...). I can almost get it to work with my library, (with much monkeypatching of the GSPath class) but it is not quite working yet.

as seen in the documentation :

Node types:

Line node.

Curve node. Make sure that each curve node is preceded by two off-curve nodes.


addtionally you can check this condition >> type(obj)==GSNode and obj.type==35

there is a property GSPath.pathSegments that returns a list of GSPathSegments. The setter of this is not implemented, yet.
The GSPath.segments property retunes a list of list containing points. This can be set again. (the points are stored in NSValues so you need to access the values like this:

for segment in segments:
    if len(segment) == 2:
        # its  a line
        print segment[0].pointValue(), segment[1].pointValue()
    elif len(segment) == 4:

.pathSegments looks promising but still gives me NSPoints rather than nodes. I’m still not sure how to do tell the difference between a smooth and a sharp connection using a set of NSPoints. It might make more sense (although it would break compatibility) if .segments returned tuples of GSNodes instead.

Setting segments is not working reliably for me. This should delete short segments:

from math import sqrt

def seglength(seg):
    l1 = seg[0].x - seg[-1].x
    l2 = seg[0].y - seg[-1].y
    return sqrt(l1 * l1 + l2 * l2)

for p in Glyphs.font.selectedLayers[0].paths:
	p.segments = [ seg for seg in p.segments if seglength(seg) > 20 ]
	for seg in p.segments:
		if seglength(seg) < 20:
			print(str(seg) + " wasn't deleted")


    "NSPoint: {213, 389}",
    "NSPoint: {213, 387}"
) wasn't deleted