# First script in my life = first problem with scripting

Hi
This is my first script for creating inktraps(also this is my first try in programming).
For this experiment I removed overlap in whole glyph “m” and created component _corner.corner with anchor on “zero” X-Y position.

``````import math
#calcAngle counts Angle between two lines
def calcAngle(lineA,lineB):
line1Y1 = lineA[0][1]
line1X1 = lineA[0][0]
line1Y2 = lineA[1][1]
line1X2 = lineA[1][0]

line2Y1 = lineB[0][1]
line2X1 = lineB[0][0]
line2Y2 = lineB[1][1]
line2X2 = lineB[1][0]

angle1 = math.atan2(line1Y1-line1Y2,line1X1-line1X2)
angle2 = math.atan2(line2Y1-line2Y2,line2X1-line2X2)
angleDegree = (angle1-angle2) * 360 / (2*math.pi)
return angleDegree

layer = Glyphs.font.selectedLayers[0]

nodeList = layer.paths[0].nodes

nodeListToSelect = []

#loop which check every angle
for index in range(len(nodeList)):
nodeLeft = nodeList[index]
nodeMiddle = nodeList[index+1]
nodeRight = nodeList[index+2]
lineA = ((nodeMiddle.x,nodeMiddle.y),(nodeLeft.x,nodeLeft.y))
lineB = ((nodeMiddle.x,nodeMiddle.y),(nodeRight.x,nodeRight.y))
angle = calcAngle(lineA, lineB)

if angle < 0:
angle = angle * -1

if angle <= 45:
nodeListToSelect.append(nodeMiddle)

layer.components.append(GSComponent('_corner.corner', NSPoint(nodeListToSelect[0].x, nodeListToSelect[0].y)))
``````

after running script I’m getting this:

``````Traceback (most recent call last):
File "<string>", line 47, in <module>
NameError: name 'NSPoint' is not defined
``````

Maybe I didn’t get how to use documentation?
//sorry for my english: I have a little hangover

and i don’t know if this way of adding component will work with super-duper-corner components.
Cheers

from

`````` layer.components.append(GSComponent('_corner.corner', NSPoint(nodeListToSelect[0].x, nodeListToSelect[0].y)))
``````

I just deleted “NSPoint”.
Everything is great except my script treats corner component as regular. Any advice?

I wonder if the `NSPoint` problem is this: Python scripts not working (807)

Try `from Foundation import NSPoint`.

Corner components are not actually components. They are implemented as hints. I’ll post some sample code, soon.

Great, thanks

Thanks Simon!
I imported NSPoint. And it works without problems, but the script still doesn’t treat component as a corner. I will wait for Georg’s samples.
What’s more interesting: it looks the same as when I didn’t use NSPoint.

``````from Foundation import NSMutableOrderedSet
l = Font.selectedLayers[0]
if len(l.selection) == 1 and isinstance(l.selection[0], GSNode):

Corner = GSHint.alloc().init()
Corner.type = CORNER
Corner.setName_("_corner.test")
Corner.originNode = l.selection[0]
print Corner
l.hints.append(Corner)
l.clearSelection()
``````

Thanks a lot Georg, works fine.

I have a problem: After using this script I can’t turn back by hitting command+z. Any advice?
Now script looks like this:

``````import math
#This script needs corner-component called "_corner.inktrap" to work
def calcAngle(lineA,lineB):

line1Y1 = lineA[0][1]
line1X1 = lineA[0][0]
line1Y2 = lineA[1][1]
line1X2 = lineA[1][0]

line2Y1 = lineB[0][1]
line2X1 = lineB[0][0]
line2Y2 = lineB[1][1]
line2X2 = lineB[1][0]

angle1 = math.atan2(line1Y1-line1Y2,line1X1-line1X2)
angle2 = math.atan2(line2Y1-line2Y2,line2X1-line2X2)
angleDegree = (angle1-angle2) * 360 / (2*math.pi)
return angleDegree

layer = Glyphs.font.selectedLayers[0]
layer.removeOverlap()

nodeList = layer.paths[0].nodes #wejscie przez scierzki "paths" do jej wszystkich nodesow w formie listy

nodeListToSelect = []

for index in range(len(nodeList)):
nodeLeft = nodeList[index]
nodeMiddle = nodeList[index+1]
nodeRight = nodeList[index+2]
lineA = ((nodeMiddle.x,nodeMiddle.y),(nodeLeft.x,nodeLeft.y))
lineB = ((nodeMiddle.x,nodeMiddle.y),(nodeRight.x,nodeRight.y))
angle = calcAngle(lineA, lineB)

if angle < 0:
angle = angle * -1

if angle <= 50:
nodeListToSelect.append(nodeMiddle)

print nodeListToSelect

for index in range(len(nodeListToSelect)):

Corner = GSHint.alloc().init()
Corner.type = CORNER
Corner.setName_("_corner.inktrap")
Corner.originNode = nodeListToSelect[index]
layer.hints.append(Corner)``````

Have you tried to use `beginUndo()` and `endUndo()` ?
http://docu.glyphsapp.com/#beginUndo

No. thanks a lot. Dummy’s omission

Crashes when pressing command+z: I’m doing something wrong

``````import math
#skrypt potrzebuje componentu _corner.corner, w ktorym jest narysowany inktrap
def calcAngle(lineA,lineB):

line1Y1 = lineA[0][1]
line1X1 = lineA[0][0]
line1Y2 = lineA[1][1]
line1X2 = lineA[1][0]

line2Y1 = lineB[0][1]
line2X1 = lineB[0][0]
line2Y2 = lineB[1][1]
line2X2 = lineB[1][0]

#oblicza kat mixedzy dwoma prostymi
angle1 = math.atan2(line1Y1-line1Y2,line1X1-line1X2)
angle2 = math.atan2(line2Y1-line2Y2,line2X1-line2X2)
angleDegree = (angle1-angle2) * 360 / (2*math.pi)
return angleDegree

layer = Glyphs.font.selectedLayers[0] #wejscie w layer zaznaczonej litery, tak na prawde ne potrzebne w tym wypadku, gdyz layer juz zostalo w AP przypisane glownemu layer-masterowi glyph'u(np. regular-layer). za pomoca tego, co tu utworzono mozna sie dostawac do layerow pobocznych.

layer.removeOverlap()

nodeList = layer.paths[0].nodes #wejscie przez scierzki "paths" do jej wszystkich nodesow w formie listy

nodeListToSelect = []

#petla, ktora jako powtorzenie dowiaduje sie wspolrzednych trzech kolejnych po sobie punktow(tak przez cala scierzke)
#jej zadaniem jest obliczenie kata, ktorego wierzcholkiem jest punkt nodeMiddle,
#a jego ramiona przecinaja punkty: nodeLeft oraz nodeRight.
for index in range(len(nodeList)):
nodeLeft = nodeList[index]
nodeMiddle = nodeList[index+1]
nodeRight = nodeList[index+2]
lineA = ((nodeMiddle.x,nodeMiddle.y),(nodeLeft.x,nodeLeft.y))
lineB = ((nodeMiddle.x,nodeMiddle.y),(nodeRight.x,nodeRight.y))
angle = calcAngle(lineA, lineB)

if angle < 0:
angle = angle * -1

if angle <= 45:
nodeListToSelect.append(nodeMiddle)

print nodeListToSelect

for index in range(len(nodeListToSelect)):
#layer.components.append(GSComponent('_corner.corner', (nodeListToSelect[index].x, nodeListToSelect[index].y)))

Corner = GSHint.alloc().init()
Corner.type = CORNER
Corner.setName_("_corner.corner")
Corner.originNode = nodeListToSelect[index]
layer.hints.append(Corner)

for thisLayer in listOfSelectedLayers:
thisGlyph = thisLayer.parent
thisGlyph.beginUndo() # begin undo grouping
thisGlyph.name
unRound( thisLayer )
thisGlyph.endUndo()   # end undo grouping``````

Another, maybe stupid question: I tried to search in documentation, but didn’t find it(maybe I don’t understand everything correctly):
How can I affect changes(for example with little “flipping” script showed below) in all masters at once? In this script I can only flip letter in active layer (selectedLayer). I did’n find a solution.

``````#MenuTitle: flipper
# -*- coding: utf-8 -*-
__doc__="""script flips glyphs"""

myMaster = Glyphs.font.selectedFontMaster
totalHeight = myMaster.xHeight
myLetters = Glyphs.font.selectedLayers

#counting x of middle point

allXnodes = []
for myLetter in myLetters:

myPaths = myLetter.paths

for myPath in myPaths:
for myNodes in myPath.nodes:
allXnodes.append(myNodes.x)

minXvalue = min(allXnodes)

maxXvalue = max(allXnodes)
#This is x value of mille point:
middlePointX = maxXvalue - (maxXvalue - minXvalue)/2

myMaster = Glyphs.font.selectedFontMaster
totalHeight = myMaster.xHeight
myLetters = Glyphs.font.selectedLayers

#counting y of middle point

allYnodes = []
for myLetter in myLetters:

myPaths = myLetter.paths

for myPath in myPaths:
for myNodes in myPath.nodes:
allYnodes.append(myNodes.y)

minYvalue = min(allYnodes)

maxYvalue = max(allYnodes)
#This is y value of mille point:
middlePointY = maxYvalue - (maxYvalue - minYvalue)/2

middlePoint = [middlePointX,middlePointY]
print middlePoint

#flipping:
for myLetter in myLetters:

myPaths = myLetter.paths

for myPath in myPaths:
for myNodes in myPath.nodes:
myNodes.x = middlePoint[0]-(myNodes.x-middlePoint[0])
myNodes.y = middlePoint[1]-(myNodes.y-middlePoint[1])
index += 1

flippedLSB = myLetter.RSB
flippedRSB = myLetter.LSB
myLetter.LSB = flippedLSB
myLetter.RSB = flippedRSB``````

I tried your corner script and it almost works. There is loop at the bottom of the script that seems relies on a missing variable: `listOfSelectedLayers` and calls a missing method: `unRound`.

iterating over all layers of a glyph:

``````selectedLayer = Font.selectedLayers[0]
for layer in selectedLayer.parent.layers:
print layer

``````

I tried your corner script and it almost works. There is loop at the bottom of the script that seems relies on a missing variable: listOfSelectedLayers and calls a missing method: unRound.

Thanks,I missed that. To be honest I copied these lines of code from other script and tried to figure out how it works. As a begginer I still have problems with using some methods, functions etc. In this example beginUndo/endUndo. I will figure it out

iterating over all layers of a glyph:

selectedLayer = Font.selectedLayers[0]
for layer in selectedLayer.parent.layers:
print layer

With printing informations about layer works fine. I did something wrong with for-loop. I get error message

Traceback (most recent call last):
File “”, line 12, in
TypeError: ‘NSKVONotifying_GSLayer’ object is not iterable

``````#MenuTitle: flipper left/right
# -*- coding: utf-8 -*-
__doc__="""flips along axis y"""

selectedLayer = Font.selectedLayers[0]
print selectedLayer
for myLetters in selectedLayer.parent.layers:
#counting x of middle point

allXnodes = []
for myLetter in myLetters:

myPaths = myLetter.paths

for myPath in myPaths:
for myNodes in myPath.nodes:
allXnodes.append(myNodes.x)

minXvalue = min(allXnodes)

maxXvalue = max(allXnodes)
#This is x value of mille point:
middlePointX = maxXvalue - (maxXvalue - minXvalue)/2

myMaster = Glyphs.font.selectedFontMaster
totalHeight = myMaster.xHeight
myLetters = Glyphs.font.selectedLayers

#counting y of middle point

allYnodes = []
for myLetter in myLetters:

myPaths = myLetter.paths

for myPath in myPaths:
for myNodes in myPath.nodes:
allYnodes.append(myNodes.y)

minYvalue = min(allYnodes)

maxYvalue = max(allYnodes)
#This is y value of mille point:
middlePointY = maxYvalue - (maxYvalue - minYvalue)/2

middlePoint = [middlePointX,middlePointY]
print middlePoint

#flipping:
for myLetter in myLetters:

myPaths = myLetter.paths

for myPath in myPaths:
for myNodes in myPath.nodes:
myNodes.x = middlePoint[0]-(myNodes.x-middlePoint[0])
myNodes.y = middlePoint[1]-(myNodes.y-middlePoint[1])

flippedLSB = myLetter.RSB
flippedRSB = myLetter.LSB
myLetter.LSB = flippedLSB
myLetter.RSB = flippedRSB``````

I hope my posts are not too annoying:
I can not deal with one thing whole day:
My script,which should flip components (and paths) works correctly only with one component.
If there are more than one component, code will mess with components’ positions.
I have been searching the code for few hours, but I haven’t found the problem.
Thanks for help.

test_flipper.py.zip (972 Bytes)