001: /*
002: * $Id: Pfm2afm.java 2700 2007-04-19 14:11:50Z blowagie $
003: *
004: * Copyright 2005-2007 Paulo Soares
005: *
006: * The contents of this file are subject to the Mozilla Public License Version 1.1
007: * (the "License"); you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
009: *
010: * Software distributed under the License is distributed on an "AS IS" basis,
011: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
012: * for the specific language governing rights and limitations under the License.
013: *
014: * The Original Code is 'iText, a free JAVA-PDF library'.
015: *
016: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
017: * the Initial Developer are Copyright (C) 1999-2007 by Bruno Lowagie.
018: * All Rights Reserved.
019: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
020: * are Copyright (C) 2000-2007 by Paulo Soares. All Rights Reserved.
021: *
022: * Contributor(s): all the names of the contributors are added in the source code
023: * where applicable.
024: *
025: * Alternatively, the contents of this file may be used under the terms of the
026: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
027: * provisions of LGPL are applicable instead of those above. If you wish to
028: * allow use of your version of this file only under the terms of the LGPL
029: * License and not to allow others to use your version of this file under
030: * the MPL, indicate your decision by deleting the provisions above and
031: * replace them with the notice and other provisions required by the LGPL.
032: * If you do not delete the provisions above, a recipient may use your version
033: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
034: *
035: * This library is free software; you can redistribute it and/or modify it
036: * under the terms of the MPL as stated above or under the terms of the GNU
037: * Library General Public License as published by the Free Software Foundation;
038: * either version 2 of the License, or any later version.
039: *
040: * This library is distributed in the hope that it will be useful, but WITHOUT
041: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
042: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
043: * details.
044: *
045: * If you didn't download this code from the following link, you should check if
046: * you aren't using an obsolete version:
047: * http://www.lowagie.com/iText/
048: */
049: /********************************************************************
050: * *
051: * Title: pfm2afm - Convert Windows .pfm files to .afm files *
052: * *
053: * Author: Ken Borgendale 10/9/91 Version 1.0 *
054: * *
055: * Function: *
056: * Convert a Windows .pfm (Printer Font Metrics) file to a *
057: * .afm (Adobe Font Metrics) file. The purpose of this is *
058: * to allow fonts put out for Windows to be used with OS/2. *
059: * *
060: * Syntax: *
061: * pfm2afm infile [outfile] -a *
062: * *
063: * Copyright: *
064: * pfm2afm - Copyright (C) IBM Corp., 1991 *
065: * *
066: * This code is released for public use as long as the *
067: * copyright remains intact. This code is provided asis *
068: * without any warrenties, express or implied. *
069: * *
070: * Notes: *
071: * 1. Much of the information in the original .afm file is *
072: * lost when the .pfm file is created, and thus cannot be *
073: * reconstructed by this utility. This is especially true *
074: * of data for characters not in the Windows character set. *
075: * *
076: * 2. This module is coded to be compiled by the MSC 6.0. *
077: * For other compilers, be careful of the packing of the *
078: * PFM structure. *
079: * *
080: ********************************************************************/
081:
082: /********************************************************************
083: * *
084: * Modifications by Rod Smith, 5/22/96 *
085: * *
086: * These changes look for the strings "italic", "bold", "black", *
087: * and "light" in the font's name and set the weight accordingly *
088: * and adds an ItalicAngle line with a value of "0" or "-12.00". *
089: * This allows OS/2 programs such as DeScribe to handle the bold *
090: * and italic attributes appropriately, which was not the case *
091: * when I used the original version on fonts from the KeyFonts *
092: * Pro 2002 font CD. *
093: * *
094: * I've also increased the size of the buffer used to load the *
095: * .PFM file; the old size was inadequate for most of the fonts *
096: * from the SoftKey collection. *
097: * *
098: * Compiled with Watcom C 10.6 *
099: * *
100: ********************************************************************/
101:
102: /********************************************************************
103: * *
104: * Further modifications, 4/21/98, by Rod Smith *
105: * *
106: * Minor changes to get the program to compile with gcc under *
107: * Linux (Red Hat 5.0, to be precise). I had to add an itoa *
108: * function from the net (the function was buggy, so I had to fix *
109: * it, too!). I also made the program more friendly towards *
110: * files with mixed-case filenames. *
111: * *
112: ********************************************************************/
113:
114: /********************************************************************
115: * *
116: * 1/31/2005, by Paulo Soares *
117: * *
118: * This code was integrated into iText. *
119: * Note that the itoa function mentioned in the comment by Rod *
120: * Smith is no longer in the code because Java has native support *
121: * in PrintWriter to convert integers to strings *
122: * *
123: ********************************************************************/
124:
125: /********************************************************************
126: * *
127: * 7/16/2005, by Bruno Lowagie *
128: * *
129: * I solved an Eclipse Warning. *
130: * *
131: ********************************************************************/
132:
133: /********************************************************************
134: * *
135: * 9/14/2006, by Xavier Le Vourch *
136: * *
137: * expand import clauses (import java.io.*) *
138: * the removal of an exception in readString was restored on 9/16 *
139: * *
140: ********************************************************************/package com.lowagie.text.pdf;
141:
142: import java.io.FileOutputStream;
143: import java.io.IOException;
144: import java.io.OutputStream;
145: import java.io.OutputStreamWriter;
146: import java.io.PrintWriter;
147:
148: /**
149: * Converts a PFM file into an AFM file.
150: */
151: public class Pfm2afm {
152: private RandomAccessFileOrArray in;
153: private PrintWriter out;
154:
155: /** Creates a new instance of Pfm2afm */
156: private Pfm2afm(RandomAccessFileOrArray in, OutputStream out)
157: throws IOException {
158: this .in = in;
159: this .out = new PrintWriter(new OutputStreamWriter(out,
160: "ISO-8859-1"));
161: }
162:
163: /**
164: * Converts a PFM file into an AFM file.
165: * @param in the PFM file
166: * @param out the AFM file
167: * @throws IOException on error
168: */
169: public static void convert(RandomAccessFileOrArray in,
170: OutputStream out) throws IOException {
171: Pfm2afm p = new Pfm2afm(in, out);
172: p.openpfm();
173: p.putheader();
174: p.putchartab();
175: p.putkerntab();
176: p.puttrailer();
177: p.out.flush();
178: }
179:
180: public static void main(String[] args) {
181: try {
182: RandomAccessFileOrArray in = new RandomAccessFileOrArray(
183: args[0]);
184: OutputStream out = new FileOutputStream(args[1]);
185: convert(in, out);
186: in.close();
187: out.close();
188: } catch (Exception e) {
189: e.printStackTrace();
190: }
191: }
192:
193: private String readString(int n) throws IOException {
194: byte b[] = new byte[n];
195: in.readFully(b);
196: int k;
197: for (k = 0; k < b.length; ++k) {
198: if (b[k] == 0)
199: break;
200: }
201: return new String(b, 0, k, "ISO-8859-1");
202: }
203:
204: private String readString() throws IOException {
205: StringBuffer buf = new StringBuffer();
206: while (true) {
207: int c = in.read();
208: if (c <= 0)
209: break;
210: buf.append((char) c);
211: }
212: return buf.toString();
213: }
214:
215: private void outval(int n) {
216: out.print(' ');
217: out.print(n);
218: }
219:
220: /*
221: * Output a character entry
222: */
223: private void outchar(int code, int width, String name) {
224: out.print("C ");
225: outval(code);
226: out.print(" ; WX ");
227: outval(width);
228: if (name != null) {
229: out.print(" ; N ");
230: out.print(name);
231: }
232: out.print(" ;\n");
233: }
234:
235: private void openpfm() throws IOException {
236: in.seek(0);
237: vers = in.readShortLE();
238: h_len = in.readIntLE();
239: copyright = readString(60);
240: type = in.readShortLE();
241: points = in.readShortLE();
242: verres = in.readShortLE();
243: horres = in.readShortLE();
244: ascent = in.readShortLE();
245: intleading = in.readShortLE();
246: extleading = in.readShortLE();
247: italic = (byte) in.read();
248: uline = (byte) in.read();
249: overs = (byte) in.read();
250: weight = in.readShortLE();
251: charset = (byte) in.read();
252: pixwidth = in.readShortLE();
253: pixheight = in.readShortLE();
254: kind = (byte) in.read();
255: avgwidth = in.readShortLE();
256: maxwidth = in.readShortLE();
257: firstchar = in.read();
258: lastchar = in.read();
259: defchar = (byte) in.read();
260: brkchar = (byte) in.read();
261: widthby = in.readShortLE();
262: device = in.readIntLE();
263: face = in.readIntLE();
264: bits = in.readIntLE();
265: bitoff = in.readIntLE();
266: extlen = in.readShortLE();
267: psext = in.readIntLE();
268: chartab = in.readIntLE();
269: res1 = in.readIntLE();
270: kernpairs = in.readIntLE();
271: res2 = in.readIntLE();
272: fontname = in.readIntLE();
273: if (h_len != in.length() || extlen != 30 || fontname < 75
274: || fontname > 512)
275: throw new IOException("Not a valid PFM file.");
276: in.seek(psext + 14);
277: capheight = in.readShortLE();
278: xheight = in.readShortLE();
279: ascender = in.readShortLE();
280: descender = in.readShortLE();
281: }
282:
283: private void putheader() throws IOException {
284: out.print("StartFontMetrics 2.0\n");
285: if (copyright.length() > 0)
286: out.print("Comment " + copyright + '\n');
287: out.print("FontName ");
288: in.seek(fontname);
289: String fname = readString();
290: out.print(fname);
291: out.print("\nEncodingScheme ");
292: if (charset != 0)
293: out.print("FontSpecific\n");
294: else
295: out.print("AdobeStandardEncoding\n");
296: /*
297: * The .pfm is missing full name, so construct from font name by
298: * changing the hyphen to a space. This actually works in a lot
299: * of cases.
300: */
301: out.print("FullName " + fname.replace('-', ' '));
302: if (face != 0) {
303: in.seek(face);
304: out.print("\nFamilyName " + readString());
305: }
306:
307: out.print("\nWeight ");
308: if (weight > 475 || fname.toLowerCase().indexOf("bold") >= 0)
309: out.print("Bold");
310: else if ((weight < 325 && weight != 0)
311: || fname.toLowerCase().indexOf("light") >= 0)
312: out.print("Light");
313: else if (fname.toLowerCase().indexOf("black") >= 0)
314: out.print("Black");
315: else
316: out.print("Medium");
317:
318: out.print("\nItalicAngle ");
319: if (italic != 0 || fname.toLowerCase().indexOf("italic") >= 0)
320: out.print("-12.00");
321: /* this is a typical value; something else may work better for a
322: specific font */
323: else
324: out.print("0");
325:
326: /*
327: * The mono flag in the pfm actually indicates whether there is a
328: * table of font widths, not if they are all the same.
329: */
330: out.print("\nIsFixedPitch ");
331: if ((kind & 1) == 0 || /* Flag for mono */
332: avgwidth == maxwidth) { /* Avg width = max width */
333: out.print("true");
334: isMono = true;
335: } else {
336: out.print("false");
337: isMono = false;
338: }
339:
340: /*
341: * The font bounding box is lost, but try to reconstruct it.
342: * Much of this is just guess work. The bounding box is required in
343: * the .afm, but is not used by the PM font installer.
344: */
345: out.print("\nFontBBox");
346: if (isMono)
347: outval(-20); /* Just guess at left bounds */
348: else
349: outval(-100);
350: outval(-(descender + 5)); /* Descender is given as positive value */
351: outval(maxwidth + 10);
352: outval(ascent + 5);
353:
354: /*
355: * Give other metrics that were kept
356: */
357: out.print("\nCapHeight");
358: outval(capheight);
359: out.print("\nXHeight");
360: outval(xheight);
361: out.print("\nDescender");
362: outval(descender);
363: out.print("\nAscender");
364: outval(ascender);
365: out.print('\n');
366: }
367:
368: private void putchartab() throws IOException {
369: int count = lastchar - firstchar + 1;
370: int ctabs[] = new int[count];
371: in.seek(chartab);
372: for (int k = 0; k < count; ++k)
373: ctabs[k] = in.readUnsignedShortLE();
374: int back[] = new int[256];
375: if (charset == 0) {
376: for (int i = firstchar; i <= lastchar; ++i) {
377: if (Win2PSStd[i] != 0)
378: back[Win2PSStd[i]] = i;
379: }
380: }
381: /* Put out the header */
382: out.print("StartCharMetrics");
383: outval(count);
384: out.print('\n');
385:
386: /* Put out all encoded chars */
387: if (charset != 0) {
388: /*
389: * If the charset is not the Windows standard, just put out
390: * unnamed entries.
391: */
392: for (int i = firstchar; i <= lastchar; i++) {
393: if (ctabs[i - firstchar] != 0) {
394: outchar(i, ctabs[i - firstchar], null);
395: }
396: }
397: } else {
398: for (int i = 0; i < 256; i++) {
399: int j = back[i];
400: if (j != 0) {
401: outchar(i, ctabs[j - firstchar], WinChars[j]);
402: ctabs[j - firstchar] = 0;
403: }
404: }
405: /* Put out all non-encoded chars */
406: for (int i = firstchar; i <= lastchar; i++) {
407: if (ctabs[i - firstchar] != 0) {
408: outchar(-1, ctabs[i - firstchar], WinChars[i]);
409: }
410: }
411: }
412: /* Put out the trailer */
413: out.print("EndCharMetrics\n");
414:
415: }
416:
417: private void putkerntab() throws IOException {
418: if (kernpairs == 0)
419: return;
420: in.seek(kernpairs);
421: int count = in.readUnsignedShortLE();
422: int nzero = 0;
423: int kerns[] = new int[count * 3];
424: for (int k = 0; k < kerns.length;) {
425: kerns[k++] = in.read();
426: kerns[k++] = in.read();
427: if ((kerns[k++] = in.readShortLE()) != 0)
428: ++nzero;
429: }
430: if (nzero == 0)
431: return;
432: out.print("StartKernData\nStartKernPairs");
433: outval(nzero);
434: out.print('\n');
435: for (int k = 0; k < kerns.length; k += 3) {
436: if (kerns[k + 2] != 0) {
437: out.print("KPX ");
438: out.print(WinChars[kerns[k]]);
439: out.print(' ');
440: out.print(WinChars[kerns[k + 1]]);
441: outval(kerns[k + 2]);
442: out.print('\n');
443: }
444: }
445: /* Put out trailer */
446: out.print("EndKernPairs\nEndKernData\n");
447: }
448:
449: private void puttrailer() {
450: out.print("EndFontMetrics\n");
451: }
452:
453: private short vers;
454: private int h_len; /* Total length of .pfm file */
455: private String copyright; /* Copyright string [60]*/
456: private short type;
457: private short points;
458: private short verres;
459: private short horres;
460: private short ascent;
461: private short intleading;
462: private short extleading;
463: private byte italic;
464: private byte uline;
465: private byte overs;
466: private short weight;
467: private byte charset; /* 0=windows, otherwise nomap */
468: private short pixwidth; /* Width for mono fonts */
469: private short pixheight;
470: private byte kind; /* Lower bit off in mono */
471: private short avgwidth; /* Mono if avg=max width */
472: private short maxwidth; /* Use to compute bounding box */
473: private int firstchar; /* First char in table */
474: private int lastchar; /* Last char in table */
475: private byte defchar;
476: private byte brkchar;
477: private short widthby;
478: private int device;
479: private int face; /* Face name */
480: private int bits;
481: private int bitoff;
482: private short extlen;
483: private int psext; /* PostScript extension */
484: private int chartab; /* Character width tables */
485: private int res1;
486: private int kernpairs; /* Kerning pairs */
487: private int res2;
488: private int fontname; /* Font name */
489:
490: /*
491: * Some metrics from the PostScript extension
492: */
493: private short capheight; /* Cap height */
494: private short xheight; /* X height */
495: private short ascender; /* Ascender */
496: private short descender; /* Descender (positive) */
497:
498: private boolean isMono;
499: /*
500: * Translate table from 1004 to psstd. 1004 is an extension of the
501: * Windows translate table used in PM.
502: */
503: private int Win2PSStd[] = { 0, 0, 0, 0, 197, 198, 199, 0, 202, 0,
504: 205, 206, 207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
505: 0, 0, 0, 0, 32, 33, 34, 35, 36, 37, 38, 169, 40, 41, 42,
506: 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
507: 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
508: 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
509: 88, 89, 90, 91, 92, 93, 94, 95, 193, 97, 98, 99, 100, 101,
510: 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
511: 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
512: 126, 127, 0, 0, 184, 0, 185, 188, 178, 179, 94, 189, 0,
513: 172, 234, 0, 0, 0, 0, 96, 0, 170, 186, 0, 177, 208, 126, 0,
514: 0, 173, 250, 0, 0, 0, 0, 161, 162, 163, 168, 165, 0, 167,
515: 200, 0, 227, 171, 0, 0, 0, 0, 0, 0, 0, 0, 194, 0, 182, 180,
516: 203, 0, 235, 187, 0, 0, 0, 191, 0, 0, 0, 0, 0, 0, 225, 0,
517: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 0, 0,
518: 0, 0, 0, 0, 251, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 0,
519: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 249, 0, 0, 0, 0, 0, 0, 0 };
520:
521: /*
522: * Character class. This is a minor attempt to overcome the problem that
523: * in the pfm file, all unused characters are given the width of space.
524: */
525: private int WinClass[] = { 0, 0, 0, 0, 2, 2, 2, 0, 2, 0, 2, 2, 2,
526: 0, 0, 0, /* 00 */
527: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 */
528: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20 */
529: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 30 */
530: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40 */
531: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 50 */
532: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60 */
533: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, /* 70 */
534: 0, 0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, /* 80 */
535: 0, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, /* 90 */
536: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* a0 */
537: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* b0 */
538: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* c0 */
539: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* d0 */
540: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e0 */
541: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /* f0 */
542: };
543:
544: /*
545: * Windows chararacter names. Give a name to the usused locations
546: * for when the all flag is specified.
547: */
548: private String WinChars[] = { "W00", /* 00 */
549: "W01", /* 01 */
550: "W02", /* 02 */
551: "W03", /* 03 */
552: "macron", /* 04 */
553: "breve", /* 05 */
554: "dotaccent", /* 06 */
555: "W07", /* 07 */
556: "ring", /* 08 */
557: "W09", /* 09 */
558: "W0a", /* 0a */
559: "W0b", /* 0b */
560: "W0c", /* 0c */
561: "W0d", /* 0d */
562: "W0e", /* 0e */
563: "W0f", /* 0f */
564: "hungarumlaut", /* 10 */
565: "ogonek", /* 11 */
566: "caron", /* 12 */
567: "W13", /* 13 */
568: "W14", /* 14 */
569: "W15", /* 15 */
570: "W16", /* 16 */
571: "W17", /* 17 */
572: "W18", /* 18 */
573: "W19", /* 19 */
574: "W1a", /* 1a */
575: "W1b", /* 1b */
576: "W1c", /* 1c */
577: "W1d", /* 1d */
578: "W1e", /* 1e */
579: "W1f", /* 1f */
580: "space", /* 20 */
581: "exclam", /* 21 */
582: "quotedbl", /* 22 */
583: "numbersign", /* 23 */
584: "dollar", /* 24 */
585: "percent", /* 25 */
586: "ampersand", /* 26 */
587: "quotesingle", /* 27 */
588: "parenleft", /* 28 */
589: "parenright", /* 29 */
590: "asterisk", /* 2A */
591: "plus", /* 2B */
592: "comma", /* 2C */
593: "hyphen", /* 2D */
594: "period", /* 2E */
595: "slash", /* 2F */
596: "zero", /* 30 */
597: "one", /* 31 */
598: "two", /* 32 */
599: "three", /* 33 */
600: "four", /* 34 */
601: "five", /* 35 */
602: "six", /* 36 */
603: "seven", /* 37 */
604: "eight", /* 38 */
605: "nine", /* 39 */
606: "colon", /* 3A */
607: "semicolon", /* 3B */
608: "less", /* 3C */
609: "equal", /* 3D */
610: "greater", /* 3E */
611: "question", /* 3F */
612: "at", /* 40 */
613: "A", /* 41 */
614: "B", /* 42 */
615: "C", /* 43 */
616: "D", /* 44 */
617: "E", /* 45 */
618: "F", /* 46 */
619: "G", /* 47 */
620: "H", /* 48 */
621: "I", /* 49 */
622: "J", /* 4A */
623: "K", /* 4B */
624: "L", /* 4C */
625: "M", /* 4D */
626: "N", /* 4E */
627: "O", /* 4F */
628: "P", /* 50 */
629: "Q", /* 51 */
630: "R", /* 52 */
631: "S", /* 53 */
632: "T", /* 54 */
633: "U", /* 55 */
634: "V", /* 56 */
635: "W", /* 57 */
636: "X", /* 58 */
637: "Y", /* 59 */
638: "Z", /* 5A */
639: "bracketleft", /* 5B */
640: "backslash", /* 5C */
641: "bracketright", /* 5D */
642: "asciicircum", /* 5E */
643: "underscore", /* 5F */
644: "grave", /* 60 */
645: "a", /* 61 */
646: "b", /* 62 */
647: "c", /* 63 */
648: "d", /* 64 */
649: "e", /* 65 */
650: "f", /* 66 */
651: "g", /* 67 */
652: "h", /* 68 */
653: "i", /* 69 */
654: "j", /* 6A */
655: "k", /* 6B */
656: "l", /* 6C */
657: "m", /* 6D */
658: "n", /* 6E */
659: "o", /* 6F */
660: "p", /* 70 */
661: "q", /* 71 */
662: "r", /* 72 */
663: "s", /* 73 */
664: "t", /* 74 */
665: "u", /* 75 */
666: "v", /* 76 */
667: "w", /* 77 */
668: "x", /* 78 */
669: "y", /* 79 */
670: "z", /* 7A */
671: "braceleft", /* 7B */
672: "bar", /* 7C */
673: "braceright", /* 7D */
674: "asciitilde", /* 7E */
675: "W7f", /* 7F */
676: "W80", /* 80 */
677: "W81", /* 81 */
678: "quotesinglbase", /* 82 */
679: "W83", /* 83 */
680: "quotedblbase", /* 84 */
681: "ellipsis", /* 85 */
682: "dagger", /* 86 */
683: "daggerdbl", /* 87 */
684: "asciicircum", /* 88 */
685: "perthousand", /* 89 */
686: "Scaron", /* 8A */
687: "guilsinglleft", /* 8B */
688: "OE", /* 8C */
689: "W8d", /* 8D */
690: "W8e", /* 8E */
691: "W8f", /* 8F */
692: "W90", /* 90 */
693: "quoteleft", /* 91 */
694: "quoteright", /* 92 */
695: "quotedblleft", /* 93 */
696: "quotedblright", /* 94 */
697: "bullet1", /* 95 */
698: "endash", /* 96 */
699: "emdash", /* 97 */
700: "asciitilde", /* 98 */
701: "trademark", /* 99 */
702: "scaron", /* 9A */
703: "guilsinglright", /* 9B */
704: "oe", /* 9C */
705: "W9d", /* 9D */
706: "W9e", /* 9E */
707: "Ydieresis", /* 9F */
708: "reqspace", /* A0 */
709: "exclamdown", /* A1 */
710: "cent", /* A2 */
711: "sterling", /* A3 */
712: "currency", /* A4 */
713: "yen", /* A5 */
714: "brokenbar", /* A6 */
715: "section", /* A7 */
716: "dieresis", /* A8 */
717: "copyright", /* A9 */
718: "ordfeminine", /* AA */
719: "guillemotleft", /* AB */
720: "logicalnot", /* AC */
721: "syllable", /* AD */
722: "registered", /* AE */
723: "overbar", /* AF */
724: "degree", /* B0 */
725: "plusminus", /* B1 */
726: "twosuperior", /* B2 */
727: "threesuperior", /* B3 */
728: "acute", /* B4 */
729: "mu", /* B5 */
730: "paragraph", /* B6 */
731: "periodcentered", /* B7 */
732: "cedilla", /* B8 */
733: "onesuperior", /* B9 */
734: "ordmasculine", /* BA */
735: "guillemotright", /* BB */
736: "onequarter", /* BC */
737: "onehalf", /* BD */
738: "threequarters", /* BE */
739: "questiondown", /* BF */
740: "Agrave", /* C0 */
741: "Aacute", /* C1 */
742: "Acircumflex", /* C2 */
743: "Atilde", /* C3 */
744: "Adieresis", /* C4 */
745: "Aring", /* C5 */
746: "AE", /* C6 */
747: "Ccedilla", /* C7 */
748: "Egrave", /* C8 */
749: "Eacute", /* C9 */
750: "Ecircumflex", /* CA */
751: "Edieresis", /* CB */
752: "Igrave", /* CC */
753: "Iacute", /* CD */
754: "Icircumflex", /* CE */
755: "Idieresis", /* CF */
756: "Eth", /* D0 */
757: "Ntilde", /* D1 */
758: "Ograve", /* D2 */
759: "Oacute", /* D3 */
760: "Ocircumflex", /* D4 */
761: "Otilde", /* D5 */
762: "Odieresis", /* D6 */
763: "multiply", /* D7 */
764: "Oslash", /* D8 */
765: "Ugrave", /* D9 */
766: "Uacute", /* DA */
767: "Ucircumflex", /* DB */
768: "Udieresis", /* DC */
769: "Yacute", /* DD */
770: "Thorn", /* DE */
771: "germandbls", /* DF */
772: "agrave", /* E0 */
773: "aacute", /* E1 */
774: "acircumflex", /* E2 */
775: "atilde", /* E3 */
776: "adieresis", /* E4 */
777: "aring", /* E5 */
778: "ae", /* E6 */
779: "ccedilla", /* E7 */
780: "egrave", /* E8 */
781: "eacute", /* E9 */
782: "ecircumflex", /* EA */
783: "edieresis", /* EB */
784: "igrave", /* EC */
785: "iacute", /* ED */
786: "icircumflex", /* EE */
787: "idieresis", /* EF */
788: "eth", /* F0 */
789: "ntilde", /* F1 */
790: "ograve", /* F2 */
791: "oacute", /* F3 */
792: "ocircumflex", /* F4 */
793: "otilde", /* F5 */
794: "odieresis", /* F6 */
795: "divide", /* F7 */
796: "oslash", /* F8 */
797: "ugrave", /* F9 */
798: "uacute", /* FA */
799: "ucircumflex", /* FB */
800: "udieresis", /* FC */
801: "yacute", /* FD */
802: "thorn", /* FE */
803: "ydieresis" /* FF */
804: };
805: }
|