Couple of tweaks to existing import / export scripts. Couple more import and export options.
git-svn-id: http://svn.robofab.com/trunk@81 b5fa9d6c-a76f-4ffd-b3cb-f825fc41095c
This commit is contained in:
parent
630b06cf57
commit
d36721f978
@ -1,9 +1,11 @@
|
|||||||
#FLM: Glyph to Glif, not in UFO
|
#FLM: Glyph to Glif, not in UFO
|
||||||
|
|
||||||
"""Dump the selected glyph to a Glif as a seperate, individual file.
|
"""
|
||||||
|
Dump the selected glyph to a Glif as a seperate, individual file.
|
||||||
This is not saved through a GlyphSet and any contents.plist in the
|
This is not saved through a GlyphSet and any contents.plist in the
|
||||||
same directory will not be updated. If that's what you need use
|
same directory will not be updated. If that's what you need use
|
||||||
DumpOneGlyphToUFO.py
|
DumpOneGlyphToUFO.py
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#FLM: Export Selected Glyph to UFO
|
#FLM: Export Selected Glyph to UFO
|
||||||
|
|
||||||
|
|
||||||
"""Dump the selected glyph to a .glif as part of a UFO.
|
"""
|
||||||
It saves the .glif through a GlyphSet and updates the contents.plist.
|
Dump the selected glyph to a .glif as part of a UFO.
|
||||||
|
It saves the .glif through a GlyphSet and updates the contents.plist.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
102
Scripts/RoboFabUFO/ExportAllOpenFontsAsUFO.py
Normal file
102
Scripts/RoboFabUFO/ExportAllOpenFontsAsUFO.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#FLM: Export glyphs, features from all open fonts to UFO
|
||||||
|
|
||||||
|
"""
|
||||||
|
Export all open fonts as UFO
|
||||||
|
Iterate through all open fonts, and export UFOs.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
This script will look for a UFO named <vbf_name_without_extension>.ufo.
|
||||||
|
If it can't find this UFO, it will make a new one.
|
||||||
|
If it can find the UFO, it will only export:
|
||||||
|
glyphs
|
||||||
|
feature data
|
||||||
|
font.lib
|
||||||
|
alignment zones (if the installed robofab supports them)
|
||||||
|
|
||||||
|
Kerning and kerning groups are NOT exported. This is to make it
|
||||||
|
easier to edit the glyphs in FontLab, but edit the kerning in the UFO,
|
||||||
|
with (for instance) MetricsMachine.
|
||||||
|
|
||||||
|
This script is useful for workflows which edit in FontLab,
|
||||||
|
but take interpolation, metrics and OTF compilation outside.
|
||||||
|
|
||||||
|
When running, the script will first save and close all open fonts.
|
||||||
|
Then it will open the vfb's one by one, and export, then close.
|
||||||
|
Finally it will open all fonts again.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from robofab.world import AllFonts, OpenFont
|
||||||
|
from robofab.tools.glyphNameSchemes import glyphNameToShortFileName
|
||||||
|
from robofab.glifLib import GlyphSet
|
||||||
|
from robofab.objects.objectsFL import RGlyph
|
||||||
|
from robofab.ufoLib import makeUFOPath, UFOWriter
|
||||||
|
from robofab.interface.all.dialogs import ProgressBar
|
||||||
|
|
||||||
|
try:
|
||||||
|
from robofab.objects.objectsFL import PostScriptFontHintValues, postScriptHintDataLibKey
|
||||||
|
supportHints = True
|
||||||
|
except ImportError:
|
||||||
|
supportHints = False
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
paths = []
|
||||||
|
for f in AllFonts():
|
||||||
|
paths.append(f.path)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
for p in paths:
|
||||||
|
ufoPath = p.replace(".vfb", ".ufo")
|
||||||
|
if os.path.exists(ufoPath):
|
||||||
|
# the ufo exists, only export the glyphs and the features
|
||||||
|
print "There is a UFO for this font already, exporting glyphs."
|
||||||
|
path = os.path.join(os.path.dirname(ufoPath), os.path.basename(ufoPath), "glyphs")
|
||||||
|
f = OpenFont(p)
|
||||||
|
|
||||||
|
fl.CallCommand(fl_cmd.FontSortByCodepage)
|
||||||
|
|
||||||
|
gs = GlyphSet(path, glyphNameToFileNameFunc=glyphNameToShortFileName)
|
||||||
|
for g in f:
|
||||||
|
print "saving glyph %s in %s"%(g.name, path)
|
||||||
|
gs.writeGlyph(g.name, g, g.drawPoints)
|
||||||
|
gs.writeContents()
|
||||||
|
|
||||||
|
# make a new writer
|
||||||
|
u = UFOWriter(ufoPath)
|
||||||
|
# font info
|
||||||
|
print "exporting font info.."
|
||||||
|
u.writeInfo(f.info)
|
||||||
|
|
||||||
|
# features
|
||||||
|
print "exporting features.."
|
||||||
|
glyphOrder = []
|
||||||
|
for nakedGlyph in f.naked().glyphs:
|
||||||
|
glyph = RGlyph(nakedGlyph)
|
||||||
|
glyphOrder.append(glyph.name)
|
||||||
|
assert None not in glyphOrder, glyphOrder
|
||||||
|
# We make a shallow copy if lib, since we add some stuff for export
|
||||||
|
# that doesn't need to be retained in memory.
|
||||||
|
fontLib = dict(f.lib)
|
||||||
|
|
||||||
|
if supportHints:
|
||||||
|
psh = PostScriptFontHintValues(f)
|
||||||
|
d = psh.asDict()
|
||||||
|
fontLib[postScriptHintDataLibKey] = d
|
||||||
|
|
||||||
|
fontLib["org.robofab.glyphOrder"] = glyphOrder
|
||||||
|
f._writeOpenTypeFeaturesToLib(fontLib)
|
||||||
|
print "fontLib", fontLib
|
||||||
|
u.writeLib(fontLib)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
else:
|
||||||
|
print "Making a new UFO at", ufoPath
|
||||||
|
f = OpenFont(p)
|
||||||
|
f.writeUFO()
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
for p in paths:
|
||||||
|
OpenFont(p)
|
||||||
|
|
@ -1,6 +1,8 @@
|
|||||||
#FLM: Export Current Font to UFO Format
|
#FLM: Export Current Font to UFO Format
|
||||||
|
|
||||||
"""Export the current font to UFO format.
|
"""
|
||||||
|
Export the current font to UFO format.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from robofab.world import CurrentFont
|
from robofab.world import CurrentFont
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
#FLM: Import all UFOs in a folder
|
#FLM: Import all UFOs in a folder
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
Import all UFOs in a folder
|
||||||
|
|
||||||
|
Note this is a relatively dumb import script.
|
||||||
|
|
||||||
|
"""
|
||||||
from robofab.world import NewFont
|
from robofab.world import NewFont
|
||||||
from robofab.interface.mac.getFileOrFolder import GetFileOrFolder
|
from robofab.interface.mac.getFileOrFolder import GetFileOrFolder
|
||||||
|
|
||||||
|
44
Scripts/RoboFabUFO/SelectedGlyphsToUFO.py
Normal file
44
Scripts/RoboFabUFO/SelectedGlyphsToUFO.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#FLM: Export selected glyphs to UFO
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Dump the selected glyph to a .glif as part of a UFO.
|
||||||
|
It saves the .glif through a GlyphSet and updates the contents.plist.
|
||||||
|
|
||||||
|
EvB 08
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from robofab.glifLib import GlyphSet
|
||||||
|
from robofab.world import CurrentFont, CurrentGlyph
|
||||||
|
from robofab.interface.all.dialogs import Message, GetFolder
|
||||||
|
from robofab.tools.glyphNameSchemes import glyphNameToShortFileName
|
||||||
|
import os
|
||||||
|
|
||||||
|
f = CurrentFont()
|
||||||
|
g = CurrentGlyph()
|
||||||
|
|
||||||
|
f.save()
|
||||||
|
|
||||||
|
ufoPath = None
|
||||||
|
ufoPath = f.path.replace(".vfb", ".ufo")
|
||||||
|
if not os.path.exists(ufoPath):
|
||||||
|
ufoPath = GetFolder("Select a UFO to save the GLIF in:")
|
||||||
|
if ufoPath.find(".ufo") == -1:
|
||||||
|
Message("You need to select an UFO. Quitting.")
|
||||||
|
ufoPath = None
|
||||||
|
|
||||||
|
if ufoPath is not None:
|
||||||
|
todo = f.selection
|
||||||
|
print "selection", todo
|
||||||
|
if g is not None:
|
||||||
|
todo.append(g.name)
|
||||||
|
for c in todo:
|
||||||
|
g = f[c]
|
||||||
|
path = os.path.join(os.path.dirname(ufoPath), os.path.basename(ufoPath), "glyphs")
|
||||||
|
print "saving glyph %s in %s"%(g.name, path)
|
||||||
|
gs = GlyphSet(path, glyphNameToFileNameFunc=glyphNameToShortFileName)
|
||||||
|
gs.writeGlyph(g.name, g, g.drawPoints)
|
||||||
|
gs.writeContents()
|
||||||
|
|
||||||
|
print 'done'
|
58
Scripts/RoboFabUFO/SelectedGlyphsToUFOForAllFonts.py
Normal file
58
Scripts/RoboFabUFO/SelectedGlyphsToUFOForAllFonts.py
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#FLM: Selected glyphs from all fonts to UFO
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Get the name of the current glyph,
|
||||||
|
then for each open font, export that glyph to UFO.
|
||||||
|
It saves the .glif through a GlyphSet and updates the contents.plist.
|
||||||
|
|
||||||
|
This script is useful when you're working on several interpolation
|
||||||
|
masters as separate vfb source files.
|
||||||
|
|
||||||
|
EvB 08
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from robofab.glifLib import GlyphSet
|
||||||
|
from robofab.world import CurrentFont, CurrentGlyph, AllFonts
|
||||||
|
from robofab.interface.all.dialogs import Message, GetFolder
|
||||||
|
from robofab.tools.glyphNameSchemes import glyphNameToShortFileName
|
||||||
|
import os
|
||||||
|
|
||||||
|
f = CurrentFont()
|
||||||
|
g = CurrentGlyph()
|
||||||
|
|
||||||
|
f.save()
|
||||||
|
|
||||||
|
todo = f.selection
|
||||||
|
print "selection", todo
|
||||||
|
if g is not None:
|
||||||
|
todo.append(g.name)
|
||||||
|
|
||||||
|
for f in AllFonts():
|
||||||
|
ufoPath = None
|
||||||
|
print "f.path", f, f.path
|
||||||
|
if f.path is None:
|
||||||
|
# huh, in case there is a ghost font.
|
||||||
|
print "skipping", f
|
||||||
|
continue
|
||||||
|
ufoPath = f.path.replace(".vfb", ".ufo")
|
||||||
|
if not os.path.exists(ufoPath):
|
||||||
|
ufoPath = GetFolder("Select a UFO to save the GLIF in:")
|
||||||
|
if ufoPath.find(".ufo") == -1:
|
||||||
|
Message("You need to select an UFO. Quitting.")
|
||||||
|
ufoPath = None
|
||||||
|
if ufoPath is None:
|
||||||
|
continue
|
||||||
|
for c in todo:
|
||||||
|
if c not in f:
|
||||||
|
print "font is missing", c
|
||||||
|
continue
|
||||||
|
g = f[c]
|
||||||
|
path = os.path.join(os.path.dirname(ufoPath), os.path.basename(ufoPath), "glyphs")
|
||||||
|
print "saving glyph %s in %s"%(g.name, path)
|
||||||
|
gs = GlyphSet(path, glyphNameToFileNameFunc=glyphNameToShortFileName)
|
||||||
|
gs.writeGlyph(g.name, g, g.drawPoints)
|
||||||
|
gs.writeContents()
|
||||||
|
|
||||||
|
print 'done'
|
131
Scripts/RoboFabUFO/UpdateFromUFO.py
Normal file
131
Scripts/RoboFabUFO/UpdateFromUFO.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#FLM: Compare and update from UFO
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Compare and Update from UFO.
|
||||||
|
If the .vfb has a UFO in the same folder, and the names match
|
||||||
|
<fontname>.vfb -> <fontname>.ufo
|
||||||
|
compare the digests for each glyph in the vfb and the ufo
|
||||||
|
update the glyph in the vfb if there is no match
|
||||||
|
don't touch groups, kerning, other values.
|
||||||
|
|
||||||
|
evb 08
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
from robofab.interface.all.dialogs import AskYesNoCancel
|
||||||
|
from robofab.interface.all.dialogs import Message
|
||||||
|
|
||||||
|
from robofab.world import AllFonts, OpenFont, CurrentFont
|
||||||
|
from robofab.objects.objectsRF import RFont as _RFont
|
||||||
|
from robofab.tools.glyphNameSchemes import glyphNameToShortFileName
|
||||||
|
from robofab.glifLib import GlyphSet
|
||||||
|
from robofab.objects.objectsFL import RGlyph
|
||||||
|
from robofab.ufoLib import makeUFOPath, UFOWriter
|
||||||
|
from robofab.interface.all.dialogs import ProgressBar
|
||||||
|
|
||||||
|
from dialogKit import *
|
||||||
|
from sets import Set
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
class UpdateFromUFODialogDialog(object):
|
||||||
|
|
||||||
|
def __init__(self, ufo, vfb):
|
||||||
|
self.ufo = ufo
|
||||||
|
self.vfb = vfb
|
||||||
|
self.updateNames = []
|
||||||
|
self.w = ModalDialog((200, 400), 'Update Font From UFO', okCallback=self.okCallback)
|
||||||
|
self.w.list = List((5, 70, -5, -100), ['Comparing VFB', "to its UFO.", "Click Compare to begin."], callback=self.listHitCallback)
|
||||||
|
self.w.updateButton = Button((10, 10, 90, 20), 'Update', callback=self.updateCallback)
|
||||||
|
self.w.updateAllButton = Button((10, 40, 90, 20), 'Update All', callback=self.updateAllCallback)
|
||||||
|
self.w.checkButton = Button((110, 10, -10, 50), 'Compare', callback=self.checkCallback)
|
||||||
|
self.w.open()
|
||||||
|
|
||||||
|
def okCallback(self, sender):
|
||||||
|
print 'this final list contains:', list(self.w.list)
|
||||||
|
|
||||||
|
def listHitCallback(self, sender):
|
||||||
|
selection = sender.getSelection()
|
||||||
|
if not selection:
|
||||||
|
selectedItem = None
|
||||||
|
else:
|
||||||
|
selectionIndex = selection[0]
|
||||||
|
selectedItem = sender[selectionIndex]
|
||||||
|
print 'selection:', selectedItem
|
||||||
|
|
||||||
|
def updateAllCallback(self, sender):
|
||||||
|
print "Update all glyphs"
|
||||||
|
names = self.updateNames[:]
|
||||||
|
for n in self.updateNames:
|
||||||
|
self.updateGlyph(n)
|
||||||
|
names.remove(n)
|
||||||
|
self.w.list.set(names)
|
||||||
|
self.w.list.setSelection([-1])
|
||||||
|
|
||||||
|
def updateCallback(self, sender):
|
||||||
|
print "Update selected glyph"
|
||||||
|
names = []
|
||||||
|
for index in self.w.list.getSelection():
|
||||||
|
names.append(self.updateNames[index])
|
||||||
|
for n in names:
|
||||||
|
self.updateGlyph(n)
|
||||||
|
self.updateNames.remove(n)
|
||||||
|
self.w.list.set(self.updateNames)
|
||||||
|
self.w.list.setSelection([-1])
|
||||||
|
|
||||||
|
def checkCallback(self, sender):
|
||||||
|
print "checking fonts"
|
||||||
|
self.analyseFonts()
|
||||||
|
|
||||||
|
def analyseFonts(self):
|
||||||
|
ufoDigests = {}
|
||||||
|
print "calculating UFO digests"
|
||||||
|
ufoNames = self.ufo.keys()
|
||||||
|
vfbNames = self.vfb.keys()
|
||||||
|
self.w.list.set([])
|
||||||
|
self.updateNames = []
|
||||||
|
for n in ufoNames:
|
||||||
|
if n not in vfbNames:
|
||||||
|
self.updateNames.append(n)
|
||||||
|
self.updateNames.sort()
|
||||||
|
self.w.list.set(self.updateNames)
|
||||||
|
self.w.list.setSelection([-1])
|
||||||
|
relevantNames = Set(ufoNames)&Set(vfbNames)
|
||||||
|
names = list(relevantNames)
|
||||||
|
names.sort()
|
||||||
|
for name in names:
|
||||||
|
print name
|
||||||
|
ufoDigest = self.ufo[name]._getDigest()
|
||||||
|
vfbDigest = self.vfb[name]._getDigest()
|
||||||
|
if ufoDigest != vfbDigest:
|
||||||
|
self.updateNames.append(name)
|
||||||
|
self.w.list.set(self.updateNames)
|
||||||
|
self.w.list.setSelection([-1])
|
||||||
|
|
||||||
|
def updateGlyph(self, name):
|
||||||
|
print "importing", name
|
||||||
|
self.vfb[name].clear()
|
||||||
|
self.vfb.insertGlyph(self.ufo[name], as=name)
|
||||||
|
self.vfb[name].width = self.ufo[name].width
|
||||||
|
self.vfb[name].note = self.ufo[name].note
|
||||||
|
self.vfb[name].psHints.update(self.ufo[name].psHints)
|
||||||
|
self.vfb[name].mark = 50
|
||||||
|
self.vfb[name].update()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
|
||||||
|
f = CurrentFont()
|
||||||
|
ufoPath = f.path.replace(".vfb", ".ufo")
|
||||||
|
if os.path.exists(ufoPath):
|
||||||
|
print "there is a ufo for this font at", ufoPath
|
||||||
|
ufo = _RFont(ufoPath)
|
||||||
|
UpdateFromUFODialogDialog(ufo, f)
|
||||||
|
f.update()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
print "done"
|
Loading…
x
Reference in New Issue
Block a user