-
Notifications
You must be signed in to change notification settings - Fork 0
/
Align to Layer Horizontal Center.py
85 lines (80 loc) · 2.98 KB
/
Align to Layer Horizontal Center.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#MenuTitle: Align to Layer Horizontal Center
from __future__ import division
from math import radians, tan
__doc__="""
Align selection to horizontal center of the layer.
"""
layer = Glyphs.font.selectedLayers[0]
selection = layer.selection
if len(selection) > 0:
# detect if the selection contains only nodes or only one component
onlyNodes = True
onlyComponent = True
componentsCount = 0
for element in selection:
if type(element) != GSNode and onlyNodes == True:
onlyNodes = False
if type(element) != GSComponent and onlyComponent == True:
onlyComponent = False
if type(element) == GSComponent:
componentsCount += 1
if onlyComponent and componentsCount != 1:
onlyComponent = False
# ignore the handles positions if only nodes are selected (not components/anchors/guides)
if onlyNodes:
box = layer.selectionPath().bounds()
else:
box = layer.selectionBounds
# find the horizontal difference between the layer center and the selection center
layerCenterX = layer.width / 2
selectionCenterX = box.origin.x + box.size.width / 2
shift = layerCenterX - selectionCenterX
# take into account the italic angle if set
italicAngle = layer.master.italicAngle
if italicAngle != 0:
# get the italic vertical origin
# check if x-height is set or not
italicVerticalZero = 0
if layer.master.xHeight < Glyphs.font.upm:
italicVerticalZero = layer.master.xHeight / 2
italicAngleRadiansTan = tan(radians(italicAngle))
# find the left and right extremes respected to italic angle
extremeLeft = False
extremeRight = False
if onlyNodes:
# for nodes
for node in selection:
# ignoring the handles
if type(node) == GSNode and node.type != OFFCURVE:
x = node.x + italicAngleRadiansTan * (italicVerticalZero - node.y)
if extremeLeft == False or x < extremeLeft:
extremeLeft = x
if extremeRight == False or x > extremeRight:
extremeRight = x
# get slanted shift
shift = -(extremeLeft + (extremeRight - extremeLeft) / 2 - layerCenterX)
elif onlyComponent:
# for components
# find the left and right extremes inside the component and respected to italic angle
componentHome = element.component.layers[Layer.associatedMasterId]
for path in componentHome.paths:
for node in path.nodes:
# ignoring the handles
if type(node) == GSNode and node.type != OFFCURVE:
x = node.x + italicAngleRadiansTan * (italicVerticalZero - node.y)
if extremeLeft == False or x < extremeLeft:
extremeLeft = x
if extremeRight == False or x > extremeRight:
extremeRight = x
# get component shift
componentShift = element.x - (italicAngleRadiansTan * element.y)
# get slanted shift
shift = -(extremeLeft + (extremeRight - extremeLeft) / 2 - layerCenterX + componentShift)
else:
# for components/anchors/guides
selectionCenterY = box.origin.y + box.size.height / 2
shift -= italicAngleRadiansTan * (italicVerticalZero - selectionCenterY)
shift = int(shift)
# move selection
for node in selection:
node.x += shift