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’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’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’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’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}