aboutsummaryrefslogtreecommitdiff
path: root/Lib/fontTools/misc/homeResFile.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/fontTools/misc/homeResFile.py')
-rw-r--r--Lib/fontTools/misc/homeResFile.py96
1 files changed, 96 insertions, 0 deletions
diff --git a/Lib/fontTools/misc/homeResFile.py b/Lib/fontTools/misc/homeResFile.py
new file mode 100644
index 00000000..a2d1c8c0
--- /dev/null
+++ b/Lib/fontTools/misc/homeResFile.py
@@ -0,0 +1,96 @@
+"""Mac-only module to find the home file of a resource."""
+
+from __future__ import print_function, division, absolute_import
+from fontTools.misc.py23 import *
+from fontTools.misc import sstruct
+import array
+import calldll
+import macfs, Res
+
+
+def HomeResFile(res):
+ """Return a path to the file in which resource 'res' lives."""
+ return GetFileLocation(res.HomeResFile())
+
+
+def GetFileLocation(refNum):
+ """Return a path to the open file identified with refNum."""
+ pb = ParamBlock(refNum)
+ return pb.getPath()
+
+#
+# Internal cruft, adapted from MoreFiles
+#
+
+_InterfaceLib = calldll.getlibrary("InterfaceLib")
+GetVRefNum = calldll.newcall(_InterfaceLib.GetVRefNum, "None", "InShort", "OutShort")
+_getInfo = calldll.newcall(_InterfaceLib.PBGetFCBInfoSync, "Short", "InLong")
+
+
+_FCBPBFormat = """
+ qLink: l
+ qType: h
+ ioTrap: h
+ ioCmdAddr: l
+ ioCompletion: l
+ ioResult: h
+ ioNamePtr: l
+ ioVRefNum: h
+ ioRefNum: h
+ filler: h
+ ioFCBIndx: h
+ filler1: h
+ ioFCBFINm: l
+ ioFCBFlags: h
+ ioFCBStBlk: h
+ ioFCBEOF: l
+ ioFCBPLen: l
+ ioFCBCrPs: l
+ ioFCBVRefNum: h
+ ioFCBClpSiz: l
+ ioFCBParID: l
+"""
+
+class ParamBlock(object):
+
+ """Wrapper for the very low level FCBPB record."""
+
+ def __init__(self, refNum):
+ self.__fileName = array.array("c", "\0" * 64)
+ sstruct.unpack(_FCBPBFormat,
+ "\0" * sstruct.calcsize(_FCBPBFormat), self)
+ self.ioNamePtr = self.__fileName.buffer_info()[0]
+ self.ioRefNum = refNum
+ self.ioVRefNum = GetVRefNum(refNum)
+ self.__haveInfo = 0
+
+ def getInfo(self):
+ if self.__haveInfo:
+ return
+ data = sstruct.pack(_FCBPBFormat, self)
+ buf = array.array("c", data)
+ ptr = buf.buffer_info()[0]
+ err = _getInfo(ptr)
+ if err:
+ raise Res.Error("can't get file info", err)
+ sstruct.unpack(_FCBPBFormat, buf.tostring(), self)
+ self.__haveInfo = 1
+
+ def getFileName(self):
+ self.getInfo()
+ data = self.__fileName.tostring()
+ return data[1:byteord(data[0])+1]
+
+ def getFSSpec(self):
+ self.getInfo()
+ vRefNum = self.ioVRefNum
+ parID = self.ioFCBParID
+ return macfs.FSSpec((vRefNum, parID, self.getFileName()))
+
+ def getPath(self):
+ return self.getFSSpec().as_pathname()
+
+
+if __name__ == "__main__":
+ fond = Res.GetNamedResource("FOND", "Helvetica")
+ print(HomeResFile(fond))