Tranformations on selected nodes/paths via scripting?

I’m trying to make a script that can scale down portions of a glyph—similar to a partial selection reshaped by dragging the edge of the bounding box. I gather that NSAffineTransform should maybe be involved, but does that only operate on layers? If not, how do I use it applied to only a portion of segments of a glyph?

Not wrapped, but a method available: GSNode.transform_()

You would construct the NSAffineTransform, then iterate through the nodes you want to change, and apply the transformation with that method.

1 Like

You can use an NSAffineTransformation but you could calculate the values yourself, too. And you don’t need to use hidden API.

transform = NSAffineTransform.new()
transform.translateXBy_yBy_(origin.x, origin.y)
transform.scaleXBy_yBy_(factorX, factorY)
transform.translateXBy_yBy_(-origin.x, -origin.y)
node.position = transform.transformPoint_(node.position)
1 Like

are all those periods vs underscores correct?

Here is an example that you can run in the Macro Panel:

from AppKit import NSAffineTransform

transform = NSAffineTransform.new()
transform.translateXBy_yBy_(20, 50)
transform.scaleXBy_yBy_(1.1, 0.8)

for node in Layer.selection:
	node.position = transform.transformPoint_(node.position)

See the NSAffineTransform documentation for a list of all supported methods. (Replace colons : with underscore _ in the method names.)

1 Like

Got it working. Thanks for the help guys!

def smooshLeft(layer):
    setsToMove = []
    setToAdd = []
    for path in layer.paths:
        for node in path.nodes:
            if node.position.x < margin:
                setToAdd.append(node)
                if node.nextNode.position.x >= margin:
                    setsToMove.append(setToAdd)
                    setToAdd = []
    print (setsToMove)
    for set in setsToMove:
        minX = margin
        for node in set:
            if node.x < minX:
                minX = node.x
        deltaX = margin - minX
        for node in set:
            scale = (zoneWidth - margin) / (zoneWidth - margin + deltaX)
            originX = zoneWidth
            transform = NSAffineTransform.new()
            transform.translateXBy_yBy_(originX, 0)
            transform.scaleXBy_yBy_(scale, 1)
            transform.translateXBy_yBy_(-originX, 0)
            node.position = transform.transformPoint_(node.position)