~ubuntu-branches/ubuntu/maverick/fonttools/maverick

« back to all changes in this revision

Viewing changes to Mac/TTX.py

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Fok
  • Date: 2003-11-18 00:53:59 UTC
  • Revision ID: james.westby@ubuntu.com-20031118005359-pqirsxbgdz0f0xmx
Tags: upstream-1.99+2.0b1+cvs20031014
ImportĀ upstreamĀ versionĀ 1.99+2.0b1+cvs20031014

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Main TTX application, Mac-only"""
 
2
 
 
3
 
 
4
#make sure we don't lose events to SIOUX
 
5
import MacOS
 
6
MacOS.EnableAppswitch(-1)
 
7
 
 
8
def SetWatchCursor():
 
9
        import Qd, QuickDraw
 
10
        Qd.SetCursor(Qd.GetCursor(QuickDraw.watchCursor).data)
 
11
 
 
12
def SetArrowCursor():
 
13
        import Qd
 
14
        Qd.SetCursor(Qd.qd.arrow)
 
15
 
 
16
SetWatchCursor()
 
17
 
 
18
# a few constants
 
19
LOGFILENAME = "TTX errors"
 
20
PREFSFILENAME = "TTX preferences"
 
21
DEFAULTXMLOUTPUT = ":XML output"
 
22
DEFAULTTTOUTPUT = ":TrueType output"
 
23
 
 
24
 
 
25
import FrameWork
 
26
import MiniAEFrame, AppleEvents
 
27
import EasyDialogs
 
28
import Res
 
29
import macfs
 
30
import os
 
31
import sys, time
 
32
import re, string
 
33
import traceback
 
34
from fontTools import ttLib, version
 
35
from fontTools.ttLib import xmlImport
 
36
from fontTools.ttLib.macUtils import ProgressBar
 
37
 
 
38
abouttext = """\
 
39
TTX - The free TrueType to XML to TrueType converter
 
40
(version %s)
 
41
Copyright 1999-2001, Just van Rossum (Letterror)
 
42
just@letterror.com""" % version
 
43
 
 
44
 
 
45
class TTX(FrameWork.Application, MiniAEFrame.AEServer):
 
46
        
 
47
        def __init__(self):
 
48
                FrameWork.Application.__init__(self)
 
49
                MiniAEFrame.AEServer.__init__(self)
 
50
                self.installaehandler(
 
51
                        AppleEvents.kCoreEventClass, AppleEvents.kAEOpenApplication, self.do_nothing)
 
52
                self.installaehandler(
 
53
                        AppleEvents.kCoreEventClass, AppleEvents.kAEPrintDocuments, self.do_nothing)
 
54
                self.installaehandler(
 
55
                        AppleEvents.kCoreEventClass, AppleEvents.kAEOpenDocuments, self.handle_opendocumentsevent)
 
56
                self.installaehandler(
 
57
                        AppleEvents.kCoreEventClass, AppleEvents.kAEQuitApplication, self.handle_quitevent)
 
58
        
 
59
        def idle(self, event):
 
60
                SetArrowCursor()
 
61
        
 
62
        def makeusermenus(self):
 
63
                m = FrameWork.Menu(self.menubar, "File")
 
64
                FrameWork.MenuItem(m, "Open...", "O", self.domenu_open)
 
65
                FrameWork.Separator(m)
 
66
                FrameWork.MenuItem(m, "Quit", "Q", self._quit)
 
67
        
 
68
        def do_about(self, *args):
 
69
                EasyDialogs.Message(abouttext)
 
70
        
 
71
        def handle_quitevent(self, *args, **kwargs):
 
72
                self._quit()
 
73
        
 
74
        def domenu_open(self, *args):
 
75
                fss, ok = macfs.StandardGetFile()
 
76
                if ok:
 
77
                        self.opendocument(fss.as_pathname())
 
78
        
 
79
        def handle_opendocumentsevent(self, docs, **kwargs):
 
80
                if type(docs) <> type([]):
 
81
                        docs = [docs]
 
82
                for doc in docs:
 
83
                        fss, a = doc.Resolve()
 
84
                        path = fss.as_pathname()
 
85
                        self.opendocument(path)
 
86
        
 
87
        def opendocument(self, path):
 
88
                filename = os.path.basename(path)
 
89
                filetype = guessfiletype(path)
 
90
                handler = getattr(self, "handle_%s_file" % filetype)
 
91
                handler(path)
 
92
        
 
93
        def handle_xml_file(self, path):
 
94
                prefs = getprefs()
 
95
                makesuitcase = int(prefs.get("makesuitcases", 0))
 
96
                dstfolder = prefs.get("ttoutput", DEFAULTTTOUTPUT)
 
97
                if not os.path.exists(dstfolder):
 
98
                        os.mkdir(dstfolder)
 
99
                srcfilename = dstfilename = os.path.basename(path)
 
100
                if dstfilename[-4:] in (".ttx", ".xml"):
 
101
                        dstfilename = dstfilename[:-4]
 
102
                if dstfilename[-4:] not in (".TTF", ".ttf"):
 
103
                        dstfilename = dstfilename + ".TTF"
 
104
                dst = os.path.join(dstfolder, dstfilename)
 
105
                
 
106
                if makesuitcase:
 
107
                        try:
 
108
                                # see if the destination file is writable,
 
109
                                # otherwise we'll get an error waaay at the end of
 
110
                                # the parse procedure
 
111
                                testref = Res.FSpOpenResFile(macfs.FSSpec(dst), 3)  # read-write
 
112
                        except Res.Error, why:
 
113
                                if why[0] <> -43: # file not found
 
114
                                        EasyDialogs.Message("Can't create '%s'; file already open" % dst)
 
115
                                        return
 
116
                        else:
 
117
                                Res.CloseResFile(testref)
 
118
                else:
 
119
                        try:
 
120
                                f = open(dst, "wb")
 
121
                        except IOError, why:
 
122
                                EasyDialogs.Message("Can't create '%s'; file already open" % dst)
 
123
                                return
 
124
                        else:
 
125
                                f.close()
 
126
                pb = ProgressBar("Reading TTX file '%s'..." % srcfilename)
 
127
                try:
 
128
                        tt = ttLib.TTFont()
 
129
                        tt.importXML(path, pb)
 
130
                        pb.setlabel("Compiling and saving...")
 
131
                        tt.save(dst, makesuitcase)
 
132
                finally:
 
133
                        pb.close()
 
134
        
 
135
        def handle_datafork_file(self, path):
 
136
                prefs = getprefs()
 
137
                dstfolder = prefs.get("xmloutput", DEFAULTXMLOUTPUT)
 
138
                if not os.path.exists(dstfolder):
 
139
                        os.mkdir(dstfolder)
 
140
                filename = os.path.basename(path)
 
141
                pb = ProgressBar("Dumping '%s' to XML..." % filename)
 
142
                if filename[-4:] in (".TTF", ".ttf"):
 
143
                        filename = filename[:-4]
 
144
                filename = filename + ".ttx"
 
145
                dst = os.path.join(dstfolder, filename)
 
146
                try:
 
147
                        tt = ttLib.TTFont(path)
 
148
                        tt.saveXML(dst, pb)
 
149
                finally:
 
150
                        pb.close()
 
151
        
 
152
        def handle_resource_file(self, path):
 
153
                prefs = getprefs()
 
154
                dstfolder = prefs.get("xmloutput", DEFAULTXMLOUTPUT)
 
155
                if not os.path.exists(dstfolder):
 
156
                        os.mkdir(dstfolder)
 
157
                filename = os.path.basename(path)
 
158
                fss = macfs.FSSpec(path)
 
159
                try:
 
160
                        resref = Res.FSpOpenResFile(fss, 1)  # read-only
 
161
                except:
 
162
                        return "unknown"
 
163
                Res.UseResFile(resref)
 
164
                pb = None
 
165
                try:
 
166
                        n = Res.Count1Resources("sfnt")
 
167
                        for i in range(1, n+1):
 
168
                                res = Res.Get1IndResource('sfnt', i)
 
169
                                resid, restype, resname = res.GetResInfo()
 
170
                                if not resname:
 
171
                                        resname = filename + `i`
 
172
                                pb = ProgressBar("Dumping '%s' to XML..." % resname)
 
173
                                dst = os.path.join(dstfolder, resname + ".ttx")
 
174
                                try:
 
175
                                        tt = ttLib.TTFont(path, i)
 
176
                                        tt.saveXML(dst, pb)
 
177
                                finally:
 
178
                                        pb.close()
 
179
                finally:
 
180
                        Res.CloseResFile(resref)
 
181
        
 
182
        def handle_python_file(self, path):
 
183
                pass
 
184
                #print "python", path
 
185
        
 
186
        def handle_unknown_file(self, path):
 
187
                EasyDialogs.Message("Cannot open '%s': unknown file kind" % os.path.basename(path))
 
188
        
 
189
        def do_nothing(self, *args, **kwargs):
 
190
                pass
 
191
        
 
192
        def mainloop(self, mask=FrameWork.everyEvent, wait=0):
 
193
                self.quitting = 0
 
194
                while not self.quitting:
 
195
                        try:
 
196
                                self.do1event(mask, wait)
 
197
                        except self.__class__:
 
198
                                # D'OH! FrameWork tries to quit us on cmd-.!
 
199
                                pass
 
200
                        except KeyboardInterrupt:
 
201
                                pass
 
202
                        except ttLib.xmlImport.xml_parse_error, why:
 
203
                                EasyDialogs.Message(
 
204
                                        "An error occurred while parsing the XML file:\n" + why)
 
205
                        except:
 
206
                                exc = traceback.format_exception(sys.exc_type, sys.exc_value, None)[0]
 
207
                                exc = string.strip(exc)
 
208
                                EasyDialogs.Message("An error occurred!\n%s\n[see the logfile '%s' for details]" % 
 
209
                                                (exc, LOGFILENAME))
 
210
                                traceback.print_exc()
 
211
        
 
212
        def do_kHighLevelEvent(self, event):
 
213
                import AE
 
214
                AE.AEProcessAppleEvent(event)
 
215
 
 
216
 
 
217
 
 
218
def guessfiletype(path):
 
219
        #if path[-3:] == ".py":
 
220
        #       return "python"
 
221
        f = open(path, "rb")
 
222
        data = f.read(21)
 
223
        f.close()
 
224
        if data[:5] == "<?xml":
 
225
                return "xml"
 
226
        elif data[:4] in ("\000\001\000\000", "OTTO", "true"):
 
227
                return "datafork"
 
228
        else:
 
229
                # assume res fork font
 
230
                fss = macfs.FSSpec(path)
 
231
                try:
 
232
                        resref = Res.FSpOpenResFile(fss, 1)  # read-only
 
233
                except:
 
234
                        return "unknown"
 
235
                Res.UseResFile(resref)
 
236
                i = Res.Count1Resources("sfnt")
 
237
                Res.CloseResFile(resref)
 
238
                if i > 0:
 
239
                        return "resource"
 
240
        return "unknown"
 
241
 
 
242
 
 
243
default_prefs = """\
 
244
xmloutput:      ":XML output"
 
245
ttoutput:       ":TrueType output"
 
246
makesuitcases:  1
 
247
"""
 
248
 
 
249
def getprefs(path=PREFSFILENAME):
 
250
        if not os.path.exists(path):
 
251
                f = open(path, "w")
 
252
                f.write(default_prefs)
 
253
                f.close()
 
254
        f = open(path)
 
255
        lines = f.readlines()
 
256
        prefs = {}
 
257
        for line in lines:
 
258
                if line[-1:] == "\n":
 
259
                        line = line[:-1]
 
260
                try:
 
261
                        name, value = re.split(":", line, 1)
 
262
                        prefs[string.strip(name)] = eval(value)
 
263
                except:
 
264
                        pass
 
265
        return prefs
 
266
 
 
267
 
 
268
class dummy_stdin:
 
269
        def readline(self):
 
270
                return ""
 
271
sys.stdin = dummy_stdin()
 
272
 
 
273
# redirect all output to a log file
 
274
sys.stdout = sys.stderr = open(LOGFILENAME, "w", 0)  # unbuffered
 
275
print "Starting TTX at " + time.ctime(time.time())
 
276
 
 
277
# fire it up!
 
278
ttx = TTX()
 
279
ttx.mainloop()
 
280
 
 
281
 
 
282
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
283
# clues for BuildApplication/MacFreeze. 
 
284
#
 
285
# These modules somehow get imported, but we don't want/have them:
 
286
#
 
287
# macfreeze: exclude msvcrt
 
288
# macfreeze: exclude W
 
289
# macfreeze: exclude SOCKS
 
290
# macfreeze: exclude TERMIOS
 
291
# macfreeze: exclude termios
 
292
# macfreeze: exclude icglue
 
293
# macfreeze: exclude ce
 
294
#
 
295
# these modules are imported dynamically, so MacFreeze won't see them:
 
296
#
 
297
# macfreeze: include fontTools.ttLib.tables._c_m_a_p
 
298
# macfreeze: include fontTools.ttLib.tables._c_v_t
 
299
# macfreeze: include fontTools.ttLib.tables._f_p_g_m
 
300
# macfreeze: include fontTools.ttLib.tables._g_a_s_p
 
301
# macfreeze: include fontTools.ttLib.tables._g_l_y_f
 
302
# macfreeze: include fontTools.ttLib.tables._h_d_m_x
 
303
# macfreeze: include fontTools.ttLib.tables._h_e_a_d
 
304
# macfreeze: include fontTools.ttLib.tables._h_h_e_a
 
305
# macfreeze: include fontTools.ttLib.tables._h_m_t_x
 
306
# macfreeze: include fontTools.ttLib.tables._k_e_r_n
 
307
# macfreeze: include fontTools.ttLib.tables._l_o_c_a
 
308
# macfreeze: include fontTools.ttLib.tables._m_a_x_p
 
309
# macfreeze: include fontTools.ttLib.tables._n_a_m_e
 
310
# macfreeze: include fontTools.ttLib.tables._p_o_s_t
 
311
# macfreeze: include fontTools.ttLib.tables._p_r_e_p
 
312
# macfreeze: include fontTools.ttLib.tables._v_h_e_a
 
313
# macfreeze: include fontTools.ttLib.tables._v_m_t_x
 
314
# macfreeze: include fontTools.ttLib.tables.L_T_S_H_
 
315
# macfreeze: include fontTools.ttLib.tables.O_S_2f_2
 
316
# macfreeze: include fontTools.ttLib.tables.T_S_I__0
 
317
# macfreeze: include fontTools.ttLib.tables.T_S_I__1
 
318
# macfreeze: include fontTools.ttLib.tables.T_S_I__2
 
319
# macfreeze: include fontTools.ttLib.tables.T_S_I__3
 
320
# macfreeze: include fontTools.ttLib.tables.T_S_I__5
 
321
# macfreeze: include fontTools.ttLib.tables.C_F_F_
 
322