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