Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: gnu/java/awt/font/opentype/GlyphNamer.java


1   /* GlyphNamer.java -- Provides glyph names.
2      Copyright (C) 2006 Free Software Foundation, Inc.
3   
4   This file is part of GNU Classpath.
5   
6   GNU Classpath is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10  
11  GNU Classpath is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  General Public License for more details.
15  
16  You should have received a copy of the GNU General Public License
17  along with GNU Classpath; see the file COPYING.  If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301 USA.
20  
21  Linking this library statically or dynamically with other modules is
22  making a combined work based on this library.  Thus, the terms and
23  conditions of the GNU General Public License cover the whole
24  combination.
25  
26  As a special exception, the copyright holders of this library give you
27  permission to link this library with independent modules to produce an
28  executable, regardless of the license terms of these independent
29  modules, and to copy and distribute the resulting executable under
30  terms of your choice, provided that you also meet, for each linked
31  independent module, the terms and conditions of the license of that
32  module.  An independent module is a module which is not derived from
33  or based on this library.  If you modify this library, you may extend
34  this exception to your version of the library, but you are not
35  obligated to do so.  If you do not wish to do so, delete this
36  exception statement from your version. */
37  
38  package gnu.java.awt.font.opentype;
39  
40  import java.nio.ByteBuffer;
41  import java.nio.IntBuffer;
42  import java.nio.CharBuffer;
43  
44  
45  /**
46   * Provides names for glyphs, which is useful when embedding fonts
47   * in PostScript or PDF documents.
48   *
49   * <p>If the font has a <code>Zapf</code> table, it is used to map
50   * glyph IDs back to a sequence of Unicode codepoints, which then
51   * makes it possible to look up or synthesize a PostScript glyph name
52   * according to Adobe&#x2019;s conventions. This allows to extract the
53   * original text from the generated PDF or PostScript file, which is
54   * important for indexing, searching and extracting.
55   *
56   * <p>Otherwise, glyph names are taken from the <a href=
57   * "http://developer.apple.com/fonts/TTRefMan/RM06/Chap6post.html"
58   * ><code>post</code> table</a>. All known formats (1, 2, 2.5, 3 and
59   * 4) are supported.
60   *
61   * <p><b>Open Tasks:</b> The code could be cleaner structured by
62   * having separate sub-classes for each variant of the POST table.
63   * Also, the implementation should not read in all glyph names if a
64   * font provides them in a POST table of type 2. It would be
65   * sufficient to just read in the offsets and delay the String
66   * fetching and conversion to the time when the glyph name is actually
67   * requested.
68   *
69   * <p><b>Lack of Thread Safety:</b> The GlyphNamer class is
70   * intentionally <i>not</i> safe to access from multiple concurrent
71   * threads. Synchronization needs to be performed externally. Usually,
72   * the font has already obtained a lock before calling the GlyphNamer.
73   * It would thus be wasteful to acquire additional locks for the
74   * GlyphNamer.
75   *
76   * @author Sascha Brawer (brawer@dandelis.ch)
77   */
78  final class GlyphNamer
79  {
80    /**
81     * The 'post' table of the font.
82     */
83    private ByteBuffer postTable;
84  
85  
86    /**
87     * The 'Zapf' table of the font, or null if the font has no
88     * such table.
89     */
90    private ByteBuffer zapfTable;
91  
92  
93    /**
94     * The offset of each glyph relative to the Zapf table,
95     * or null if the font does not have a Zapf table.
96     */
97    private IntBuffer zapfOffsets;
98  
99  
100   /**
101    * The offset from the start of the Zapf table to the start
102    * of the extra info area.
103    */
104   private int zapfExtraInfo;
105 
106 
107   /**
108    * The format of the post table, a Fixed 16.16 number.
109    */
110   private int postFormat;
111 
112 
113   /**
114    * An array of glyph names. Used for table formats 1, 2, 2.5.
115    */
116   private String[] glyphNames;
117 
118 
119   /**
120    * An array from glyph to character codes. Similar to the
121    * workings of a Zapf table, but maps to CID instead of
122    * Unicode. Used for table format 4.
123    */
124   private CharBuffer glyphCharacterCodes;
125 
126 
127   /**
128    * The PostScript names of the 258 standard Macintosh glyphs.  Note
129    * that some of these glyphs are not in the Adobe Standard Glyph
130    * List for New Fonts, namely .notdef, .null, nonmarkingreturn,
131    * nonbreakingspace, apple, onesuperior, twosuperior, and
132    * threesuperior.
133    */
134   private static final String[] STANDARD_POSTSCRIPT_GLYPH_NAMES =
135   {
136     ".notdef",               // glyph #0
137     ".null",                 // glyph #1
138     "nonmarkingreturn",      // glyph #2
139     "space",                 // glyph #3
140     "exclam",                // glyph #4
141     "quotedbl",              // glyph #5
142     "numbersign",            // glyph #6
143     "dollar",                // glyph #7
144     "percent",               // glyph #8
145     "ampersand",             // glyph #9
146     "quotesingle",           // glyph #10
147     "parenleft",             // glyph #11
148     "parenright",            // glyph #12
149     "asterisk",              // glyph #13
150     "plus",                  // glyph #14
151     "comma",                 // glyph #15
152     "hyphen",                // glyph #16
153     "period",                // glyph #17
154     "slash",                 // glyph #18
155     "zero",                  // glyph #19
156     "one",                   // glyph #20
157     "two",                   // glyph #21
158     "three",                 // glyph #22
159     "four",                  // glyph #23
160     "five",                  // glyph #24
161     "six",                   // glyph #25
162     "seven",                 // glyph #26
163     "eight",                 // glyph #27
164     "nine",                  // glyph #28
165     "colon",                 // glyph #29
166     "semicolon",             // glyph #30
167     "less",                  // glyph #31
168     "equal",                 // glyph #32
169     "greater",               // glyph #33
170     "question",              // glyph #34
171     "at",                    // glyph #35
172     "A",                     // glyph #36
173     "B",                     // glyph #37
174     "C",                     // glyph #38
175     "D",                     // glyph #39
176     "E",                     // glyph #40
177     "F",                     // glyph #41
178     "G",                     // glyph #42
179     "H",                     // glyph #43
180     "I",                     // glyph #44
181     "J",                     // glyph #45
182     "K",                     // glyph #46
183     "L",                     // glyph #47
184     "M",                     // glyph #48
185     "N",                     // glyph #49
186     "O",                     // glyph #50
187     "P",                     // glyph #51
188     "Q",                     // glyph #52
189     "R",                     // glyph #53
190     "S",                     // glyph #54
191     "T",                     // glyph #55
192     "U",                     // glyph #56
193     "V",                     // glyph #57
194     "W",                     // glyph #58
195     "X",                     // glyph #59
196     "Y",                     // glyph #60
197     "Z",                     // glyph #61
198     "bracketleft",           // glyph #62
199     "backslash",             // glyph #63
200     "bracketright",          // glyph #64
201     "asciicircum",           // glyph #65
202     "underscore",            // glyph #66
203     "grave",                 // glyph #67
204     "a",                     // glyph #68
205     "b",                     // glyph #69
206     "c",                     // glyph #70
207     "d",                     // glyph #71
208     "e",                     // glyph #72
209     "f",                     // glyph #73
210     "g",                     // glyph #74
211     "h",                     // glyph #75
212     "i",                     // glyph #76
213     "j",                     // glyph #77
214     "k",                     // glyph #78
215     "l",                     // glyph #79
216     "m",                     // glyph #80
217     "n",                     // glyph #81
218     "o",                     // glyph #82
219     "p",                     // glyph #83
220     "q",                     // glyph #84
221     "r",                     // glyph #85
222     "s",                     // glyph #86
223     "t",                     // glyph #87
224     "u",                     // glyph #88
225     "v",                     // glyph #89
226     "w",                     // glyph #90
227     "x",                     // glyph #91
228     "y",                     // glyph #92
229     "z",                     // glyph #93
230     "braceleft",             // glyph #94
231     "bar",                   // glyph #95
232     "braceright",            // glyph #96
233     "asciitilde",            // glyph #97
234     "Adieresis",             // glyph #98
235     "Aring",                 // glyph #99
236     "Ccedilla",              // glyph #100
237     "Eacute",                // glyph #101
238     "Ntilde",                // glyph #102
239     "Odieresis",             // glyph #103
240     "Udieresis",             // glyph #104
241     "aacute",                // glyph #105
242     "agrave",                // glyph #106
243     "acircumflex",           // glyph #107
244     "adieresis",             // glyph #108
245     "atilde",                // glyph #109
246     "aring",                 // glyph #110
247     "ccedilla",              // glyph #111
248     "eacute",                // glyph #112
249     "egrave",                // glyph #113
250     "ecircumflex",           // glyph #114
251     "edieresis",             // glyph #115
252     "iacute",                // glyph #116
253     "igrave",                // glyph #117
254     "icircumflex",           // glyph #118
255     "idieresis",             // glyph #119
256     "ntilde",                // glyph #120
257     "oacute",                // glyph #121
258     "ograve",                // glyph #122
259     "ocircumflex",           // glyph #123
260     "odieresis",             // glyph #124
261     "otilde",                // glyph #125
262     "uacute",                // glyph #126
263     "ugrave",                // glyph #127
264     "ucircumflex",           // glyph #128
265     "udieresis",             // glyph #129
266     "dagger",                // glyph #130
267     "degree",                // glyph #131
268     "cent",                  // glyph #132
269     "sterling",              // glyph #133
270     "section",               // glyph #134
271     "bullet",                // glyph #135
272     "paragraph",             // glyph #136
273     "germandbls",            // glyph #137
274     "registered",            // glyph #138
275     "copyright",             // glyph #139
276     "trademark",             // glyph #140
277     "acute",                 // glyph #141
278     "dieresis",              // glyph #142
279     "notequal",              // glyph #143
280     "AE",                    // glyph #144
281     "Oslash",                // glyph #145
282     "infinity",              // glyph #146
283     "plusminus",             // glyph #147
284     "lessequal",             // glyph #148
285     "greaterequal",          // glyph #149
286     "yen",                   // glyph #150
287     "mu",                    // glyph #151
288     "partialdiff",           // glyph #152
289     "summation",             // glyph #153
290     "product",               // glyph #154
291     "pi",                    // glyph #155
292     "integral",              // glyph #156
293     "ordfeminine",           // glyph #157
294     "ordmasculine",          // glyph #158
295     "Omega",                 // glyph #159
296     "ae",                    // glyph #160
297     "oslash",                // glyph #161
298     "questiondown",          // glyph #162
299     "exclamdown",            // glyph #163
300     "logicalnot",            // glyph #164
301     "radical",               // glyph #165
302     "florin",                // glyph #166
303     "approxequal",           // glyph #167
304     "Delta",                 // glyph #168
305     "guillemotleft",         // glyph #169
306     "guillemotright",        // glyph #170
307     "ellipsis",              // glyph #171
308     "nonbreakingspace",      // glyph #172
309     "Agrave",                // glyph #173
310     "Atilde",                // glyph #174
311     "Otilde",                // glyph #175
312     "OE",                    // glyph #176
313     "oe",                    // glyph #177
314     "endash",                // glyph #178
315     "emdash",                // glyph #179
316     "quotedblleft",          // glyph #180
317     "quotedblright",         // glyph #181
318     "quoteleft",             // glyph #182
319     "quoteright",            // glyph #183
320     "divide",                // glyph #184
321     "lozenge",               // glyph #185
322     "ydieresis",             // glyph #186
323     "Ydieresis",             // glyph #187
324     "fraction",              // glyph #188
325     "currency",              // glyph #189
326     "guilsinglleft",         // glyph #190
327     "guilsinglright",        // glyph #191
328     "fi",                    // glyph #192
329     "fl",                    // glyph #193
330     "daggerdbl",             // glyph #194
331     "periodcentered",        // glyph #195
332     "quotesinglbase",        // glyph #196
333     "quotedblbase",          // glyph #197
334     "perthousand",           // glyph #198
335     "Acircumflex",           // glyph #199
336     "Ecircumflex",           // glyph #200
337     "Aacute",                // glyph #201
338     "Edieresis",             // glyph #202
339     "Egrave",                // glyph #203
340     "Iacute",                // glyph #204
341     "Icircumflex",           // glyph #205
342     "Idieresis",             // glyph #206
343     "Igrave",                // glyph #207
344     "Oacute",                // glyph #208
345     "Ocircumflex",           // glyph #209
346     "apple",                 // glyph #210
347     "Ograve",                // glyph #211
348     "Uacute",                // glyph #212
349     "Ucircumflex",           // glyph #213
350     "Ugrave",                // glyph #214
351     "dotlessi",              // glyph #215
352     "circumflex",            // glyph #216
353     "tilde",                 // glyph #217
354     "macron",                // glyph #218
355     "breve",                 // glyph #219
356     "dotaccent",             // glyph #220
357     "ring",                  // glyph #221
358     "cedilla",               // glyph #222
359     "hungarumlaut",          // glyph #223
360     "ogonek",                // glyph #224
361     "caron",                 // glyph #225
362     "Lslash",                // glyph #226
363     "lslash",                // glyph #227
364     "Scaron",                // glyph #228
365     "scaron",                // glyph #229
366     "Zcaron",                // glyph #230
367     "zcaron",                // glyph #231
368     "brokenbar",             // glyph #232
369     "Eth",                   // glyph #233
370     "eth",                   // glyph #234
371     "Yacute",                // glyph #235
372     "yacute",                // glyph #236
373     "Thorn",                 // glyph #237
374     "thorn",                 // glyph #238
375     "minus",                 // glyph #239
376     "multiply",              // glyph #240
377     "onesuperior",           // glyph #241
378     "twosuperior",           // glyph #242
379     "threesuperior",         // glyph #243
380     "onehalf",               // glyph #244
381     "onequarter",            // glyph #245
382     "threequarters",         // glyph #246
383     "franc",                 // glyph #247
384     "Gbreve",                // glyph #248
385     "gbreve",                // glyph #249
386     "Idotaccent",            // glyph #250
387     "Scedilla",              // glyph #251
388     "scedilla",              // glyph #252
389     "Cacute",                // glyph #253
390     "cacute",                // glyph #254
391     "Ccaron",                // glyph #255
392     "ccaron",                // glyph #256
393     "dcroat"                 // glyph #257
394   };
395 
396 
397   private GlyphNamer(int numGlyphs,
398                      ByteBuffer postTable,
399                      ByteBuffer zapfTable)
400   {
401     this.postTable = postTable;
402     this.zapfTable = zapfTable;
403 
404     if ((zapfTable != null) && (zapfTable.getInt(0) == 0x00010000))
405     {
406       readZapf(numGlyphs);
407       return;
408     }
409 
410     readPost();
411   }
412   
413 
414   /**
415    * Sets up the information which allows to retrieve the information
416    * on demand.
417    *
418    * @param numGlyphs the number of glyphs in the font. This value
419    * comes from the <code>maxp</code> table.
420    */
421   public static GlyphNamer forTables(int numGlyphs,
422                                      ByteBuffer postTable,
423                                      ByteBuffer zapfTable)
424   {
425     return new GlyphNamer(numGlyphs, postTable, zapfTable);
426   }
427 
428 
429   /**
430    * Retrieves or synthesizes a PostScript name for the glyph.
431    * Although the code is reasonably fast, it is recommended
432    * to cache the results in the printer driver.
433    *
434    * <p>If a font provides a 'Zapf' table, the reverse mapping
435    * from glyph to UTF-16 sequence is performed, and a glyph
436    * name is synthesized following the recommendations by Adobe.
437    * This allows to extract the original text from the generated
438    * PostScript or PDF, which is a requirement for indexing
439    * and searching.
440    *
441    * <p>If a font does not provide a 'Zapf' table, the glyph name
442    * is taken from the 'post' table. Note that some fonts have
443    * wrong data in their post data, in which case the resulting
444    * name will be garbage. Usually, this does not hurt, unless
445    * the user wants to extract text from the generated PostScript
446    * or PDF file. The GNU implementation understands all known
447    * formats of the post table (1, 2, 2.5, 3 and 4).
448    *
449    * @param glyph the index of the glyph whose name is to be
450    * retrieved.
451    *
452    * @return the glyph name, such as <code>A</code>,
453    * <code>gcircumflex</code>, <code>z_uni0302</code>, or
454    * <code>u11C42</code>.</li>
455    */
456   String getGlyphName(int glyph)
457   {
458     if (zapfOffsets != null)
459     {
460       zapfTable.position(zapfOffsets.get(glyph) + 8);
461       int numChars = zapfTable.getChar();
462       char[] chars = new char[numChars];
463       for (int i = 0; i < numChars; i++)
464         chars[i] = zapfTable.getChar();
465       return getGlyphName(chars);
466     }
467 
468 
469     /* Type 1, Type 2, Type 2.5 */
470     if (glyphNames != null)
471       return glyphNames[glyph];
472 
473     /* Type 4: Synthesized glyph name. */
474     if (glyphCharacterCodes != null)
475       return "a" + glyphCharacterCodes.get(glyph);
476 
477     /* Type 3: Arbitrary, but unique name for the glyph.
478      *
479      * To find out what a good naming scheme would be, we have printed
480      * a document containing the character U+201C in the font
481      * "Hiragino Kaku Gothic Pro W3" (by Dainippon Screen Mfg. Co.,
482      * Ltd.) on Apple MacOS X 10.1.5.  This font has a type 3 'post'
483      * table, and its 'cmap' maps U+201C to glyph #108. The generated
484      * PostScript file defined a character whose name was "g108".
485      *
486      * Therefore, we use 'g' as name prefix. According to the
487      * TrueType/OpenType specification, it should not matter what
488      * prefix we use. On the other hand, it does not hurt either to be
489      * compatible with a good printer driver.
490      *
491      * Actually, that specific font also contains a 'Zapf' table,
492      * which allows to generate glyph names according to Adobe's
493      * conventions, so that extracting text from and searching in the
494      * generated PostScript or PDF becomes possible. While the Apple
495      * PostScript printer driver does not seem to use the 'Zapf' table
496      * for this purpose, we do.
497      */
498     return "g" + glyph;
499   }
500 
501 
502   /**
503    * Sets up some buffers which allow to quickly read information from
504    * the Zapf table.
505    *
506    * @see <a href=
507    *      "http://developer.apple.com/fonts/TTRefMan/RM06/Chap6Zapf.html">
508    *      Apple&#x2019;s documentation of the <code>Zapf</code> table</a>
509    */
510   private void readZapf(int numGlyphs)
511   {
512     zapfExtraInfo = zapfTable.getInt(4);
513     zapfTable.position(8);
514     zapfOffsets = zapfTable.asIntBuffer();
515     zapfOffsets.limit(numGlyphs);
516   }
517 
518 
519   /**
520    * Reads in the PostScript data from a <code>post</code> table of a
521    * TrueType or OpenType font. The implementation currently
522    * understands the table formats 1, 2, 2.5, 3, and 4.
523    */
524   private void readPost()
525   {
526     int numGlyphs, nameIndex, maxNameIndex;
527     char[] nameIndices;
528     String[] names;
529     byte[] pascalName;
530 
531     postTable.position(0);
532     postFormat = postTable.getInt();
533     switch (postFormat)
534     {
535     case 0x00010000:
536       glyphNames = STANDARD_POSTSCRIPT_GLYPH_NAMES;
537       return;
538 
539     case 0x00020000:
540       postTable.position(32);
541       numGlyphs = postTable.getChar();
542       glyphNames = new String[numGlyphs];
543       pascalName = new byte[255];
544       nameIndices = new char[numGlyphs];
545       maxNameIndex = 0;
546       for (int i = 0; i < numGlyphs; i++)
547         maxNameIndex = Math.max(maxNameIndex,
548                                 nameIndices[i] = postTable.getChar());
549 
550       names = new String[Math.max(maxNameIndex - 258 + 1, 0)];
551       for (int i = 258; i <= maxNameIndex; i++)
552       {
553         int nameLen = (postTable.get() & 0xff);
554         postTable.get(pascalName, 0, nameLen);
555         names[i - 258] = new String(pascalName, 0, nameLen);
556       }
557       for (int i = 0; i < numGlyphs; i++)
558       {
559         nameIndex = nameIndices[i];
560         if (nameIndex < 258)
561           glyphNames[i] = STANDARD_POSTSCRIPT_GLYPH_NAMES[nameIndex];
562         else
563           glyphNames[i] = names[nameIndex - 258];
564       }
565       return;
566 
567     case 0x00025000: // in case some font has a wrong representation of 2.5
568     case 0x00028000:
569       /* Format 2.5 is a re-ordering of the standard names. It has
570        * been deprecated in February 2000, but might still occasionally
571        * float around. Since it can be supported with so little code,
572        * we do so.
573        */
574       postTable.position(32);
575       numGlyphs = postTable.getChar();
576       glyphNames = new String[numGlyphs];
577       for (int i = 0; i < numGlyphs; i++)
578         glyphNames[i] = STANDARD_POSTSCRIPT_GLYPH_NAMES[i + postTable.get()];
579       return;
580 
581     case 0x00030000:
582       /* Format 3 leaves it to the printer driver to choose whatever
583        * name it wants to.
584        */
585       return;
586 
587     case 0x00040000:
588       /* Format 4 is used by Apple for composite fonts that have
589        * synthetic glyph names. The name of a glyph is "a" plus
590        * the integer (in decimal notation) that follows the table
591        * after numGlyphs.
592        */
593       postTable.position(32);
594       numGlyphs = postTable.getChar();
595       glyphCharacterCodes = postTable.asCharBuffer();
596       glyphCharacterCodes.limit(numGlyphs);
597       return;
598     }
599   }
600 
601 
602 
603   /* For generating the following tables, a quick-and-dirty Python
604    * script was used. It is unlikely that we ever need to run it
605    * again, but for information and convenient access, it is included
606    * below. Initial '#' characters need to be removed from the generated
607    * strings, they are present so that the lines not break in the middle
608    * of Java escape sequences (no, this is not very clean).
609    *
610    * import string
611    *
612    * javaEscapes = {0x22:'\\"', 0x5c:'\\\\'}
613    * def escape(c):
614    *     if javaEscapes.has_key(c):
615    *         return javaEscapes[c]
616    *     elif 0x20 <= c <= 0x7e:
617    *         return chr(c)
618    *     else:
619    *         return '\\u%04x' % c
620    *
621    * def dump(name, s, stride):
622    *     s = ('#' * stride) + s
623    *     print "  private static final String %s" % name
624    *     for i in range(0, len(s), 60):
625    *         print '    + "%s"' % s[i:i+60]
626    *     
627    * glyphs = {}
628    * for line in open('aglfn13.txt', 'r').readlines():
629    *     if line[0] == '#': continue
630    *     [ucs, glyphName, desc] = line.split(';')
631    *     glyph = int('0x' + ucs, 0)
632    *     assert (not glyphs.has_key(glyph)) or (glyphs[glyph] == glyphName)
633    *     glyphs[glyph] = glyphName
634    * del glyphs[0] # arrowvertex
635    * k = glyphs.keys()
636    * k.sort()
637    * numGlyphs = len(k)
638    * names = ''
639    * pos = []
640    * for glyph in k:
641    *     pos.append(len(names) + 1)
642    *     names = names + '/' + glyphs[glyph]
643    * dump('AGLFN_GLYPHS', string.join(map(escape, k), ''), 5)
644    * dump('AGLFN_NAME_OFFSET', string.join(map(escape, pos), ''), 4)
645    * dump('AGLFN_NAMES', names + '/', 0)
646    */
647 
648 
649   /**
650    * A String that contains the Unicode codepoint for each glyph
651    * in the Adobe Glyph List. The characters are in sorted order.
652    *
653    * Generated from the Adobe Glyph List for New Fonts, version 1.1
654    * of 17 April 2003.
655    *
656    * @see <a href=
657    * "http://partners.adobe.com/asn/tech/type/aglfn13.txt" >Adobe
658    * Glyph List for New Fonts</a>
659    */
660   private static final String AGLFN_GLYPHS
661     = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU"
662     + "VWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u00a1\u00a2\u00a3"
663     + "\u00a4\u00a5\u00a6\u00a7\u00a8\u00a9\u00aa\u00ab\u00ac\u00ae"
664     + "\u00af\u00b0\u00b1\u00b4\u00b5\u00b6\u00b7\u00b8\u00ba\u00bb"
665     + "\u00bc\u00bd\u00be\u00bf\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5"
666     + "\u00c6\u00c7\u00c8\u00c9\u00ca\u00cb\u00cc\u00cd\u00ce\u00cf"
667     + "\u00d0\u00d1\u00d2\u00d3\u00d4\u00d5\u00d6\u00d7\u00d8\u00d9"
668     + "\u00da\u00db\u00dc\u00dd\u00de\u00df\u00e0\u00e1\u00e2\u00e3"
669     + "\u00e4\u00e5\u00e6\u00e7\u00e8\u00e9\u00ea\u00eb\u00ec\u00ed"
670     + "\u00ee\u00ef\u00f0\u00f1\u00f2\u00f3\u00f4\u00f5\u00f6\u00f7"
671     + "\u00f8\u00f9\u00fa\u00fb\u00fc\u00fd\u00fe\u00ff\u0100\u0101"
672     + "\u0102\u0103\u0104\u0105\u0106\u0107\u0108\u0109\u010a\u010b"
673     + "\u010c\u010d\u010e\u010f\u0110\u0111\u0112\u0113\u0114\u0115"
674     + "\u0116\u0117\u0118\u0119\u011a\u011b\u011c\u011d\u011e\u011f"
675     + "\u0120\u0121\u0122\u0123\u0124\u0125\u0126\u0127\u0128\u0129"
676     + "\u012a\u012b\u012c\u012d\u012e\u012f\u0130\u0131\u0132\u0133"
677     + "\u0134\u0135\u0136\u0137\u0138\u0139\u013a\u013b\u013c\u013d"
678     + "\u013e\u013f\u0140\u0141\u0142\u0143\u0144\u0145\u0146\u0147"
679     + "\u0148\u0149\u014a\u014b\u014c\u014d\u014e\u014f\u0150\u0151"
680     + "\u0152\u0153\u0154\u0155\u0156\u0157\u0158\u0159\u015a\u015b"
681     + "\u015c\u015d\u015e\u015f\u0160\u0161\u0162\u0163\u0164\u0165"
682     + "\u0166\u0167\u0168\u0169\u016a\u016b\u016c\u016d\u016e\u016f"
683     + "\u0170\u0171\u0172\u0173\u0174\u0175\u0176\u0177\u0178\u0179"
684     + "\u017a\u017b\u017c\u017d\u017e\u017f\u0192\u01a0\u01a1\u01af"
685     + "\u01b0\u01e6\u01e7\u01fa\u01fb\u01fc\u01fd\u01fe\u01ff\u0218"
686     + "\u0219\u02bc\u02bd\u02c6\u02c7\u02d8\u02d9\u02da\u02db\u02dc"
687     + "\u02dd\u0300\u0301\u0303\u0309\u0323\u0384\u0385\u0386\u0387"
688     + "\u0388\u0389\u038a\u038c\u038e\u038f\u0390\u0391\u0392\u0393"
689     + "\u0395\u0396\u0397\u0398\u0399\u039a\u039b\u039c\u039d\u039e"
690     + "\u039f\u03a0\u03a1\u03a3\u03a4\u03a5\u03a6\u03a7\u03a8\u03aa"
691     + "\u03ab\u03ac\u03ad\u03ae\u03af\u03b0\u03b1\u03b2\u03b3\u03b4"
692     + "\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bd\u03be\u03bf"
693     + "\u03c0\u03c1\u03c2\u03c3\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9"
694     + "\u03ca\u03cb\u03cc\u03cd\u03ce\u03d1\u03d2\u03d5\u03d6\u0401"
695     + "\u0402\u0403\u0404\u0405\u0406\u0407\u0408\u0409\u040a\u040b"
696     + "\u040c\u040e\u040f\u0410\u0411\u0412\u0413\u0414\u0415\u0416"
697     + "\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f\u0420"
698     + "\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a"
699     + "\u042b\u042c\u042d\u042e\u042f\u0430\u0431\u0432\u0433\u0434"
700     + "\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e"
701     + "\u043f\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448"
702     + "\u0449\u044a\u044b\u044c\u044d\u044e\u044f\u0451\u0452\u0453"
703     + "\u0454\u0455\u0456\u0457\u0458\u0459\u045a\u045b\u045c\u045e"
704     + "\u045f\u0462\u0463\u0472\u0473\u0474\u0475\u0490\u0491\u04d9"
705     + "\u05b0\u05b1\u05b2\u05b3\u05b4\u05b5\u05b6\u05b7\u05b8\u05b9"
706     + "\u05bb\u05bc\u05bd\u05be\u05bf\u05c0\u05c1\u05c2\u05c3\u05d0"
707     + "\u05d1\u05d2\u05d3\u05d4\u05d5\u05d6\u05d7\u05d8\u05d9\u05da"
708     + "\u05db\u05dc\u05dd\u05de\u05df\u05e0\u05e1\u05e2\u05e3\u05e4"
709     + "\u05e5\u05e6\u05e7\u05e8\u05e9\u05ea\u05f0\u05f1\u05f2\u060c"
710     + "\u061b\u061f\u0621\u0622\u0623\u0624\u0625\u0626\u0627\u0628"
711     + "\u0629\u062a\u062b\u062c\u062d\u062e\u062f\u0630\u0631\u0632"
712     + "\u0633\u0634\u0635\u0636\u0637\u0638\u0639\u063a\u0640\u0641"
713     + "\u0642\u0643\u0644\u0645\u0646\u0647\u0648\u0649\u064a\u064b"
714     + "\u064c\u064d\u064e\u064f\u0650\u0651\u0652\u0660\u0661\u0662"
715     + "\u0663\u0664\u0665\u0666\u0667\u0668\u0669\u066a\u066d\u0679"
716     + "\u067e\u0686\u0688\u0691\u0698\u06a4\u06af\u06ba\u06d2\u06d5"
717     + "\u1e80\u1e81\u1e82\u1e83\u1e84\u1e85\u1ef2\u1ef3\u200c\u200d"
718     + "\u200e\u200f\u2012\u2013\u2014\u2015\u2017\u2018\u2019\u201a"
719     + "\u201b\u201c\u201d\u201e\u2020\u2021\u2022\u2024\u2025\u2026"
720     + "\u202c\u202d\u202e\u2030\u2032\u2033\u2039\u203a\u203c\u2044"
721     + "\u20a1\u20a3\u20a4\u20a7\u20aa\u20ab\u20ac\u2105\u2111\u2113"
722     + "\u2116\u2118\u211c\u211e\u2122\u2126\u212e\u2135\u2153\u2154"
723     + "\u215b\u215c\u215d\u215e\u2190\u2191\u2192\u2193\u2194\u2195"
724     + "\u21a8\u21b5\u21d0\u21d1\u21d2\u21d3\u21d4\u2200\u2202\u2203"
725     + "\u2205\u2206\u2207\u2208\u2209\u220b\u220f\u2211\u2212\u2217"
726     + "\u221a\u221d\u221e\u221f\u2220\u2227\u2228\u2229\u222a\u222b"
727     + "\u2234\u223c\u2245\u2248\u2260\u2261\u2264\u2265\u2282\u2283"
728     + "\u2284\u2286\u2287\u2295\u2297\u22a5\u22c5\u2302\u2310\u2320"
729     + "\u2321\u2329\u232a\u2500\u2502\u250c\u2510\u2514\u2518\u251c"
730     + "\u2524\u252c\u2534\u253c\u2550\u2551\u2552\u2553\u2554\u2555"
731     + "\u2556\u2557\u2558\u2559\u255a\u255b\u255c\u255d\u255e\u255f"
732     + "\u2560\u2561\u2562\u2563\u2564\u2565\u2566\u2567\u2568\u2569"
733     + "\u256a\u256b\u256c\u2580\u2584\u2588\u258c\u2590\u2591\u2592"
734     + "\u2593\u25a0\u25a1\u25aa\u25ab\u25ac\u25b2\u25ba\u25bc\u25c4"
735     + "\u25ca\u25cb\u25cf\u25d8\u25d9\u25e6\u263a\u263b\u263c\u2640"
736     + "\u2642\u2660\u2663\u2665\u2666\u266a\u266b";
737 
738 
739   /**
740    * The offset of each glyph name in AGLFN_NAMES.
741    *
742    * Generated from the Adobe Glyph List for New Fonts, version 1.1
743    * of 17 April 2003.
744    *
745    * @see <a href=
746    * "http://partners.adobe.com/asn/tech/type/aglfn13.txt" >Adobe
747    * Glyph List for New Fonts</a>
748    */
749   private static final String AGLFN_NAME_OFFSET
750     = "\u0001\u0007\u000e\u0017\")1;GQ\\ejpw~\u0084\u0089\u008d"
751     + "\u0091\u0097\u009c\u00a1\u00a5\u00ab\u00b1\u00b6\u00bc\u00c6"
752     + "\u00cb\u00d1\u00d9\u00e2\u00e5\u00e7\u00e9\u00eb\u00ed\u00ef"
753     + "\u00f1\u00f3\u00f5\u00f7\u00f9\u00fb\u00fd\u00ff\u0101\u0103"
754     + "\u0105\u0107\u0109\u010b\u010d\u010f\u0111\u0113\u0115\u0117"
755     + "\u0119\u0125\u012f\u013c\u0148\u0153\u0159\u015b\u015d\u015f"
756     + "\u0161\u0163\u0165\u0167\u0169\u016b\u016d\u016f\u0171\u0173"
757     + "\u0175\u0177\u0179\u017b\u017d\u017f\u0181\u0183\u0185\u0187"
758     + "\u0189\u018b\u018d\u0197\u019b\u01a6\u01b1\u01bc\u01c1\u01ca"
759     + "\u01d3\u01d7\u01e1\u01e9\u01f2\u01fc\u0208\u0216\u0221\u022c"
760     + "\u0233\u023a\u0244\u024a\u024d\u0257\u0266\u026e\u027b\u028a"
761     + "\u0295\u029d\u02ab\u02b8\u02bf\u02c6\u02d2\u02d9\u02e3\u02e9"
762     + "\u02ec\u02f5\u02fc\u0303\u030f\u0319\u0320\u0327\u0333\u033d"
763     + "\u0341\u0348\u034f\u0356\u0362\u0369\u0373\u037c\u0383\u038a"
764     + "\u0391\u039d\u03a7\u03ae\u03b4\u03bf\u03c6\u03cd\u03d9\u03e0"
765     + "\u03ea\u03f0\u03f3\u03fc\u0403\u040a\u0416\u0420\u0427\u042e"
766     + "\u043a\u0444\u0448\u044f\u0456\u045d\u0469\u0470\u047a\u0481"
767     + "\u0488\u048f\u0496\u04a2\u04ac\u04b3\u04b9\u04c3\u04cb\u04d3"
768     + "\u04da\u04e1\u04e9\u04f1\u04f8\u04ff\u050b\u0517\u0522\u052d"
769     + "\u0534\u053b\u0542\u0549\u0550\u0557\u055f\u0567\u056e\u0575"
770     + "\u0580\u058b\u0593\u059b\u05a2\u05a9\u05b5\u05c1\u05c8\u05cf"
771     + "\u05da\u05e5\u05f2\u05ff\u060b\u0617\u061c\u0621\u0628\u062f"
772     + "\u0637\u063f\u0646\u064d\u0655\u065d\u0668\u0671\u0674\u0677"
773     + "\u0683\u068f\u069c\u06a9\u06b6\u06bd\u06c4\u06d1\u06de\u06e5"
774     + "\u06ec\u06f1\u06f6\u06fd\u0704\u070b\u0712\u071f\u072c\u0733"
775     + "\u073a\u0746\u074a\u074e\u0756\u075e\u0765\u076c\u077a\u0788"
776     + "\u078b\u078e\u0795\u079c\u07a9\u07b6\u07bd\u07c4\u07cb\u07d2"
777     + "\u07de\u07ea\u07f3\u07fc\u0803\u080a\u0817\u0824\u082b\u0832"
778     + "\u0837\u083c\u0843\u084a\u0852\u085a\u0861\u0868\u086e\u0874"
779     + "\u0882\u0890\u0898\u08a0\u08ac\u08b8\u08c4\u08d0\u08da\u08e1"
780     + "\u08e8\u08f3\u08fe\u0905\u090c\u0912\u0919\u091f\u0925\u092b"
781     + "\u0931\u0938\u093f\u094a\u0955\u095d\u0965\u0971\u097d\u098a"
782     + "\u0997\u09a1\u09ab\u09b6\u09bc\u09c2\u09cc\u09d1\u09d8\u09de"
783     + "\u09eb\u09f5\u09ff\u0a09\u0a17\u0a24\u0a2a\u0a38\u0a43\u0a4d"
784     + "\u0a5a\u0a63\u0a6d\u0a7a\u0a87\u0a92\u0aa4\u0aaa\u0aaf\u0ab5"
785     + "\u0abd\u0ac2\u0ac6\u0acc\u0ad1\u0ad7\u0ade\u0ae1\u0ae4\u0ae7"
786     + "\u0aef\u0af2\u0af6\u0afc\u0b00\u0b08\u0b0c\u0b10\u0b14\u0b21"
787     + "\u0b31\u0b3c\u0b49\u0b52\u0b5c\u0b71\u0b77\u0b7c\u0b82\u0b88"
788     + "\u0b90\u0b95\u0b99\u0b9f\u0ba4\u0baa\u0bb1\u0bb4\u0bb7\u0bbf"
789     + "\u0bc2\u0bc6\u0bcd\u0bd3\u0bd7\u0bdf\u0be3\u0be7\u0beb\u0bf1"
790     + "\u0bfe\u0c0e\u0c1b\u0c28\u0c33\u0c3a\u0c43\u0c48\u0c4f\u0c59"
791     + "\u0c63\u0c6d\u0c77\u0c81\u0c8b\u0c95\u0c9f\u0ca9\u0cb3\u0cbd"
792     + "\u0cc7\u0cd1\u0cdb\u0ce5\u0cef\u0cf9\u0d03\u0d0d\u0d17\u0d21"
793     + "\u0d2b\u0d35\u0d3f\u0d49\u0d53\u0d5d\u0d67\u0d71\u0d7b\u0d85"
794     + "\u0d8f\u0d99\u0da3\u0dad\u0db7\u0dc1\u0dcb\u0dd5\u0ddf\u0de9"
795     + "\u0df3\u0dfd\u0e07\u0e11\u0e1b\u0e25\u0e2f\u0e39\u0e43\u0e4d"
796     + "\u0e57\u0e61\u0e6b\u0e75\u0e7f\u0e89\u0e93\u0e9d\u0ea7\u0eb1"
797     + "\u0ebb\u0ec5\u0ecf\u0ed9\u0ee3\u0eed\u0ef7\u0f01\u0f0b\u0f15"
798     + "\u0f1f\u0f29\u0f33\u0f3d\u0f47\u0f51\u0f5b\u0f65\u0f6f\u0f79"
799     + "\u0f83\u0f8d\u0f97\u0fa1\u0fab\u0fb5\u0fbf\u0fc9\u0fd3\u0fdd"
800     + "\u0fe7\u0ff1\u0ffb\u1005\u100f\u1019\u1023\u102d\u1037\u1041"
801     + "\u104b\u1055\u105f\u1069\u1073\u107d\u1087\u1091\u109b\u10a5"
802     + "\u10af\u10b9\u10c3\u10cd\u10d7\u10e1\u10eb\u10f5\u10ff\u1109"
803     + "\u1113\u111d\u1127\u1131\u113b\u1145\u114f\u1159\u1163\u116d"
804     + "\u1177\u1181\u118b\u1195\u119f\u11a9\u11b3\u11bd\u11c7\u11d1"
805     + "\u11db\u11e5\u11ef\u11f9\u1203\u120d\u1217\u1221\u122b\u1235"
806     + "\u123f\u1249\u1253\u125d\u1267\u1271\u127b\u1285\u128f\u1299"
807     + "\u12a3\u12ad\u12b7\u12c1\u12cb\u12d5\u12df\u12e9\u12f3\u12fd"
808     + "\u1307\u1311\u131b\u1325\u132f\u1339\u1343\u134d\u1357\u1361"
809     + "\u136b\u1375\u137f\u1389\u1393\u139d\u13a7\u13b1\u13bb\u13c5"
810     + "\u13cf\u13d9\u13e3\u13ed\u13f7\u1401\u140b\u1415\u141f\u1429"
811     + "\u1433\u143d\u1447\u1451\u145b\u1465\u146f\u1479\u1483\u148d"
812     + "\u1497\u14a1\u14ab\u14b5\u14bf\u14c9\u14d3\u14dd\u14e7\u14f1"
813     + "\u14f8\u14ff\u1506\u150d\u1517\u1521\u1528\u152f\u1539\u1541"
814     + "\u1549\u1551\u155c\u1563\u156a\u1574\u1582\u158c\u1597\u15a6"
815     + "\u15b4\u15c1\u15cf\u15dc\u15e3\u15ed\u15f4\u1603\u1612\u161b"
816     + "\u1625\u162f\u1639\u1645\u164c\u1653\u1661\u1670\u167a\u1683"
817     + "\u1691\u1697\u169c\u16a3\u16ad\u16b2\u16b7\u16c1\u16ca\u16d4"
818     + "\u16de\u16ea\u16f3\u1700\u170a\u1710\u171a\u1720\u1729\u1733"
819     + "\u173d\u174a\u1756\u1763\u176d\u1775\u1780\u178a\u1794\u179e"
820     + "\u17ab\u17ba\u17c7\u17d2\u17e0\u17ed\u17fa\u1804\u1810\u181c"
821     + "\u1825\u182b\u1834\u183c\u1847\u1850\u1858\u1862\u1868\u1875"
822     + "\u187d\u188a\u1893\u189e\u18a4\u18af\u18b9\u18c6\u18cc\u18d5"
823     + "\u18df\u18e7\u18f1\u18fd\u1906\u1912\u191c\u1929\u1936\u1945"
824     + "\u194f\u195c\u196b\u1976\u1985\u1993\u199b\u19a1\u19af\u19ba"
825     + "\u19c5\u19cf\u19da\u19e3\u19ec\u19f5\u19fe\u1a07\u1a10\u1a19"
826     + "\u1a22\u1a2b\u1a34\u1a3d\u1a46\u1a4f\u1a58\u1a61\u1a6a\u1a73"
827     + "\u1a7c\u1a85\u1a8e\u1a97\u1aa0\u1aa9\u1ab2\u1abb\u1ac4\u1acd"
828     + "\u1ad6\u1adf\u1ae8\u1af1\u1afa\u1b03\u1b0c\u1b15\u1b1e\u1b27"
829     + "\u1b30\u1b39\u1b42\u1b4a\u1b52\u1b58\u1b60\u1b68\u1b70\u1b76"
830     + "\u1b7e\u1b88\u1b8f\u1b96\u1b9d\u1ba8\u1bb0\u1bb8\u1bc0\u1bc8"
831     + "\u1bd0\u1bd7\u1bde\u1be8\u1bf2\u1bfd\u1c07\u1c14\u1c18\u1c1f"
832     + "\u1c24\u1c2a\u1c2f\u1c35\u1c3d\u1c49";
833 
834 
835   /**
836    * The name of each glyph in the Adobe Glyph List for New Fonts
837    * (AGLFN). The name of the n-th glyph starts at position
838    * AGLFN_NAME_OFFSET.charAt(n). It ends before the following
839    * slash (slashes cannot be part of a PostScript name, which
840    * is why we use it for separation).
841    *
842    * <p>Generated from the Adobe Glyph List for New Fonts, version 1.1
843    * of 17 April 2003.
844    *
845    * @see <a href=
846    * "http://partners.adobe.com/asn/tech/type/aglfn13.txt" >Adobe
847    * Glyph List for New Fonts</a>
848    */
849   private static final String AGLFN_NAMES
850     = "/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/q"
851     + "uotesingle/parenleft/parenright/asterisk/plus/comma/hyphen/p"
852     + "eriod/slash/zero/one/two/three/four/five/six/seven/eight/nin"
853     + "e/colon/semicolon/less/equal/greater/question/at/A/B/C/D/E/F"
854     + "/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backsla"
855     + "sh/bracketright/asciicircum/underscore/grave/a/b/c/d/e/f/g/h"
856     + "/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/bracerigh"
857     + "t/asciitilde/exclamdown/cent/sterling/currency/yen/brokenbar"
858     + "/section/dieresis/copyright/ordfeminine/guillemotleft/logica"
859     + "lnot/registered/macron/degree/plusminus/acute/mu/paragraph/p"
860     + "eriodcentered/cedilla/ordmasculine/guillemotright/onequarter"
861     + "/onehalf/threequarters/questiondown/Agrave/Aacute/Acircumfle"
862     + "x/Atilde/Adieresis/Aring/AE/Ccedilla/Egrave/Eacute/Ecircumfl"
863     + "ex/Edieresis/Igrave/Iacute/Icircumflex/Idieresis/Eth/Ntilde/"
864     + "Ograve/Oacute/Ocircumflex/Otilde/Odieresis/multiply/Oslash/U"
865     + "grave/Uacute/Ucircumflex/Udieresis/Yacute/Thorn/germandbls/a"
866     + "grave/aacute/acircumflex/atilde/adieresis/aring/ae/ccedilla/"
867     + "egrave/eacute/ecircumflex/edieresis/igrave/iacute/icircumfle"
868     + "x/idieresis/eth/ntilde/ograve/oacute/ocircumflex/otilde/odie"
869     + "resis/divide/oslash/ugrave/uacute/ucircumflex/udieresis/yacu"
870     + "te/thorn/ydieresis/Amacron/amacron/Abreve/abreve/Aogonek/aog"
871     + "onek/Cacute/cacute/Ccircumflex/ccircumflex/Cdotaccent/cdotac"
872     + "cent/Ccaron/ccaron/Dcaron/dcaron/Dcroat/dcroat/Emacron/emacr"
873     + "on/Ebreve/ebreve/Edotaccent/edotaccent/Eogonek/eogonek/Ecaro"
874     + "n/ecaron/Gcircumflex/gcircumflex/Gbreve/gbreve/Gdotaccent/gd"
875     + "otaccent/Gcommaaccent/gcommaaccent/Hcircumflex/hcircumflex/H"
876     + "bar/hbar/Itilde/itilde/Imacron/imacron/Ibreve/ibreve/Iogonek"
877     + "/iogonek/Idotaccent/dotlessi/IJ/ij/Jcircumflex/jcircumflex/K"
878     + "commaaccent/kcommaaccent/kgreenlandic/Lacute/lacute/Lcommaac"
879     + "cent/lcommaaccent/Lcaron/lcaron/Ldot/ldot/Lslash/lslash/Nacu"
880     + "te/nacute/Ncommaaccent/ncommaaccent/Ncaron/ncaron/napostroph"
881     + "e/Eng/eng/Omacron/omacron/Obreve/obreve/Ohungarumlaut/ohunga"
882     + "rumlaut/OE/oe/Racute/racute/Rcommaaccent/rcommaaccent/Rcaron"
883     + "/rcaron/Sacute/sacute/Scircumflex/scircumflex/Scedilla/scedi"
884     + "lla/Scaron/scaron/Tcommaaccent/tcommaaccent/Tcaron/tcaron/Tb"
885     + "ar/tbar/Utilde/utilde/Umacron/umacron/Ubreve/ubreve/Uring/ur"
886     + "ing/Uhungarumlaut/uhungarumlaut/Uogonek/uogonek/Wcircumflex/"
887     + "wcircumflex/Ycircumflex/ycircumflex/Ydieresis/Zacute/zacute/"
888     + "Zdotaccent/zdotaccent/Zcaron/zcaron/longs/florin/Ohorn/ohorn"
889     + "/Uhorn/uhorn/Gcaron/gcaron/Aringacute/aringacute/AEacute/aea"
890     + "cute/Oslashacute/oslashacute/Scommaaccent/scommaaccent/afii5"
891     + "7929/afii64937/circumflex/caron/breve/dotaccent/ring/ogonek/"
892     + "tilde/hungarumlaut/gravecomb/acutecomb/tildecomb/hookaboveco"
893     + "mb/dotbelowcomb/tonos/dieresistonos/Alphatonos/anoteleia/Eps"
894     + "ilontonos/Etatonos/Iotatonos/Omicrontonos/Upsilontonos/Omega"
895     + "tonos/iotadieresistonos/Alpha/Beta/Gamma/Epsilon/Zeta/Eta/Th"
896     + "eta/Iota/Kappa/Lambda/Mu/Nu/Xi/Omicron/Pi/Rho/Sigma/Tau/Upsi"
897     + "lon/Phi/Chi/Psi/Iotadieresis/Upsilondieresis/alphatonos/epsi"
898     + "lontonos/etatonos/iotatonos/upsilondieresistonos/alpha/beta/"
899     + "gamma/delta/epsilon/zeta/eta/theta/iota/kappa/lambda/nu/xi/o"
900     + "micron/pi/rho/sigma1/sigma/tau/upsilon/phi/chi/psi/omega/iot"
901     + "adieresis/upsilondieresis/omicrontonos/upsilontonos/omegaton"
902     + "os/theta1/Upsilon1/phi1/omega1/afii10023/afii10051/afii10052"
903     + "/afii10053/afii10054/afii10055/afii10056/afii10057/afii10058"
904     + "/afii10059/afii10060/afii10061/afii10062/afii10145/afii10017"
905     + "/afii10018/afii10019/afii10020/afii10021/afii10022/afii10024"
906     + "/afii10025/afii10026/afii10027/afii10028/afii10029/afii10030"
907     + "/afii10031/afii10032/afii10033/afii10034/afii10035/afii10036"
908     + "/afii10037/afii10038/afii10039/afii10040/afii10041/afii10042"
909     + "/afii10043/afii10044/afii10045/afii10046/afii10047/afii10048"
910     + "/afii10049/afii10065/afii10066/afii10067/afii10068/afii10069"
911     + "/afii10070/afii10072/afii10073/afii10074/afii10075/afii10076"
912     + "/afii10077/afii10078/afii10079/afii10080/afii10081/afii10082"
913     + "/afii10083/afii10084/afii10085/afii10086/afii10087/afii10088"
914     + "/afii10089/afii10090/afii10091/afii10092/afii10093/afii10094"
915     + "/afii10095/afii10096/afii10097/afii10071/afii10099/afii10100"
916     + "/afii10101/afii10102/afii10103/afii10104/afii10105/afii10106"
917     + "/afii10107/afii10108/afii10109/afii10110/afii10193/afii10146"
918     + "/afii10194/afii10147/afii10195/afii10148/afii10196/afii10050"
919     + "/afii10098/afii10846/afii57799/afii57801/afii57800/afii57802"
920     + "/afii57793/afii57794/afii57795/afii57798/afii57797/afii57806"
921     + "/afii57796/afii57807/afii57839/afii57645/afii57841/afii57842"
922     + "/afii57804/afii57803/afii57658/afii57664/afii57665/afii57666"
923     + "/afii57667/afii57668/afii57669/afii57670/afii57671/afii57672"
924     + "/afii57673/afii57674/afii57675/afii57676/afii57677/afii57678"
925     + "/afii57679/afii57680/afii57681/afii57682/afii57683/afii57684"
926     + "/afii57685/afii57686/afii57687/afii57688/afii57689/afii57690"
927     + "/afii57716/afii57717/afii57718/afii57388/afii57403/afii57407"
928     + "/afii57409/afii57410/afii57411/afii57412/afii57413/afii57414"
929     + "/afii57415/afii57416/afii57417/afii57418/afii57419/afii57420"
930     + "/afii57421/afii57422/afii57423/afii57424/afii57425/afii57426"
931     + "/afii57427/afii57428/afii57429/afii57430/afii57431/afii57432"
932     + "/afii57433/afii57434/afii57440/afii57441/afii57442/afii57443"
933     + "/afii57444/afii57445/afii57446/afii57470/afii57448/afii57449"
934     + "/afii57450/afii57451/afii57452/afii57453/afii57454/afii57455"
935     + "/afii57456/afii57457/afii57458/afii57392/afii57393/afii57394"
936     + "/afii57395/afii57396/afii57397/afii57398/afii57399/afii57400"
937     + "/afii57401/afii57381/afii63167/afii57511/afii57506/afii57507"
938     + "/afii57512/afii57513/afii57508/afii57505/afii57509/afii57514"
939     + "/afii57519/afii57534/Wgrave/wgrave/Wacute/wacute/Wdieresis/w"
940     + "dieresis/Ygrave/ygrave/afii61664/afii301/afii299/afii300/fig"
941     + "uredash/endash/emdash/afii00208/underscoredbl/quoteleft/quot"
942     + "eright/quotesinglbase/quotereversed/quotedblleft/quotedblrig"
943     + "ht/quotedblbase/dagger/daggerdbl/bullet/onedotenleader/twodo"
944     + "tenleader/ellipsis/afii61573/afii61574/afii61575/perthousand"
945     + "/minute/second/guilsinglleft/guilsinglright/exclamdbl/fracti"
946     + "on/colonmonetary/franc/lira/peseta/afii57636/dong/Euro/afii6"
947     + "1248/Ifraktur/afii61289/afii61352/weierstrass/Rfraktur/presc"
948     + "ription/trademark/Omega/estimated/aleph/onethird/twothirds/o"
949     + "neeighth/threeeighths/fiveeighths/seveneighths/arrowleft/arr"
950     + "owup/arrowright/arrowdown/arrowboth/arrowupdn/arrowupdnbse/c"
951     + "arriagereturn/arrowdblleft/arrowdblup/arrowdblright/arrowdbl"
952     + "down/arrowdblboth/universal/partialdiff/existential/emptyset"
953     + "/Delta/gradient/element/notelement/suchthat/product/summatio"
954     + "n/minus/asteriskmath/radical/proportional/infinity/orthogona"
955     + "l/angle/logicaland/logicalor/intersection/union/integral/the"
956     + "refore/similar/congruent/approxequal/notequal/equivalence/le"
957     + "ssequal/greaterequal/propersubset/propersuperset/notsubset/r"
958     + "eflexsubset/reflexsuperset/circleplus/circlemultiply/perpend"
959     + "icular/dotmath/house/revlogicalnot/integraltp/integralbt/ang"
960     + "leleft/angleright/SF100000/SF110000/SF010000/SF030000/SF0200"
961     + "00/SF040000/SF080000/SF090000/SF060000/SF070000/SF050000/SF4"
962     + "30000/SF240000/SF510000/SF520000/SF390000/SF220000/SF210000/"
963     + "SF250000/SF500000/SF490000/SF380000/SF280000/SF270000/SF2600"
964     + "00/SF360000/SF370000/SF420000/SF190000/SF200000/SF230000/SF4"
965     + "70000/SF480000/SF410000/SF450000/SF460000/SF400000/SF540000/"
966     + "SF530000/SF440000/upblock/dnblock/block/lfblock/rtblock/ltsh"
967     + "ade/shade/dkshade/filledbox/H22073/H18543/H18551/filledrect/"
968     + "triagup/triagrt/triagdn/triaglf/lozenge/circle/H18533/invbul"
969     + "let/invcircle/openbullet/smileface/invsmileface/sun/female/m"
970     + "ale/spade/club/heart/diamond/musicalnote/musicalnotedbl/";
971 
972 
973   /**
974    * Determines the name of a glyph according to the Adobe Glyph List
975    * for New Fonts (AGLFN). Because all glyphs in AGLFN correspond to
976    * a precomposed Unicode codepoint, the mismatch between characters
977    * and glyphs is not an issue here.
978    *
979    * @param c the Unicode codepoint that corresponds to the glyph, for
980    * example <code>0x010a</code> for <code>LATIN CAPITAL LETTER C WITH
981    * DOT ABOVE</code>.
982    *
983    * @return the glyph name, for example <code>Cdotaccent</code>. If
984    * the glyph is not in the <i>Adobe Glyph List for New Fonts</i>,
985    * <code>null</code> is returned.
986    *
987    * @see <a href=
988    * "http://partners.adobe.com/asn/tech/type/aglfn13.txt" >Adobe
989    * Glyph List for New Fonts (AGLFN), version 1.1 of April 17,
990    * 2003</a>
991    *
992    * @see <a href=
993    * "http://partners.adobe.com/asn/developer/type/unicodegn.html#6"
994    * >Adobe&#x2019;s guidelines related to Unicode</a>
995    */
996   private static String getAGLFNName(char c)
997   {
998     int min, max, mid;
999     char midChar;
1000
1001    /* Performs a binary search in the sorted array (actually, a
1002     * String) of glyphs in the Adobe Glyph List for New Fonts.
1003     *
1004     * A good compiler might be able to optimize a call to charAt for
1005     * a static final String, but this routine is probably not that
1006     * critical to performance.
1007     */
1008    min = 0;
1009    max = AGLFN_GLYPHS.length() - 1;
1010    mid = max >> 1;    
1011    midChar = AGLFN_GLYPHS.charAt(mid);
1012    do
1013    {
1014      if (midChar == c)
1015        break;
1016      else if (midChar < c)
1017        min = mid + 1;
1018      else
1019        max = mid;
1020      mid = (min + max) >> 1;
1021      midChar = AGLFN_GLYPHS.charAt(mid);
1022    }
1023    while (min < max);
1024    
1025    if (midChar != c)
1026      return null;
1027
1028    int pos = AGLFN_NAME_OFFSET.charAt(mid);
1029    return AGLFN_NAMES.substring(pos, AGLFN_NAMES.indexOf('/', pos));
1030  }
1031
1032
1033  /**
1034   * Returns the PostScript name of a glyph, given the sequence of
1035   * Unicode characters that is required to produce the glyph.  The
1036   * returned name follows Adobe&#x2019;s glyph naming recommendations
1037   * in order to allow searching and indexing of the produced
1038   * PostScript and PDF.
1039   *
1040   * <p>Some examples:
1041   * <ul><li><code>U+0041</code> gives <code>A</code>;</li>
1042   * <li><code>U+011D</code> gives <code>gcircumflex</code>;</li>
1043   * <li><code>U+007A U+0302</code> gives <code>z_uni0302</code>;</li>
1044   * <li><code>U+D807 U+DC42</code> (an UTF-16 escape sequence)
1045   * gives <code>u11C42</code>;</li>
1046   *  </ul>.
1047   *
1048   * <p>The routine does <i>not</i> bring sequences in any canonical
1049   * form. Therefore, the result for <code>U+0067 U+0302</code> (the
1050   * decomposition of <code>U+011D</code>) will be
1051   * <code>g_uni0302</code>, not <code>gcircumflex</code>.
1052   *
1053   * @see <a href=
1054   * "http://partners.adobe.com/asn/tech/type/unicodegn.jsp" >Unicode
1055   * and Glyph Names</a> and <a href=
1056   * "http://partners.adobe.com/asn/tech/type/glyphnamelimits.jsp"
1057   * >Glyph Names and Current Implementations</a>
1058   */
1059  private static String getGlyphName(char[] chars)
1060  {
1061    char c;
1062    String name;
1063    int numChars;
1064    boolean hasSurrogates = false;
1065
1066    if ((chars == null) || ((numChars = chars.length) == 0))
1067      return ".notdef";
1068
1069    /* The vast majority of cases will be just a single character.
1070     * Therefore, we have a special code path for this case.
1071     */
1072    if (numChars == 1)
1073    {
1074      c = chars[0];
1075      name = getAGLFNName(c);
1076      if (name != null)
1077        return name;
1078    }
1079    
1080    StringBuffer buf = new StringBuffer(numChars * 8);
1081    for (int i = 0; i < numChars; i++)
1082    {
1083      if (i > 0)
1084        buf.append('_');
1085      c = chars[i];
1086
1087      /* handle surrogate pairs */
1088      if (c >> 10 == 0x36) // U+D800 .. U+DBFF: High surrogate
1089      {
1090        /* Adobe recommends using the 'u' prefix only for
1091         * characters outside the Unicode Basic Multilingual Plane,
1092         * because Acrobat 4 and 5 understand only the "uni" prefix.
1093         * The 'u' prefix will be supported by Acrobat 6 and later.
1094         *
1095         * For further information, please refer to this page:
1096         * http://partners.adobe.com/asn/tech/type/glyphnamelimits.jsp#3
1097         */
1098        int ucs4 = (((c & 0x3ff) << 10) | (chars[++i] & 0x3ff)) + 0x10000;
1099        buf.append('u');
1100        buf.append(Integer.toHexString(ucs4).toUpperCase());
1101      }
1102      else
1103      {
1104        /* Try the Adobe Glyph List. */
1105        name = getAGLFNName(c);
1106        if (name != null)
1107          buf.append(name);
1108        else
1109        {
1110          char nibble;
1111          buf.append("uni");
1112          nibble = (char) (((c >> 12) & 0xf) + 0x30);
1113          if (nibble > 0x39)
1114            nibble += 7;
1115          buf.append(nibble);
1116          nibble = (char) (((c >> 8) & 0xf) + 0x30);
1117          if (nibble > 0x39)
1118            nibble += 7;
1119          buf.append(nibble);
1120          nibble = (char) (((c >> 4) & 0xf) + 0x30);
1121          if (nibble > 0x39)
1122            nibble += 7;
1123          buf.append(nibble);
1124          nibble = (char) (((c >> 0) & 0xf) + 0x30);
1125          if (nibble > 0x39)
1126            nibble += 7;
1127          buf.append(nibble);
1128        }
1129      }
1130    }
1131    return buf.toString();
1132  }
1133}