Transform selected segment across select set of masters

I am wondering if there is a more efficient way to write this snippet for applying a specific transformation (shifting 2 units to the right, in this case) for a selected path but for only a select set of masters.

my_masters = []
for name in [
	"Regular Light", 
	"Ultra Light",
	"Regular Light Italic",
	"Ultra Light Italic",
	]:
		
	for master in Font.masters:
		if master.name == name:
			my_masters.append ( master )
			
theseLayers = []
for m in my_masters:
	layer = Font.glyphs[gname].layers[m.id]
	theseLayers.append( layer )

transform = NSAffineTransform.new()
transform.translateXBy_yBy_(2, 0)

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

It’s pieced together from mekkablue Lines by Master and a transform snippet by Florian

I don’t think you need to use NSAffineTransform. You can just do something like

node.position = (node.position.x + 2, node.position.y)
1 Like

Nice. That is simpler.

Ah, and actually just looking back at your previous snippet for looping through masters, and seems like it would be faster to directly list the masters + index rather than looping through every time.

my_masters = [Font.masters[0], Font.masters[3]]

Thanks, Sebastian

It gets even simpler with node.x+=2

But if you use affine transformation, you can apply it to the whole layer at once with layer.applyTransform(matrix). I assume that’s going to be faster.

1 Like

Splitting hairs;-) Thanks, Rainer.

Oh, also realized there was a part missing to say when a new glyph is selected. Added below.
This should be good enough for current purposes.

my_masters = [
	Font.masters[0], 
	Font.masters[1],
	Font.masters[2],
	Font.masters[3],
	]

theseLayers = []
for m in my_masters:
	# get active layer
	layer = Font.selectedLayers[0]
	# get glyph of this layer
	glyph = layer.parent
	gname = glyph.name

	layer = Font.glyphs[gname].layers[m.id]
	theseLayers.append( layer )

# transform = NSAffineTransform.new()
# transform.translateXBy_yBy_(2, 0)

for thisLayer in theseLayers:
	for node in thisLayer.selection:
		node.x+=2
#		node.position = transform.transformPoint_(node.position)
#		node.position = (node.position.x + 2, node.position.y)

Now all that’s left is to properly format your code (because Rainer’s objectiveC habits result in very PEP-unconform code :kissing_heart:)

Variables are always written lowercase with underscores (so these_layers instead of theseLayers), and you need a space around your maths operators, so node.x += 2. Also, no spaces before or after parentheses.

:yawning_face: :sleeping: :sleeping_bed:

You can use camelCase in python even when it is not very popular.
A random line from the vanilla code:

def _calcFrame(parentFrame, posSize, absolutePositioning=False):

I agree with the spaces around math operators. But that would be the same in c and objectiveC.

Why not? I find it much more readable

I agree with @SCarewe