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
|
||||
|
||||
"""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
|
||||
same directory will not be updated. If that's what you need use
|
||||
DumpOneGlyphToUFO.py
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
#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
|
||||
|
||||
"""Export the current font to UFO format.
|
||||
"""
|
||||
Export the current font to UFO format.
|
||||
|
||||
"""
|
||||
|
||||
from robofab.world import CurrentFont
|
||||
|
@ -1,5 +1,12 @@
|
||||
#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.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