-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding useful scripts for Glyphs font editor.
- Loading branch information
Daniel Spreadbury
committed
Feb 16, 2019
1 parent
74db8e3
commit 96f269c
Showing
8 changed files
with
513 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
For these scripts to work, you'll need to put three SMuFL metadata files into the same folder as the scripts: | ||
|
||
- bravura_metadata.json | ||
- glyphnames.json | ||
- ranges.json | ||
|
||
**Important note: these scripts will modify your Glyphs project / font file so it's critical to have backups before running any operations. While I've tested the scripts here, I cannot guarantee that it will work in every single situation.** | ||
|
||
Now I've got the disclaimer out of the way, the first thing to run is the "Set metadata.." script. You should see all your glyphs coloured and categorised. If you then run the "Set Glyph names to SMuFL names" it should sort them into the categories. You can switch between SMuFL names, descriptions and codepoints using these three scripts. My understanding is that you should run the "Set Glyph names to codepoints" before doing a final export of your font file for maximum compatibility with various applications which expect the glyph names to correspond to the codepoint. | ||
|
||
Once the metadata is set on the glyphs, the "generate_font_metadata.py" script should work as expected. | ||
|
||
There's one more extra script which is called "Populate ranges". If you select one or more glyphs and run this script, it will create any other missing glyphs from that range as empty glyphs. You can also edit the script and uncomment or edit the DEFAULT_RANGES_TO_POPULATE array with the range you'd like to create. Running the script with no glyphs selected will create the default ranges from this list. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#MenuTitle: Generate SMuFL metadata JSON (Anchors + BBoxes) | ||
# -*- coding: utf-8 -*- | ||
# SMuFL metadata generator for Glyohs | ||
# The script should be added to Glyphs scripts folder | ||
# | ||
# By default it will output the metadata file onto the user's desktop, but this can be changed | ||
# by adjusting the value of the OUTPUT_DIR variable. | ||
# | ||
# Features currently supported: | ||
# - engraving defaults | ||
# - bounding boxes | ||
# - anchors | ||
# | ||
# Written by Ben Timms - Steinberg Media Technologies GmbH 2018 | ||
# Use, distribute and edit this script as you wish! | ||
|
||
import json | ||
import os | ||
from time import gmtime, strftime | ||
|
||
OUTPUT_DIR = os.path.join( os.path.expanduser("~"), "Desktop" ) | ||
|
||
currentFont = Glyphs.font | ||
|
||
# The values in the dictionary below should be manually edited | ||
font_metadata = { | ||
"fontName": currentFont.familyName, | ||
"fontVersion": 1.12, | ||
"engravingDefaults": { | ||
"arrowShaftThickness": 0.16, | ||
"barlineSeparation": 0.4, | ||
"beamSpacing": 0.25, | ||
"beamThickness": 0.5, | ||
"bracketThickness": 0.5, | ||
"dashedBarlineDashLength": 0.5, | ||
"dashedBarlineGapLength": 0.25, | ||
"dashedBarlineThickness": 0.16, | ||
"hairpinThickness": 0.16, | ||
"legerLineExtension": 0.4, | ||
"legerLineThickness": 0.16, | ||
"lyricLineThickness": 0.16, | ||
"octaveLineThickness": 0.16, | ||
"pedalLineThickness": 0.16, | ||
"repeatBarlineDotSeparation": 0.16, | ||
"repeatEndingLineThickness": 0.16, | ||
"slurEndpointThickness": 0.1, | ||
"slurMidpointThickness": 0.22, | ||
"staffLineThickness": 0.13, | ||
"stemThickness": 0.12, | ||
"subBracketThickness": 0.16, | ||
"textEnclosureThickness": 0.16, | ||
"thickBarlineThickness": 0.5, | ||
"thinBarlineThickness": 0.16, | ||
"tieEndpointThickness": 0.1, | ||
"tieMidpointThickness": 0.22, | ||
"tupletBracketThickness": 0.16 | ||
}, | ||
"glyphsWithAnchors": {}, | ||
"glyphBBoxes": {}, | ||
"optionalGlyphs": {}} | ||
|
||
|
||
metadata_filename = os.path.join(OUTPUT_DIR, "%s_metadata_%s.json" % ( currentFont.familyName, | ||
strftime( "%Y%m%d_%H%M%S", gmtime() ) ) ) | ||
|
||
print "Writing metadata to: %s" % metadata_filename | ||
|
||
def to_cartesian(val): | ||
return float(val)/250 | ||
|
||
for g in currentFont.glyphs: | ||
if len(g.layers) != 1: | ||
print g, len(g.layers) | ||
|
||
layer = g.layers[0] | ||
|
||
glyph_name = g.userData['name'] | ||
font_metadata["glyphBBoxes"][glyph_name] = \ | ||
{"bBoxSW": [ | ||
to_cartesian(layer.bounds.origin.x), | ||
to_cartesian(layer.bounds.origin.y) | ||
], | ||
"bBoxNE": [ | ||
to_cartesian(layer.bounds.origin.x + layer.bounds.size.width), | ||
to_cartesian(layer.bounds.origin.y + layer.bounds.size.height) | ||
] | ||
} | ||
if len(layer.anchors) > 0: | ||
font_metadata['glyphsWithAnchors'][glyph_name] = {} | ||
|
||
for anchor in layer.anchors: | ||
font_metadata['glyphsWithAnchors'][glyph_name][anchor.name] = \ | ||
[to_cartesian(anchor.position.x), to_cartesian(anchor.position.y)] | ||
|
||
with open(metadata_filename, 'w') as outfile: | ||
json.dump(font_metadata, outfile, indent=True, sort_keys=True) | ||
|
||
print "Done..." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#!/usr/bin/env python | ||
#MenuTitle: Populate ranges | ||
# -*- coding: utf-8 -*- | ||
# | ||
# If you have one or more glyphs selected in given ranges, it will ensure that | ||
# all the rest of the glyphs from those ranges are created. | ||
# | ||
# Note: it will default to setting the display name of newly created glyphs to | ||
# the codepoint. This can be easily remedied by running one of the "set display | ||
# name scripts". | ||
# | ||
# If the script is invoked with no selection it will populate the default ranges | ||
# that are uncommented below. | ||
# | ||
# The script should be added to Glyphs scripts folder and expects the following | ||
# SMuFL and Bravura metadata files to be present in the same directory. | ||
# | ||
# - bravura_metadata.json | ||
# - glyphnames.json | ||
# - ranges.json | ||
# | ||
# Written by Ben Timms - Steinberg Media Technologies GmbH 2018 | ||
# Use, distribute and edit this script as you wish! | ||
# | ||
__doc__=""" | ||
""" | ||
|
||
import sys | ||
from smufl_glyphs import SMuFLFontSyncer, invoke_menu_item | ||
|
||
# Uncomment any ranges that you'd like to be populated when nothing is selected. | ||
DEFAULT_RANGES_TO_POPULATE = [ | ||
# u'articulation', | ||
# u'articulationSupplement', | ||
# u'barlines', | ||
# u'barRepeats', | ||
# u'beamedGroupsOfNotes', | ||
# u'beamsAndSlurs', | ||
# u'chordSymbols', | ||
# u'clefs', | ||
# u'clefsSupplement', | ||
# u'commonOrnaments', | ||
# u'dynamics', | ||
# u'flags', | ||
# u'holdsAndPauses', | ||
# u'individualNotes', | ||
# u'lyrics', | ||
# u'miscellaneousSymbols', | ||
# u'multiSegmentLines', | ||
# u'noteheads', | ||
# u'noteNameNoteheads', | ||
# u'octaves', | ||
# u'octavesSupplement', | ||
# u'otherAccidentals', | ||
# u'otherBaroqueOrnaments', | ||
# u'precomposedTrillsAndMordents', | ||
# u'repeats', | ||
# u'rests', | ||
# u'roundAndSquareNoteheads', | ||
# u'shapeNoteNoteheads', | ||
# u'shapeNoteNoteheadsSupplement', | ||
# u'slashNoteheads', | ||
# u'staffBracketsAndDividers', | ||
# u'standardAccidentals12Edo', | ||
# u'standardAccidentalsChordSymbols', | ||
# u'staves', | ||
# u'stems', | ||
# u'stringTechniques', | ||
# u'timeSignatures', | ||
# u'timeSignaturesSupplement', | ||
# u'tremolos', | ||
# u'tuplets', | ||
# u'vocalTechniques', | ||
] | ||
|
||
currentFont = Glyphs.font | ||
|
||
selected_glyphs = currentFont.selection | ||
if len(selected_glyphs) == 0: | ||
ranges_to_populate = DEFAULT_RANGES_TO_POPULATE | ||
else: | ||
ranges_to_populate = [] | ||
for g in selected_glyphs: | ||
range_id = g.userData['smufl_range'] | ||
if range_id is not None and range_id not in ranges_to_populate: | ||
ranges_to_populate.append(range_id) | ||
|
||
if len(ranges_to_populate) == 0: | ||
print("No ranges to populate") | ||
sys.exit() | ||
|
||
smufl_font_syncer = SMuFLFontSyncer(currentFont) | ||
currentFont.disableUpdateInterface() | ||
smufl_font_syncer.populate_ranges(ranges_to_populate) | ||
currentFont.enableUpdateInterface() | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
#MenuTitle: Set Glyph names to codepoints | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Set the display name of the selected glyphs to show the codepoint. | ||
# If the script is invoked with no selection it will apply to all glyphs. | ||
# | ||
# NOTE: this should be run before exporting for maximum compatibility with apps | ||
# that expect the glyphs to be named according to their codepoint. | ||
# | ||
# The script should be added to Glyphs scripts folder and expects the following | ||
# SMuFL and Bravura metadata files to be present in the same directory. | ||
# | ||
# - bravura_metadata.json | ||
# - glyphnames.json | ||
# - ranges.json | ||
# | ||
# Written by Ben Timms - Steinberg Media Technologies GmbH 2018 | ||
# Use, distribute and edit this script as you wish! | ||
# | ||
__doc__=""" | ||
Set the display name of the glyph to the unicode codepoint | ||
""" | ||
|
||
from smufl_glyphs import set_display_name_to, invoke_menu_item, GLYPHS_EDIT_MENU_DESELECT_ALL_IDX | ||
|
||
currentFont = Glyphs.font | ||
|
||
selected_glyphs = currentFont.selection | ||
if len(selected_glyphs) == 0: | ||
glyphs_to_change = currentFont.glyphs | ||
else: | ||
glyphs_to_change = selected_glyphs | ||
|
||
currentFont.disableUpdateInterface() | ||
set_display_name_to(glyphs_to_change, 'uniCodepoint') | ||
currentFont.enableUpdateInterface() | ||
if len(selected_glyphs) == 0: | ||
print ("Deselecting...") | ||
invoke_menu_item(Glyphs, EDIT_MENU, GLYPHS_EDIT_MENU_DESELECT_ALL_IDX) |
38 changes: 38 additions & 0 deletions
38
scripts/glyphsapp/set_display_name_to_glyph_description.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#MenuTitle: Set Glyph names to SMuFL descriptions | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Set the display name of the selected glyphs to show the SMuFL description | ||
# | ||
# If the script is invoked with no selection it will apply to all glyphs. | ||
# | ||
# The script should be added to Glyphs scripts folder and expects the following | ||
# SMuFL and Bravura metadata files to be present in the same directory. | ||
# | ||
# - bravura_metadata.json | ||
# - glyphnames.json | ||
# - ranges.json | ||
# | ||
# Written by Ben Timms - Steinberg Media Technologies GmbH 2018 | ||
# Use, distribute and edit this script as you wish! | ||
# | ||
__doc__=""" | ||
Set the display name of the glyph to the description of the glyph | ||
""" | ||
|
||
from smufl_glyphs import set_display_name_to, invoke_menu_item, GLYPHS_EDIT_MENU_DESELECT_ALL_IDX | ||
|
||
currentFont = Glyphs.font | ||
|
||
selected_glyphs = currentFont.selection | ||
if len(selected_glyphs) == 0: | ||
glyphs_to_change = currentFont.glyphs | ||
else: | ||
glyphs_to_change = selected_glyphs | ||
|
||
currentFont.disableUpdateInterface() | ||
set_display_name_to(glyphs_to_change, 'description') | ||
currentFont.enableUpdateInterface() | ||
# If there weren't any glyphs selected when this script was invoked, make sure there aren't any afterwards. | ||
if len(selected_glyphs) == 0: | ||
print ("Deselecting...") | ||
invoke_menu_item(Glyphs, EDIT_MENU, GLYPHS_EDIT_MENU_DESELECT_ALL_IDX) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#MenuTitle: Set Glyph names to SMuFL names | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Set the display name of the selected glyphs to show the SMuFL glyph name. | ||
# | ||
# NOTE: this should be run before exporting for maximum compatibility with apps | ||
# that expect the glyphs to be named according to their codepoint. | ||
# | ||
# The script should be added to Glyphs scripts folder and expects the following | ||
# SMuFL and Bravura metadata files to be present in the same directory. | ||
# | ||
# - bravura_metadata.json | ||
# - glyphnames.json | ||
# - ranges.json | ||
# | ||
# Written by Ben Timms - Steinberg Media Technologies GmbH 2018 | ||
# Use, distribute and edit this script as you wish! | ||
# | ||
__doc__=""" | ||
Set the display name of the glyph to the SMuFL name of the glyph | ||
""" | ||
|
||
from smufl_glyphs import set_display_name_to, invoke_menu_item, GLYPHS_EDIT_MENU_DESELECT_ALL_IDX | ||
|
||
currentFont = Glyphs.font | ||
|
||
selected_glyphs = currentFont.selection | ||
if len(selected_glyphs) == 0: | ||
glyphs_to_change = currentFont.glyphs | ||
else: | ||
glyphs_to_change = selected_glyphs | ||
|
||
currentFont.disableUpdateInterface() | ||
set_display_name_to(glyphs_to_change, 'name') | ||
currentFont.enableUpdateInterface() | ||
if len(selected_glyphs) == 0: | ||
print ("Deselecting...") | ||
invoke_menu_item(Glyphs, EDIT_MENU, GLYPHS_EDIT_MENU_DESELECT_ALL_IDX) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#!/usr/bin/env python | ||
#MenuTitle: Set metadata on selected (or all) glyphs, including categorisation | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Set the metadata for all the selected glyphs in the font. | ||
# If the script is invoked with no selection it will apply to all glyphs. | ||
# | ||
# The script should be added to Glyphs scripts folder and expects the following | ||
# SMuFL and Bravura metadata files to be present in the same directory. | ||
# | ||
# - bravura_metadata.json | ||
# - glyphnames.json | ||
# - ranges.json | ||
# | ||
# Written by Ben Timms - Steinberg Media Technologies GmbH 2018 | ||
# Use, distribute and edit this script as you wish! | ||
# | ||
__doc__=""" | ||
""" | ||
|
||
from smufl_glyphs import SMuFLFontSyncer, invoke_menu_item, GLYPHS_EDIT_MENU_DESELECT_ALL_IDX | ||
|
||
BRAVURA_METADATA_FILENAME = "bravura_metadata.json" | ||
GLYPHNAMES_FILENAME = "glyphnames.json" | ||
RANGES_FILENAME = "ranges.json" | ||
|
||
currentFont = Glyphs.font | ||
|
||
selected_glyphs = currentFont.selection | ||
if len(selected_glyphs) == 0: | ||
glyphs_to_change = currentFont.glyphs | ||
else: | ||
glyphs_to_change = selected_glyphs | ||
|
||
smufl_font_syncer = SMuFLFontSyncer(currentFont, BRAVURA_METADATA_FILENAME, GLYPHNAMES_FILENAME, RANGES_FILENAME) | ||
currentFont.disableUpdateInterface() | ||
smufl_font_syncer.sync_metadata(glyphs_to_change) | ||
currentFont.enableUpdateInterface() | ||
# If there weren't any glyphs selected when this script was invoked, make sure there aren't any afterwards. | ||
if len(selected_glyphs) == 0: | ||
invoke_menu_item(Glyphs, EDIT_MENU, GLYPHS_EDIT_MENU_DESELECT_ALL_IDX) |
Oops, something went wrong.