~ubuntu-branches/ubuntu/trusty/pyx/trusty

« back to all changes in this revision

Viewing changes to pyx/font/afmfile.py

  • Committer: Bazaar Package Importer
  • Author(s): Stuart Prescott
  • Date: 2011-05-20 00:13:52 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110520001352-7jfc1unuvduxji05
Tags: 0.11.1-1
* New upstream release.
* Change documentation build system to sphinx in line with new upstream docs.
* Rebuild lfs files as part of build process.
* Refresh patchs for new version:
  - drop manual-latex-define.patch no longer needed with sphinx.
  - drop siteconfig-static.patch: not needed with new build system
  - drop pyx-text-warnings26.patch: warnings fixed upstream
* Add patch sphinx-mathjax.patch to use pngmath in sphinx rather than mathjax
  which is not yet in Debian.
* Add patch createlfs-no-foiltex.patch to skip generation of foiltex-based
  lfs files that would require non-free components.
* Switch to dpkg-source 3.0 (quilt) format.
* Switch from python-support to dh_python2 as build helper.
* Update copyright format to newer DEP-5 specification.
* Add new files to copyright file.
* Bump standards version to 3.9.2 (no changes required).
* Set DM-Upload-Allowed: yes

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- encoding: utf-8 -*-
 
2
#
 
3
#
 
4
# Copyright (C) 2006-2011 Jörg Lehmann <joergl@users.sourceforge.net>
 
5
# Copyright (C) 2007-2011 André Wobst <wobsta@users.sourceforge.net>
 
6
#
 
7
# This file is part of PyX (http://pyx.sourceforge.net/).
 
8
#
 
9
# PyX is free software; you can redistribute it and/or modify
 
10
# it under the terms of the GNU General Public License as published by
 
11
# the Free Software Foundation; either version 2 of the License, or
 
12
# (at your option) any later version.
 
13
#
 
14
# PyX is distributed in the hope that it will be useful,
 
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
# GNU General Public License for more details.
 
18
#
 
19
# You should have received a copy of the GNU General Public License
 
20
# along with PyX; if not, write to the Free Software
 
21
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 
22
 
 
23
import string
 
24
import metric
 
25
 
 
26
unicodestring = {u" ": "space",
 
27
                 u"!": "exclam",
 
28
                 u"\"": "quotedbl",
 
29
                 u"#": "numbersign",
 
30
                 u"$": "dollar",
 
31
                 u"%": "percent",
 
32
                 u"&": "ampersand",
 
33
                 u"'": "quotesingle",
 
34
                 u"(": "parenleft",
 
35
                 u")": "parenright",
 
36
                 u"*": "asterisk",
 
37
                 u"+": "plus",
 
38
                 u",": "comma",
 
39
                 u"-": "hyphen",
 
40
                 u".": "period",
 
41
                 u"/": "slash",
 
42
                 u"0": "zero",
 
43
                 u"1": "one",
 
44
                 u"2": "two",
 
45
                 u"3": "three",
 
46
                 u"4": "four",
 
47
                 u"5": "five",
 
48
                 u"6": "six",
 
49
                 u"7": "seven",
 
50
                 u"8": "eight",
 
51
                 u"9": "nine",
 
52
                 u":": "colon",
 
53
                 u";": "semicolon",
 
54
                 u"<": "less",
 
55
                 u"=": "equal",
 
56
                 u">": "greater",
 
57
                 u"?": "question",
 
58
                 u"@": "at",
 
59
                 u"A": "A",
 
60
                 u"B": "B",
 
61
                 u"C": "C",
 
62
                 u"D": "D",
 
63
                 u"E": "E",
 
64
                 u"F": "F",
 
65
                 u"G": "G",
 
66
                 u"H": "H",
 
67
                 u"I": "I",
 
68
                 u"J": "J",
 
69
                 u"K": "K",
 
70
                 u"L": "L",
 
71
                 u"M": "M",
 
72
                 u"N": "N",
 
73
                 u"O": "O",
 
74
                 u"P": "P",
 
75
                 u"Q": "Q",
 
76
                 u"R": "R",
 
77
                 u"S": "S",
 
78
                 u"T": "T",
 
79
                 u"U": "U",
 
80
                 u"V": "V",
 
81
                 u"W": "W",
 
82
                 u"X": "X",
 
83
                 u"Y": "Y",
 
84
                 u"Z": "Z",
 
85
                 u"[": "bracketleft",
 
86
                 u"\\": "backslash",
 
87
                 u"]": "bracketright",
 
88
                 u"^": "asciicircum",
 
89
                 u"_": "underscore",
 
90
                 u"`": "grave",
 
91
                 u"a": "a",
 
92
                 u"b": "b",
 
93
                 u"c": "c",
 
94
                 u"d": "d",
 
95
                 u"e": "e",
 
96
                 u"f": "f",
 
97
                 u"g": "g",
 
98
                 u"h": "h",
 
99
                 u"i": "i",
 
100
                 u"j": "j",
 
101
                 u"k": "k",
 
102
                 u"l": "l",
 
103
                 u"m": "m",
 
104
                 u"n": "n",
 
105
                 u"o": "o",
 
106
                 u"p": "p",
 
107
                 u"q": "q",
 
108
                 u"r": "r",
 
109
                 u"s": "s",
 
110
                 u"t": "t",
 
111
                 u"u": "u",
 
112
                 u"v": "v",
 
113
                 u"w": "w",
 
114
                 u"x": "x",
 
115
                 u"y": "y",
 
116
                 u"z": "z",
 
117
                 u"{": "braceleft",
 
118
                 u"|": "bar",
 
119
                 u"}": "braceright",
 
120
                 u"~": "asciitilde",
 
121
                 u"\xa0": "space",
 
122
                 u"\xa1": "exclamdown",
 
123
                 u"\xa2": "cent",
 
124
                 u"\xa3": "sterling",
 
125
                 u"\xa4": "currency",
 
126
                 u"\xa5": "yen",
 
127
                 u"\xa6": "brokenbar",
 
128
                 u"\xa7": "section",
 
129
                 u"\xa8": "dieresis",
 
130
                 u"\xa9": "copyright",
 
131
                 u"\xaa": "ordfeminine",
 
132
                 u"\xab": "guillemotleft",
 
133
                 u"\xac": "logicalnot",
 
134
                 u"\xad": "hyphen",
 
135
                 u"\xae": "registered",
 
136
                 u"\xaf": "macron",
 
137
                 u"\xb0": "degree",
 
138
                 u"\xb1": "plusminus",
 
139
                 u"\xb4": "acute",
 
140
                 u"\xb6": "paragraph",
 
141
                 u"\xb7": "periodcentered",
 
142
                 u"\xb8": "cedilla",
 
143
                 u"\xba": "ordmasculine",
 
144
                 u"\xbb": "guillemotright",
 
145
                 u"\xbc": "onequarter",
 
146
                 u"\xbd": "onehalf",
 
147
                 u"\xbe": "threequarters",
 
148
                 u"\xbf": "questiondown",
 
149
                 u"\xc0": "Agrave",
 
150
                 u"\xc1": "Aacute",
 
151
                 u"\xc2": "Acircumflex",
 
152
                 u"\xc3": "Atilde",
 
153
                 u"\xc4": "Adieresis",
 
154
                 u"\xc5": "Aring",
 
155
                 u"\xc6": "AE",
 
156
                 u"\xc7": "Ccedilla",
 
157
                 u"\xc8": "Egrave",
 
158
                 u"\xc9": "Eacute",
 
159
                 u"\xca": "Ecircumflex",
 
160
                 u"\xcb": "Edieresis",
 
161
                 u"\xcc": "Igrave",
 
162
                 u"\xcd": "Iacute",
 
163
                 u"\xce": "Icircumflex",
 
164
                 u"\xcf": "Idieresis",
 
165
                 u"\xd0": "Eth",
 
166
                 u"\xd1": "Ntilde",
 
167
                 u"\xd2": "Ograve",
 
168
                 u"\xd3": "Oacute",
 
169
                 u"\xd4": "Ocircumflex",
 
170
                 u"\xd5": "Otilde",
 
171
                 u"\xd6": "Odieresis",
 
172
                 u"\xd7": "multiply",
 
173
                 u"\xd8": "Oslash",
 
174
                 u"\xd9": "Ugrave",
 
175
                 u"\xda": "Uacute",
 
176
                 u"\xdb": "Ucircumflex",
 
177
                 u"\xdc": "Udieresis",
 
178
                 u"\xdd": "Yacute",
 
179
                 u"\xde": "Thorn",
 
180
                 u"\xdf": "germandbls",
 
181
                 u"\xe0": "agrave",
 
182
                 u"\xe1": "aacute",
 
183
                 u"\xe2": "acircumflex",
 
184
                 u"\xe3": "atilde",
 
185
                 u"\xe4": "adieresis",
 
186
                 u"\xe5": "aring",
 
187
                 u"\xe6": "ae",
 
188
                 u"\xe7": "ccedilla",
 
189
                 u"\xe8": "egrave",
 
190
                 u"\xe9": "eacute",
 
191
                 u"\xea": "ecircumflex",
 
192
                 u"\xeb": "edieresis",
 
193
                 u"\xec": "igrave",
 
194
                 u"\xed": "iacute",
 
195
                 u"\xee": "icircumflex",
 
196
                 u"\xef": "idieresis",
 
197
                 u"\xf0": "eth",
 
198
                 u"\xf1": "ntilde",
 
199
                 u"\xf2": "ograve",
 
200
                 u"\xf3": "oacute",
 
201
                 u"\xf4": "ocircumflex",
 
202
                 u"\xf5": "otilde",
 
203
                 u"\xf6": "odieresis",
 
204
                 u"\xf7": "divide",
 
205
                 u"\xf8": "oslash",
 
206
                 u"\xf9": "ugrave",
 
207
                 u"\xfa": "uacute",
 
208
                 u"\xfb": "ucircumflex",
 
209
                 u"\xfc": "udieresis",
 
210
                 u"\xfd": "yacute",
 
211
                 u"\xfe": "thorn",
 
212
                 u"\xff": "ydieresis",
 
213
                 u"\u0100": "Amacron",
 
214
                 u"\u0101": "amacron",
 
215
                 u"\u0102": "Abreve",
 
216
                 u"\u0103": "abreve",
 
217
                 u"\u0104": "Aogonek",
 
218
                 u"\u0105": "aogonek",
 
219
                 u"\u0106": "Cacute",
 
220
                 u"\u0107": "cacute",
 
221
                 u"\u0108": "Ccircumflex",
 
222
                 u"\u0109": "ccircumflex",
 
223
                 u"\u010a": "Cdotaccent",
 
224
                 u"\u010b": "cdotaccent",
 
225
                 u"\u010c": "Ccaron",
 
226
                 u"\u010d": "ccaron",
 
227
                 u"\u010e": "Dcaron",
 
228
                 u"\u010f": "dcaron",
 
229
                 u"\u0110": "Dcroat",
 
230
                 u"\u0111": "dcroat",
 
231
                 u"\u0112": "Emacron",
 
232
                 u"\u0113": "emacron",
 
233
                 u"\u0114": "Ebreve",
 
234
                 u"\u0115": "ebreve",
 
235
                 u"\u0116": "Edotaccent",
 
236
                 u"\u0117": "edotaccent",
 
237
                 u"\u0118": "Eogonek",
 
238
                 u"\u0119": "eogonek",
 
239
                 u"\u011a": "Ecaron",
 
240
                 u"\u011b": "ecaron",
 
241
                 u"\u011c": "Gcircumflex",
 
242
                 u"\u011d": "gcircumflex",
 
243
                 u"\u011e": "Gbreve",
 
244
                 u"\u011f": "gbreve",
 
245
                 u"\u0120": "Gdotaccent",
 
246
                 u"\u0121": "gdotaccent",
 
247
                 u"\u0122": "Gcommaaccent",
 
248
                 u"\u0123": "gcommaaccent",
 
249
                 u"\u0124": "Hcircumflex",
 
250
                 u"\u0125": "hcircumflex",
 
251
                 u"\u0126": "Hbar",
 
252
                 u"\u0127": "hbar",
 
253
                 u"\u0128": "Itilde",
 
254
                 u"\u0129": "itilde",
 
255
                 u"\u012a": "Imacron",
 
256
                 u"\u012b": "imacron",
 
257
                 u"\u012c": "Ibreve",
 
258
                 u"\u012d": "ibreve",
 
259
                 u"\u012e": "Iogonek",
 
260
                 u"\u012f": "iogonek",
 
261
                 u"\u0130": "Idotaccent",
 
262
                 u"\u0131": "dotlessi",
 
263
                 u"\u0132": "IJ",
 
264
                 u"\u0133": "ij",
 
265
                 u"\u0134": "Jcircumflex",
 
266
                 u"\u0135": "jcircumflex",
 
267
                 u"\u0136": "Kcommaaccent",
 
268
                 u"\u0137": "kcommaaccent",
 
269
                 u"\u0138": "kgreenlandic",
 
270
                 u"\u0139": "Lacute",
 
271
                 u"\u013a": "lacute",
 
272
                 u"\u013b": "Lcommaaccent",
 
273
                 u"\u013c": "lcommaaccent",
 
274
                 u"\u013d": "Lcaron",
 
275
                 u"\u013e": "lcaron",
 
276
                 u"\u013f": "Ldot",
 
277
                 u"\u0140": "ldot",
 
278
                 u"\u0141": "Lslash",
 
279
                 u"\u0142": "lslash",
 
280
                 u"\u0143": "Nacute",
 
281
                 u"\u0144": "nacute",
 
282
                 u"\u0145": "Ncommaaccent",
 
283
                 u"\u0146": "ncommaaccent",
 
284
                 u"\u0147": "Ncaron",
 
285
                 u"\u0148": "ncaron",
 
286
                 u"\u0149": "napostrophe",
 
287
                 u"\u014a": "Eng",
 
288
                 u"\u014b": "eng",
 
289
                 u"\u014c": "Omacron",
 
290
                 u"\u014d": "omacron",
 
291
                 u"\u014e": "Obreve",
 
292
                 u"\u014f": "obreve",
 
293
                 u"\u0150": "Ohungarumlaut",
 
294
                 u"\u0151": "ohungarumlaut",
 
295
                 u"\u0152": "OE",
 
296
                 u"\u0153": "oe",
 
297
                 u"\u0154": "Racute",
 
298
                 u"\u0155": "racute",
 
299
                 u"\u0156": "Rcommaaccent",
 
300
                 u"\u0157": "rcommaaccent",
 
301
                 u"\u0158": "Rcaron",
 
302
                 u"\u0159": "rcaron",
 
303
                 u"\u015a": "Sacute",
 
304
                 u"\u015b": "sacute",
 
305
                 u"\u015c": "Scircumflex",
 
306
                 u"\u015d": "scircumflex",
 
307
                 u"\u015e": "Scedilla",
 
308
                 u"\u015f": "scedilla",
 
309
                 u"\u0160": "Scaron",
 
310
                 u"\u0161": "scaron",
 
311
                 u"\u0162": "Tcommaaccent",
 
312
                 u"\u0163": "tcommaaccent",
 
313
                 u"\u0164": "Tcaron",
 
314
                 u"\u0165": "tcaron",
 
315
                 u"\u0166": "Tbar",
 
316
                 u"\u0167": "tbar",
 
317
                 u"\u0168": "Utilde",
 
318
                 u"\u0169": "utilde",
 
319
                 u"\u016a": "Umacron",
 
320
                 u"\u016b": "umacron",
 
321
                 u"\u016c": "Ubreve",
 
322
                 u"\u016d": "ubreve",
 
323
                 u"\u016e": "Uring",
 
324
                 u"\u016f": "uring",
 
325
                 u"\u0170": "Uhungarumlaut",
 
326
                 u"\u0171": "uhungarumlaut",
 
327
                 u"\u0172": "Uogonek",
 
328
                 u"\u0173": "uogonek",
 
329
                 u"\u0174": "Wcircumflex",
 
330
                 u"\u0175": "wcircumflex",
 
331
                 u"\u0176": "Ycircumflex",
 
332
                 u"\u0177": "ycircumflex",
 
333
                 u"\u0178": "Ydieresis",
 
334
                 u"\u0179": "Zacute",
 
335
                 u"\u017a": "zacute",
 
336
                 u"\u017b": "Zdotaccent",
 
337
                 u"\u017c": "zdotaccent",
 
338
                 u"\u017d": "Zcaron",
 
339
                 u"\u017e": "zcaron",
 
340
                 u"\u017f": "longs",
 
341
                 u"\u0192": "florin",
 
342
                 u"\u01a0": "Ohorn",
 
343
                 u"\u01a1": "ohorn",
 
344
                 u"\u01af": "Uhorn",
 
345
                 u"\u01b0": "uhorn",
 
346
                 u"\u01e6": "Gcaron",
 
347
                 u"\u01e7": "gcaron",
 
348
                 u"\u01fa": "Aringacute",
 
349
                 u"\u01fb": "aringacute",
 
350
                 u"\u01fc": "AEacute",
 
351
                 u"\u01fd": "aeacute",
 
352
                 u"\u01fe": "Oslashacute",
 
353
                 u"\u01ff": "oslashacute",
 
354
                 u"\u0218": "Scommaaccent",
 
355
                 u"\u0219": "scommaaccent",
 
356
                 u"\u02bc": "afii57929",
 
357
                 u"\u02bd": "afii64937",
 
358
                 u"\u02c6": "circumflex",
 
359
                 u"\u02c7": "caron",
 
360
                 u"\u02c9": "macron",
 
361
                 u"\u02d8": "breve",
 
362
                 u"\u02d9": "dotaccent",
 
363
                 u"\u02da": "ring",
 
364
                 u"\u02db": "ogonek",
 
365
                 u"\u02dc": "tilde",
 
366
                 u"\u02dd": "hungarumlaut",
 
367
                 u"\u0300": "gravecomb",
 
368
                 u"\u0301": "acutecomb",
 
369
                 u"\u0303": "tildecomb",
 
370
                 u"\u0309": "hookabovecomb",
 
371
                 u"\u0323": "dotbelowcomb",
 
372
                 u"\u0384": "tonos",
 
373
                 u"\u0385": "dieresistonos",
 
374
                 u"\u0386": "Alphatonos",
 
375
                 u"\u0387": "anoteleia",
 
376
                 u"\u0388": "Epsilontonos",
 
377
                 u"\u0389": "Etatonos",
 
378
                 u"\u038a": "Iotatonos",
 
379
                 u"\u038c": "Omicrontonos",
 
380
                 u"\u038e": "Upsilontonos",
 
381
                 u"\u038f": "Omegatonos",
 
382
                 u"\u0390": "iotadieresistonos",
 
383
                 u"\u0391": "Alpha",
 
384
                 u"\u0392": "Beta",
 
385
                 u"\u0393": "Gamma",
 
386
                 u"\u0394": "Delta",
 
387
                 u"\u0395": "Epsilon",
 
388
                 u"\u0396": "Zeta",
 
389
                 u"\u0397": "Eta",
 
390
                 u"\u0398": "Theta",
 
391
                 u"\u0399": "Iota",
 
392
                 u"\u039a": "Kappa",
 
393
                 u"\u039b": "Lambda",
 
394
                 u"\u039c": "Mu",
 
395
                 u"\u039d": "Nu",
 
396
                 u"\u039e": "Xi",
 
397
                 u"\u039f": "Omicron",
 
398
                 u"\u03a0": "Pi",
 
399
                 u"\u03a1": "Rho",
 
400
                 u"\u03a3": "Sigma",
 
401
                 u"\u03a4": "Tau",
 
402
                 u"\u03a5": "Upsilon",
 
403
                 u"\u03a6": "Phi",
 
404
                 u"\u03a7": "Chi",
 
405
                 u"\u03a8": "Psi",
 
406
                 u"\u03a9": "Omega",
 
407
                 u"\u03aa": "Iotadieresis",
 
408
                 u"\u03ab": "Upsilondieresis",
 
409
                 u"\u03ac": "alphatonos",
 
410
                 u"\u03ad": "epsilontonos",
 
411
                 u"\u03ae": "etatonos",
 
412
                 u"\u03af": "iotatonos",
 
413
                 u"\u03b0": "upsilondieresistonos",
 
414
                 u"\u03b1": "alpha",
 
415
                 u"\u03b2": "beta",
 
416
                 u"\u03b3": "gamma",
 
417
                 u"\u03b4": "delta",
 
418
                 u"\u03b5": "epsilon",
 
419
                 u"\u03b6": "zeta",
 
420
                 u"\u03b7": "eta",
 
421
                 u"\u03b8": "theta",
 
422
                 u"\u03b9": "iota",
 
423
                 u"\u03ba": "kappa",
 
424
                 u"\u03bb": "lambda",
 
425
                 u"\u03bc": "mu",
 
426
                 u"\u03bd": "nu",
 
427
                 u"\u03be": "xi",
 
428
                 u"\u03bf": "omicron",
 
429
                 u"\u03c0": "pi",
 
430
                 u"\u03c1": "rho",
 
431
                 u"\u03c2": "sigma1",
 
432
                 u"\u03c3": "sigma",
 
433
                 u"\u03c4": "tau",
 
434
                 u"\u03c5": "upsilon",
 
435
                 u"\u03c6": "phi",
 
436
                 u"\u03c7": "chi",
 
437
                 u"\u03c8": "psi",
 
438
                 u"\u03c9": "omega",
 
439
                 u"\u03ca": "iotadieresis",
 
440
                 u"\u03cb": "upsilondieresis",
 
441
                 u"\u03cc": "omicrontonos",
 
442
                 u"\u03cd": "upsilontonos",
 
443
                 u"\u03ce": "omegatonos",
 
444
                 u"\u03d1": "theta1",
 
445
                 u"\u03d2": "Upsilon1",
 
446
                 u"\u03d5": "phi1",
 
447
                 u"\u03d6": "omega1",
 
448
                 u"\u0401": "afii10023",
 
449
                 u"\u0402": "afii10051",
 
450
                 u"\u0403": "afii10052",
 
451
                 u"\u0404": "afii10053",
 
452
                 u"\u0405": "afii10054",
 
453
                 u"\u0406": "afii10055",
 
454
                 u"\u0407": "afii10056",
 
455
                 u"\u0408": "afii10057",
 
456
                 u"\u0409": "afii10058",
 
457
                 u"\u040a": "afii10059",
 
458
                 u"\u040b": "afii10060",
 
459
                 u"\u040c": "afii10061",
 
460
                 u"\u040e": "afii10062",
 
461
                 u"\u040f": "afii10145",
 
462
                 u"\u0410": "afii10017",
 
463
                 u"\u0411": "afii10018",
 
464
                 u"\u0412": "afii10019",
 
465
                 u"\u0413": "afii10020",
 
466
                 u"\u0414": "afii10021",
 
467
                 u"\u0415": "afii10022",
 
468
                 u"\u0416": "afii10024",
 
469
                 u"\u0417": "afii10025",
 
470
                 u"\u0418": "afii10026",
 
471
                 u"\u0419": "afii10027",
 
472
                 u"\u041a": "afii10028",
 
473
                 u"\u041b": "afii10029",
 
474
                 u"\u041c": "afii10030",
 
475
                 u"\u041d": "afii10031",
 
476
                 u"\u041e": "afii10032",
 
477
                 u"\u041f": "afii10033",
 
478
                 u"\u0420": "afii10034",
 
479
                 u"\u0421": "afii10035",
 
480
                 u"\u0422": "afii10036",
 
481
                 u"\u0423": "afii10037",
 
482
                 u"\u0424": "afii10038",
 
483
                 u"\u0425": "afii10039",
 
484
                 u"\u0426": "afii10040",
 
485
                 u"\u0427": "afii10041",
 
486
                 u"\u0428": "afii10042",
 
487
                 u"\u0429": "afii10043",
 
488
                 u"\u042a": "afii10044",
 
489
                 u"\u042b": "afii10045",
 
490
                 u"\u042c": "afii10046",
 
491
                 u"\u042d": "afii10047",
 
492
                 u"\u042e": "afii10048",
 
493
                 u"\u042f": "afii10049",
 
494
                 u"\u0430": "afii10065",
 
495
                 u"\u0431": "afii10066",
 
496
                 u"\u0432": "afii10067",
 
497
                 u"\u0433": "afii10068",
 
498
                 u"\u0434": "afii10069",
 
499
                 u"\u0435": "afii10070",
 
500
                 u"\u0436": "afii10072",
 
501
                 u"\u0437": "afii10073",
 
502
                 u"\u0438": "afii10074",
 
503
                 u"\u0439": "afii10075",
 
504
                 u"\u043a": "afii10076",
 
505
                 u"\u043b": "afii10077",
 
506
                 u"\u043c": "afii10078",
 
507
                 u"\u043d": "afii10079",
 
508
                 u"\u043e": "afii10080",
 
509
                 u"\u043f": "afii10081",
 
510
                 u"\u0440": "afii10082",
 
511
                 u"\u0441": "afii10083",
 
512
                 u"\u0442": "afii10084",
 
513
                 u"\u0443": "afii10085",
 
514
                 u"\u0444": "afii10086",
 
515
                 u"\u0445": "afii10087",
 
516
                 u"\u0446": "afii10088",
 
517
                 u"\u0447": "afii10089",
 
518
                 u"\u0448": "afii10090",
 
519
                 u"\u0449": "afii10091",
 
520
                 u"\u044a": "afii10092",
 
521
                 u"\u044b": "afii10093",
 
522
                 u"\u044c": "afii10094",
 
523
                 u"\u044d": "afii10095",
 
524
                 u"\u044e": "afii10096",
 
525
                 u"\u044f": "afii10097",
 
526
                 u"\u0451": "afii10071",
 
527
                 u"\u0452": "afii10099",
 
528
                 u"\u0453": "afii10100",
 
529
                 u"\u0454": "afii10101",
 
530
                 u"\u0455": "afii10102",
 
531
                 u"\u0456": "afii10103",
 
532
                 u"\u0457": "afii10104",
 
533
                 u"\u0458": "afii10105",
 
534
                 u"\u0459": "afii10106",
 
535
                 u"\u045a": "afii10107",
 
536
                 u"\u045b": "afii10108",
 
537
                 u"\u045c": "afii10109",
 
538
                 u"\u045e": "afii10110",
 
539
                 u"\u045f": "afii10193",
 
540
                 u"\u0462": "afii10146",
 
541
                 u"\u0463": "afii10194",
 
542
                 u"\u0472": "afii10147",
 
543
                 u"\u0473": "afii10195",
 
544
                 u"\u0474": "afii10148",
 
545
                 u"\u0475": "afii10196",
 
546
                 u"\u0490": "afii10050",
 
547
                 u"\u0491": "afii10098",
 
548
                 u"\u04d9": "afii10846",
 
549
                 u"\u05b0": "afii57799",
 
550
                 u"\u05b1": "afii57801",
 
551
                 u"\u05b2": "afii57800",
 
552
                 u"\u05b3": "afii57802",
 
553
                 u"\u05b4": "afii57793",
 
554
                 u"\u05b5": "afii57794",
 
555
                 u"\u05b6": "afii57795",
 
556
                 u"\u05b7": "afii57798",
 
557
                 u"\u05b8": "afii57797",
 
558
                 u"\u05b9": "afii57806",
 
559
                 u"\u05bb": "afii57796",
 
560
                 u"\u05bc": "afii57807",
 
561
                 u"\u05bd": "afii57839",
 
562
                 u"\u05be": "afii57645",
 
563
                 u"\u05bf": "afii57841",
 
564
                 u"\u05c0": "afii57842",
 
565
                 u"\u05c1": "afii57804",
 
566
                 u"\u05c2": "afii57803",
 
567
                 u"\u05c3": "afii57658",
 
568
                 u"\u05d0": "afii57664",
 
569
                 u"\u05d1": "afii57665",
 
570
                 u"\u05d2": "afii57666",
 
571
                 u"\u05d3": "afii57667",
 
572
                 u"\u05d4": "afii57668",
 
573
                 u"\u05d5": "afii57669",
 
574
                 u"\u05d6": "afii57670",
 
575
                 u"\u05d7": "afii57671",
 
576
                 u"\u05d8": "afii57672",
 
577
                 u"\u05d9": "afii57673",
 
578
                 u"\u05da": "afii57674",
 
579
                 u"\u05db": "afii57675",
 
580
                 u"\u05dc": "afii57676",
 
581
                 u"\u05dd": "afii57677",
 
582
                 u"\u05de": "afii57678",
 
583
                 u"\u05df": "afii57679",
 
584
                 u"\u05e0": "afii57680",
 
585
                 u"\u05e1": "afii57681",
 
586
                 u"\u05e2": "afii57682",
 
587
                 u"\u05e3": "afii57683",
 
588
                 u"\u05e4": "afii57684",
 
589
                 u"\u05e5": "afii57685",
 
590
                 u"\u05e6": "afii57686",
 
591
                 u"\u05e7": "afii57687",
 
592
                 u"\u05e8": "afii57688",
 
593
                 u"\u05e9": "afii57689",
 
594
                 u"\u05ea": "afii57690",
 
595
                 u"\u05f0": "afii57716",
 
596
                 u"\u05f1": "afii57717",
 
597
                 u"\u05f2": "afii57718",
 
598
                 u"\u060c": "afii57388",
 
599
                 u"\u061b": "afii57403",
 
600
                 u"\u061f": "afii57407",
 
601
                 u"\u0621": "afii57409",
 
602
                 u"\u0622": "afii57410",
 
603
                 u"\u0623": "afii57411",
 
604
                 u"\u0624": "afii57412",
 
605
                 u"\u0625": "afii57413",
 
606
                 u"\u0626": "afii57414",
 
607
                 u"\u0627": "afii57415",
 
608
                 u"\u0628": "afii57416",
 
609
                 u"\u0629": "afii57417",
 
610
                 u"\u062a": "afii57418",
 
611
                 u"\u062b": "afii57419",
 
612
                 u"\u062c": "afii57420",
 
613
                 u"\u062d": "afii57421",
 
614
                 u"\u062e": "afii57422",
 
615
                 u"\u062f": "afii57423",
 
616
                 u"\u0630": "afii57424",
 
617
                 u"\u0631": "afii57425",
 
618
                 u"\u0632": "afii57426",
 
619
                 u"\u0633": "afii57427",
 
620
                 u"\u0634": "afii57428",
 
621
                 u"\u0635": "afii57429",
 
622
                 u"\u0636": "afii57430",
 
623
                 u"\u0637": "afii57431",
 
624
                 u"\u0638": "afii57432",
 
625
                 u"\u0639": "afii57433",
 
626
                 u"\u063a": "afii57434",
 
627
                 u"\u0640": "afii57440",
 
628
                 u"\u0641": "afii57441",
 
629
                 u"\u0642": "afii57442",
 
630
                 u"\u0643": "afii57443",
 
631
                 u"\u0644": "afii57444",
 
632
                 u"\u0645": "afii57445",
 
633
                 u"\u0646": "afii57446",
 
634
                 u"\u0647": "afii57470",
 
635
                 u"\u0648": "afii57448",
 
636
                 u"\u0649": "afii57449",
 
637
                 u"\u064a": "afii57450",
 
638
                 u"\u064b": "afii57451",
 
639
                 u"\u064c": "afii57452",
 
640
                 u"\u064d": "afii57453",
 
641
                 u"\u064e": "afii57454",
 
642
                 u"\u064f": "afii57455",
 
643
                 u"\u0650": "afii57456",
 
644
                 u"\u0651": "afii57457",
 
645
                 u"\u0652": "afii57458",
 
646
                 u"\u0660": "afii57392",
 
647
                 u"\u0661": "afii57393",
 
648
                 u"\u0662": "afii57394",
 
649
                 u"\u0663": "afii57395",
 
650
                 u"\u0664": "afii57396",
 
651
                 u"\u0665": "afii57397",
 
652
                 u"\u0666": "afii57398",
 
653
                 u"\u0667": "afii57399",
 
654
                 u"\u0668": "afii57400",
 
655
                 u"\u0669": "afii57401",
 
656
                 u"\u066a": "afii57381",
 
657
                 u"\u066d": "afii63167",
 
658
                 u"\u0679": "afii57511",
 
659
                 u"\u067e": "afii57506",
 
660
                 u"\u0686": "afii57507",
 
661
                 u"\u0688": "afii57512",
 
662
                 u"\u0691": "afii57513",
 
663
                 u"\u0698": "afii57508",
 
664
                 u"\u06a4": "afii57505",
 
665
                 u"\u06af": "afii57509",
 
666
                 u"\u06ba": "afii57514",
 
667
                 u"\u06d2": "afii57519",
 
668
                 u"\u06d5": "afii57534",
 
669
                 u"\u1e80": "Wgrave",
 
670
                 u"\u1e81": "wgrave",
 
671
                 u"\u1e82": "Wacute",
 
672
                 u"\u1e83": "wacute",
 
673
                 u"\u1e84": "Wdieresis",
 
674
                 u"\u1e85": "wdieresis",
 
675
                 u"\u1ef2": "Ygrave",
 
676
                 u"\u1ef3": "ygrave",
 
677
                 u"\u200c": "afii61664",
 
678
                 u"\u200d": "afii301",
 
679
                 u"\u200e": "afii299",
 
680
                 u"\u200f": "afii300",
 
681
                 u"\u2012": "figuredash",
 
682
                 u"\u2013": "endash",
 
683
                 u"\u2014": "emdash",
 
684
                 u"\u2015": "afii00208",
 
685
                 u"\u2017": "underscoredbl",
 
686
                 u"\u2018": "quoteleft",
 
687
                 u"\u2019": "quoteright",
 
688
                 u"\u201a": "quotesinglbase",
 
689
                 u"\u201b": "quotereversed",
 
690
                 u"\u201c": "quotedblleft",
 
691
                 u"\u201d": "quotedblright",
 
692
                 u"\u201e": "quotedblbase",
 
693
                 u"\u2020": "dagger",
 
694
                 u"\u2021": "daggerdbl",
 
695
                 u"\u2022": "bullet",
 
696
                 u"\u2024": "onedotenleader",
 
697
                 u"\u2025": "twodotenleader",
 
698
                 u"\u2026": "ellipsis",
 
699
                 u"\u202c": "afii61573",
 
700
                 u"\u202d": "afii61574",
 
701
                 u"\u202e": "afii61575",
 
702
                 u"\u2030": "perthousand",
 
703
                 u"\u2032": "minute",
 
704
                 u"\u2033": "second",
 
705
                 u"\u2039": "guilsinglleft",
 
706
                 u"\u203a": "guilsinglright",
 
707
                 u"\u203c": "exclamdbl",
 
708
                 u"\u2044": "fraction",
 
709
                 u"\u20a1": "colonmonetary",
 
710
                 u"\u20a3": "franc",
 
711
                 u"\u20a4": "lira",
 
712
                 u"\u20a7": "peseta",
 
713
                 u"\u20aa": "afii57636",
 
714
                 u"\u20ab": "dong",
 
715
                 u"\u20ac": "Euro",
 
716
                 u"\u2105": "afii61248",
 
717
                 u"\u2111": "Ifraktur",
 
718
                 u"\u2113": "afii61289",
 
719
                 u"\u2116": "afii61352",
 
720
                 u"\u2118": "weierstrass",
 
721
                 u"\u211c": "Rfraktur",
 
722
                 u"\u211e": "prescription",
 
723
                 u"\u2122": "trademark",
 
724
                 u"\u212e": "estimated",
 
725
                 u"\u2135": "aleph",
 
726
                 u"\u2153": "onethird",
 
727
                 u"\u2154": "twothirds",
 
728
                 u"\u215b": "oneeighth",
 
729
                 u"\u215c": "threeeighths",
 
730
                 u"\u215d": "fiveeighths",
 
731
                 u"\u215e": "seveneighths",
 
732
                 u"\u2190": "arrowleft",
 
733
                 u"\u2191": "arrowup",
 
734
                 u"\u2192": "arrowright",
 
735
                 u"\u2193": "arrowdown",
 
736
                 u"\u2194": "arrowboth",
 
737
                 u"\u2195": "arrowupdn",
 
738
                 u"\u21a8": "arrowupdnbse",
 
739
                 u"\u21b5": "carriagereturn",
 
740
                 u"\u21d0": "arrowdblleft",
 
741
                 u"\u21d1": "arrowdblup",
 
742
                 u"\u21d2": "arrowdblright",
 
743
                 u"\u21d3": "arrowdbldown",
 
744
                 u"\u21d4": "arrowdblboth",
 
745
                 u"\u2200": "universal",
 
746
                 u"\u2202": "partialdiff",
 
747
                 u"\u2203": "existential",
 
748
                 u"\u2205": "emptyset",
 
749
                 u"\u2207": "gradient",
 
750
                 u"\u2208": "element",
 
751
                 u"\u2209": "notelement",
 
752
                 u"\u220b": "suchthat",
 
753
                 u"\u220f": "product",
 
754
                 u"\u2211": "summation",
 
755
                 u"\u2212": "minus",
 
756
                 u"\u2215": "fraction",
 
757
                 u"\u2217": "asteriskmath",
 
758
                 u"\u2219": "periodcentered",
 
759
                 u"\u221a": "radical",
 
760
                 u"\u221d": "proportional",
 
761
                 u"\u221e": "infinity",
 
762
                 u"\u221f": "orthogonal",
 
763
                 u"\u2220": "angle",
 
764
                 u"\u2227": "logicaland",
 
765
                 u"\u2228": "logicalor",
 
766
                 u"\u2229": "intersection",
 
767
                 u"\u222a": "union",
 
768
                 u"\u222b": "integral",
 
769
                 u"\u2234": "therefore",
 
770
                 u"\u223c": "similar",
 
771
                 u"\u2245": "congruent",
 
772
                 u"\u2248": "approxequal",
 
773
                 u"\u2260": "notequal",
 
774
                 u"\u2261": "equivalence",
 
775
                 u"\u2264": "lessequal",
 
776
                 u"\u2265": "greaterequal",
 
777
                 u"\u2282": "propersubset",
 
778
                 u"\u2283": "propersuperset",
 
779
                 u"\u2284": "notsubset",
 
780
                 u"\u2286": "reflexsubset",
 
781
                 u"\u2287": "reflexsuperset",
 
782
                 u"\u2295": "circleplus",
 
783
                 u"\u2297": "circlemultiply",
 
784
                 u"\u22a5": "perpendicular",
 
785
                 u"\u22c5": "dotmath",
 
786
                 u"\u2302": "house",
 
787
                 u"\u2310": "revlogicalnot",
 
788
                 u"\u2320": "integraltp",
 
789
                 u"\u2321": "integralbt",
 
790
                 u"\u2329": "angleleft",
 
791
                 u"\u232a": "angleright",
 
792
                 u"\u2500": "SF100000",
 
793
                 u"\u2502": "SF110000",
 
794
                 u"\u250c": "SF010000",
 
795
                 u"\u2510": "SF030000",
 
796
                 u"\u2514": "SF020000",
 
797
                 u"\u2518": "SF040000",
 
798
                 u"\u251c": "SF080000",
 
799
                 u"\u2524": "SF090000",
 
800
                 u"\u252c": "SF060000",
 
801
                 u"\u2534": "SF070000",
 
802
                 u"\u253c": "SF050000",
 
803
                 u"\u2550": "SF430000",
 
804
                 u"\u2551": "SF240000",
 
805
                 u"\u2552": "SF510000",
 
806
                 u"\u2553": "SF520000",
 
807
                 u"\u2554": "SF390000",
 
808
                 u"\u2555": "SF220000",
 
809
                 u"\u2556": "SF210000",
 
810
                 u"\u2557": "SF250000",
 
811
                 u"\u2558": "SF500000",
 
812
                 u"\u2559": "SF490000",
 
813
                 u"\u255a": "SF380000",
 
814
                 u"\u255b": "SF280000",
 
815
                 u"\u255c": "SF270000",
 
816
                 u"\u255d": "SF260000",
 
817
                 u"\u255e": "SF360000",
 
818
                 u"\u255f": "SF370000",
 
819
                 u"\u2560": "SF420000",
 
820
                 u"\u2561": "SF190000",
 
821
                 u"\u2562": "SF200000",
 
822
                 u"\u2563": "SF230000",
 
823
                 u"\u2564": "SF470000",
 
824
                 u"\u2565": "SF480000",
 
825
                 u"\u2566": "SF410000",
 
826
                 u"\u2567": "SF450000",
 
827
                 u"\u2568": "SF460000",
 
828
                 u"\u2569": "SF400000",
 
829
                 u"\u256a": "SF540000",
 
830
                 u"\u256b": "SF530000",
 
831
                 u"\u256c": "SF440000",
 
832
                 u"\u2580": "upblock",
 
833
                 u"\u2584": "dnblock",
 
834
                 u"\u2588": "block",
 
835
                 u"\u258c": "lfblock",
 
836
                 u"\u2590": "rtblock",
 
837
                 u"\u2591": "ltshade",
 
838
                 u"\u2592": "shade",
 
839
                 u"\u2593": "dkshade",
 
840
                 u"\u25a0": "filledbox",
 
841
                 u"\u25a1": "H22073",
 
842
                 u"\u25aa": "H18543",
 
843
                 u"\u25ab": "H18551",
 
844
                 u"\u25ac": "filledrect",
 
845
                 u"\u25b2": "triagup",
 
846
                 u"\u25ba": "triagrt",
 
847
                 u"\u25bc": "triagdn",
 
848
                 u"\u25c4": "triaglf",
 
849
                 u"\u25ca": "lozenge",
 
850
                 u"\u25cb": "circle",
 
851
                 u"\u25cf": "H18533",
 
852
                 u"\u25d8": "invbullet",
 
853
                 u"\u25d9": "invcircle",
 
854
                 u"\u25e6": "openbullet",
 
855
                 u"\u263a": "smileface",
 
856
                 u"\u263b": "invsmileface",
 
857
                 u"\u263c": "sun",
 
858
                 u"\u2640": "female",
 
859
                 u"\u2642": "male",
 
860
                 u"\u2660": "spade",
 
861
                 u"\u2663": "club",
 
862
                 u"\u2665": "heart",
 
863
                 u"\u2666": "diamond",
 
864
                 u"\u266a": "musicalnote",
 
865
                 u"\u266b": "musicalnotedbl",
 
866
                 u"\ufb01": "fi",
 
867
                 u"\ufb02": "fl"}
 
868
 
 
869
class AFMError(Exception):
 
870
    pass
 
871
 
 
872
# reader states
 
873
_READ_START       = 0
 
874
_READ_MAIN        = 1
 
875
_READ_DIRECTION   = 2
 
876
_READ_CHARMETRICS = 3
 
877
_READ_KERNDATA    = 4
 
878
_READ_TRACKKERN   = 5
 
879
_READ_KERNPAIRS   = 6
 
880
_READ_COMPOSITES  = 7
 
881
_READ_END         = 8
 
882
 
 
883
# various parsing functions
 
884
def _parseint(s):
 
885
    try:
 
886
        return int(s)
 
887
    except:
 
888
        raise AFMError("Expecting int, got '%s'" % s)
 
889
 
 
890
def _parsehex(s):
 
891
    try:
 
892
        if s[0] != "<" or s[-1] != ">":
 
893
            raise AFMError()
 
894
        return int(s[1:-1], 16)
 
895
    except:
 
896
        raise AFMError("Expecting hexadecimal int, got '%s'" % s)
 
897
 
 
898
def _parsefloat(s):
 
899
    try:
 
900
        return float(s)
 
901
    except:
 
902
        raise AFMError("Expecting float, got '%s'" % s)
 
903
 
 
904
def _parsefloats(s, nos):
 
905
    try:
 
906
        numbers = s.split()
 
907
        result = map(float, numbers)
 
908
        if len(result) != nos:
 
909
            raise AFMError()
 
910
    except:
 
911
        raise AFMError("Expecting list of %d numbers, got '%s'" % (s, nos))
 
912
    return result
 
913
 
 
914
def _parsestr(s):
 
915
    # XXX: check for invalid characters in s
 
916
    return s
 
917
 
 
918
def _parsebool(s):
 
919
    s = s.rstrip()
 
920
    if s == "true":
 
921
       return 1
 
922
    elif s == "false":
 
923
       return 0
 
924
    else:
 
925
        raise AFMError("Expecting boolean, got '%s'" % s)
 
926
 
 
927
 
 
928
class AFMcharmetrics:
 
929
    def __init__(self, code, widths=None, vvector=None, name=None, bbox=None, ligatures=None):
 
930
        self.code = code
 
931
        if widths is None:
 
932
            self.widths = [None] * 2
 
933
        else:
 
934
            self.widths = widths
 
935
        self.vvector = vvector
 
936
        self.name = name
 
937
        self.bbox = bbox
 
938
        if ligatures is None:
 
939
            self.ligatures = []
 
940
        else:
 
941
            self.ligatures = ligatures
 
942
 
 
943
 
 
944
class AFMtrackkern:
 
945
    def __init__(self, degree, min_ptsize, min_kern, max_ptsize, max_kern):
 
946
        self.degree = degree
 
947
        self.min_ptsize = min_ptsize
 
948
        self.min_kern = min_kern
 
949
        self.max_ptsize = max_ptsize
 
950
        self.max_kern = max_kern
 
951
 
 
952
 
 
953
class AFMkernpair:
 
954
    def __init__(self, name1, name2, x, y):
 
955
        self.name1 = name1
 
956
        self.name2 = name2
 
957
        self.x = x
 
958
        self.y = y
 
959
 
 
960
 
 
961
class AFMcomposite:
 
962
    def __init__(self, name, parts):
 
963
        self.name = name
 
964
        self.parts = parts
 
965
 
 
966
 
 
967
class AFMfile(metric.metric):
 
968
 
 
969
    def __init__(self, file):
 
970
       self.metricssets = 0                     # int, optional
 
971
       self.fontname = None                     # str, required
 
972
       self.fullname = None                     # str, optional
 
973
       self.familyname = None                   # str, optional
 
974
       self.weight = None                       # str, optional
 
975
       self.fontbbox = None                     # 4 floats, required
 
976
       self.version = None                      # str, optional
 
977
       self.notice = None                       # str, optional
 
978
       self.encodingscheme = None               # str, optional
 
979
       self.mappingscheme = None                # int, optional (not present in base font programs)
 
980
       self.escchar = None                      # int, required if mappingscheme == 3
 
981
       self.characterset = None                 # str, optional
 
982
       self.characters = None                   # int, optional
 
983
       self.isbasefont = 1                      # bool, optional
 
984
       self.vvector = None                      # 2 floats, required if metricssets == 2
 
985
       self.isfixedv = None                     # bool, default: true if vvector present, false otherwise
 
986
       self.capheight = None                    # float, optional
 
987
       self.xheight = None                      # float, optional
 
988
       self.ascender = None                     # float, optional
 
989
       self.descender = None                    # float, optional
 
990
       self.stdhw = None                        # float, optional
 
991
       self.stdvw = None                        # float, optional
 
992
       self.underlinepositions = [None] * 2     # int, optional (for each direction)
 
993
       self.underlinethicknesses = [None] * 2   # float, optional (for each direction)
 
994
       self.italicangles = [None] * 2           # float, optional (for each direction)
 
995
       self.charwidths = [None] * 2             # 2 floats, optional (for each direction)
 
996
       self.isfixedpitchs = [None] * 2          # bool, optional (for each direction)
 
997
       self.charmetrics = None                  # list of character metrics information, optional
 
998
       self.charmetricsdict = {}                # helper dictionary mapping glyph names to character metrics information
 
999
       self.trackkerns = None                   # list of track kernings, optional
 
1000
       self.kernpairs = [None] * 2              # list of list of kerning pairs (for each direction), optional
 
1001
       self.kernpairsdict = {}                  # helper dictionary mapping glyph names to kerning pairs, first direction
 
1002
       self.kernpairsdict1 = {}                 # helper dictionary mapping glyph names to kerning pairs, second direction
 
1003
       self.composites = None                   # list of composite character data sets, optional
 
1004
       self.parse(file)
 
1005
       if self.isfixedv is None:
 
1006
           self.isfixedv = self.vvector is not None
 
1007
       # XXX we should check the constraints on some parameters
 
1008
 
 
1009
    # the following methods process a line when the reader is in the corresponding
 
1010
    # state and return the new state
 
1011
    def _processline_start(self, line):
 
1012
        key, args = line.split(None, 1)
 
1013
        if key != "StartFontMetrics":
 
1014
            raise AFMError("Expecting StartFontMetrics, no found")
 
1015
        return _READ_MAIN, None
 
1016
 
 
1017
    def _processline_main(self, line):
 
1018
        try:
 
1019
            key, args = line.split(None, 1)
 
1020
        except ValueError:
 
1021
            key = line.rstrip()
 
1022
        if key == "Comment":
 
1023
            return _READ_MAIN, None
 
1024
        elif key == "MetricsSets":
 
1025
            self.metricssets = _parseint(args)
 
1026
            if direction is not None:
 
1027
                raise AFMError("MetricsSets not allowed after first (implicit) StartDirection")
 
1028
        elif key == "FontName":
 
1029
            self.fontname = _parsestr(args)
 
1030
        elif key == "FullName":
 
1031
            self.fullname = _parsestr(args)
 
1032
        elif key == "FamilyName":
 
1033
            self.familyname = _parsestr(args)
 
1034
        elif key == "Weight":
 
1035
            self.weight = _parsestr(args)
 
1036
        elif key == "FontBBox":
 
1037
            self.fontbbox = _parsefloats(args, 4)
 
1038
        elif key == "Version":
 
1039
            self.version = _parsestr(args)
 
1040
        elif key == "Notice":
 
1041
            self.notice = _parsestr(args)
 
1042
        elif key == "EncodingScheme":
 
1043
            self.encodingscheme = _parsestr(args)
 
1044
        elif key == "MappingScheme":
 
1045
            self.mappingscheme = _parseint(args)
 
1046
        elif key == "EscChar":
 
1047
            self.escchar = _parseint(args)
 
1048
        elif key == "CharacterSet":
 
1049
            self.characterset = _parsestr(args)
 
1050
        elif key == "Characters":
 
1051
            self.characters = _parseint(args)
 
1052
        elif key == "IsBaseFont":
 
1053
            self.isbasefont = _parsebool(args)
 
1054
        elif key == "VVector":
 
1055
            self.vvector = _parsefloats(args, 2)
 
1056
        elif key == "IsFixedV":
 
1057
            self.isfixedv = _parsebool(args)
 
1058
        elif key == "CapHeight":
 
1059
            self.capheight = _parsefloat(args)
 
1060
        elif key == "XHeight":
 
1061
            self.xheight = _parsefloat(args)
 
1062
        elif key == "Ascender":
 
1063
            self.ascender = _parsefloat(args)
 
1064
        elif key == "Descender":
 
1065
            self.descender = _parsefloat(args)
 
1066
        elif key == "StdHW":
 
1067
            self.stdhw = _parsefloat(args)
 
1068
        elif key == "StdVW":
 
1069
            self.stdvw = _parsefloat(args)
 
1070
        elif key == "StartDirection":
 
1071
            direction = _parseint(args)
 
1072
            if 0 <= direction <= 2:
 
1073
                return _READ_DIRECTION, direction
 
1074
            else:
 
1075
                raise AFMError("Wrong direction number %d" % direction)
 
1076
        elif (key == "UnderLinePosition" or key == "UnderlineThickness" or key == "ItalicAngle" or
 
1077
              key == "Charwidth" or key == "IsFixedPitch"):
 
1078
            # we implicitly entered a direction section, so we should process the line again
 
1079
            return self._processline_direction(line, 0)
 
1080
        elif key == "StartCharMetrics":
 
1081
            if self.charmetrics is not None:
 
1082
                raise AFMError("Multiple character metrics sections")
 
1083
            self.charmetrics = [None] * _parseint(args)
 
1084
            return _READ_CHARMETRICS, 0
 
1085
        elif key == "StartKernData":
 
1086
            return _READ_KERNDATA, None
 
1087
        elif key == "StartComposites":
 
1088
            if self.composites is not None:
 
1089
                raise AFMError("Multiple composite character data sections")
 
1090
            self.composites = [None] * _parseint(args)
 
1091
            return _READ_COMPOSITES, 0
 
1092
        elif key == "EndFontMetrics":
 
1093
            return _READ_END, None
 
1094
        elif key[0] in string.lowercase:
 
1095
            # ignoring private commands
 
1096
            pass
 
1097
        return _READ_MAIN, None
 
1098
 
 
1099
    def _processline_direction(self, line, direction):
 
1100
        try:
 
1101
            key, args = line.split(None, 1)
 
1102
        except ValueError:
 
1103
            key = line.rstrip()
 
1104
        if key == "UnderLinePosition":
 
1105
            self.underlinepositions[direction] = _parseint(args)
 
1106
        elif key == "UnderlineThickness":
 
1107
            self.underlinethicknesses[direction] = _parsefloat(args)
 
1108
        elif key == "ItalicAngle":
 
1109
            self.italicangles[direction] = _parsefloat(args)
 
1110
        elif key == "Charwidth":
 
1111
            self.charwidths[direction] = _parsefloats(args, 2)
 
1112
        elif key == "IsFixedPitch":
 
1113
            self.isfixedpitchs[direction] = _parsebool(args)
 
1114
        elif key == "EndDirection":
 
1115
            return _READ_MAIN, None
 
1116
        else:
 
1117
            # we assume that we are implicitly leaving the direction section again,
 
1118
            # so try to reprocess the line in the header reader state
 
1119
            return self._processline_main(line)
 
1120
        return _READ_DIRECTION, direction
 
1121
 
 
1122
    def _processline_charmetrics(self, line, charno):
 
1123
        if line.rstrip() == "EndCharMetrics":
 
1124
            if charno != len(self.charmetrics):
 
1125
                raise AFMError("Fewer character metrics than expected")
 
1126
            return _READ_MAIN, None
 
1127
        if charno >= len(self.charmetrics):
 
1128
            raise AFMError("More character metrics than expected")
 
1129
 
 
1130
        has_name = False
 
1131
        char = None
 
1132
        for s in line.split(";"):
 
1133
            s = s.strip()
 
1134
            if not s:
 
1135
               continue
 
1136
            key, args = s.split(None, 1)
 
1137
            if key == "C":
 
1138
                if char is not None:
 
1139
                    raise AFMError("Cannot define char code twice")
 
1140
                char = AFMcharmetrics(_parseint(args))
 
1141
            elif key == "CH":
 
1142
                if char is not None:
 
1143
                    raise AFMError("Cannot define char code twice")
 
1144
                char = AFMcharmetrics(_parsehex(args))
 
1145
            elif key == "WX" or key == "W0X":
 
1146
                char.widths[0] = _parsefloat(args), 0
 
1147
            elif key == "W1X":
 
1148
                char.widths[1] = _parsefloat(args), 0
 
1149
            elif key == "WY" or key == "W0Y":
 
1150
                char.widths[0] = 0, _parsefloat(args)
 
1151
            elif key == "W1Y":
 
1152
                char.widths[1] = 0, _parsefloat(args)
 
1153
            elif key == "W" or key == "W0":
 
1154
                char.widths[0] = _parsefloats(args, 2)
 
1155
            elif key == "W1":
 
1156
                char.widths[1] = _parsefloats(args, 2)
 
1157
            elif key == "VV":
 
1158
                char.vvector = _parsefloats(args, 2)
 
1159
            elif key == "N":
 
1160
                # XXX: we should check that name is valid (no whitespace, etc.)
 
1161
                has_name = True
 
1162
                char.name = _parsestr(args)
 
1163
            elif key == "B":
 
1164
                char.bbox = _parsefloats(args, 4)
 
1165
            elif key == "L":
 
1166
                successor, ligature = args.split(None, 1)
 
1167
                char.ligatures.append((_parsestr(successor), ligature))
 
1168
            else:
 
1169
                raise AFMError("Undefined command in character widths specification: '%s'", s)
 
1170
        if char is None:
 
1171
            raise AFMError("Character metrics not defined")
 
1172
 
 
1173
        self.charmetrics[charno] = char
 
1174
        if has_name:
 
1175
            self.charmetricsdict[char.name] = char
 
1176
        return _READ_CHARMETRICS, charno+1
 
1177
 
 
1178
    def _processline_kerndata(self, line):
 
1179
        try:
 
1180
            key, args = line.split(None, 1)
 
1181
        except ValueError:
 
1182
            key = line.rstrip()
 
1183
        if key == "Comment":
 
1184
            return _READ_KERNDATA, None
 
1185
        if key == "StartTrackKern":
 
1186
            if self.trackkerns is not None:
 
1187
                raise AFMError("Multiple track kernings data sections")
 
1188
            self.trackkerns = [None] * _parseint(args)
 
1189
            return _READ_TRACKKERN, 0
 
1190
        elif key == "StartKernPairs" or key == "StartKernPairs0":
 
1191
            if self.kernpairs[0] is not None:
 
1192
                raise AFMError("Multiple kerning pairs data sections for direction 0")
 
1193
            self.kernpairs[0] = [None] * _parseint(args)
 
1194
            return _READ_KERNPAIRS, (0, 0)
 
1195
        elif key == "StartKernPairs1":
 
1196
            if self.kernpairs[1] is not None:
 
1197
                raise AFMError("Multiple kerning pairs data sections for direction 1")
 
1198
            self.kernpairs[1] = [None] * _parseint(args)
 
1199
            return _READ_KERNPAIRS, (1, 0)
 
1200
        elif key == "EndKernData":
 
1201
            return _READ_MAIN, None
 
1202
        else:
 
1203
            raise AFMError("Unsupported key %s in kerning data section" % key)
 
1204
 
 
1205
    def _processline_trackkern(self, line, i):
 
1206
        try:
 
1207
            key, args = line.split(None, 1)
 
1208
        except ValueError:
 
1209
            key = line.rstrip()
 
1210
        if key == "Comment":
 
1211
            return _READ_TRACKKERN, i
 
1212
        elif key == "TrackKern":
 
1213
            if i >= len(self.trackkerns):
 
1214
                raise AFMError("More track kerning data sets than expected")
 
1215
            degrees, args = args.split(None, 1)
 
1216
            self.trackkerns[i] = AFMtrackkern(int(degrees), *_parsefloats(args, 4))
 
1217
            return _READ_TRACKKERN, i+1
 
1218
        elif key == "EndTrackKern":
 
1219
            if i < len(self.trackkerns):
 
1220
                raise AFMError("Fewer track kerning data sets than expected")
 
1221
            return _READ_KERNDATA, None
 
1222
        else:
 
1223
            raise AFMError("Unsupported key %s in kerning data section" % key)
 
1224
 
 
1225
    def _processline_kernpairs(self, line, (direction, i)):
 
1226
        try:
 
1227
            key, args = line.split(None, 1)
 
1228
        except ValueError:
 
1229
            key = line.rstrip()
 
1230
        if key == "Comment":
 
1231
            return _READ_KERNPAIRS, (direction, i)
 
1232
        elif key == "EndKernPairs":
 
1233
            if i < len(self.kernpairs[direction]):
 
1234
                raise AFMError("Fewer kerning pairs than expected")
 
1235
            return _READ_KERNDATA, None
 
1236
        else:
 
1237
            if i >= len(self.kernpairs[direction]):
 
1238
                raise AFMError("More kerning pairs than expected")
 
1239
            if key == "KP":
 
1240
                try:
 
1241
                    name1, name2, x, y = args.split()
 
1242
                except:
 
1243
                    raise AFMError("Expecting name1, name2, x, y, got '%s'" % args)
 
1244
                x = _parsefloat(x)
 
1245
                y = _parsefloat(y)
 
1246
            elif key == "KPH":
 
1247
                try:
 
1248
                    hex1, hex2, x, y = args.split()
 
1249
                except:
 
1250
                    raise AFMError("Expecting <hex1>, <hex2>, x, y, got '%s'" % args)
 
1251
                name1 = _parsehex(hex1)
 
1252
                name2 = _parsehex(hex2)
 
1253
                x = _parsefloat(x)
 
1254
                y = _parsefloat(y)
 
1255
            elif key == "KPX":
 
1256
                try:
 
1257
                    name1, name2, x = args.split()
 
1258
                except:
 
1259
                    raise AFMError("Expecting name1, name2, x, got '%s'" % args)
 
1260
                x = _parsefloat(x)
 
1261
                y = 0
 
1262
                self.kernpairs[direction][i] = AFMkernpair(name1, name2, _parsefloat(x), 0)
 
1263
            elif key == "KPY":
 
1264
                try:
 
1265
                    name1, name2, y = args.split()
 
1266
                except:
 
1267
                    raise AFMError("Expecting name1, name2, y, got '%s'" % args)
 
1268
                x = 0
 
1269
                y = _parsefloat(y)
 
1270
                self.kernpairs[direction][i] = AFMkernpair(name1, name2, 0, _parsefloat(y))
 
1271
            else:
 
1272
                raise AFMError("Unknown key '%s' in kern pair section" % key)
 
1273
            kernpair = AFMkernpair(name1, name2, x, y)
 
1274
            self.kernpairs[direction][i] = kernpair
 
1275
            if direction:
 
1276
                self.kernpairsdict1[name1, name2] = kernpair
 
1277
            else:
 
1278
                self.kernpairsdict[name1, name2] = kernpair
 
1279
            return _READ_KERNPAIRS, (direction, i+1)
 
1280
 
 
1281
    def _processline_composites(self, line, i):
 
1282
        if line.rstrip() == "EndComposites":
 
1283
            if i < len(self.composites):
 
1284
                raise AFMError("Fewer composite character data sets than expected")
 
1285
            return _READ_MAIN, None
 
1286
        if i >= len(self.composites):
 
1287
            raise AFMError("More composite character data sets than expected")
 
1288
 
 
1289
        name = None
 
1290
        no = None
 
1291
        parts = []
 
1292
        for s in line.split(";"):
 
1293
            s = s.strip()
 
1294
            if not s:
 
1295
               continue
 
1296
            key, args = s.split(None, 1)
 
1297
            if key == "CC":
 
1298
                try:
 
1299
                    name, no = args.split()
 
1300
                except:
 
1301
                    raise AFMError("Expecting name number, got '%s'" % args)
 
1302
                no = _parseint(no)
 
1303
            elif key == "PCC":
 
1304
                try:
 
1305
                    name1, x, y = args.split()
 
1306
                except:
 
1307
                    raise AFMError("Expecting name x y, got '%s'" % args)
 
1308
                parts.append((name1, _parsefloat(x), _parsefloat(y)))
 
1309
            else:
 
1310
                raise AFMError("Unknown key '%s' in composite character data section" % key)
 
1311
        if len(parts) != no:
 
1312
            raise AFMError("Wrong number of composite characters")
 
1313
        return _READ_COMPOSITES, i+1
 
1314
 
 
1315
    def parse(self, f):
 
1316
         # state of the reader, consisting of 
 
1317
         #  - the main state, i.e. the type of the section
 
1318
         #  - a parameter sstate
 
1319
         state = _READ_START, None
 
1320
         # Note that we do a line by line processing here, since one
 
1321
         # of the states (_READ_DIRECTION) can be entered implicitly, i.e.
 
1322
         # without a corresponding StartDirection section and we thus
 
1323
         # may need to reprocess a line in the context of the new state
 
1324
         for line in f:
 
1325
            line = line[:-1]
 
1326
            mstate, sstate = state
 
1327
            if mstate == _READ_START:
 
1328
                state = self._processline_start(line)
 
1329
            else: 
 
1330
                # except for the first line, any empty will be ignored
 
1331
                if not line.strip():
 
1332
                   continue
 
1333
                if mstate == _READ_MAIN:
 
1334
                    state = self._processline_main(line)
 
1335
                elif mstate == _READ_DIRECTION:
 
1336
                    state = self._processline_direction(line, sstate)
 
1337
                elif mstate == _READ_CHARMETRICS:
 
1338
                    state = self._processline_charmetrics(line, sstate)
 
1339
                elif mstate == _READ_KERNDATA:
 
1340
                    state = self._processline_kerndata(line)
 
1341
                elif mstate == _READ_TRACKKERN:
 
1342
                    state = self._processline_trackkern(line, sstate)
 
1343
                elif mstate == _READ_KERNPAIRS:
 
1344
                    state = self._processline_kernpairs(line, sstate)
 
1345
                elif mstate == _READ_COMPOSITES:
 
1346
                    state = self._processline_composites(line, sstate)
 
1347
                else:
 
1348
                    raise AFMError("Undefined state in AFM reader")
 
1349
 
 
1350
    def fucking_scale(self):
 
1351
        # XXX XXX XXX
 
1352
        return 1000.0
 
1353
 
 
1354
    def width_ds(self, glyphname):
 
1355
        return self.charmetricsdict[glyphname].widths[0][0]
 
1356
 
 
1357
    def width_pt(self, glyphnames, size):
 
1358
        return sum([self.charmetricsdict[glyphname].widths[0][0] for glyphname in glyphnames])*size/self.fucking_scale()
 
1359
 
 
1360
    def height_pt(self, glyphnames, size):
 
1361
        return max([self.charmetricsdict[glyphname].bbox[3] for glyphname in glyphnames])*size/self.fucking_scale()
 
1362
 
 
1363
    def depth_pt(self, glyphnames, size):
 
1364
        return min([self.charmetricsdict[glyphname].bbox[1] for glyphname in glyphnames])*size/self.fucking_scale()
 
1365
 
 
1366
    def resolveligatures(self, glyphnames):
 
1367
        i = 1
 
1368
        while i < len(glyphnames):
 
1369
            for glyphname, replacement in self.charmetricsdict[glyphnames[i-1]].ligatures:
 
1370
                if glyphname == glyphnames[i]:
 
1371
                    glyphnames[i-1] = replacement
 
1372
                    del glyphnames[i]
 
1373
                    break
 
1374
            else:
 
1375
                i += 1
 
1376
        return glyphnames
 
1377
 
 
1378
    def resolvekernings(self, glyphnames, size=None):
 
1379
        result = [None]*(2*len(glyphnames)-1)
 
1380
        for i, glyphname in enumerate(glyphnames):
 
1381
            result[2*i] = glyphname
 
1382
            if i:
 
1383
                kernpair = self.kernpairsdict.get((glyphnames[i-1], glyphname))
 
1384
                if kernpair:
 
1385
                    if size is not None:
 
1386
                        result[2*i-1] = kernpair.x*size/self.fucking_scale()
 
1387
                    else:
 
1388
                        result[2*i-1] = kernpair.x
 
1389
        return result
 
1390
 
 
1391
    def writePDFfontinfo(self, file, seriffont=False, symbolfont=True):
 
1392
        flags = 0
 
1393
        if self.isfixedpitchs[0]:
 
1394
            flags += 1<<0
 
1395
        if seriffont:
 
1396
            flags += 1<<1
 
1397
        if symbolfont:
 
1398
            flags += 1<<2
 
1399
        else:
 
1400
            flags += 1<<5
 
1401
        if self.italicangles[0]:
 
1402
            flags += 1<<6
 
1403
        file.write("/Flags %d\n" % flags)
 
1404
        if self.italicangles[0] is not None:
 
1405
            file.write("/ItalicAngles %d\n" % self.italicangles[0])
 
1406
        if self.ascender is not None:
 
1407
            ascent = self.ascender
 
1408
        elif self.fontbbox is not None:
 
1409
            ascent = self.fontbbox[3]
 
1410
        else:
 
1411
            ascent = 1000 # guessed default
 
1412
        file.write("/Ascent %d\n" % ascent)
 
1413
        if self.descender is not None:
 
1414
            descent = self.descender
 
1415
        elif self.fontbbox is not None:
 
1416
            descent = self.fontbbox[3]
 
1417
        else:
 
1418
            descent = -200 # guessed default
 
1419
        file.write("/Descent %d\n" % descent)
 
1420
        if self.fontbbox is not None:
 
1421
            file.write("/FontBBox [%d %d %d %d]\n" % tuple(self.fontbbox))
 
1422
        else:
 
1423
            # the fontbbox is required, so we have to have to provide some default
 
1424
            file.write("/FontBBox [0 %d 1000 %d]\n" % (descent, ascent))
 
1425
        if self.capheight is not None:
 
1426
            file.write("/CapHeight %d\n" % self.capheight)
 
1427
        else:
 
1428
            # the CapHeight is required, so we have to have to provide some default
 
1429
            file.write("/CapHeight %d\n" % ascent)
 
1430
        if self.stdvw is not None:
 
1431
            stemv = self.stdvw
 
1432
        elif self.weight is not None and ("bold" in self.weight.lower() or "black" in self.weight.lower()):
 
1433
            stemv = 120 # guessed default
 
1434
        else:
 
1435
            stemv = 70 # guessed default
 
1436
        file.write("/StemV %d\n" % stemv)
 
1437
 
 
1438
 
 
1439
if __name__ == "__main__":
 
1440
    a = AFMfile("/opt/local/share/texmf-dist/fonts/afm/yandy/lucida/lbc.afm")
 
1441
    print a.charmetrics[0].name
 
1442
    a = AFMfile("/usr/share/enscript/hv.afm")
 
1443
    print a.charmetrics[32].name