/
Build ellipsis from period components.py
96 lines (81 loc) · 3.66 KB
/
Build ellipsis from period components.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
86
87
88
89
90
91
92
93
94
95
96
# MenuTitle: Build ellipsis from period components
# -*- coding: utf-8 -*-
from __future__ import division, print_function, unicode_literals
__doc__ = """
Inserts exit and entry anchors in the period glyph and rebuilds ellipsis with auto-aligned components of period. Hold down OPT+SHIFT to have LSB and RSB exactly like period (otherwise with slight padding).\n\nATTENTION: decomposes all period components used in other glyphs (e.g., colon).
"""
from AppKit import NSPoint, NSEvent, NSEventModifierFlagOption, NSEventModifierFlagShift
from GlyphsApp import Glyphs, GSGlyph, GSAnchor, GSComponent, Message
Glyphs.clearLog() # clears log in Macro window
keysPressed = NSEvent.modifierFlags()
optionKeyPressed = keysPressed & NSEventModifierFlagOption == NSEventModifierFlagOption
shiftKeyPressed = keysPressed & NSEventModifierFlagShift == NSEventModifierFlagShift
keepSidebearingsSnug = optionKeyPressed & shiftKeyPressed
thisFont = Glyphs.font # frontmost font
period = thisFont.glyphs["period"]
def decomposeGlyphsContaining(font, componentName, exceptions=[]):
glyphNames = []
for master in font.masters:
for glyph in font.glyphsContainingComponentWithName_masterId_(componentName, master.id):
if glyph.name not in glyphNames and glyph.name not in exceptions:
glyphNames.append(glyph.name)
if glyphNames:
for glyphName in glyphNames:
glyph = font.glyphs[glyphName]
for layer in glyph.layers:
if layer.components:
for i in range(len(layer.components) - 1, -1, -1):
component = layer.components[i]
if component.componentName == componentName:
layer.decomposeComponent_(component)
return glyphNames
if not period:
Message(title="Build ellipsis Script Error", message="No period glyph in font. Add it and try again.", OKButton=None)
exit()
ellipsis = thisFont.glyphs["ellipsis"]
if not ellipsis:
print("⚙️ Creating ellipsis glyph (did not exist)")
ellipsis = GSGlyph("ellipsis")
thisFont.glyphs.append(ellipsis)
# decomposing non-ellipsis components:
decomposedGlyphs = decomposeGlyphsContaining(thisFont, period.name, exceptions=(ellipsis.name, ))
if decomposedGlyphs:
print("⚠️ Decomposed %s components in %i glyph%s: %s" % (period.name, len(decomposedGlyphs), "" if len(decomposedGlyphs) == 1 else "s", ", ".join(decomposedGlyphs)))
thisFont.disableUpdateInterface() # suppresses UI updates in Font View
try:
for thisMaster in thisFont.masters:
print(f"Ⓜ️ {thisMaster.name}")
print(" Adding #exit and #entry in period...")
mID = thisMaster.id
periodLayer = period.layers[mID]
distance = periodLayer.width - int((periodLayer.width - periodLayer.bounds.size.width) * 0.3)
for anchorName, anchorX in zip(("#entry", "#exit"), (0, distance)):
anchor = GSAnchor()
anchor.name = anchorName
anchor.position = NSPoint(anchorX, 0)
periodLayer.anchors.append(anchor)
print(" Backing up period...")
ellipsisLayer = ellipsis.layers[mID]
ellipsisLayer.swapForegroundWithBackground()
ellipsisLayer.background.decomposeComponents()
ellipsisLayer.shapes = None
for i in range(3):
ellipsisLayer.shapes.append(GSComponent("period"))
for thisComponent in ellipsisLayer.components:
thisComponent.setDisableAlignment_(False)
ellipsisLayer.updateMetrics()
if not keepSidebearingsSnug:
print("🔢 Setting Metrics Keys for ellipsis...")
ellipsis.leftMetricsKey = "=+20"
ellipsis.rightMetricsKey = "=+20"
thisFont.newTab(".…")
print("✅Done.")
except Exception as e:
Glyphs.showMacroWindow()
print("\n⚠️ Error in script: Build ellipsis from period components\n")
import traceback
print(traceback.format_exc())
print()
raise e
finally:
thisFont.enableUpdateInterface() # re-enables UI updates in Font View