summaryrefslogtreecommitdiff
path: root/misc/pylib/robofab/tools/remote.py
diff options
context:
space:
mode:
Diffstat (limited to 'misc/pylib/robofab/tools/remote.py')
-rwxr-xr-xmisc/pylib/robofab/tools/remote.py175
1 files changed, 175 insertions, 0 deletions
diff --git a/misc/pylib/robofab/tools/remote.py b/misc/pylib/robofab/tools/remote.py
new file mode 100755
index 000000000..288afcfe7
--- /dev/null
+++ b/misc/pylib/robofab/tools/remote.py
@@ -0,0 +1,175 @@
+"""Remote control for MacOS FontLab.
+initFontLabRemote() registers a callback for appleevents and
+runFontLabRemote() sends the code from a different application,
+such as a Mac Python IDE or Python interpreter.
+"""
+
+from robofab.world import world
+
+if world.inFontLab and world.mac is not None:
+ from Carbon import AE as _AE
+
+else:
+ import sys
+ from aetools import TalkTo
+
+ class FontLab(TalkTo):
+ pass
+
+__all__ = ['initFontLabRemote', 'runFontLabRemote']
+
+def _executePython(theAppleEvent, theReply):
+ import aetools
+ import cStringIO
+ import traceback
+ import sys
+ parms, attrs = aetools.unpackevent(theAppleEvent)
+ source = parms.get("----")
+ if source is None:
+ return
+ stdout = cStringIO.StringIO()
+ #print "<executing remote command>"
+ save = sys.stdout, sys.stderr
+ sys.stdout = sys.stderr = stdout
+ namespace = {}
+ try:
+ try:
+ exec source in namespace
+ except:
+ traceback.print_exc()
+ finally:
+ sys.stdout, sys.stderr = save
+ output = stdout.getvalue()
+ aetools.packevent(theReply, {"----": output})
+
+_imported = False
+
+def initFontLabRemote():
+ """Call this in FontLab at startup of the application to switch on the remote."""
+ print "FontLabRemote is on."
+ _AE.AEInstallEventHandler("Rfab", "exec", _executePython)
+
+if world.inFontLab and world.mac is not None:
+ initFontLabRemote()
+
+def runFontLabRemote(code):
+ """Call this in the MacOS Python IDE to make FontLab execute the code."""
+ fl = FontLab("FLab", start=1)
+ ae, parms, attrs = fl.send("Rfab", "exec", {"----": code})
+ output = parms.get("----")
+ return output
+
+
+
+# GlyphTransmit
+# Convert a glyph to a string using digestPen, transmit string, unpack string with pointpen.
+#
+
+
+def Glyph2String(glyph):
+ from robofab.pens.digestPen import DigestPointPen
+ import pickle
+ p = DigestPointPen(glyph)
+ glyph.drawPoints(p)
+ info = {}
+ info['name'] = glyph.name
+ info['width'] = glyph.width
+ info['points'] = p.getDigest()
+ return str(pickle.dumps(info))
+
+def String2Glyph(gString, penClass, font):
+ import pickle
+ if gString is None:
+ return None
+ info = pickle.loads(gString)
+ name = info['name']
+ if not name in font.keys():
+ glyph = font.newGlyph(name)
+ else:
+ glyph = font[name]
+ pen = penClass(glyph)
+ for p in info['points']:
+ if p == "beginPath":
+ pen.beginPath()
+ elif p == "endPath":
+ pen.endPath()
+ else:
+ pt, type = p
+ pen.addPoint(pt, type)
+ glyph.width = info['width']
+ glyph.update()
+ return glyph
+
+_makeFLGlyph = """
+from robofab.world import CurrentFont
+from robofab.tools.remote import receiveGlyph
+code = '''%s'''
+receiveGlyph(code, CurrentFont())
+"""
+
+def transmitGlyph(glyph):
+ from robofab.world import world
+ if world.inFontLab and world.mac is not None:
+ # we're in fontlab, on a mac
+ print Glyph2String(glyph)
+ pass
+ else:
+ remoteProgram = _makeFLGlyph%Glyph2String(glyph)
+ print "remoteProgram", remoteProgram
+ return runFontLabRemote(remoteProgram)
+
+def receiveGlyph(glyphString, font=None):
+ from robofab.world import world
+ if world.inFontLab and world.mac is not None:
+ # we're in fontlab, on a mac
+ from robofab.pens.flPen import FLPointPen
+ print String2Glyph(glyphString, FLPointPen, font)
+ pass
+ else:
+ from robofab.pens.rfUFOPen import RFUFOPointPen
+ print String2Glyph(glyphString, RFUFOPointPen, font)
+
+
+#
+# command to tell FontLab to open a UFO and save it as a vfb
+
+def os9PathConvert(path):
+ """Attempt to convert a unix style path to a Mac OS9 style path.
+ No support for relative paths!
+ """
+ if path.find("/Volumes") == 0:
+ # it's on the volumes list, some sort of external volume
+ path = path[len("/Volumes")+1:]
+ elif path[0] == "/":
+ # a dir on the root volume
+ path = path[1:]
+ new = path.replace("/", ":")
+ return new
+
+
+_remoteUFOImportProgram = """
+from robofab.objects.objectsFL import NewFont
+import os.path
+destinationPathVFB = "%(destinationPathVFB)s"
+font = NewFont()
+font.readUFO("%(sourcePathUFO)s", doProgress=True)
+font.update()
+font.save(destinationPathVFB)
+print font, "done"
+font.close()
+"""
+
+def makeVFB(sourcePathUFO, destinationPathVFB=None):
+ """FontLab convenience function to import a UFO and save it as a VFB"""
+ import os
+ fl = FontLab("FLab", start=1)
+ if destinationPathVFB is None:
+ destinationPathVFB = os.path.splitext(sourcePathUFO)[0]+".vfb"
+ src9 = os9PathConvert(sourcePathUFO)
+ dst9 = os9PathConvert(destinationPathVFB)
+ code = _remoteUFOImportProgram%{'sourcePathUFO': src9, 'destinationPathVFB':dst9}
+ ae, parms, attrs = fl.send("Rfab", "exec", {"----": code})
+ output = parms.get("----")
+ return output
+
+ \ No newline at end of file