add some changenotes to some recent changes by Michael Schindler
[PyX/mjg.git] / pyx / font / afmfile.py
blobf4e5ca575a77eb0def7d4c5d57301160dbd22f06
1 # -*- encoding: utf-8 -*-
4 # Copyright (C) 2006-2011 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2007-2011 André Wobst <wobsta@users.sourceforge.net>
7 # This file is part of PyX (http://pyx.sourceforge.net/).
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.
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.
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
23 import string
24 import metric
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"}
869 class AFMError(Exception):
870 pass
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
883 # various parsing functions
884 def _parseint(s):
885 try:
886 return int(s)
887 except:
888 raise AFMError("Expecting int, got '%s'" % s)
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)
898 def _parsefloat(s):
899 try:
900 return float(s)
901 except:
902 raise AFMError("Expecting float, got '%s'" % s)
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
914 def _parsestr(s):
915 # XXX: check for invalid characters in s
916 return s
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)
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
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
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
961 class AFMcomposite:
962 def __init__(self, name, parts):
963 self.name = name
964 self.parts = parts
967 class AFMfile(metric.metric):
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
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, 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")
1350 def fucking_scale(self):
1351 # XXX XXX XXX
1352 return 1000.0
1354 def width_ds(self, glyphname):
1355 return self.charmetricsdict[glyphname].widths[0][0]
1357 def width_pt(self, glyphnames, size):
1358 return sum([self.charmetricsdict[glyphname].widths[0][0] for glyphname in glyphnames])*size/self.fucking_scale()
1360 def height_pt(self, glyphnames, size):
1361 return max([self.charmetricsdict[glyphname].bbox[3] for glyphname in glyphnames])*size/self.fucking_scale()
1363 def depth_pt(self, glyphnames, size):
1364 return min([self.charmetricsdict[glyphname].bbox[1] for glyphname in glyphnames])*size/self.fucking_scale()
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
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
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)
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